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:
Igor Sirotin 2023-11-06 19:26:44 +00:00 committed by GitHub
parent 10f71e7413
commit 52dd0abbce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 333 additions and 42 deletions

View File

@ -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)

View File

@ -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")

View File

@ -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))

View File

@ -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)

View File

@ -7,6 +7,8 @@ type
Item* = ref object
unfurled*: bool
immutable*: bool
isLocalData*: bool
loadingLocalData*: bool
linkPreview*: LinkPreview
proc delete*(self: Item) =

View File

@ -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)

View File

@ -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]

View File

@ -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]

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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])

View File

@ -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>

View 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 {

View File

@ -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
}
}
}

View File

@ -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
}

View File

@ -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 : ""
}
}

View File

@ -769,6 +769,10 @@ Loader {
gifUnfurlingEnabled: RootStore.gifUnfurlingEnabled
canAskToUnfurlGifs: !RootStore.neverAskAboutUnfurlingAgain
onSetNeverAskAboutUnfurlingAgain: RootStore.setNeverAskAboutUnfurlingAgain(neverAskAgain)
Component.onCompleted: {
root.messageStore.messageModule.forceLinkPreviewsLocalData(root.messageId)
}
}
}