feature: live status link previews (#12613)
* feat: live received status link previews * link preview cards: active members count * update `requestCommunityInfo` to new backend. Add `requiredTimeSinceLastRequest` arg
This commit is contained in:
parent
10f71e7413
commit
52dd0abbce
|
@ -1,4 +1,4 @@
|
|||
import chronicles, uuids
|
||||
import chronicles, uuids, times
|
||||
import io_interface
|
||||
import json
|
||||
|
||||
|
@ -213,8 +213,7 @@ proc init*(self: Controller) =
|
|||
self.events.on(SIGNAL_COMMUNITIES_UPDATE) do(e: Args):
|
||||
let args = CommunitiesArgs(e)
|
||||
for community in args.communities:
|
||||
if (community.id == self.sectionId):
|
||||
self.delegate.updateCommunityDetails(community)
|
||||
self.delegate.updateCommunityDetails(community)
|
||||
|
||||
self.events.on(SIGNAL_FIRST_UNSEEN_MESSAGE_LOADED) do(e: Args):
|
||||
let args = FirstUnseenMessageLoadedArgs(e)
|
||||
|
@ -238,6 +237,12 @@ proc getChatDetails*(self: Controller): ChatDto =
|
|||
proc getCommunityDetails*(self: Controller): CommunityDto =
|
||||
return self.communityService.getCommunityById(self.sectionId)
|
||||
|
||||
proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
|
||||
return self.communityService.getCommunityById(communityId)
|
||||
|
||||
proc requestCommunityInfo*(self: Controller, communityId: string, useDataabse: bool, requiredTimeSinceLastRequest: Duration) =
|
||||
self.communityService.requestCommunityInfo(communityId, false, useDataabse, requiredTimeSinceLastRequest)
|
||||
|
||||
proc getOneToOneChatNameAndImage*(self: Controller):
|
||||
tuple[name: string, image: string, largeImage: string] =
|
||||
return self.chatService.getOneToOneChatNameAndImage(self.chatId)
|
||||
|
@ -264,6 +269,9 @@ proc getContactById*(self: Controller, contactId: string): ContactsDto =
|
|||
proc getContactDetails*(self: Controller, contactId: string): ContactDetails =
|
||||
return self.contactService.getContactDetails(contactId)
|
||||
|
||||
proc requestContactInfo*(self: Controller, contactId: string) =
|
||||
self.contactService.requestContactInfo(contactId)
|
||||
|
||||
proc getNumOfPinnedMessages*(self: Controller): int =
|
||||
return self.messageService.getNumOfPinnedMessages(self.chatId)
|
||||
|
||||
|
|
|
@ -176,3 +176,6 @@ method reevaluateViewLoadingState*(self: AccessInterface) {.base.} =
|
|||
|
||||
method onGetMessageById*(self: AccessInterface, requestId: UUID, messageId: string, message: MessageDto, error: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method forceLinkPreviewsLocalData*(self: AccessInterface, messageId: string) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, chronicles, sequtils, uuids
|
||||
import NimQml, chronicles, sequtils, uuids, sets, times
|
||||
import io_interface
|
||||
import ../io_interface as delegate_interface
|
||||
import view, controller
|
||||
|
@ -6,6 +6,7 @@ import ../../../../shared_models/message_model
|
|||
import ../../../../shared_models/message_item
|
||||
import ../../../../shared_models/message_reaction_item
|
||||
import ../../../../shared_models/message_transaction_parameters_item
|
||||
import ../../../../shared_models/link_preview_model
|
||||
import ../../../../../global/global_singleton
|
||||
import ../../../../../core/eventemitter
|
||||
import ../../../../../../app_service/service/contacts/dto/contacts
|
||||
|
@ -62,6 +63,8 @@ proc createChatIdentifierItem(self: Module): Item
|
|||
proc createFetchMoreMessagesItem(self: Module): Item
|
||||
proc setChatDetails(self: Module, chatDetails: ChatDto)
|
||||
proc updateItemsByAlbum(self: Module, items: var seq[Item], message: MessageDto): bool
|
||||
proc updateLinkPreviewsContacts(self: Module, item: Item, requestFromMailserver: bool)
|
||||
proc updateLinkPreviewsCommunities(self: Module, item: Item, requestFromMailserver: bool)
|
||||
|
||||
method delete*(self: Module) =
|
||||
self.controller.delete
|
||||
|
@ -319,6 +322,9 @@ method newMessagesLoaded*(self: Module, messages: seq[MessageDto], reactions: se
|
|||
message.albumImagesCount,
|
||||
)
|
||||
|
||||
self.updateLinkPreviewsContacts(item, requestFromMailserver = item.seen)
|
||||
self.updateLinkPreviewsCommunities(item, requestFromMailserver = item.seen)
|
||||
|
||||
for r in reactions:
|
||||
if(r.messageId == message.id):
|
||||
var emojiIdAsEnum: EmojiId
|
||||
|
@ -454,6 +460,9 @@ method messagesAdded*(self: Module, messages: seq[MessageDto]) =
|
|||
)
|
||||
items.add(item)
|
||||
|
||||
self.updateLinkPreviewsContacts(item, requestFromMailserver = item.seen)
|
||||
self.updateLinkPreviewsCommunities(item, requestFromMailserver = item.seen)
|
||||
|
||||
self.view.model().insertItemsBasedOnClock(items)
|
||||
|
||||
method removeNewMessagesMarker*(self: Module)
|
||||
|
@ -596,6 +605,8 @@ method updateContactDetails*(self: Module, contactId: string) =
|
|||
let communityChats = self.controller.getCommunityDetails().chats
|
||||
item.messageText = self.controller.getRenderedText(item.parsedText, communityChats)
|
||||
|
||||
item.linkPreviewModel.setContactInfo(updatedContact)
|
||||
|
||||
method deleteMessage*(self: Module, messageId: string) =
|
||||
self.controller.deleteMessage(messageId)
|
||||
|
||||
|
@ -728,8 +739,12 @@ method markMessagesAsRead*(self: Module, messages: seq[string]) =
|
|||
self.view.model().markAsSeen(messages)
|
||||
|
||||
method updateCommunityDetails*(self: Module, community: CommunityDto) =
|
||||
self.view.setAmIChatAdmin(community.isPrivilegedUser)
|
||||
self.view.setIsPinMessageAllowedForMembers(community.adminSettings.pinMessageAllMembersEnabled)
|
||||
if community.id == self.getSectionId():
|
||||
self.view.setAmIChatAdmin(community.isPrivilegedUser)
|
||||
self.view.setIsPinMessageAllowedForMembers(community.adminSettings.pinMessageAllMembersEnabled)
|
||||
|
||||
for item in self.view.model().items:
|
||||
item.linkPreviewModel.setCommunityInfo(community)
|
||||
|
||||
proc setChatDetails(self: Module, chatDetails: ChatDto) =
|
||||
self.view.setChatColor(chatDetails.color)
|
||||
|
@ -766,3 +781,40 @@ method onFirstUnseenMessageLoaded*(self: Module, messageId: string) =
|
|||
self.firstUnseenMessageState.initialized = true
|
||||
self.firstUnseenMessageState.fetching = false
|
||||
self.reevaluateViewLoadingState()
|
||||
|
||||
method forceLinkPreviewsLocalData*(self: Module, messageId: string) =
|
||||
let item = self.view.model().getItemWithMessageId(messageId)
|
||||
debug "forceLinkPreviewsLocalData", messageId, itemFound = $(item != nil)
|
||||
if item == nil:
|
||||
return
|
||||
self.updateLinkPreviewsContacts(item, requestFromMailserver = true)
|
||||
self.updateLinkPreviewsCommunities(item, requestFromMailserver = true)
|
||||
|
||||
proc updateLinkPreviewsContacts(self: Module, item: Item, requestFromMailserver: bool) =
|
||||
for contactId in item.linkPreviewModel.getContactIds().items:
|
||||
let contact = self.controller.getContactDetails(contactId)
|
||||
|
||||
if contact.dto.displayName != "":
|
||||
item.linkPreviewModel.setContactInfo(contact)
|
||||
|
||||
if not requestFromMailserver:
|
||||
continue
|
||||
|
||||
debug "updateLinkPreviewsContacts: contact not found, requesting from mailserver", contactId
|
||||
item.linkPreviewModel.onContactDataRequested(contactId)
|
||||
self.controller.requestContactInfo(contactId)
|
||||
|
||||
proc updateLinkPreviewsCommunities(self: Module, item: Item, requestFromMailserver: bool) =
|
||||
for communityId in item.linkPreviewModel.getCommunityIds().items:
|
||||
let community = self.controller.getCommunityById(communityId)
|
||||
|
||||
if community.id != "":
|
||||
item.linkPreviewModel.setCommunityInfo(community)
|
||||
|
||||
if not requestFromMailserver:
|
||||
continue
|
||||
|
||||
debug "updateLinkPreviewsCommunites: requesting from mailserver", communityId
|
||||
item.linkPreviewModel.onCommunityInfoRequested(communityId)
|
||||
self.controller.requestCommunityInfo(communityId, false, initDuration(minutes = 10))
|
||||
|
||||
|
|
|
@ -224,3 +224,6 @@ QtObject:
|
|||
|
||||
proc firstUnseenMentionMessageId(self: View): string {.slot.} =
|
||||
return self.model.getFirstUnseenMentionMessageId()
|
||||
|
||||
proc forceLinkPreviewsLocalData*(self: View, messageId: string) {.slot.} =
|
||||
self.delegate.forceLinkPreviewsLocalData(messageId)
|
||||
|
|
|
@ -7,6 +7,8 @@ type
|
|||
Item* = ref object
|
||||
unfurled*: bool
|
||||
immutable*: bool
|
||||
isLocalData*: bool
|
||||
loadingLocalData*: bool
|
||||
linkPreview*: LinkPreview
|
||||
|
||||
proc delete*(self: Item) =
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, strformat, tables, sequtils
|
||||
import NimQml, strformat, tables, sequtils, sets
|
||||
import ./link_preview_item
|
||||
import ../../../app_service/service/message/dto/link_preview
|
||||
import ../../../app_service/service/message/dto/standard_link_preview
|
||||
|
@ -6,12 +6,16 @@ import ../../../app_service/service/message/dto/status_link_preview
|
|||
import ../../../app_service/service/message/dto/status_contact_link_preview
|
||||
import ../../../app_service/service/message/dto/status_community_link_preview
|
||||
import ../../../app_service/service/message/dto/status_community_channel_link_preview
|
||||
import ../../../app_service/service/contacts/dto/contact_details
|
||||
import ../../../app_service/service/community/dto/community
|
||||
|
||||
type
|
||||
ModelRole {.pure.} = enum
|
||||
Url = UserRole + 1
|
||||
Unfurled
|
||||
Immutable
|
||||
IsLocalData
|
||||
LoadingLocalData
|
||||
Empty
|
||||
PreviewType
|
||||
# Standard unfurled link (oembed, opengraph, image)
|
||||
|
@ -83,6 +87,8 @@ QtObject:
|
|||
ModelRole.Url.int:"url",
|
||||
ModelRole.Unfurled.int:"unfurled",
|
||||
ModelRole.Immutable.int:"immutable",
|
||||
ModelRole.IsLocalData.int:"isLocalData",
|
||||
ModelRole.LoadingLocalData.int:"loadingLocalData",
|
||||
ModelRole.Empty.int:"empty",
|
||||
ModelRole.PreviewType.int:"previewType",
|
||||
# Standard
|
||||
|
@ -119,6 +125,10 @@ QtObject:
|
|||
result = newQVariant(item.unfurled)
|
||||
of ModelRole.Immutable:
|
||||
result = newQVariant(item.immutable)
|
||||
of ModelRole.IsLocalData:
|
||||
result = newQVariant(item.isLocalData)
|
||||
of ModelRole.LoadingLocalData:
|
||||
result = newQVariant(item.loadingLocalData)
|
||||
of ModelRole.Empty:
|
||||
result = newQVariant(item.linkPreview.empty())
|
||||
of ModelRole.PreviewType:
|
||||
|
@ -234,6 +244,8 @@ QtObject:
|
|||
var item = Item()
|
||||
item.unfurled = false
|
||||
item.immutable = false
|
||||
item.isLocalData = false
|
||||
item.loadingLocalData = false
|
||||
item.linkPreview = linkPreview
|
||||
|
||||
let parentModelIndex = newQModelIndex()
|
||||
|
@ -276,3 +288,56 @@ QtObject:
|
|||
result = @[]
|
||||
for item in self.items:
|
||||
result.add(item.linkPreview.url)
|
||||
|
||||
|
||||
proc getContactIds*(self: Model): HashSet[string] =
|
||||
for item in self.items:
|
||||
let contactId = item.linkPreview.getContactId()
|
||||
if contactId != "":
|
||||
result.incl(contactId)
|
||||
|
||||
proc getCommunityIds*(self: Model): HashSet[string] =
|
||||
for item in self.items:
|
||||
let communityId = item.linkPreview.getCommunityId()
|
||||
if communityId != "":
|
||||
result.incl(communityId)
|
||||
|
||||
proc setItemLoadingLocalData(self: Model, row: int, item: Item, value: bool) =
|
||||
if item.loadingLocalData == value:
|
||||
return
|
||||
item.loadingLocalData = value
|
||||
let modelIndex = self.createIndex(row, 0, nil)
|
||||
defer: modelIndex.delete
|
||||
self.dataChanged(modelIndex, modelIndex, @[ModelRole.LoadingLocalData.int])
|
||||
|
||||
proc setItemIsLocalData(self: Model, row: int, item: Item) =
|
||||
if item.isLocalData:
|
||||
return
|
||||
var roles = @[ModelRole.IsLocalData.int]
|
||||
item.isLocalData = true
|
||||
if item.loadingLocalData:
|
||||
item.loadingLocalData = false
|
||||
roles.add(ModelRole.LoadingLocalData.int)
|
||||
let modelIndex = self.createIndex(row, 0, nil)
|
||||
defer: modelIndex.delete
|
||||
self.dataChanged(modelIndex, modelIndex, roles)
|
||||
|
||||
proc setContactInfo*(self: Model, contactDetails: ContactDetails) =
|
||||
for row, item in self.items:
|
||||
if item.linkPreview.setContactInfo(contactDetails):
|
||||
self.setItemIsLocalData(row, item)
|
||||
|
||||
proc setCommunityInfo*(self: Model, community: CommunityDto) =
|
||||
for row, item in self.items:
|
||||
if item.linkPreview.setCommunityInfo(community):
|
||||
self.setItemIsLocalData(row, item)
|
||||
|
||||
proc onContactDataRequested*(self: Model, contactId: string) =
|
||||
for row, item in self.items:
|
||||
if item.linkPreview.getContactId() == contactId:
|
||||
self.setItemLoadingLocalData(row, item, true)
|
||||
|
||||
proc onCommunityInfoRequested*(self: Model, communityId: string) =
|
||||
for row, item in self.items:
|
||||
if item.linkPreview.getCommunityId() == communityId:
|
||||
self.setItemLoadingLocalData(row, item, true)
|
||||
|
|
|
@ -552,6 +552,10 @@ QtObject:
|
|||
return
|
||||
self.items[index].toJsonNode()
|
||||
|
||||
iterator items*(self: Model): Item =
|
||||
for i in 0 ..< self.items.len:
|
||||
yield self.items[i]
|
||||
|
||||
iterator modelContactUpdateIterator*(self: Model, contactId: string): Item =
|
||||
for i in 0 ..< self.items.len:
|
||||
yield self.items[i]
|
||||
|
|
|
@ -415,3 +415,8 @@ proc hasMoreMessagesToRequest*(chatDto: ChatDto, syncedFrom: int64): bool =
|
|||
|
||||
proc hasMoreMessagesToRequest*(chatDto: ChatDto): bool =
|
||||
chatDto.hasMoreMessagesToRequest(chatDto.syncedFrom)
|
||||
|
||||
proc communityChannelUuid*(self: ChatDto): string =
|
||||
if self.communityId == "":
|
||||
return ""
|
||||
return self.id[self.communityId.len .. ^1]
|
||||
|
|
|
@ -53,11 +53,12 @@ type
|
|||
AsyncRequestCommunityInfoTaskArg = ref object of QObjectTaskArg
|
||||
communityId: string
|
||||
importing: bool
|
||||
tryDatabase: bool
|
||||
|
||||
const asyncRequestCommunityInfoTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncRequestCommunityInfoTaskArg](argEncoded)
|
||||
try:
|
||||
let response = status_go.requestCommunityInfo(arg.communityId)
|
||||
let response = status_go.requestCommunityInfo(arg.communityId, arg.tryDatabase)
|
||||
arg.finish(%* {
|
||||
"communityId": arg.communityId,
|
||||
"importing": arg.importing,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, Tables, json, sequtils, std/sets, std/algorithm, strformat, strutils, chronicles, json_serialization, sugar
|
||||
import NimQml, Tables, json, sequtils, std/sets, std/algorithm, strformat, strutils, chronicles, json_serialization, sugar, times
|
||||
import json_serialization/std/tables as ser_tables
|
||||
|
||||
import ./dto/community as community_dto
|
||||
|
@ -241,6 +241,7 @@ QtObject:
|
|||
requestedCommunityIds*: HashSet[string]
|
||||
communityMetrics: Table[string, CommunityMetricsDto]
|
||||
myAwaitingAddressesRequestsToJoin: Table[string, CommunityMembershipRequestDto]
|
||||
communityInfoRequests: Table[string, Time]
|
||||
|
||||
# Forward declaration
|
||||
proc asyncLoadCuratedCommunities*(self: Service)
|
||||
|
@ -279,6 +280,7 @@ QtObject:
|
|||
result.historyArchiveDownloadTaskCommunityIds = initHashSet[string]()
|
||||
result.requestedCommunityIds = initHashSet[string]()
|
||||
result.communityMetrics = initTable[string, CommunityMetricsDto]()
|
||||
result.communityInfoRequests = initTable[string, Time]()
|
||||
|
||||
proc getFilteredJoinedCommunities(self: Service): Table[string, CommunityDto] =
|
||||
result = initTable[string, CommunityDto]()
|
||||
|
@ -762,7 +764,6 @@ QtObject:
|
|||
return
|
||||
|
||||
if not self.communities.hasKey(communityId):
|
||||
error "requested community doesn't exist", communityId
|
||||
return
|
||||
|
||||
return self.communities[communityId]
|
||||
|
@ -1469,11 +1470,13 @@ QtObject:
|
|||
return
|
||||
|
||||
self.communities[community.id] = community
|
||||
debug "asyncRequestCommunityInfoTask finished", communityId = requestedCommunityId, communityName = community.name
|
||||
|
||||
if rpcResponseObj{"importing"}.getBool():
|
||||
self.events.emit(SIGNAL_COMMUNITY_IMPORTED, CommunityArgs(community: community))
|
||||
|
||||
self.events.emit(SIGNAL_COMMUNITY_DATA_IMPORTED, CommunityArgs(community: community))
|
||||
self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[community]))
|
||||
|
||||
proc asyncCheckPermissionsToJoin*(self: Service, communityId: string, addresses: seq[string]) =
|
||||
let arg = AsyncCheckPermissionsToJoinTaskArg(
|
||||
|
@ -1736,13 +1739,23 @@ QtObject:
|
|||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc requestCommunityInfo*(self: Service, communityId: string, importing = false) =
|
||||
proc requestCommunityInfo*(self: Service, communityId: string, importing = false, tryDatabase = true, requiredTimeSinceLastRequest = initDuration(0, 0)) =
|
||||
|
||||
if communityId in self.requestedCommunityIds:
|
||||
info "requestCommunityInfo: skipping as already requested", communityId
|
||||
self.events.emit(SIGNAL_COMMUNITY_INFO_ALREADY_REQUESTED, Args())
|
||||
return
|
||||
return
|
||||
|
||||
let now = now().toTime()
|
||||
if self.communityInfoRequests.hasKey(communityId):
|
||||
let lastRequestTime = self.communityInfoRequests[communityId]
|
||||
let actualTimeSincLastRequest = now - lastRequestTime
|
||||
debug "requestCommunityInfo: TIME", communityId, now, lastRequestTime, requiredTimeSinceLastRequest, actualTimeSincLastRequest
|
||||
if actualTimeSincLastRequest < requiredTimeSinceLastRequest:
|
||||
debug "requestCommunityInfo: skipping as required time has not passed yet since last request", communityId, actualTimeSincLastRequest, requiredTimeSinceLastRequest
|
||||
return
|
||||
|
||||
self.communityInfoRequests[communityId] = now
|
||||
self.requestedCommunityIds.incl(communityId)
|
||||
|
||||
let arg = AsyncRequestCommunityInfoTaskArg(
|
||||
|
@ -1750,7 +1763,8 @@ QtObject:
|
|||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "asyncCommunityInfoLoaded",
|
||||
communityId: communityId,
|
||||
importing: importing
|
||||
importing: importing,
|
||||
tryDatabase: tryDatabase
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import json, strformat, tables
|
||||
import ./link_preview_thumbnail, ./status_link_preview, ./standard_link_preview
|
||||
import ./status_contact_link_preview, ./status_community_link_preview, ./status_community_channel_link_preview
|
||||
import ../../contacts/dto/contact_details
|
||||
import ../../community/dto/community
|
||||
include ../../../common/json_utils
|
||||
|
||||
|
||||
type
|
||||
PreviewType {.pure.} = enum
|
||||
PreviewType* {.pure.} = enum
|
||||
NoPreview = 0
|
||||
StandardPreview
|
||||
StatusContactPreview
|
||||
|
@ -126,3 +128,27 @@ proc getChannelCommunity*(self: LinkPreview): StatusCommunityLinkPreview =
|
|||
if self.statusCommunityChannelPreview == nil:
|
||||
return nil
|
||||
return self.statusCommunityChannelPreview.getCommunity()
|
||||
|
||||
proc getContactId*(self: LinkPreview): string =
|
||||
if self.previewType == PreviewType.StatusContactPreview:
|
||||
return self.statusContactPreview.getPublicKey()
|
||||
return ""
|
||||
|
||||
proc getCommunityId*(self: LinkPreview): string =
|
||||
if self.previewType == PreviewType.StatusCommunityPreview:
|
||||
return self.statusCommunityPreview.getCommunityId()
|
||||
if self.previewType == PreviewType.StatusCommunityChannelPreview:
|
||||
return self.statusCommunityChannelPreview.getCommunity().getCommunityId()
|
||||
return ""
|
||||
|
||||
proc setContactInfo*(self: LinkPreview, contactDetails: ContactDetails): bool =
|
||||
if self.previewType == PreviewType.StatusContactPreview:
|
||||
return self.statusContactPreview.setContactInfo(contactDetails)
|
||||
return false
|
||||
|
||||
proc setCommunityInfo*(self: LinkPreview, community: CommunityDto): bool =
|
||||
if self.previewType == PreviewType.StatusCommunityPreview:
|
||||
return self.statusCommunityPreview.setCommunityInfo(community)
|
||||
if self.previewType == PreviewType.StatusCommunityChannelPreview:
|
||||
return self.statusCommunityChannelPreview.setCommunityInfo(community)
|
||||
return false
|
||||
|
|
|
@ -14,11 +14,7 @@ QtObject:
|
|||
proc delete*(self: LinkPreviewThumbnail) =
|
||||
self.QObject.delete()
|
||||
|
||||
proc update*(self: LinkPreviewThumbnail, width: int, height: int, url: string, dataUri: string) =
|
||||
self.width = width
|
||||
self.height = height
|
||||
self.url = url
|
||||
self.dataUri = dataUri
|
||||
proc update*(self: LinkPreviewThumbnail, width: int, height: int, url: string, dataUri: string)
|
||||
|
||||
proc copy*(self: LinkPreviewThumbnail, other: LinkPreviewThumbnail) =
|
||||
if other != nil:
|
||||
|
@ -82,3 +78,17 @@ QtObject:
|
|||
"url": self.url,
|
||||
"dataUri": self.dataUri
|
||||
}
|
||||
|
||||
proc update*(self: LinkPreviewThumbnail, width: int, height: int, url: string, dataUri: string) =
|
||||
if self.width != width:
|
||||
self.width = width
|
||||
self.widthChanged()
|
||||
if self.height != height:
|
||||
self.height = height
|
||||
self.heightChanged()
|
||||
if self.url != url:
|
||||
self.url = url
|
||||
self.urlChanged()
|
||||
if self.dataUri != dataUri:
|
||||
self.dataUri = dataUri
|
||||
self.dataUriChanged()
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import json, strformat, NimQml, chronicles
|
||||
import link_preview_thumbnail
|
||||
import status_community_link_preview
|
||||
import ../../community/dto/community
|
||||
import ../../chat/dto/chat
|
||||
include ../../../common/json_utils
|
||||
|
||||
QtObject:
|
||||
|
@ -93,3 +95,31 @@ QtObject:
|
|||
|
||||
proc empty*(self: StatusCommunityChannelLinkPreview): bool =
|
||||
return self.channelUUID.len == 0
|
||||
|
||||
proc setCommunityInfo*(self: StatusCommunityChannelLinkPreview, community: CommunityDto): bool =
|
||||
if not self.community.setCommunityInfo(community):
|
||||
return false
|
||||
|
||||
for chat in community.chats:
|
||||
if chat.communityChannelUuid() != self.channelUuid:
|
||||
continue
|
||||
|
||||
debug "setChannelInfo", communityId = $self.community.getCommunityId(), channelUuid = $self.channelUuid
|
||||
|
||||
if self.displayName != chat.name:
|
||||
self.displayName = chat.name
|
||||
self.displayNameChanged()
|
||||
|
||||
if self.description != chat.description:
|
||||
self.description = chat.description
|
||||
self.descriptionChanged()
|
||||
|
||||
if self.emoji != chat.emoji:
|
||||
self.emoji = chat.emoji
|
||||
self.emojiChanged()
|
||||
|
||||
if self.color != community.color:
|
||||
self.color = community.color
|
||||
self.colorChanged()
|
||||
|
||||
return true
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import json, strformat, NimQml, chronicles
|
||||
import link_preview_thumbnail
|
||||
import ../../community/dto/community
|
||||
|
||||
include ../../../common/json_utils
|
||||
|
||||
QtObject:
|
||||
type StatusCommunityLinkPreview* = ref object of QObject
|
||||
communityID: string
|
||||
communityId: string
|
||||
displayName: string
|
||||
description: string
|
||||
membersCount: int
|
||||
activeMembersCount: int
|
||||
color: string
|
||||
icon: LinkPreviewThumbnail
|
||||
banner: LinkPreviewThumbnail
|
||||
|
@ -25,7 +28,7 @@ QtObject:
|
|||
|
||||
proc communityIdChanged*(self: StatusCommunityLinkPreview) {.signal.}
|
||||
proc getCommunityId*(self: StatusCommunityLinkPreview): string {.slot.} =
|
||||
result = self.communityID
|
||||
result = self.communityId
|
||||
QtProperty[string] communityId:
|
||||
read = getCommunityId
|
||||
notify = communityIdChanged
|
||||
|
@ -50,6 +53,13 @@ QtObject:
|
|||
QtProperty[int] membersCount:
|
||||
read = getMembersCount
|
||||
notify = membersCountChanged
|
||||
|
||||
proc activeMembersCountChanged*(self: StatusCommunityLinkPreview) {.signal.}
|
||||
proc getActiveMembersCount*(self: StatusCommunityLinkPreview): int {.slot.} =
|
||||
result = int(self.activeMembersCount)
|
||||
QtProperty[int] activeMembersCount:
|
||||
read = getActiveMembersCount
|
||||
notify = activeMembersCountChanged
|
||||
|
||||
proc colorChanged*(self: StatusCommunityLinkPreview) {.signal.}
|
||||
proc getColor*(self: StatusCommunityLinkPreview): string {.slot.} =
|
||||
|
@ -71,10 +81,11 @@ QtObject:
|
|||
var icon: LinkPreviewThumbnail
|
||||
var banner: LinkPreviewThumbnail
|
||||
|
||||
discard jsonObj.getProp("communityId", result.communityID)
|
||||
discard jsonObj.getProp("communityId", result.communityId)
|
||||
discard jsonObj.getProp("displayName", result.displayName)
|
||||
discard jsonObj.getProp("description", result.description)
|
||||
discard jsonObj.getProp("membersCount", result.membersCount)
|
||||
discard jsonObj.getProp("activeMembersCount", result.activeMembersCount)
|
||||
discard jsonObj.getProp("color", result.color)
|
||||
|
||||
var iconJson: JsonNode
|
||||
|
@ -90,10 +101,11 @@ QtObject:
|
|||
|
||||
proc `$`*(self: StatusCommunityLinkPreview): string =
|
||||
result = fmt"""StatusCommunityLinkPreview(
|
||||
communityId: {self.communityID},
|
||||
communityId: {self.communityId},
|
||||
displayName: {self.displayName},
|
||||
description: {self.description},
|
||||
membersCount: {self.membersCount},
|
||||
activeMembersCount: {self.activeMembersCount},
|
||||
color: {self.color},
|
||||
icon: {self.icon},
|
||||
banner: {self.banner}
|
||||
|
@ -101,14 +113,46 @@ QtObject:
|
|||
|
||||
proc `%`*(self: StatusCommunityLinkPreview): JsonNode =
|
||||
result = %* {
|
||||
"communityID": self.communityID,
|
||||
"communityId": self.communityId,
|
||||
"displayName": self.displayName,
|
||||
"description": self.description,
|
||||
"membersCount": self.membersCount,
|
||||
"activeMembersCount": self.activeMembersCount,
|
||||
"color": self.color,
|
||||
"icon": self.icon,
|
||||
"banner": self.banner
|
||||
}
|
||||
|
||||
proc empty*(self: StatusCommunityLinkPreview): bool =
|
||||
return self.communityID.len == 0
|
||||
return self.communityId.len == 0
|
||||
|
||||
proc setCommunityInfo*(self: StatusCommunityLinkPreview, community: CommunityDto): bool =
|
||||
if self.communityId != community.id:
|
||||
return false
|
||||
|
||||
debug "setCommunityInfo", communityId = self.communityId, communityName = community.name
|
||||
|
||||
if self.displayName != community.name:
|
||||
self.displayName = community.name
|
||||
self.displayNameChanged()
|
||||
|
||||
if self.description != community.description:
|
||||
self.description = community.description
|
||||
self.descriptionChanged()
|
||||
|
||||
if self.membersCount != community.members.len:
|
||||
self.membersCount = community.members.len
|
||||
self.membersCountChanged()
|
||||
|
||||
if self.activeMembersCount != community.activeMembersCount:
|
||||
self.activeMembersCount = int(community.activeMembersCount)
|
||||
self.activeMembersCountChanged()
|
||||
|
||||
if self.color != community.color:
|
||||
self.color = community.color
|
||||
self.colorChanged()
|
||||
|
||||
self.icon.update(0, 0, "", community.images.thumbnail)
|
||||
self.banner.update(0, 0, "", community.images.banner)
|
||||
|
||||
return true
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import json, strformat, NimQml, chronicles
|
||||
import link_preview_thumbnail
|
||||
include ../../../common/json_utils
|
||||
import ../../contacts/dto/contact_details
|
||||
|
||||
include ../../../common/json_utils
|
||||
|
||||
QtObject:
|
||||
type StatusContactLinkPreview* = ref object of QObject
|
||||
|
@ -18,7 +19,7 @@ QtObject:
|
|||
self.QObject.delete()
|
||||
self.icon.delete()
|
||||
|
||||
proc newStatusContactLinkPreview*(publicKey: string, displayName: string, description: string, icon: LinkPreviewThumbnail): StatusContactLinkPreview =
|
||||
proc newStatusContactLinkPreview*(publicKey: var string, displayName: string, description: string, icon: LinkPreviewThumbnail): StatusContactLinkPreview =
|
||||
new(result, delete)
|
||||
result.setup()
|
||||
result.publicKey = publicKey
|
||||
|
@ -85,3 +86,21 @@ QtObject:
|
|||
|
||||
proc empty*(self: StatusContactLinkPreview): bool =
|
||||
return self.publicKey.len == 0
|
||||
|
||||
proc setContactInfo*(self: StatusContactLinkPreview, contactDetails: ContactDetails): bool =
|
||||
if self.publicKey != contactDetails.dto.id:
|
||||
return false
|
||||
|
||||
debug "setContactInfo", publicKey = self.publicKey, displayName = $contactDetails.dto.displayname
|
||||
|
||||
if self.displayName != contactDetails.defaultDisplayName:
|
||||
self.displayName = contactDetails.defaultDisplayName
|
||||
self.displayNameChanged()
|
||||
|
||||
if self.description != contactDetails.dto.bio:
|
||||
self.description = contactDetails.dto.bio
|
||||
self.descriptionChanged()
|
||||
|
||||
self.icon.update(0, 0, contactDetails.dto.image.thumbnail, "")
|
||||
|
||||
return true
|
||||
|
|
|
@ -408,8 +408,12 @@ proc collectCommunityMetrics*(communityId: string, metricsType: int, intervals:
|
|||
"intervals": intervals
|
||||
}])
|
||||
|
||||
proc requestCommunityInfo*(communityId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
result = callPrivateRPC("requestCommunityInfoFromMailserver".prefix, %*[communityId])
|
||||
proc requestCommunityInfo*(communityId: string, tryDatabase: bool): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
result = callPrivateRPC("fetchCommunity".prefix, %*[{
|
||||
"communityKey": communityId,
|
||||
"tryDatabase": tryDatabase,
|
||||
"waitForResponse": true
|
||||
}])
|
||||
|
||||
proc importCommunity*(communityKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||
result = callPrivateRPC("importCommunity".prefix, %*[communityKey])
|
||||
|
|
|
@ -202,6 +202,7 @@
|
|||
<file>assets/img/icons/github.svg</file>
|
||||
<file>assets/img/icons/group-chat.svg</file>
|
||||
<file>assets/img/icons/group.svg</file>
|
||||
<file>assets/img/icons/active-members.svg</file>
|
||||
<file>assets/img/icons/help.svg</file>
|
||||
<file>assets/img/icons/hide.svg</file>
|
||||
<file>assets/img/icons/history.svg</file>
|
||||
|
|
|
@ -366,15 +366,6 @@ Item {
|
|||
notificationType,
|
||||
"")
|
||||
}
|
||||
|
||||
function onCommunityInfoAlreadyRequested() {
|
||||
Global.displayToastMessage(qsTr("Community data not loaded yet."),
|
||||
qsTr("Please wait for the unfurl to show"),
|
||||
"",
|
||||
true,
|
||||
Constants.ephemeralNotificationType.normal,
|
||||
"")
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
|
|
|
@ -191,7 +191,7 @@ CalloutCard {
|
|||
}
|
||||
FooterText {
|
||||
Layout.fillHeight: true
|
||||
Layout.fillWidth: communityData.activeMembersCount === -1 //TODO: remove magic number once we have activeMembersCount
|
||||
Layout.fillWidth: !communityData.activeMembersCountAvailable
|
||||
color: Theme.palette.directColor1
|
||||
text: LocaleUtils.numberToLocaleStringInCompactForm(communityData.membersCount)
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
|
@ -202,7 +202,7 @@ CalloutCard {
|
|||
color: Theme.palette.directColor1
|
||||
width: 16
|
||||
height: width
|
||||
visible: communityData.activeMembersCount > -1
|
||||
visible: communityData.activeMembersCountAvailable
|
||||
}
|
||||
FooterText {
|
||||
Layout.fillWidth: true
|
||||
|
@ -210,7 +210,7 @@ CalloutCard {
|
|||
color: Theme.palette.directColor1
|
||||
text: LocaleUtils.numberToLocaleStringInCompactForm(communityData.activeMembersCount)
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
visible: communityData.activeMembersCount > -1
|
||||
visible: communityData.activeMembersCountAvailable
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,5 +7,6 @@ QtObject {
|
|||
property string image
|
||||
property string color
|
||||
property int membersCount
|
||||
property int activeMembersCount: -1 // TODO: implement this and remove the magic number
|
||||
property int activeMembersCount // -1 when not available. >= 0 otherwise.
|
||||
readonly property bool activeMembersCountAvailable: activeMembersCount >= 0
|
||||
}
|
||||
|
|
|
@ -34,6 +34,8 @@ LinkPreviewCard {
|
|||
required property bool empty
|
||||
required property string url
|
||||
required property bool immutable
|
||||
required property bool isLocalData
|
||||
required property bool loadingLocalData
|
||||
required property int previewType
|
||||
required property var standardPreview
|
||||
required property var standardPreviewThumbnail
|
||||
|
@ -69,6 +71,7 @@ LinkPreviewCard {
|
|||
banner: statusCommunityPreviewBanner ? (statusCommunityPreviewBanner.url || statusCommunityPreviewBanner.dataUri) || "" : ""
|
||||
image: statusCommunityPreviewIcon ? (statusCommunityPreviewIcon.url || statusCommunityPreviewIcon.dataUri) || "" : ""
|
||||
membersCount: statusCommunityPreview ? statusCommunityPreview.membersCount : 0
|
||||
activeMembersCount: statusCommunityPreview && isLocalData ? statusCommunityPreview.activeMembersCount : -1
|
||||
color: statusCommunityPreview ? statusCommunityPreview.color : ""
|
||||
}
|
||||
channelData {
|
||||
|
@ -82,6 +85,7 @@ LinkPreviewCard {
|
|||
banner: statusCommunityChannelCommunityPreviewBanner ? (statusCommunityChannelCommunityPreviewBanner.url || statusCommunityChannelCommunityPreviewBanner.dataUri) || "" : ""
|
||||
image: statusCommunityChannelCommunityPreviewIcon ? (statusCommunityChannelCommunityPreviewIcon.url || statusCommunityChannelCommunityPreviewIcon.dataUri) || "" : ""
|
||||
membersCount: statusCommunityChannelCommunityPreview ? statusCommunityChannelCommunityPreview.membersCount : 0
|
||||
activeMembersCount: statusCommunityChannelCommunityPreview && isLocalData ? statusCommunityChannelCommunityPreview.activeMembersCount : -1
|
||||
color: statusCommunityChannelCommunityPreview ? statusCommunityChannelCommunityPreview.color : ""
|
||||
}
|
||||
}
|
||||
|
|
|
@ -769,6 +769,10 @@ Loader {
|
|||
gifUnfurlingEnabled: RootStore.gifUnfurlingEnabled
|
||||
canAskToUnfurlGifs: !RootStore.neverAskAboutUnfurlingAgain
|
||||
onSetNeverAskAboutUnfurlingAgain: RootStore.setNeverAskAboutUnfurlingAgain(neverAskAgain)
|
||||
|
||||
Component.onCompleted: {
|
||||
root.messageStore.messageModule.forceLinkPreviewsLocalData(root.messageId)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue