fix(members): fix slow chat switching by improving model (#16279)

Fixes #16132
This commit is contained in:
Jonathan Rainville 2024-09-25 11:29:26 -04:00 committed by GitHub
parent 86fdc668e6
commit bb7e5be065
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 223 additions and 126 deletions

View File

@ -28,6 +28,7 @@ QtObject:
canPostReactions: bool
hideIfPermissionsNotMet: bool
missingEncryptionKey: bool
requiresPermissions: bool
proc delete*(self: ChatDetails) =
self.QObject.delete
@ -58,6 +59,7 @@ QtObject:
canPostReactions: bool = true,
hideIfPermissionsNotMet: bool,
missingEncryptionKey: bool,
requiresPermissions: bool,
) =
self.id = id
self.`type` = `type`
@ -82,6 +84,7 @@ QtObject:
self.canPostReactions = canPostReactions
self.hideIfPermissionsNotMet = hideIfPermissionsNotMet
self.missingEncryptionKey = missingEncryptionKey
self.requiresPermissions = requiresPermissions
proc getId(self: ChatDetails): string {.slot.} =
return self.id
@ -111,6 +114,8 @@ QtObject:
notify = nameChanged
proc setName*(self: ChatDetails, value: string) = # this is not a slot
if self.name == value:
return
self.name = value
self.nameChanged()
@ -122,6 +127,8 @@ QtObject:
notify = iconChanged
proc setIcon*(self: ChatDetails, icon: string) = # this is not a slot
if self.icon == icon:
return
self.icon = icon
self.iconChanged()
@ -133,6 +140,8 @@ QtObject:
notify = colorChanged
proc setColor*(self: ChatDetails, value: string) = # this is not a slot
if self.color == value:
return
self.color = value
self.colorChanged()
@ -144,6 +153,8 @@ QtObject:
notify = emojiChanged
proc setEmoji*(self: ChatDetails, value: string) = # this is not a slot
if self.emoji == value:
return
self.emoji = value
self.emojiChanged()
@ -155,6 +166,8 @@ QtObject:
notify = descriptionChanged
proc setDescription*(self: ChatDetails, value: string) = # this is not a slot
if self.description == value:
return
self.description = value
self.descriptionChanged()
@ -166,6 +179,8 @@ QtObject:
notify = hasUnreadMessages
proc setHasUnreadMessages*(self: ChatDetails, value: bool) = # this is not a slot
if self.hasUnreadMessages == value:
return
self.hasUnreadMessages = value
self.hasUnreadMessagesChanged()
@ -177,6 +192,8 @@ QtObject:
notify = notificationCountChanged
proc setNotificationCount*(self: ChatDetails, value: int) = # this is not a slot
if self.notificationsCount == value:
return
self.notificationsCount = value
self.notificationCountChanged()
@ -188,6 +205,8 @@ QtObject:
notify = highlightChanged
proc setHighlight*(self: ChatDetails, value: bool) = # this is not a slot
if self.highlight == value:
return
self.highlight = value
self.highlightChanged()
@ -199,6 +218,8 @@ QtObject:
notify = mutedChanged
proc setMuted*(self: ChatDetails, value: bool) = # this is not a slot
if self.muted == value:
return
self.muted = value
self.mutedChanged()
@ -210,6 +231,8 @@ QtObject:
notify = positionChanged
proc setPotion*(self: ChatDetails, value: int) = # this is not a slot
if self.position == value:
return
self.position = value
self.positionChanged()
@ -221,6 +244,8 @@ QtObject:
notify = isMutualContactChanged
proc setIsMutualContact*(self: ChatDetails, value: bool) = # this is not a slot
if self.isContact == value:
return
self.isContact = value
self.isMutualContactChanged()
@ -232,6 +257,8 @@ QtObject:
notify = isUntrustworthyChanged
proc setIsUntrustworthy*(self: ChatDetails, value: bool) = # this is not a slot
if self.isUntrustworthy == value:
return
self.isUntrustworthy = value
self.isUntrustworthyChanged()
@ -243,6 +270,8 @@ QtObject:
notify = activeChanged
proc setActive*(self: ChatDetails, value: bool) =
if self.active == value:
return
self.active = value
self.activeChanged()
@ -254,6 +283,8 @@ QtObject:
notify = blockedChanged
proc setBlocked*(self: ChatDetails, value: bool) =
if self.blocked == value:
return
self.blocked = value
self.blockedChanged()
@ -265,6 +296,8 @@ QtObject:
notify = canPostChanged
proc setCanPost*(self: ChatDetails, value: bool) =
if self.canPost == value:
return
self.canPost = value
self.canPostChanged()
@ -276,6 +309,8 @@ QtObject:
notify = canViewChanged
proc setCanView*(self: ChatDetails, value: bool) =
if self.canView == value:
return
self.canView = value
self.canViewChanged()
@ -287,6 +322,8 @@ QtObject:
notify = canPostReactionsChanged
proc setCanPostReactions*(self: ChatDetails, value: bool) =
if self.canPostReactions == value:
return
self.canPostReactions = value
self.canPostReactionsChanged()
@ -298,6 +335,8 @@ QtObject:
notify = hideIfPermissionsNotMetChanged
proc setHideIfPermissionsNotMet*(self: ChatDetails, value: bool) =
if self.hideIfPermissionsNotMet == value:
return
self.hideIfPermissionsNotMet = value
self.hideIfPermissionsNotMetChanged()
@ -309,5 +348,20 @@ QtObject:
notify = missingEncryptionKeyChanged
proc setMissingEncryptionKey*(self: ChatDetails, value: bool) =
if self.missingEncryptionKey == value:
return
self.missingEncryptionKey = value
self.missingEncryptionKeyChanged()
proc requiresPermissionsChanged(self: ChatDetails) {.signal.}
proc getRequiresPermissions(self: ChatDetails): bool {.slot.} =
return self.requiresPermissions
QtProperty[bool] requiresPermissions:
read = getRequiresPermissions
notify = requiresPermissionsChanged
proc setRequiresPermissions*(self: ChatDetails, value: bool) =
if self.requiresPermissions == value:
return
self.requiresPermissions = value
self.requiresPermissionsChanged()

View File

@ -97,7 +97,7 @@ method load*(self: Module, chatItem: chat_item.Item) =
chatItem.color, chatItem.description, chatItem.emoji, chatItem.hasUnreadMessages, chatItem.notificationsCount,
chatItem.highlight, chatItem.muted, chatItem.position, isUntrustworthy = trustStatus == TrustStatus.Untrustworthy,
isContact, chatItem.blocked, chatItem.canPost, chatItem.canView, chatItem.canPostReactions,
chatItem.hideIfPermissionsNotMet, chatItem.missingEncryptionKey)
chatItem.hideIfPermissionsNotMet, chatItem.missingEncryptionKey, chatItem.requiresPermissions)
self.view.chatDetailsChanged()
@ -383,6 +383,7 @@ method onChatUpdated*(self: Module, chatItem: chat_item.Item) =
self.view.chatDetails.setCanPostReactions(chatItem.canPostReactions)
self.view.chatDetails.setHideIfPermissionsNotMet(chat_item.hideIfPermissionsNotMet)
self.view.chatDetails.setMissingEncryptionKey(chat_item.missingEncryptionKey)
self.view.chatDetails.setRequiresPermissions(chat_item.requiresPermissions)
self.messagesModule.updateChatFetchMoreMessages()
self.messagesModule.updateChatIdentifier()
@ -400,6 +401,7 @@ method onCommunityChannelEdited*(self: Module, chatDto: ChatDto) =
self.view.chatDetails.setName(chatDto.name)
self.view.chatDetails.setIcon(chatDto.icon)
self.view.chatDetails.setMissingEncryptionKey(chatDto.missingEncryptionKey)
self.view.chatDetails.setRequiresPermissions(chatDto.tokenGated)
self.messagesModule.updateChatFetchMoreMessages()
self.messagesModule.updateChatIdentifier()

View File

@ -22,7 +22,7 @@ type
moduleLoaded: bool
# Forward declaration
proc addChatMember(self: Module, member: ChatMember)
proc processChatMember(self: Module, member: ChatMember): MemberItem
proc newModule*(
events: EventEmitter, sectionId: string, chatId: string,
@ -95,7 +95,9 @@ method userProfileUpdated*(self: Module) =
method loggedInUserImageChanged*(self: Module) =
self.view.model().setIcon(singletonInstance.userProfile.getPubKey(), singletonInstance.userProfile.getIcon())
proc addChatMember(self: Module, member: ChatMember) =
# This function either removes the member if it is no longer part of the community,
# does nothing if the member is already in the model or creates the MemberItem
proc processChatMember(self: Module, member: ChatMember): MemberItem =
if member.id == "":
return
@ -118,7 +120,7 @@ proc addChatMember(self: Module, member: ChatMember) =
let statusUpdateDto = self.controller.getStatusForContact(member.id)
status = toOnlineStatus(statusUpdateDto.statusType)
self.view.model().addItem(initMemberItem(
return initMemberItem(
pubKey = member.id,
displayName = contactDetails.dto.displayName,
ensName = contactDetails.dto.name,
@ -134,11 +136,17 @@ proc addChatMember(self: Module, member: ChatMember) =
memberRole = member.role,
joined = member.joined,
isUntrustworthy = contactDetails.dto.trustStatus == TrustStatus.Untrustworthy,
))
)
method onChatMembersAdded*(self: Module, ids: seq[string]) =
var memberItems: seq[MemberItem] = @[]
for memberId in ids:
self.addChatMember(ChatMember(id: memberId, role: MemberRole.None, joined: true))
let item = self.processChatMember(ChatMember(id: memberId, role: MemberRole.None, joined: true))
if item.pubKey != "":
memberItems.add(item)
self.view.model().addItems(memberItems)
method onChatMemberRemoved*(self: Module, id: string) =
self.view.model().removeItemById(id)
@ -148,8 +156,12 @@ method onMembersChanged*(self: Module, members: seq[ChatMember]) =
let membersAdded = filter(members, member => not modelIDs.contains(member.id))
let membersRemoved = filter(modelIDs, id => not members.any(member => member.id == id))
var memberItems: seq[MemberItem] = @[]
for member in membersAdded:
self.addChatMember(member)
let item = self.processChatMember(member)
if item.pubKey != "":
memberItems.add(item)
self.view.model().addItems(memberItems)
for id in membersRemoved:
self.onChatMemberRemoved(id)
@ -181,5 +193,11 @@ method removeGroupMembers*(self: Module, pubKeys: seq[string]) =
method updateMembersList*(self: Module) =
let members = self.controller.getChatMembers()
var memberItems: seq[MemberItem] = @[]
for member in members:
self.addChatMember(member)
let item = self.processChatMember(member)
if item.pubKey != "":
memberItems.add(item)
self.view.model().addItems(memberItems)

View File

@ -10,6 +10,7 @@ type
ModelRole {.pure.} = enum
PubKey = UserRole + 1
DisplayName
PreferredDisplayName
EnsName
IsEnsVerified
LocalNickname
@ -79,6 +80,7 @@ QtObject:
{
ModelRole.PubKey.int: "pubKey",
ModelRole.DisplayName.int: "displayName",
ModelRole.PreferredDisplayName.int: "preferredDisplayName",
ModelRole.EnsName.int: "ensName",
ModelRole.IsEnsVerified.int: "isEnsVerified",
ModelRole.LocalNickname.int: "localNickname",
@ -117,6 +119,14 @@ QtObject:
result = newQVariant(item.pubKey)
of ModelRole.DisplayName:
result = newQVariant(item.displayName)
of ModelRole.PreferredDisplayName:
if item.localNickname != "":
return newQVariant(item.localNickname)
if item.ensName != "":
return newQVariant(item.ensName)
if item.displayName != "":
return newQVariant(item.displayName)
return newQVariant(item.alias)
of ModelRole.EnsName:
result = newQVariant(item.ensName)
of ModelRole.IsEnsVerified:
@ -168,6 +178,21 @@ QtObject:
self.endInsertRows()
self.countChanged()
proc addItems*(self: Model, items: seq[MemberItem]) =
if items.len == 0:
return
let modelIndex = newQModelIndex()
defer: modelIndex.delete
let first = self.items.len
let last = first + items.len - 1
self.beginInsertRows(modelIndex, first, last)
self.items.add(items)
self.endInsertRows()
self.countChanged()
proc findIndexForMember(self: Model, pubKey: string): int =
for i in 0 ..< self.items.len:
if(self.items[i].pubKey == pubKey):
@ -187,27 +212,40 @@ QtObject:
proc isContactWithIdAdded*(self: Model, id: string): bool =
return self.findIndexForMember(id) != -1
proc setName*(self: Model, pubKey: string, displayName: string,
ensName: string, localNickname: string) =
proc setName*(self: Model, pubKey: string, displayName: string, ensName: string, localNickname: string) =
let ind = self.findIndexForMember(pubKey)
if(ind == -1):
if ind == -1:
return
self.items[ind].displayName = displayName
self.items[ind].ensName = ensName
self.items[ind].localNickname = localNickname
var roles: seq[int] = @[]
if self.items[ind].displayName != displayName:
self.items[ind].displayName = displayName
roles.add(ModelRole.DisplayName.int)
if self.items[ind].ensName != ensName:
self.items[ind].ensName = ensName
roles.add(ModelRole.EnsName.int)
if self.items[ind].localNickname != localNickname:
self.items[ind].localNickname = localNickname
roles.add(ModelRole.LocalNickname.int)
if roles.len == 0:
return
roles.add(ModelRole.PreferredDisplayName.int)
let index = self.createIndex(ind, 0, nil)
defer: index.delete
self.dataChanged(index, index, @[
ModelRole.DisplayName.int,
ModelRole.EnsName.int,
ModelRole.LocalNickname.int,
])
self.dataChanged(index, index, roles)
proc setIcon*(self: Model, pubKey: string, icon: string) =
let ind = self.findIndexForMember(pubKey)
if(ind == -1):
if ind == -1:
return
if self.items[ind].icon == icon:
return
self.items[ind].icon = icon
@ -232,36 +270,70 @@ QtObject:
isUntrustworthy: bool,
) =
let ind = self.findIndexForMember(pubKey)
if(ind == -1):
if ind == -1:
return
self.items[ind].displayName = displayName
self.items[ind].ensName = ensName
self.items[ind].isEnsVerified = isEnsVerified
self.items[ind].localNickname = localNickname
self.items[ind].alias = alias
self.items[ind].icon = icon
self.items[ind].isContact = isContact
self.items[ind].isVerified = isVerified
self.items[ind].memberRole = memberRole
self.items[ind].joined = joined
self.items[ind].isUntrustworthy = isUntrustworthy
var roles: seq[int] = @[]
var preferredNameMightHaveChanged = false
if self.items[ind].displayName != displayName:
self.items[ind].displayName = displayName
preferredNameMightHaveChanged = true
roles.add(ModelRole.DisplayName.int)
if self.items[ind].ensName != ensName:
self.items[ind].ensName = ensName
preferredNameMightHaveChanged = true
roles.add(ModelRole.EnsName.int)
if self.items[ind].localNickname != localNickname:
self.items[ind].localNickname = localNickname
preferredNameMightHaveChanged = true
roles.add(ModelRole.LocalNickname.int)
if self.items[ind].isEnsVerified != isEnsVerified:
self.items[ind].isEnsVerified = isEnsVerified
roles.add(ModelRole.IsEnsVerified.int)
if self.items[ind].alias != alias:
self.items[ind].alias = alias
preferredNameMightHaveChanged = true
roles.add(ModelRole.Alias.int)
if self.items[ind].icon != icon:
self.items[ind].icon = icon
roles.add(ModelRole.Icon.int)
if self.items[ind].isContact != isContact:
self.items[ind].isContact = isContact
roles.add(ModelRole.IsContact.int)
if self.items[ind].isVerified != isVerified:
self.items[ind].isVerified = isVerified
roles.add(ModelRole.IsVerified.int)
if self.items[ind].memberRole != memberRole:
self.items[ind].memberRole = memberRole
roles.add(ModelRole.MemberRole.int)
if self.items[ind].joined != joined:
self.items[ind].joined = joined
roles.add(ModelRole.Joined.int)
if self.items[ind].isUntrustworthy != isUntrustworthy:
self.items[ind].isUntrustworthy = isUntrustworthy
roles.add(ModelRole.IsUntrustworthy.int)
if preferredNameMightHaveChanged:
roles.add(ModelRole.PreferredDisplayName.int)
if roles.len == 0:
return
let index = self.createIndex(ind, 0, nil)
defer: index.delete
self.dataChanged(index, index, @[
ModelRole.DisplayName.int,
ModelRole.IsEnsVerified.int,
ModelRole.EnsName.int,
ModelRole.LocalNickname.int,
ModelRole.Alias.int,
ModelRole.Icon.int,
ModelRole.IsContact.int,
ModelRole.IsVerified.int,
ModelRole.MemberRole.int,
ModelRole.Joined.int,
ModelRole.IsUntrustworthy.int,
])
self.dataChanged(index, index, roles)
proc updateItem*(
self: Model,
@ -277,39 +349,30 @@ QtObject:
isUntrustworthy: bool,
) =
let ind = self.findIndexForMember(pubKey)
if(ind == -1):
if ind == -1:
return
self.items[ind].displayName = displayName
self.items[ind].ensName = ensName
self.items[ind].isEnsVerified = isEnsVerified
self.items[ind].localNickname = localNickname
self.items[ind].alias = alias
self.items[ind].icon = icon
self.items[ind].isContact = isContact
self.items[ind].isVerified = isVerified
self.items[ind].isUntrustworthy = isUntrustworthy
let index = self.createIndex(ind, 0, nil)
defer: index.delete
self.dataChanged(index, index, @[
ModelRole.DisplayName.int,
ModelRole.EnsName.int,
ModelRole.IsEnsVerified.int,
ModelRole.LocalNickname.int,
ModelRole.Alias.int,
ModelRole.Icon.int,
ModelRole.IsContact.int,
ModelRole.IsVerified.int,
ModelRole.IsUntrustworthy.int,
])
self.updateItem(
pubKey,
displayName,
ensName,
isEnsVerified,
localNickname,
alias,
icon,
isContact,
isVerified,
memberRole = self.items[ind].memberRole,
joined = self.items[ind].joined,
isUntrustworthy,
)
proc setOnlineStatus*(self: Model, pubKey: string, onlineStatus: OnlineStatus) =
let idx = self.findIndexForMember(pubKey)
if(idx == -1):
if idx == -1:
return
if(self.items[idx].onlineStatus == onlineStatus):
if self.items[idx].onlineStatus == onlineStatus:
return
self.items[idx].onlineStatus = onlineStatus
@ -321,10 +384,10 @@ QtObject:
proc setAirdropAddress*(self: Model, pubKey: string, airdropAddress: string) =
let idx = self.findIndexForMember(pubKey)
if(idx == -1):
if idx == -1:
return
if(self.items[idx].airdropAddress == airdropAddress):
if self.items[idx].airdropAddress == airdropAddress:
return
self.items[idx].airdropAddress = airdropAddress
@ -337,7 +400,7 @@ QtObject:
# TODO: rename me to removeItemByPubkey
proc removeItemById*(self: Model, pubKey: string) =
let ind = self.findIndexForMember(pubKey)
if(ind == -1):
if ind == -1:
return
self.removeItemWithIndex(ind)
@ -348,7 +411,10 @@ QtObject:
proc updateLoadingState*(self: Model, memberKey: string, requestToJoinLoading: bool) =
let idx = self.findIndexForMember(memberKey)
if(idx == -1):
if idx == -1:
return
if self.items[idx].requestToJoinLoading == requestToJoinLoading:
return
self.items[idx].requestToJoinLoading = requestToJoinLoading
@ -358,12 +424,15 @@ QtObject:
ModelRole.RequestToJoinLoading.int
])
proc updateMembershipStatus*(self: Model, memberKey: string, status: MembershipRequestState) {.inline.} =
proc updateMembershipStatus*(self: Model, memberKey: string, membershipRequestState: MembershipRequestState) {.inline.} =
let idx = self.findIndexForMember(memberKey)
if(idx == -1):
if idx == -1:
return
self.items[idx].membershipRequestState = status
if self.items[idx].membershipRequestState == membershipRequestState:
return
self.items[idx].membershipRequestState = membershipRequestState
let index = self.createIndex(idx, 0, nil)
defer: index.delete
self.dataChanged(index, index, @[

View File

@ -90,15 +90,6 @@ Item {
model: SortFilterProxyModel {
sourceModel: root.usersModel
proxyRoles: FastExpressionRole {
function displayNameProxy(nickname, ensName, displayName, aliasName) {
return ProfileUtils.displayName(nickname, ensName, displayName, aliasName)
}
name: "preferredDisplayName"
expectedRoles: ["localNickname", "ensName", "displayName", "alias"]
expression: displayNameProxy(model.localNickname, model.ensName, model.displayName, model.alias)
}
sorters: [
RoleSorter {
roleName: "onlineStatus"

View File

@ -320,29 +320,6 @@ QtObject {
return userProfileInst.pubKey
}
function getCommunity(communityId) {
// Not Refactored Yet
// try {
// const communityJson = chatsModelInst.communities.list.getCommunityByIdJson(communityId);
// if (!communityJson) {
// return null;
// }
// let community = JSON.parse(communityJson);
// if (community) {
// community.nbMembers = community.members.length;
// }
// return community
// } catch (e) {
// console.error("Error parsing community", e);
// }
return null;
}
// Not Refactored Yet
property var activeCommunityChatsModel: "" //chatsModelInst.communities.activeCommunity.chats
function createCommunity(args = {
name: "",
description: "",
@ -438,11 +415,6 @@ QtObject {
chatCommunitySectionModule.declineRequestToJoinCommunity(requestId, communityId)
}
function userNameOrAlias(pk) {
// Not Refactored Yet
// return chatsModelInst.userNameOrAlias(pk);
}
function generateAlias(pk) {
return globalUtilsInst.generateAlias(pk);
}

View File

@ -162,12 +162,11 @@ StatusSectionLayout {
return false
}
let chatContentModule = root.rootStore.currentChatContentModule()
if (!chatContentModule) {
if (!root.chatContentModule) {
return false
}
// Check if user list is available as an option for particular chat content module
return chatContentModule.chatDetails.isUsersListAvailable
return root.chatContentModule.chatDetails.isUsersListAvailable
}
rightPanel: Component {

View File

@ -149,22 +149,14 @@ QtObject {
mainModuleInst.switchTo(sectionId, chatId)
}
// Not Refactored Yet
// property var chatsModelInst: chatsModel
// Not Refactored Yet
// property var walletModelInst: walletModel
property var userProfileInst: userProfile
readonly property var accounts: walletSectionAccounts.accounts
// Not Refactored Yet
// property var profileModelInst: profileModel
property ProfileStores.ContactsStore contactStore: profileSectionStore.contactsStore
property ProfileStores.PrivacyStore privacyStore: profileSectionStore.privacyStore
property ProfileStores.MessagingStore messagingStore: profileSectionStore.messagingStore
property bool hasAddedContacts: contactStore.myContactsModel.count > 0
// property MessageStore messageStore: MessageStore { }
property real volume: !!appSettings ? appSettings.volume * 0.01 : 0.5
property bool notificationSoundsEnabled: !!appSettings ? appSettings.notificationSoundsEnabled : true