refactor(communities): add communities module to show comm list

This commit is contained in:
Jonathan Rainville 2021-12-14 14:21:50 -05:00 committed by Sale Djenic
parent 1977420db2
commit 129266497d
19 changed files with 289 additions and 55 deletions

View File

@ -70,8 +70,8 @@ method setSearchLocation*(self: Controller, location: string, subLocation: strin
self.searchLocation = location
self.searchSubLocation = subLocation
method getCommunities*(self: Controller): seq[CommunityDto] =
return self.communityService.getCommunities()
method getJoinedCommunities*(self: Controller): seq[CommunityDto] =
return self.communityService.getJoinedCommunities()
method getCommunityById*(self: Controller, communityId: string): CommunityDto =
return self.communityService.getCommunityById(communityId)

View File

@ -33,7 +33,7 @@ method searchSubLocation*(self: AccessInterface): string {.base.} =
method setSearchLocation*(self: AccessInterface, location: string, subLocation: string) {.base.} =
raise newException(ValueError, "No implementation available")
method getCommunities*(self: AccessInterface): seq[CommunityDto] {.base.} =
method getJoinedCommunities*(self: AccessInterface): seq[CommunityDto] {.base.} =
raise newException(ValueError, "No implementation available")
method getCommunityById*(self: AccessInterface, communityId: string): CommunityDto {.base.} =

View File

@ -107,7 +107,7 @@ method prepareLocationMenuModel*(self: Module) =
var items: seq[location_menu_item.Item]
items.add(self.buildLocationMenuForChat())
let communities = self.controller.getCommunities()
let communities = self.controller.getJoinedCommunities()
for c in communities:
items.add(self.buildLocationMenuForCommunity(c))
@ -153,7 +153,7 @@ method onSearchMessagesDone*(self: Module, messages: seq[MessageDto]) =
var channels: seq[result_item.Item]
# Add communities
let communities = self.controller.getCommunities()
let communities = self.controller.getJoinedCommunities()
for co in communities:
if(self.controller.searchLocation().len == 0 and co.name.toLower.startsWith(self.controller.searchTerm().toLower)):
let item = result_item.initItem(co.id, "", "", co.id, co.name, SEARCH_RESULT_COMMUNITIES_SECTION_NAME,

View File

@ -0,0 +1,33 @@
import Tables, stint
import eventemitter
import ./controller_interface
import ./io_interface
import ../../../../app/core/signals/types
import ../../../../app_service/service/community/service as community_service
export controller_interface
type
Controller*[T: controller_interface.DelegateInterface] = ref object of controller_interface.AccessInterface
delegate: io_interface.AccessInterface
events: EventEmitter
communityService: community_service.Service
proc newController*[T](
delegate: io_interface.AccessInterface,
events: EventEmitter,
communityService: community_service.Service
): Controller[T] =
result = Controller[T]()
result.delegate = delegate
result.events = events
result.communityService = communityService
method delete*[T](self: Controller[T]) =
discard
method init*[T](self: Controller[T]) =
let communities = self.communityService.getAllCommunities()
self.delegate.setAllCommunities(communities)

View File

@ -0,0 +1,16 @@
import ../../../../app_service/service/community/service as community_service
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for any input/interaction with this module.
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method init*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this
## module.
DelegateInterface* = concept c

View File

@ -0,0 +1,26 @@
import ../../../../app_service/service/community/service as community_service
type
AccessInterface* {.pure inheritable.} = ref object of RootObj
## Abstract class for any input/interaction with this module.
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method load*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method isLoaded*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
method viewDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method setAllCommunities*(self: AccessInterface, communities: seq[CommunityDto]) {.base.} =
raise newException(ValueError, "No implementation available")
type
## Abstract class (concept) which must be implemented by object/s used in this
## module.
DelegateInterface* = concept c
c.communitiesModuleDidLoad()

View File

@ -0,0 +1,60 @@
import NimQml, sequtils
import eventemitter
import ./io_interface, ./view, ./controller
import ../item
import ../../../global/global_singleton
import ../../../../app_service/service/community/service as community_service
export io_interface
type
Module* [T: io_interface.DelegateInterface] = ref object of io_interface.AccessInterface
delegate: T
controller: controller.AccessInterface
view: View
viewVariant: QVariant
moduleLoaded: bool
proc newModule*[T](
delegate: T,
events: EventEmitter,
communityService: community_service.Service
): Module[T] =
result = Module[T]()
result.delegate = delegate
result.view = newView(result)
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController[Module[T]](
result,
events,
communityService
)
result.moduleLoaded = false
method delete*[T](self: Module[T]) =
self.view.delete
method load*[T](self: Module[T]) =
singletonInstance.engine.setRootContextProperty("communitiesModule", self.viewVariant)
self.controller.init()
self.view.load()
method isLoaded*[T](self: Module[T]): bool =
return self.moduleLoaded
method viewDidLoad*[T](self: Module[T]) =
self.moduleLoaded = true
self.delegate.communitiesModuleDidLoad()
method setAllCommunities*[T](self: Module[T], communities: seq[CommunityDto]) =
for c in communities:
let communityItem = initItem(
c.id,
SectionType.Community,
c.name,
c.description,
c.images.thumbnail,
icon = "",
c.color)
self.view.addItem(communityItem)

View File

@ -0,0 +1,36 @@
import NimQml, json, strutils, json_serialization, sequtils
import ./io_interface
import ../model, ../item
QtObject:
type
View* = ref object of QObject
delegate: io_interface.AccessInterface
model: Model
modelVariant: QVariant
proc delete*(self: View) =
self.model.delete
self.modelVariant.delete
self.QObject.delete
proc newView*(delegate: io_interface.AccessInterface): View =
new(result, delete)
result.QObject.setup
result.delegate = delegate
result.model = newModel()
result.modelVariant = newQVariant(result.model)
proc load*(self: View) =
self.delegate.viewDidLoad()
proc addItem*(self: View, item: Item) =
self.model.addItem(item)
proc getModel(self: View): QVariant {.slot.} =
return newQVariant(self.modelVariant)
QtProperty[QVariant] model:
read = getModel

View File

@ -79,8 +79,8 @@ method init*(self: Controller) =
## self.delegate.disableSection(sectionType)
discard
method getCommunities*(self: Controller): seq[CommunityDto] =
return self.communityService.getCommunities()
method getJoinedCommunities*(self: Controller): seq[CommunityDto] =
return self.communityService.getJoinedCommunities()
method checkForStoringPassword*(self: Controller) =
# This method is called once user is logged in irrespective he is logged in
@ -130,7 +130,7 @@ method getNumOfNotificaitonsForChat*(self: Controller): tuple[unviewed:int, ment
result.unviewed += chat.unviewedMessagesCount
result.mentions += chat.unviewedMentionsCount
method getNumOfNotificaitonsForCommunity*(self: Controller, communityId: string): tuple[unviewed:int, mentions:int] =
method getNumOfNotificationsForCommunity*(self: Controller, communityId: string): tuple[unviewed:int, mentions:int] =
result.unviewed = 0
result.mentions = 0
let chats = self.chatService.getAllChats()

View File

@ -11,7 +11,7 @@ method delete*(self: AccessInterface) {.base.} =
method init*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getCommunities*(self: AccessInterface): seq[community_service.CommunityDto] {.base.} =
method getJoinedCommunities*(self: AccessInterface): seq[community_service.CommunityDto] {.base.} =
raise newException(ValueError, "No implementation available")
method checkForStoringPassword*(self: AccessInterface) {.base.} =
@ -26,7 +26,7 @@ method setActiveSection*(self: AccessInterface, sectionId: string, sectionType:
method getNumOfNotificaitonsForChat*(self: AccessInterface): tuple[unviewed:int, mentions:int] {.base.} =
raise newException(ValueError, "No implementation available")
method getNumOfNotificaitonsForCommunity*(self: AccessInterface, communityId: string): tuple[unviewed:int, mentions:int]
method getNumOfNotificationsForCommunity*(self: AccessInterface, communityId: string): tuple[unviewed:int, mentions:int]
{.base.} =
raise newException(ValueError, "No implementation available")

View File

@ -15,6 +15,7 @@ type
sectionType: SectionType
id: string
name: string
description: string
image: string
icon: string
color: string
@ -23,11 +24,23 @@ type
active: bool
enabled: bool
proc initItem*(id: string, sectionType: SectionType, name, image = "", icon = "", color = "", hasNotification = false,
notificationsCount: int = 0, active = false, enabled = true): Item =
proc initItem*(
id: string,
sectionType: SectionType,
name,
description = "",
image = "",
icon = "",
color = "",
hasNotification = false,
notificationsCount: int = 0,
active = false,
enabled = true
): Item =
result.id = id
result.sectionType = sectionType
result.name = name
result.description = description
result.image = image
result.icon = icon
result.color = color
@ -44,6 +57,7 @@ proc `$`*(self: Item): string =
id: {self.id},
sectionType: {self.sectionType.int},
name: {self.name},
description: {self.description},
image: {self.image},
icon: {self.icon},
color: {self.color},
@ -62,6 +76,9 @@ proc sectionType*(self: Item): SectionType {.inline.} =
proc name*(self: Item): string {.inline.} =
self.name
proc description*(self: Item): string {.inline.} =
self.description
proc image*(self: Item): string {.inline.} =
self.image

View File

@ -7,6 +7,7 @@ type
Id = UserRole + 1
SectionType
Name
Description
Image
Icon
Color
@ -54,6 +55,7 @@ QtObject:
ModelRole.Id.int:"id",
ModelRole.SectionType.int:"sectionType",
ModelRole.Name.int:"name",
ModelRole.Description.int:"description",
ModelRole.Image.int:"image",
ModelRole.Icon.int:"icon",
ModelRole.Color.int:"color",
@ -80,6 +82,8 @@ QtObject:
result = newQVariant(item.sectionType.int)
of ModelRole.Name:
result = newQVariant(item.name)
of ModelRole.Description:
result = newQVariant(item.description)
of ModelRole.Image:
result = newQVariant(item.image)
of ModelRole.Icon:

View File

@ -11,6 +11,7 @@ import profile_section/module as profile_section_module
import app_search/module as app_search_module
import stickers/module as stickers_module
import activity_center/module as activity_center_module
import communities/module as communities_module
import ../../../app_service/service/keychain/service as keychain_service
import ../../../app_service/service/chat/service as chat_service
@ -52,6 +53,7 @@ type
profileSectionModule: profile_section_module.AccessInterface
stickersModule: stickers_module.AccessInterface
activityCenterModule: activity_center_module.AccessInterface
communitiesModule: communities_module.AccessInterface
appSearchModule: app_search_module.AccessInterface
moduleLoaded: bool
@ -105,6 +107,7 @@ proc newModule*[T](
profileService, contactsService, aboutService, languageService, mnemonicService, privacyService)
result.stickersModule = stickers_module.newModule(result, events, stickersService)
result.activityCenterModule = activity_center_module.newModule(result, events, activityCenterService, contactsService)
result.communitiesModule = communities_module.newModule(result, events, communityService)
result.appSearchModule = app_search_module.newModule(result, events, contactsService, chatService, communityService,
messageService)
@ -113,6 +116,7 @@ method delete*[T](self: Module[T]) =
self.profileSectionModule.delete
self.stickersModule.delete
self.activityCenterModule.delete
self.communitiesModule.delete
for cModule in self.communitySectionsModule.values:
cModule.delete
self.communitySectionsModule.clear
@ -135,10 +139,10 @@ method load*[T](
self.controller.init()
self.view.load()
# Create community modules here, since we don't know earlier how many communities we have.
let communities = self.controller.getCommunities()
# Create community modules here, since we don't know earlier how many joined communities we have.
let joinedCommunities = self.controller.getJoinedCommunities()
for c in communities:
for c in joinedCommunities:
self.communitySectionsModule[c.id] = chat_section_module.newModule(
self,
events,
@ -157,7 +161,7 @@ method load*[T](
let (unviewedCount, mentionsCount) = self.controller.getNumOfNotificaitonsForChat()
let hasNotification = unviewedCount > 0 or mentionsCount > 0
let notificationsCount = mentionsCount
let chatSectionItem = initItem(conf.CHAT_SECTION_ID, SectionType.Chat, conf.CHAT_SECTION_NAME, "",
let chatSectionItem = initItem(conf.CHAT_SECTION_ID, SectionType.Chat, conf.CHAT_SECTION_NAME, "", "",
conf.CHAT_SECTION_ICON, "", hasNotification, notificationsCount,
false, true)
self.view.addItem(chatSectionItem)
@ -165,18 +169,18 @@ method load*[T](
activeSection = chatSectionItem
# Community Section
for c in communities:
let (unviewedCount, mentionsCount) = self.controller.getNumOfNotificaitonsForCommunity(c.id)
for c in joinedCommunities:
let (unviewedCount, mentionsCount) = self.controller.getNumOfNotificationsForCommunity(c.id)
let hasNotification = unviewedCount > 0 or mentionsCount > 0
let notificationsCount = mentionsCount # we need to add here number of requests
let communitySectionItem = initItem(c.id, SectionType.Community, c.name, c.images.thumbnail, "", c.color,
hasNotification, notificationsCount, false, singletonInstance.localAccountSensitiveSettings.getCommunitiesEnabled())
let communitySectionItem = initItem(c.id, SectionType.Community, c.name, c.description, c.images.thumbnail, "",
c.color, hasNotification, notificationsCount, false, singletonInstance.localAccountSensitiveSettings.getCommunitiesEnabled())
self.view.addItem(communitySectionItem)
if(activeSectionId == communitySectionItem.id):
activeSection = communitySectionItem
# 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, "", "",
conf.WALLET_SECTION_ICON, "", false, 0, false,
singletonInstance.localAccountSensitiveSettings.getIsWalletEnabled())
self.view.addItem(walletSectionItem)
@ -184,7 +188,7 @@ method load*[T](
activeSection = walletSectionItem
# WalletV2 Section
let walletV2SectionItem = initItem(conf.WALLETV2_SECTION_ID, SectionType.WalletV2, conf.WALLETV2_SECTION_NAME, "",
let walletV2SectionItem = initItem(conf.WALLETV2_SECTION_ID, SectionType.WalletV2, conf.WALLETV2_SECTION_NAME, "", "",
conf.WALLETV2_SECTION_ICON, "", false, 0, false,
singletonInstance.localAccountSensitiveSettings.getIsWalletV2Enabled())
self.view.addItem(walletV2SectionItem)
@ -192,7 +196,7 @@ method load*[T](
activeSection = walletV2SectionItem
# Browser Section
let browserSectionItem = initItem(conf.BROWSER_SECTION_ID, SectionType.Browser, conf.BROWSER_SECTION_NAME, "",
let browserSectionItem = initItem(conf.BROWSER_SECTION_ID, SectionType.Browser, conf.BROWSER_SECTION_NAME, "", "",
conf.BROWSER_SECTION_ICON, "", false, 0, false,
singletonInstance.localAccountSensitiveSettings.getIsBrowserEnabled())
self.view.addItem(browserSectionItem)
@ -201,7 +205,7 @@ method load*[T](
# Node Management Section
let nodeManagementSectionItem = initItem(conf.NODEMANAGEMENT_SECTION_ID, SectionType.NodeManagement,
conf.NODEMANAGEMENT_SECTION_NAME, "", conf.NODEMANAGEMENT_SECTION_ICON, "", false, 0, false,
conf.NODEMANAGEMENT_SECTION_NAME, "", "", conf.NODEMANAGEMENT_SECTION_ICON, "", false, 0, false,
singletonInstance.localAccountSensitiveSettings.getNodeManagementEnabled())
self.view.addItem(nodeManagementSectionItem)
if(activeSectionId == nodeManagementSectionItem.id):
@ -209,7 +213,7 @@ method load*[T](
# Profile Section
let profileSettingsSectionItem = initItem(conf.SETTINGS_SECTION_ID, SectionType.ProfileSettings,
conf.SETTINGS_SECTION_NAME, "", conf.SETTINGS_SECTION_ICON, "", false, 0, false, true)
conf.SETTINGS_SECTION_NAME, "", "", conf.SETTINGS_SECTION_ICON, "", false, 0, false, true)
self.view.addItem(profileSettingsSectionItem)
if(activeSectionId == profileSettingsSectionItem.id):
activeSection = profileSettingsSectionItem
@ -226,6 +230,7 @@ method load*[T](
self.profileSectionModule.load()
self.stickersModule.load()
self.activityCenterModule.load()
self.communitiesModule.load()
self.appSearchModule.load()
# Set active section on app start
@ -257,6 +262,9 @@ proc checkIfModuleDidLoad [T](self: Module[T]) =
if(not self.activityCenterModule.isLoaded()):
return
if(not self.communitiesModule.isLoaded()):
return
if(not self.appSearchModule.isLoaded()):
return
@ -278,6 +286,9 @@ proc stickersDidLoad*[T](self: Module[T]) =
proc activityCenterDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()
proc communitiesModuleDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()
proc walletSectionDidLoad*[T](self: Module[T]) =
self.checkIfModuleDidLoad()

View File

@ -1,7 +1,8 @@
{.used.}
import json
import json, sequtils
import status/statusgo_backend_new/communities
include ../../../common/json_utils
type
@ -140,3 +141,7 @@ proc toCommunityDto*(jsonObj: JsonNode): CommunityDto =
discard jsonObj.getProp("requestedToJoinAt", result.requestedToJoinAt)
discard jsonObj.getProp("isMember", result.isMember)
discard jsonObj.getProp("muted", result.muted)
proc parseCommunities*(response: RpcResponse[JsonNode]): seq[CommunityDto] =
result = map(response.result.getElems(),
proc(x: JsonNode): CommunityDto = x.toCommunityDto())

View File

@ -13,44 +13,60 @@ logScope:
type
Service* = ref object of service_interface.ServiceInterface
communities: Table[string, CommunityDto] # [community_id, CommunityDto]
joinedCommunities: Table[string, CommunityDto] # [community_id, CommunityDto]
allCommunities: Table[string, CommunityDto] # [community_id, CommunityDto]
chatService: chat_service.Service
# Forward declaration
method loadAllCommunities(self: Service): seq[CommunityDto]
method loadJoinedComunities(self: Service): seq[CommunityDto]
method delete*(self: Service) =
discard
proc newService*(chatService: chat_service.Service): Service =
result = Service()
result.communities = initTable[string, CommunityDto]()
result.joinedCommunities = initTable[string, CommunityDto]()
result.chatService = chatService
method init*(self: Service) =
try:
let response = status_go.getJoinedComunities()
let joinedCommunities = self.loadJoinedComunities()
for community in joinedCommunities:
self.joinedCommunities[community.id] = community
let communities = map(response.result.getElems(),
proc(x: JsonNode): CommunityDto = x.toCommunityDto())
for community in communities:
self.communities[community.id] = community
let allCommunities = self.loadAllCommunities()
for community in allCommunities:
self.allCommunities[community.id] = community
except Exception as e:
let errDesription = e.msg
error "error: ", errDesription
return
method getCommunities*(self: Service): seq[CommunityDto] =
return toSeq(self.communities.values)
method loadAllCommunities(self: Service): seq[CommunityDto] =
let response = status_go.getAllCommunities()
return parseCommunities(response)
method loadJoinedComunities(self: Service): seq[CommunityDto] =
let response = status_go.getJoinedComunities()
return parseCommunities(response)
method getJoinedCommunities*(self: Service): seq[CommunityDto] =
return toSeq(self.joinedCommunities.values)
method getAllCommunities*(self: Service): seq[CommunityDto] =
return toSeq(self.allCommunities.values)
method getCommunityById*(self: Service, communityId: string): CommunityDto =
if(not self.communities.hasKey(communityId)):
if(not self.joinedCommunities.hasKey(communityId)):
error "error: requested community doesn't exists"
return
return self.communities[communityId]
return self.joinedCommunities[communityId]
method getCommunityIds*(self: Service): seq[string] =
return toSeq(self.communities.keys)
return toSeq(self.joinedCommunities.keys)
proc sortAsc[T](t1, t2: T): int =
if(t1.position > t2.position):
@ -69,11 +85,11 @@ proc sortDesc[T](t1, t2: T): int =
return 0
method getCategories*(self: Service, communityId: string, order: SortOrder = SortOrder.Ascending): seq[Category] =
if(not self.communities.contains(communityId)):
if(not self.joinedCommunities.contains(communityId)):
error "trying to get community categories for an unexisting community id"
return
result = self.communities[communityId].categories
result = self.joinedCommunities[communityId].categories
if(order == SortOrder.Ascending):
result.sort(sortAsc[Category])
else:
@ -83,11 +99,11 @@ method getChats*(self: Service, communityId: string, categoryId = "", order = So
## By default returns chats which don't belong to any category, for passed `communityId`.
## If `categoryId` is set then only chats belonging to that category for passed `communityId` will be returned.
## Returned chats are sorted by position following set `order` parameter.
if(not self.communities.contains(communityId)):
if(not self.joinedCommunities.contains(communityId)):
error "trying to get community chats for an unexisting community id"
return
for chat in self.communities[communityId].chats:
for chat in self.joinedCommunities[communityId].chats:
if(chat.categoryId != categoryId):
continue
@ -101,11 +117,11 @@ method getChats*(self: Service, communityId: string, categoryId = "", order = So
method getAllChats*(self: Service, communityId: string, order = SortOrder.Ascending): seq[Chat] =
## Returns all chats belonging to the community with passed `communityId`, sorted by position.
## Returned chats are sorted by position following set `order` parameter.
if(not self.communities.contains(communityId)):
if(not self.joinedCommunities.contains(communityId)):
error "trying to get all community chats for an unexisting community id"
return
result = self.communities[communityId].chats
result = self.joinedCommunities[communityId].chats
if(order == SortOrder.Ascending):
result.sort(sortAsc[Chat])

View File

@ -13,7 +13,13 @@ method delete*(self: ServiceInterface) {.base.} =
method init*(self: ServiceInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method getCommunities*(self: ServiceInterface): seq[CommunityDto] {.base.} =
method getJoinedCommunities*(self: ServiceInterface): seq[CommunityDto] {.base.} =
raise newException(ValueError, "No implementation available")
method loadAllCommunities*(self: ServiceInterface): seq[CommunityDto] {.base.} =
raise newException(ValueError, "No implementation available")
method loadJoinedComunities*(self: ServiceInterface): seq[CommunityDto] {.base.} =
raise newException(ValueError, "No implementation available")
method getCommunityById*(self: ServiceInterface, communityId: string): CommunityDto {.base.} =

View File

@ -119,13 +119,14 @@ StatusModal {
anchors.horizontalCenter: parent.horizontalCenter
title: name
subTitle: description
// TODO refactor members in the backend
//% "%1 members"
tertiaryTitle: qsTrId("-1-members").arg(nbMembers)
// tertiaryTitle: qsTrId("-1-members").arg(nbMembers)
statusListItemTitle.font.weight: Font.Bold
statusListItemTitle.font.pixelSize: 17
image.source: thumbnailImage
icon.isLetterIdenticon: !!!thumbnailImage
icon.background.color: communityColor
image.source: model.image
icon.isLetterIdenticon: !image
icon.background.color: color
sensor.onClicked: {
if (joined && isMember) {

View File

@ -20,6 +20,9 @@ QtObject {
property var activityCenterModuleInst: activityCenterModule
property var activityCenterList: activityCenterModuleInst.model
property var communitiesModuleInst: communitiesModule
property var communitiesList: communitiesModuleInst.model
property var userProfileInst: userProfile
property bool isDebugEnabled: profileSectionModule.isDebugEnabled

View File

@ -350,8 +350,8 @@ Item {
id: communitiesPopupComponent
CommunitiesPopup {
anchors.centerIn: parent
communitiesList: root.store.communitiesList
// Not Refactored Yet
// communitiesList: root.store.chatsModelInst.communities.list
// onSetActiveCommunity: {
// root.store.chatsModelInst.communities.setActiveCommunity(id)
// }