refactor(chats): pass chat group to section to simplify UI build

Fixes #5183
This commit is contained in:
Jonathan Rainville 2022-04-12 09:47:39 -04:00 committed by Iuri Matias
parent b3cda3e755
commit 72d726f250
4 changed files with 82 additions and 93 deletions

View File

@ -18,7 +18,9 @@ type
method delete*(self: AccessInterface) {.base.} = method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method load*(self: AccessInterface, events: EventEmitter, method load*(self: AccessInterface,
channelGroup: ChannelGroupDto,
events: EventEmitter,
settingsService: settings_service.Service, settingsService: settings_service.Service,
contactService: contact_service.Service, contactService: contact_service.Service,
chatService: chat_service.Service, chatService: chat_service.Service,

View File

@ -1,4 +1,4 @@
import NimQml, Tables, chronicles, json, sequtils, strutils, strformat import NimQml, Tables, chronicles, json, sequtils, strutils, strformat, sugar
import io_interface import io_interface
import ../io_interface as delegate_interface import ../io_interface as delegate_interface
@ -35,11 +35,23 @@ type
chatContentModules: OrderedTable[string, chat_content_module.AccessInterface] chatContentModules: OrderedTable[string, chat_content_module.AccessInterface]
moduleLoaded: bool moduleLoaded: bool
# Forward declaration
proc buildChatSectionUI(self: Module,
channelGroup: ChannelGroupDto,
events: EventEmitter,
settingsService: settings_service.Service,
contactService: contact_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service)
proc newModule*( proc newModule*(
delegate: delegate_interface.AccessInterface, delegate: delegate_interface.AccessInterface,
events: EventEmitter, events: EventEmitter,
sectionId: string, sectionId: string,
# channels: seq[ChatDto],
isCommunity: bool, isCommunity: bool,
settingsService: settings_service.Service, settingsService: settings_service.Service,
contactService: contact_service.Service, contactService: contact_service.Service,
@ -96,91 +108,65 @@ proc removeSubmodule(self: Module, chatId: string) =
return return
self.chatContentModules.del(chatId) self.chatContentModules.del(chatId)
proc buildChatUI(self: Module, events: EventEmitter, proc buildChatSectionUI(
settingsService: settings_service.Service, self: Module,
contactService: contact_service.Service, channelGroup: ChannelGroupDto,
chatService: chat_service.Service, events: EventEmitter,
communityService: community_service.Service, settingsService: settings_service.Service,
messageService: message_service.Service, contactService: contact_service.Service,
gifService: gif_service.Service, chatService: chat_service.Service,
mailserversService: mailservers_service.Service) = communityService: community_service.Service,
let types = @[ChatType.OneToOne, ChatType.Public, ChatType.PrivateGroupChat] messageService: message_service.Service,
let chats = self.controller.getChatDetailsForChatTypes(types) gifService: gif_service.Service,
mailserversService: mailservers_service.Service) =
var selectedItemId = "" var selectedItemId = ""
for c in chats: var selectedSubItemId = ""
let hasNotification = c.unviewedMessagesCount > 0 or c.unviewedMentionsCount > 0
let notificationsCount = c.unviewedMentionsCount # handle channels which don't belong to any category
var chatName = c.name for chatDto in channelGroup.chats:
if (chatDto.categoryId != ""):
continue
let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0
let notificationsCount = chatDto.unviewedMentionsCount
var chatName = chatDto.name
var chatImage = "" var chatImage = ""
var colorHash: ColorHashDto = @[] var colorHash: ColorHashDto = @[]
var colorId: int = 0 var colorId: int = 0
let isUsersListAvailable = (c.chatType != ChatType.OneToOne and c.chatType != ChatType.Public) let isUsersListAvailable = (chatDto.chatType != ChatType.OneToOne and
chatDto.chatType != ChatType.Public)
var blocked = false var blocked = false
if(c.chatType == ChatType.OneToOne): let belongToCommunity = chatDto.communityId != ""
let contactDetails = self.controller.getContactDetails(c.id) if(chatDto.chatType == ChatType.OneToOne):
let contactDetails = self.controller.getContactDetails(chatDto.id)
chatName = contactDetails.displayName chatName = contactDetails.displayName
chatImage = contactDetails.icon chatImage = contactDetails.icon
blocked = contactDetails.details.isBlocked() blocked = contactDetails.details.isBlocked()
colorHash = self.controller.getColorHash(c.id) colorHash = self.controller.getColorHash(chatDto.id)
colorId = self.controller.getColorId(c.id) colorId = self.controller.getColorId(chatDto.id)
let amIChatAdmin = self.amIMarkedAsAdminUser(c.members) let amIChatAdmin = self.amIMarkedAsAdminUser(chatDto.members)
let item = initItem(c.id, chatName, chatImage, c.color, c.emoji, c.description, let channelItem = initItem(chatDto.id, chatName, chatImage, chatDto.color,
c.chatType.int, amIChatAdmin, hasNotification, notificationsCount, c.muted, blocked,
active=false, c.position, c.categoryId, colorId, colorHash)
self.view.chatsModel().appendItem(item)
self.addSubmodule(c.id, false, isUsersListAvailable, events, settingsService, contactService, chatService,
communityService, messageService, gifService, mailserversService)
# make the first Public chat active when load the app
if(selectedItemId.len == 0 and c.chatType == ChatType.Public):
selectedItemId = item.id
self.setActiveItemSubItem(selectedItemId, "")
proc buildCommunityUI(self: Module, events: EventEmitter,
settingsService: settings_service.Service,
contactService: contact_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service) =
var selectedItemId = ""
var selectedSubItemId = ""
let comm = self.controller.getMyCommunity()
# handle channels which don't belong to any category
let chats = self.controller.getChats(comm.id, "")
for c in chats:
let chatDto = self.controller.getChatDetails(comm.id, c.id)
let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0
let notificationsCount = chatDto.unviewedMentionsCount
let amIChatAdmin = comm.admin
let channelItem = initItem(chatDto.id, chatDto.name, chatDto.icon, chatDto.color,
chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification, chatDto.emoji, chatDto.description, chatDto.chatType.int, amIChatAdmin, hasNotification,
notificationsCount, chatDto.muted, blocked=false, active = false, c.position, c.categoryId) notificationsCount, chatDto.muted, blocked, chatDto.active, chatDto.position,
chatDto.categoryId, colorId, colorHash)
self.view.chatsModel().appendItem(channelItem) self.view.chatsModel().appendItem(channelItem)
self.addSubmodule(chatDto.id, true, true, events, settingsService, contactService, chatService, communityService, self.addSubmodule(chatDto.id, belongToCommunity, isUsersListAvailable, events, settingsService,
messageService, gifService, mailserversService) contactService, chatService, communityService, messageService, gifService, mailserversService)
# make the first channel which doesn't belong to any category active when load the app # make the first channel which doesn't belong to any category active when load the app
if(selectedItemId.len == 0): if(selectedItemId.len == 0):
selectedItemId = channelItem.id selectedItemId = channelItem.id
# handle categories and channels for each category # handle categories and channels for each category
let categories = self.controller.getCategories(comm.id) for cat in channelGroup.categories:
for cat in categories:
var hasNotificationPerCategory = false var hasNotificationPerCategory = false
var notificationsCountPerCategory = 0 var notificationsCountPerCategory = 0
var categoryChannels: seq[SubItem] var categoryChannels: seq[SubItem]
let categoryChats = self.controller.getChats(comm.id, cat.id) let categoryChats = channelGroup.chats.filter(c => c.categoryId == cat.id)
for c in categoryChats: for chatDto in categoryChats:
let chatDto = self.controller.getChatDetails(comm.id, c.id)
let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0 let hasNotification = chatDto.unviewedMessagesCount > 0 or chatDto.unviewedMentionsCount > 0
let notificationsCount = chatDto.unviewedMentionsCount let notificationsCount = chatDto.unviewedMentionsCount
@ -188,15 +174,16 @@ proc buildCommunityUI(self: Module, events: EventEmitter,
hasNotificationPerCategory = hasNotificationPerCategory or hasNotification hasNotificationPerCategory = hasNotificationPerCategory or hasNotification
notificationsCountPerCategory += notificationsCount notificationsCountPerCategory += notificationsCount
let amIChatAdmin = comm.admin let amIChatAdmin = channelGroup.admin
let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.icon, let channelItem = initSubItem(chatDto.id, cat.id, chatDto.name, chatDto.icon,
chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int, chatDto.color, chatDto.emoji, chatDto.description, chatDto.chatType.int,
amIChatAdmin, hasNotification, notificationsCount, chatDto.muted, blocked=false, amIChatAdmin, hasNotification, notificationsCount, chatDto.muted, blocked=false,
active=false, c.position) active=false, chatDto.position)
categoryChannels.add(channelItem) categoryChannels.add(channelItem)
self.addSubmodule(chatDto.id, true, true, events, settingsService, contactService, chatService, communityService, self.addSubmodule(chatDto.id, belongToCommunity=true, isUsersListAvailable=true, events,
messageService, gifService, mailserversService) settingsService, contactService, chatService, communityService, messageService, gifService,
mailserversService)
# in case there is no channels beyond categories, # in case there is no channels beyond categories,
# make the first channel of the first category active when load the app # make the first channel of the first category active when load the app
@ -250,22 +237,27 @@ method initListOfMyContacts*(self: Module, pubKeys: string) =
method clearListOfMyContacts*(self: Module) = method clearListOfMyContacts*(self: Module) =
self.view.listOfMyContacts().clear() self.view.listOfMyContacts().clear()
method load*(self: Module, events: EventEmitter,
settingsService: settings_service.Service, method load*(
contactService: contact_service.Service, self: Module,
chatService: chat_service.Service, channelGroup: ChannelGroupDto,
communityService: community_service.Service, events: EventEmitter,
messageService: message_service.Service, settingsService: settings_service.Service,
gifService: gif_service.Service, contactService: contact_service.Service,
mailserversService: mailservers_service.Service) = chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service) =
self.controller.init() self.controller.init()
self.view.load() self.view.load()
if(self.controller.isCommunity()): self.buildChatSectionUI(channelGroup, events, settingsService, contactService, chatService,
self.buildCommunityUI(events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) communityService, messageService, gifService, mailserversService)
else:
self.buildChatUI(events, settingsService, contactService, chatService, communityService, messageService, gifService, mailserversService) if(not self.controller.isCommunity()):
self.initContactRequestsModel() # we do this only in case of chat section (not in case of communities) # we do this only in case of chat section (not in case of communities)
self.initContactRequestsModel()
for cModule in self.chatContentModules.values: for cModule in self.chatContentModules.values:
cModule.load() cModule.load()

View File

@ -198,9 +198,6 @@ proc init*(self: Controller) =
proc isConnected*(self: Controller): bool = proc isConnected*(self: Controller): bool =
return self.nodeService.isConnected() return self.nodeService.isConnected()
proc getJoinedCommunities*(self: Controller): seq[CommunityDto] =
return self.communityService.getJoinedCommunities()
proc getChannelGroups*(self: Controller): seq[ChannelGroupDto] = proc getChannelGroups*(self: Controller): seq[ChannelGroupDto] =
return self.chatService.getChannelGroups() return self.chatService.getChannelGroups()

View File

@ -271,6 +271,9 @@ method load*[T](
self.view.model().addItem(channelGroupItem) self.view.model().addItem(channelGroupItem)
if(activeSectionId == channelGroupItem.id): if(activeSectionId == channelGroupItem.id):
activeSection = channelGroupItem activeSection = channelGroupItem
self.channelGroupModules[channelGroup.id].load(channelGroup, events, settingsService,
contactsService, chatService, communityService, messageService, gifService, mailserversService)
# Wallet Section # Wallet Section
let walletSectionItem = initItem(conf.WALLET_SECTION_ID, SectionType.Wallet, conf.WALLET_SECTION_NAME, let walletSectionItem = initItem(conf.WALLET_SECTION_ID, SectionType.Wallet, conf.WALLET_SECTION_NAME,
@ -334,11 +337,6 @@ method load*[T](
if(activeSectionId == profileSettingsSectionItem.id): if(activeSectionId == profileSettingsSectionItem.id):
activeSection = profileSettingsSectionItem activeSection = profileSettingsSectionItem
# Load all sections
for cModule in self.channelGroupModules.values:
cModule.load(events, settingsService, contactsService, chatService, communityService,
messageService, gifService, mailserversService)
self.browserSectionModule.load() self.browserSectionModule.load()
# self.nodeManagementSectionModule.load() # self.nodeManagementSectionModule.load()
self.profileSectionModule.load() self.profileSectionModule.load()
@ -578,10 +576,10 @@ method communityJoined*[T](
gifService, gifService,
mailserversService mailserversService
) )
self.channelGroupModules[community.id].load(events, settingsService, contactsService, chatService,
communityService, messageService, gifService, mailserversService)
let channelGroup = community.toChannelGroupDto() let channelGroup = community.toChannelGroupDto()
self.channelGroupModules[community.id].load(channelGroup, events, settingsService, contactsService,
chatService, communityService, messageService, gifService, mailserversService)
let communitySectionItem = self.createChannelGroupItem(channelGroup) let communitySectionItem = self.createChannelGroupItem(channelGroup)
if (firstCommunityJoined): if (firstCommunityJoined):
# If there are no other communities, add the first community after the Chat section in the model so that the order is respected # If there are no other communities, add the first community after the Chat section in the model so that the order is respected