feat(@desktop/chat): display fetch messages when needed
- it only applies to community chats closes: #6731
This commit is contained in:
parent
98b4aa849e
commit
1218de67b9
|
@ -176,6 +176,12 @@ proc init*(self: Controller) =
|
||||||
return
|
return
|
||||||
self.delegate.onChatMemberUpdated(args.id, args.admin, args.joined)
|
self.delegate.onChatMemberUpdated(args.id, args.admin, args.joined)
|
||||||
|
|
||||||
|
self.events.on(SIGNAL_MAILSERVER_SYNCED) do(e: Args):
|
||||||
|
let args = MailserverSyncedArgs(e)
|
||||||
|
if (args.chatId != self.chatId):
|
||||||
|
return
|
||||||
|
self.delegate.onMailserverSynced(args.syncedFrom)
|
||||||
|
|
||||||
proc getMySectionId*(self: Controller): string =
|
proc getMySectionId*(self: Controller): string =
|
||||||
return self.sectionId
|
return self.sectionId
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,9 @@ method getModuleAsVariant*(self: AccessInterface): QVariant {.base.} =
|
||||||
method updateChatIdentifier*(self: AccessInterface) {.base.} =
|
method updateChatIdentifier*(self: AccessInterface) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method updateChatFetchMoreMessages*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method newMessagesLoaded*(self: AccessInterface, messages: seq[MessageDto], reactions: seq[ReactionDto],
|
method newMessagesLoaded*(self: AccessInterface, messages: seq[MessageDto], reactions: seq[ReactionDto],
|
||||||
pinnedMessages: seq[PinnedMessageDto]) {.base.} =
|
pinnedMessages: seq[PinnedMessageDto]) {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
@ -79,7 +82,7 @@ method getSectionId*(self: AccessInterface): string {.base.} =
|
||||||
|
|
||||||
method getChatId*(self: AccessInterface): string {.base.} =
|
method getChatId*(self: AccessInterface): string {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getChatType*(self: AccessInterface): int {.base.} =
|
method getChatType*(self: AccessInterface): int {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
@ -129,4 +132,7 @@ method didIJoinedChat*(self: AccessInterface): bool {.base.} =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
method getMessages*(self: AccessInterface): seq[message_item.Item] =
|
method getMessages*(self: AccessInterface): seq[message_item.Item] =
|
||||||
raise newException(ValueError, "No implementation available")
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method onMailserverSynced*(self: AccessInterface, syncedFrom: int64) =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
|
@ -60,7 +60,8 @@ method isLoaded*(self: Module): bool =
|
||||||
return self.moduleLoaded
|
return self.moduleLoaded
|
||||||
|
|
||||||
method viewDidLoad*(self: Module) =
|
method viewDidLoad*(self: Module) =
|
||||||
self.view.model().appendItem(self.createFetchMoreMessagesItem())
|
if self.controller.getChatDetails().hasMoreMessagesToRequest():
|
||||||
|
self.view.model().appendItem(self.createFetchMoreMessagesItem())
|
||||||
self.view.model().appendItem(self.createChatIdentifierItem())
|
self.view.model().appendItem(self.createChatIdentifierItem())
|
||||||
|
|
||||||
self.moduleLoaded = true
|
self.moduleLoaded = true
|
||||||
|
@ -237,7 +238,8 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
|
||||||
# messages are sorted from the most recent to the least recent one
|
# messages are sorted from the most recent to the least recent one
|
||||||
viewItems.add(item)
|
viewItems.add(item)
|
||||||
|
|
||||||
viewItems.add(self.createFetchMoreMessagesItem())
|
if self.controller.getChatDetails().hasMoreMessagesToRequest():
|
||||||
|
viewItems.add(self.createFetchMoreMessagesItem())
|
||||||
viewItems.add(self.createChatIdentifierItem())
|
viewItems.add(self.createChatIdentifierItem())
|
||||||
self.view.model().removeItem(FETCH_MORE_MESSAGES_MESSAGE_ID)
|
self.view.model().removeItem(FETCH_MORE_MESSAGES_MESSAGE_ID)
|
||||||
self.view.model().removeItem(CHAT_IDENTIFIER_MESSAGE_ID)
|
self.view.model().removeItem(CHAT_IDENTIFIER_MESSAGE_ID)
|
||||||
|
@ -466,6 +468,12 @@ method updateChatIdentifier*(self: Module) =
|
||||||
# Add new loaded messages
|
# Add new loaded messages
|
||||||
self.view.model().appendItem(self.createChatIdentifierItem())
|
self.view.model().appendItem(self.createChatIdentifierItem())
|
||||||
|
|
||||||
|
method updateChatFetchMoreMessages*(self: Module) =
|
||||||
|
self.view.model().removeItem(FETCH_MORE_MESSAGES_MESSAGE_ID)
|
||||||
|
|
||||||
|
if (self.controller.getChatDetails().hasMoreMessagesToRequest()):
|
||||||
|
self.view.model().appendItem(self.createFetchMoreMessagesItem())
|
||||||
|
|
||||||
method getLinkPreviewData*(self: Module, link: string, uuid: string): string =
|
method getLinkPreviewData*(self: Module, link: string, uuid: string): string =
|
||||||
return self.controller.getLinkPreviewData(link, uuid)
|
return self.controller.getLinkPreviewData(link, uuid)
|
||||||
|
|
||||||
|
@ -507,3 +515,8 @@ method onChatMemberUpdated*(self: Module, publicKey: string, admin: bool, joined
|
||||||
|
|
||||||
method getMessages*(self: Module): seq[message_item.Item] =
|
method getMessages*(self: Module): seq[message_item.Item] =
|
||||||
return self.view.model().items
|
return self.view.model().items
|
||||||
|
|
||||||
|
method onMailserverSynced*(self: Module, syncedFrom: int64) =
|
||||||
|
let chatDto = self.controller.getChatDetails()
|
||||||
|
if (not chatDto.hasMoreMessagesToRequest(syncedFrom)):
|
||||||
|
self.view.model().removeItem(FETCH_MORE_MESSAGES_MESSAGE_ID)
|
||||||
|
|
|
@ -340,6 +340,7 @@ method onNotificationsUpdated*(self: Module, hasUnreadMessages: bool, notificati
|
||||||
|
|
||||||
method onChatEdited*(self: Module, chatDto: ChatDto) =
|
method onChatEdited*(self: Module, chatDto: ChatDto) =
|
||||||
self.view.updateChatDetails(chatDto.name, chatDto.description, chatDto.emoji, chatDto.color, chatDto.icon, chatDto.chatType == ChatType.OneToOne)
|
self.view.updateChatDetails(chatDto.name, chatDto.description, chatDto.emoji, chatDto.color, chatDto.icon, chatDto.chatType == ChatType.OneToOne)
|
||||||
|
self.messagesModule.updateChatFetchMoreMessages()
|
||||||
self.messagesModule.updateChatIdentifier()
|
self.messagesModule.updateChatIdentifier()
|
||||||
|
|
||||||
method onChatRenamed*(self: Module, newName: string) =
|
method onChatRenamed*(self: Module, newName: string) =
|
||||||
|
|
|
@ -75,6 +75,7 @@ type ChatDto* = object
|
||||||
joined*: int64 # indicates when the user joined the chat last time
|
joined*: int64 # indicates when the user joined the chat last time
|
||||||
syncedTo*: int64
|
syncedTo*: int64
|
||||||
syncedFrom*: int64
|
syncedFrom*: int64
|
||||||
|
firstMessageTimestamp: int64 # valid only for community chats, 0 - undefined, 1 - no messages, >1 valid timestamps
|
||||||
canPost*: bool
|
canPost*: bool
|
||||||
position*: int
|
position*: int
|
||||||
categoryId*: string
|
categoryId*: string
|
||||||
|
@ -132,6 +133,7 @@ proc `$`*(self: ChatDto): string =
|
||||||
canPost: {self.canPost},
|
canPost: {self.canPost},
|
||||||
syncedTo: {self.syncedTo},
|
syncedTo: {self.syncedTo},
|
||||||
syncedFrom: {self.syncedFrom},
|
syncedFrom: {self.syncedFrom},
|
||||||
|
firstMessageTimestamp: {self.firstMessageTimestamp},
|
||||||
categoryId: {self.categoryId},
|
categoryId: {self.categoryId},
|
||||||
position: {self.position},
|
position: {self.position},
|
||||||
highlight: {self.highlight}
|
highlight: {self.highlight}
|
||||||
|
@ -219,6 +221,7 @@ proc toChatDto*(jsonObj: JsonNode): ChatDto =
|
||||||
discard jsonObj.getProp("joined", result.joined)
|
discard jsonObj.getProp("joined", result.joined)
|
||||||
discard jsonObj.getProp("syncedTo", result.syncedTo)
|
discard jsonObj.getProp("syncedTo", result.syncedTo)
|
||||||
discard jsonObj.getProp("syncedFrom", result.syncedFrom)
|
discard jsonObj.getProp("syncedFrom", result.syncedFrom)
|
||||||
|
discard jsonObj.getProp("firstMessageTimestamp", result.firstMessageTimestamp)
|
||||||
discard jsonObj.getProp("highlight", result.highlight)
|
discard jsonObj.getProp("highlight", result.highlight)
|
||||||
var permissionObj: JsonNode
|
var permissionObj: JsonNode
|
||||||
if(jsonObj.getProp("permissions", permissionObj)):
|
if(jsonObj.getProp("permissions", permissionObj)):
|
||||||
|
@ -309,3 +312,21 @@ proc isPublicChat*(chatDto: ChatDto): bool =
|
||||||
|
|
||||||
proc isOneToOneChat*(chatDto: ChatDto): bool =
|
proc isOneToOneChat*(chatDto: ChatDto): bool =
|
||||||
return chatDto.chatType == ChatType.OneToOne
|
return chatDto.chatType == ChatType.OneToOne
|
||||||
|
|
||||||
|
proc hasMoreMessagesToRequest*(chatDto: ChatDto, syncedFrom: int64): bool =
|
||||||
|
# only for community chat we can determine the first message ever sent to the chat
|
||||||
|
if chatDto.chatType != ChatType.CommunityChat:
|
||||||
|
return true
|
||||||
|
|
||||||
|
const firstMessageTimestampUndefined = 0
|
||||||
|
const firstMessageTimestampNoMessages = 1
|
||||||
|
|
||||||
|
if chatDto.firstMessageTimestamp == firstMessageTimestampUndefined:
|
||||||
|
return true
|
||||||
|
if chatDto.firstMessageTimestamp == firstMessageTimestampNoMessages:
|
||||||
|
return false
|
||||||
|
|
||||||
|
return syncedFrom > chatDto.firstMessageTimestamp
|
||||||
|
|
||||||
|
proc hasMoreMessagesToRequest*(chatDto: ChatDto): bool =
|
||||||
|
chatDto.hasMoreMessagesToRequest(chatDto.syncedFrom)
|
||||||
|
|
|
@ -22,6 +22,10 @@ type
|
||||||
|
|
||||||
MailserverAvailableArgs* = ref object of Args
|
MailserverAvailableArgs* = ref object of Args
|
||||||
|
|
||||||
|
MailserverSyncedArgs* = ref object of Args
|
||||||
|
chatId*: string
|
||||||
|
syncedFrom*: int64
|
||||||
|
|
||||||
RequestMoreMessagesTaskArg = ref object of QObjectTaskArg
|
RequestMoreMessagesTaskArg = ref object of QObjectTaskArg
|
||||||
chatId*: string
|
chatId*: string
|
||||||
|
|
||||||
|
@ -33,12 +37,27 @@ type
|
||||||
const SIGNAL_ACTIVE_MAILSERVER_CHANGED* = "activeMailserverChanged"
|
const SIGNAL_ACTIVE_MAILSERVER_CHANGED* = "activeMailserverChanged"
|
||||||
const SIGNAL_MAILSERVER_AVAILABLE* = "mailserverAvailable"
|
const SIGNAL_MAILSERVER_AVAILABLE* = "mailserverAvailable"
|
||||||
const SIGNAL_MAILSERVER_NOT_WORKING* = "mailserverNotWorking"
|
const SIGNAL_MAILSERVER_NOT_WORKING* = "mailserverNotWorking"
|
||||||
|
const SIGNAL_MAILSERVER_SYNCED* = "mailserverSynced"
|
||||||
|
|
||||||
const requestMoreMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
const requestMoreMessagesTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||||
let arg = decode[RequestMoreMessagesTaskArg](argEncoded)
|
let arg = decode[RequestMoreMessagesTaskArg](argEncoded)
|
||||||
try:
|
try:
|
||||||
info "Requesting additional message history for chat", chatId=arg.chatId
|
info "Requesting additional message history for chat", chatId=arg.chatId
|
||||||
discard status_mailservers.syncChatFromSyncedFrom(arg.chatId)
|
let response = status_mailservers.syncChatFromSyncedFrom(arg.chatId)
|
||||||
|
|
||||||
|
if(not response.error.isNil):
|
||||||
|
error "Could not request additional messages due to error", errDescription = response.error.message
|
||||||
|
|
||||||
|
let syncedFrom = response.result.getInt()
|
||||||
|
if(syncedFrom != 0):
|
||||||
|
let resultJson = %* {
|
||||||
|
"chatId": arg.chatId,
|
||||||
|
"syncedFrom": syncedFrom
|
||||||
|
}
|
||||||
|
arg.finish(%resultJson)
|
||||||
|
else:
|
||||||
|
warn "Syncing mailserver failed", errDescription=arg.chatId
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
warn "Could not request additional messages due to error", errDescription=e.msg
|
warn "Could not request additional messages due to error", errDescription=e.msg
|
||||||
|
|
||||||
|
@ -88,11 +107,20 @@ QtObject:
|
||||||
let fleet = self.settingsService.getFleet()
|
let fleet = self.settingsService.getFleet()
|
||||||
discard self.settingsService.pinMailserver(MAILSERVER_ADDRESS, fleet)
|
discard self.settingsService.pinMailserver(MAILSERVER_ADDRESS, fleet)
|
||||||
|
|
||||||
|
proc mailserverSynced*(self: Service, syncInfo: string) {.slot.} =
|
||||||
|
let syncInfoParsed = parseJson(syncInfo)
|
||||||
|
let signalData = MailserverSyncedArgs(
|
||||||
|
chatId: syncInfoParsed["chatId"].getStr(),
|
||||||
|
syncedFrom: syncInfoParsed["syncedFrom"].getInt()
|
||||||
|
)
|
||||||
|
self.events.emit(SIGNAL_MAILSERVER_SYNCED, signalData)
|
||||||
|
|
||||||
proc requestMoreMessages*(self: Service, chatId: string) =
|
proc requestMoreMessages*(self: Service, chatId: string) =
|
||||||
let arg = RequestMoreMessagesTaskArg(
|
let arg = RequestMoreMessagesTaskArg(
|
||||||
tptr: cast[ByteAddress](requestMoreMessagesTask),
|
tptr: cast[ByteAddress](requestMoreMessagesTask),
|
||||||
vptr: cast[ByteAddress](self.vptr),
|
vptr: cast[ByteAddress](self.vptr),
|
||||||
chatId: chatId
|
chatId: chatId,
|
||||||
|
slot: "mailserverSynced"
|
||||||
)
|
)
|
||||||
self.threadpool.start(arg)
|
self.threadpool.start(arg)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue