Refactor out channel groups (#14202)
Fixes #12595 Gets rid of the concept of channelGroups. Instead, we use the communities and chats directly, to keep the same concepts as status-go.
This commit is contained in:
parent
2537cdc2f2
commit
b6b21c3744
|
@ -44,7 +44,7 @@ proc updateActivityGroupCounters*(self: Controller) =
|
|||
self.delegate.setActivityGroupCounters(counters)
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.once(chat_service.SIGNAL_CHANNEL_GROUPS_LOADED) do(e:Args):
|
||||
self.events.once(chat_service.SIGNAL_ACTIVE_CHATS_LOADED) do(e:Args):
|
||||
# Only fectch activity center notification once channel groups are loaded,
|
||||
# since we need the chats to associate the notifications to
|
||||
self.activity_center_service.asyncActivityNotificationLoad()
|
||||
|
@ -136,9 +136,6 @@ proc switchTo*(self: Controller, sectionId, chatId, messageId: string) =
|
|||
proc getChatDetails*(self: Controller, chatId: string): ChatDto =
|
||||
return self.chatService.getChatById(chatId)
|
||||
|
||||
proc getChannelGroups*(self: Controller): seq[ChannelGroupDto] =
|
||||
return self.chatService.getChannelGroups()
|
||||
|
||||
proc getOneToOneChatNameAndImage*(self: Controller, chatId: string):
|
||||
tuple[name: string, image: string, largeImage: string] =
|
||||
return self.chatService.getOneToOneChatNameAndImage(chatId)
|
||||
|
|
|
@ -7,6 +7,7 @@ import ../../shared_models/message_item as msg_item
|
|||
import ../../shared_models/message_item_qobject as msg_item_qobj
|
||||
import ../../shared_models/message_transaction_parameters_item
|
||||
import ../../../global/global_singleton
|
||||
import ../../../global/app_sections_config as conf
|
||||
import ../../../core/eventemitter
|
||||
import ../../../../app_service/service/activity_center/service as activity_center_service
|
||||
import ../../../../app_service/service/contacts/service as contacts_service
|
||||
|
@ -268,32 +269,33 @@ method switchTo*(self: Module, sectionId, chatId, messageId: string) =
|
|||
self.controller.switchTo(sectionId, chatId, messageId)
|
||||
|
||||
method getDetails*(self: Module, sectionId: string, chatId: string): string =
|
||||
let groups = self.controller.getChannelGroups()
|
||||
var jsonObject = newJObject()
|
||||
if sectionId == singletonInstance.userProfile.getPubKey():
|
||||
jsonObject["sType"] = %* ChatSectionType.Personal
|
||||
jsonObject["sName"] = %* conf.CHAT_SECTION_NAME
|
||||
jsonObject["sImage"] = %* ""
|
||||
jsonObject["sColor"] = %* ""
|
||||
else:
|
||||
# Community
|
||||
let community = self.controller.getCommunityById(sectionId)
|
||||
|
||||
for g in groups:
|
||||
if(g.id != sectionId):
|
||||
continue
|
||||
jsonObject["sType"] = %* ChatSectionType.Community
|
||||
jsonObject["sName"] = %* community.name
|
||||
jsonObject["sImage"] = %* community.images.thumbnail
|
||||
jsonObject["sColor"] = %* community.color
|
||||
|
||||
jsonObject["sType"] = %* g.channelGroupType
|
||||
jsonObject["sName"] = %* g.name
|
||||
jsonObject["sImage"] = %* g.images.thumbnail
|
||||
jsonObject["sColor"] = %* g.color
|
||||
let c = self.controller.getChatDetails(chatId)
|
||||
|
||||
for c in g.chats:
|
||||
if(c.id != chatId):
|
||||
continue
|
||||
var chatName = c.name
|
||||
var chatImage = c.icon
|
||||
if c.chatType == ChatType.OneToOne:
|
||||
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(c.id)
|
||||
|
||||
var chatName = c.name
|
||||
var chatImage = c.icon
|
||||
if(c.chatType == ChatType.OneToOne):
|
||||
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(c.id)
|
||||
|
||||
jsonObject["cName"] = %* chatName
|
||||
jsonObject["cImage"] = %* chatImage
|
||||
jsonObject["cColor"] = %* c.color
|
||||
jsonObject["cEmoji"] = %* c.emoji
|
||||
return $jsonObject
|
||||
jsonObject["cName"] = %* chatName
|
||||
jsonObject["cImage"] = %* chatImage
|
||||
jsonObject["cColor"] = %* c.color
|
||||
jsonObject["cEmoji"] = %* c.emoji
|
||||
return $jsonObject
|
||||
|
||||
method getChatDetailsAsJson*(self: Module, chatId: string): string =
|
||||
let chatDto = self.controller.getChatDetails(chatId)
|
||||
|
|
|
@ -85,12 +85,15 @@ proc setSearchLocation*(self: Controller, location: string, subLocation: string)
|
|||
self.searchLocation = location
|
||||
self.searchSubLocation = subLocation
|
||||
|
||||
proc getChannelGroups*(self: Controller): seq[ChannelGroupDto] =
|
||||
return self.chatService.getChannelGroups()
|
||||
|
||||
proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
|
||||
return self.communityService.getCommunityById(communityId)
|
||||
|
||||
proc getJoinedAndSpectatedCommunities*(self: Controller): seq[CommunityDto] =
|
||||
return self.communityService.getJoinedAndSpectatedCommunities()
|
||||
|
||||
proc getChatsForPersonalSection*(self: Controller): seq[ChatDto] =
|
||||
return self.chatService.getChatsForPersonalSection()
|
||||
|
||||
proc getChatDetailsForChatTypes*(self: Controller, types: seq[ChatType]): seq[ChatDto] =
|
||||
return self.chatService.getChatsOfChatTypes(types)
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import NimQml
|
||||
import json, strutils, chronicles
|
||||
import json, strutils, chronicles, sequtils
|
||||
import io_interface
|
||||
import ../io_interface as delegate_interface
|
||||
import view, controller
|
||||
|
@ -66,18 +66,8 @@ method viewDidLoad*(self: Module) =
|
|||
method getModuleAsVariant*(self: Module): QVariant =
|
||||
return self.viewVariant
|
||||
|
||||
proc buildLocationMenuForChannelGroup(self: Module, channelGroup: ChannelGroupDto): location_menu_item.Item =
|
||||
let isCommunity = channelGroup.channelGroupType == ChannelGroupType.Community
|
||||
|
||||
var item = location_menu_item.initItem(
|
||||
channelGroup.id,
|
||||
if (isCommunity): channelGroup.name else: SEARCH_MENU_LOCATION_CHAT_SECTION_NAME,
|
||||
channelGroup.images.thumbnail,
|
||||
icon=if (isCommunity): "" else: "chat",
|
||||
channelGroup.color)
|
||||
|
||||
var subItems: seq[location_menu_sub_item.SubItem]
|
||||
for chatDto in channelGroup.chats:
|
||||
proc getChatSubItems(self: Module, chats: seq[ChatDto]): seq[location_menu_sub_item.SubItem] =
|
||||
for chatDto in chats:
|
||||
var chatName = chatDto.name
|
||||
var chatImage = chatDto.icon
|
||||
var colorHash: ColorHashDto = @[]
|
||||
|
@ -95,18 +85,44 @@ proc buildLocationMenuForChannelGroup(self: Module, channelGroup: ChannelGroupDt
|
|||
chatDto.color,
|
||||
isOneToOneChat,
|
||||
colorId,
|
||||
colorHash)
|
||||
subItems.add(subItem)
|
||||
colorHash
|
||||
)
|
||||
result.add(subItem)
|
||||
|
||||
proc buildLocationMenuForCommunity(self: Module, community: CommunityDto): location_menu_item.Item =
|
||||
var item = location_menu_item.initItem(
|
||||
community.id,
|
||||
community.name,
|
||||
community.images.thumbnail,
|
||||
icon="",
|
||||
community.color
|
||||
)
|
||||
|
||||
var subItems = self.getChatSubItems(community.chats)
|
||||
item.setSubItems(subItems)
|
||||
|
||||
return item
|
||||
|
||||
method prepareLocationMenuModel*(self: Module) =
|
||||
var items: seq[location_menu_item.Item]
|
||||
let channelGroups = self.controller.getChannelGroups()
|
||||
|
||||
for c in channelGroups:
|
||||
items.add(self.buildLocationMenuForChannelGroup(c))
|
||||
# Personal Section
|
||||
let myPubKey = singletonInstance.userProfile.getPubKey()
|
||||
var personalItem = location_menu_item.initItem(
|
||||
value = myPubKey,
|
||||
text = SEARCH_MENU_LOCATION_CHAT_SECTION_NAME,
|
||||
image = "",
|
||||
icon = "chat",
|
||||
)
|
||||
|
||||
var subItems = self.getChatSubItems(self.controller.getChatsForPersonalSection())
|
||||
personalItem.setSubItems(subItems)
|
||||
items.add(personalItem)
|
||||
|
||||
# Community sections
|
||||
let communities = self.controller.getJoinedAndSpectatedCommunities()
|
||||
for c in communities:
|
||||
items.add(self.buildLocationMenuForCommunity(c))
|
||||
|
||||
self.view.locationMenuModel().setItems(items)
|
||||
|
||||
|
@ -146,80 +162,85 @@ method searchMessages*(self: Module, searchTerm: string) =
|
|||
|
||||
self.controller.searchMessages(searchTerm)
|
||||
|
||||
proc getResultItemFromChats(self: Module, sectionId: string, chats: seq[ChatDto], sectionName: string): seq[result_item.Item] =
|
||||
if (self.controller.searchSubLocation().len == 0 and self.controller.searchLocation().len == 0) or
|
||||
self.controller.searchLocation() == sectionId:
|
||||
|
||||
let searchTerm = self.controller.searchTerm().toLower
|
||||
for chatDto in chats:
|
||||
var chatName = chatDto.name
|
||||
var chatImage = chatDto.icon
|
||||
var colorHash: ColorHashDto = @[]
|
||||
var colorId: int = 0
|
||||
let isOneToOneChat = chatDto.chatType == ChatType.OneToOne
|
||||
if(isOneToOneChat):
|
||||
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(chatDto.id)
|
||||
colorHash = self.controller.getColorHash(chatDto.id)
|
||||
colorId = self.controller.getColorId(chatDto.id)
|
||||
|
||||
var rawChatName = chatName
|
||||
if(chatName.startsWith("@")):
|
||||
rawChatName = chatName[1 ..^ 1]
|
||||
|
||||
if rawChatName.toLower.contains(searchTerm):
|
||||
let item = result_item.initItem(
|
||||
chatDto.id,
|
||||
content="",
|
||||
time="",
|
||||
titleId=chatDto.id,
|
||||
title=chatName,
|
||||
SEARCH_RESULT_CHANNELS_SECTION_NAME,
|
||||
chatImage,
|
||||
chatDto.color,
|
||||
badgePrimaryText="",
|
||||
badgeSecondaryText="",
|
||||
chatImage,
|
||||
chatDto.color,
|
||||
false,
|
||||
isOneToOneChat,
|
||||
colorId,
|
||||
colorHash)
|
||||
|
||||
self.controller.addResultItemDetails(chatDto.id, sectionId, chatDto.id)
|
||||
result.add(item)
|
||||
|
||||
method onSearchMessagesDone*(self: Module, messages: seq[MessageDto]) =
|
||||
var items: seq[result_item.Item]
|
||||
var channels: seq[result_item.Item]
|
||||
|
||||
# Add Channel groups
|
||||
let channelGroups = self.controller.getChannelGroups()
|
||||
# Add Personal section chats
|
||||
let myPubKey = singletonInstance.userProfile.getPubKey()
|
||||
let personalItems = self.getResultItemFromChats(myPubKey, self.controller.getChatsForPersonalSection(), SEARCH_RESULT_CHATS_SECTION_NAME)
|
||||
var channels = personalItems
|
||||
|
||||
# Add Communities
|
||||
let communities = self.controller.getJoinedAndSpectatedCommunities()
|
||||
|
||||
let searchTerm = self.controller.searchTerm().toLower
|
||||
for channelGroup in channelGroups:
|
||||
let isCommunity = channelGroup.channelGroupType == ChannelGroupType.Community
|
||||
if(self.controller.searchLocation().len == 0 and
|
||||
channelGroup.name.toLower.contains(searchTerm)):
|
||||
for community in communities:
|
||||
if self.controller.searchLocation().len == 0 and
|
||||
community.name.toLower.contains(searchTerm):
|
||||
let item = result_item.initItem(
|
||||
channelGroup.id,
|
||||
community.id,
|
||||
content="",
|
||||
time="",
|
||||
titleId=channelGroup.id,
|
||||
title=channelGroup.name,
|
||||
if (isCommunity):
|
||||
SEARCH_RESULT_COMMUNITIES_SECTION_NAME
|
||||
else:
|
||||
SEARCH_RESULT_CHATS_SECTION_NAME,
|
||||
channelGroup.images.thumbnail,
|
||||
channelGroup.color,
|
||||
titleId=community.id,
|
||||
title=community.name,
|
||||
SEARCH_RESULT_COMMUNITIES_SECTION_NAME,
|
||||
community.images.thumbnail,
|
||||
community.color,
|
||||
badgePrimaryText="",
|
||||
badgeSecondaryText="",
|
||||
channelGroup.images.thumbnail,
|
||||
channelGroup.color,
|
||||
community.images.thumbnail,
|
||||
community.color,
|
||||
badgeIsLetterIdenticon=false)
|
||||
|
||||
self.controller.addResultItemDetails(channelGroup.id, channelGroup.id)
|
||||
self.controller.addResultItemDetails(community.id, community.id)
|
||||
items.add(item)
|
||||
|
||||
# Add channels
|
||||
if((self.controller.searchSubLocation().len == 0 and self.controller.searchLocation().len == 0) or
|
||||
self.controller.searchLocation() == channelGroup.id):
|
||||
for chatDto in channelGroup.chats:
|
||||
var chatName = chatDto.name
|
||||
var chatImage = chatDto.icon
|
||||
var colorHash: ColorHashDto = @[]
|
||||
var colorId: int = 0
|
||||
let isOneToOneChat = chatDto.chatType == ChatType.OneToOne
|
||||
if(isOneToOneChat):
|
||||
(chatName, chatImage) = self.controller.getOneToOneChatNameAndImage(chatDto.id)
|
||||
colorHash = self.controller.getColorHash(chatDto.id)
|
||||
colorId = self.controller.getColorId(chatDto.id)
|
||||
|
||||
var rawChatName = chatName
|
||||
if(chatName.startsWith("@")):
|
||||
rawChatName = chatName[1 ..^ 1]
|
||||
|
||||
if(rawChatName.toLower.contains(searchTerm)):
|
||||
let item = result_item.initItem(
|
||||
chatDto.id,
|
||||
content="",
|
||||
time="",
|
||||
titleId=chatDto.id,
|
||||
title=chatName,
|
||||
if isCommunity:
|
||||
SEARCH_RESULT_CHANNELS_SECTION_NAME
|
||||
else:
|
||||
SEARCH_RESULT_CHATS_SECTION_NAME,
|
||||
chatImage,
|
||||
chatDto.color,
|
||||
badgePrimaryText="",
|
||||
badgeSecondaryText="",
|
||||
chatImage,
|
||||
chatDto.color,
|
||||
false,
|
||||
isOneToOneChat,
|
||||
colorId,
|
||||
colorHash)
|
||||
|
||||
self.controller.addResultItemDetails(chatDto.id, channelGroup.id, chatDto.id)
|
||||
channels.add(item)
|
||||
let communityChatItems = self.getResultItemFromChats(community.id, community.chats, SEARCH_RESULT_CHANNELS_SECTION_NAME)
|
||||
if communityChatItems.len > 0:
|
||||
channels = channels.concat(channels, communityChatItems)
|
||||
|
||||
# Add channels in order as requested by the design
|
||||
items.add(channels)
|
||||
|
|
|
@ -115,11 +115,18 @@ proc init*(self: Controller) =
|
|||
proc belongsToCommunity*(self: Controller): bool =
|
||||
self.belongsToCommunity
|
||||
|
||||
proc getMyCommunity*(self: Controller): CommunityDto =
|
||||
return self.communityService.getCommunityById(self.sectionId)
|
||||
|
||||
proc getChat*(self: Controller): ChatDto =
|
||||
return self.chatService.getChatById(self.chatId)
|
||||
|
||||
proc getChatMembers*(self: Controller): seq[ChatMember] =
|
||||
return self.chatService.getChatById(self.chatId).members
|
||||
if self.belongsToCommunity:
|
||||
let myCommunity = self.getMyCommunity()
|
||||
return myCommunity.getCommunityChat(self.chatId).members
|
||||
else:
|
||||
return self.chatService.getChatById(self.chatId).members
|
||||
|
||||
proc getContactNameAndImage*(self: Controller, contactId: string):
|
||||
tuple[name: string, image: string, largeImage: string] =
|
||||
|
|
|
@ -455,9 +455,30 @@ proc getAllChats*(self: Controller, communityId: string): seq[ChatDto] =
|
|||
return self.communityService.getAllChats(communityId)
|
||||
|
||||
proc getChatsAndBuildUI*(self: Controller) =
|
||||
let channelGroup = self.chatService.getChannelGroupById(self.sectionId)
|
||||
var chats: seq[ChatDto]
|
||||
var community: CommunityDto
|
||||
if self.isCommunity():
|
||||
community = self.getMyCommunity()
|
||||
let normalChats = self.chatService.getChatsForCommunity(community.id)
|
||||
|
||||
# TODO remove this once we do this refactor https://github.com/status-im/status-desktop/issues/14219
|
||||
var fullChats: seq[ChatDto] = @[]
|
||||
for communityChat in community.chats:
|
||||
for chat in normalChats:
|
||||
if chat.id == communityChat.id:
|
||||
var c = chat
|
||||
c.updateMissingFields(communityChat)
|
||||
fullChats.add(c)
|
||||
break
|
||||
chats = fullChats
|
||||
else:
|
||||
community = CommunityDto()
|
||||
chats = self.chatService.getChatsForPersonalSection()
|
||||
|
||||
# Build chat section with the preloaded community (empty community for personal chat)
|
||||
self.delegate.onChatsLoaded(
|
||||
channelGroup,
|
||||
community,
|
||||
chats,
|
||||
self.events,
|
||||
self.settingsService,
|
||||
self.nodeConfigurationService,
|
||||
|
@ -482,8 +503,8 @@ proc getChatDetailsForChatTypes*(self: Controller, types: seq[ChatType]): seq[Ch
|
|||
proc getChatDetailsByIds*(self: Controller, chatIds: seq[string]): seq[ChatDto] =
|
||||
return self.chatService.getChatsByIds(chatIds)
|
||||
|
||||
proc chatsWithCategoryHaveUnreadMessages*(self: Controller, communityId: string, categoryId: string): bool =
|
||||
return self.chatService.chatsWithCategoryHaveUnreadMessages(communityId, categoryId)
|
||||
proc categoryHasUnreadMessages*(self: Controller, communityId: string, categoryId: string): bool =
|
||||
return self.communityService.categoryHasUnreadMessages(communityId, categoryId)
|
||||
|
||||
proc getCommunityCategoryDetails*(self: Controller, communityId: string, categoryId: string): Category =
|
||||
return self.communityService.getCategoryById(communityId, categoryId)
|
||||
|
|
|
@ -26,7 +26,8 @@ method load*(self: AccessInterface) {.base.} =
|
|||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onChatsLoaded*(self: AccessInterface,
|
||||
channelGroup: ChannelGroupDto,
|
||||
community: CommunityDto,
|
||||
chats: seq[ChatDto],
|
||||
events: UniqueUUIDEventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service,
|
||||
|
|
|
@ -57,7 +57,8 @@ type
|
|||
# Forward declaration
|
||||
proc buildChatSectionUI(
|
||||
self: Module,
|
||||
channelGroup: ChannelGroupDto,
|
||||
community: CommunityDto,
|
||||
chats: seq[ChatDto],
|
||||
events: UniqueUUIDEventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service,
|
||||
|
@ -75,7 +76,7 @@ proc changeCanPostValues*(self: Module, chatId: string, canPostReactions, viewer
|
|||
|
||||
proc addOrUpdateChat(self: Module,
|
||||
chat: ChatDto,
|
||||
channelGroup: ChannelGroupDto,
|
||||
community: CommunityDto,
|
||||
belongsToCommunity: bool,
|
||||
events: UniqueUUIDEventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
|
@ -255,7 +256,7 @@ proc removeSubmodule(self: Module, chatId: string) =
|
|||
|
||||
|
||||
proc addCategoryItem(self: Module, category: Category, memberRole: MemberRole, communityId: string, insertIntoModel: bool = true): chat_item.Item =
|
||||
let hasUnreadMessages = self.controller.chatsWithCategoryHaveUnreadMessages(communityId, category.id)
|
||||
let hasUnreadMessages = self.controller.categoryHasUnreadMessages(communityId, category.id)
|
||||
result = chat_item.initItem(
|
||||
id = category.id,
|
||||
category.name,
|
||||
|
@ -284,7 +285,8 @@ proc addCategoryItem(self: Module, category: Category, memberRole: MemberRole, c
|
|||
|
||||
proc buildChatSectionUI(
|
||||
self: Module,
|
||||
channelGroup: ChannelGroupDto,
|
||||
community: CommunityDto,
|
||||
chats: seq[ChatDto],
|
||||
events: UniqueUUIDEventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service,
|
||||
|
@ -299,11 +301,11 @@ proc buildChatSectionUI(
|
|||
let sectionLastOpenChat = singletonInstance.localAccountSensitiveSettings.getSectionLastOpenChat(self.controller.getMySectionId())
|
||||
|
||||
var items: seq[chat_item.Item] = @[]
|
||||
for categoryDto in channelGroup.categories:
|
||||
for categoryDto in community.categories:
|
||||
# Add items for the categories. We use a special type to identify categories
|
||||
items.add(self.addCategoryItem(categoryDto, channelGroup.memberRole, channelGroup.id))
|
||||
items.add(self.addCategoryItem(categoryDto, community.memberRole, community.id))
|
||||
|
||||
for chatDto in channelGroup.chats:
|
||||
for chatDto in chats:
|
||||
var categoryPosition = -1
|
||||
|
||||
# Add an empty chat item that has the category info
|
||||
|
@ -315,14 +317,14 @@ proc buildChatSectionUI(
|
|||
isActive = true
|
||||
|
||||
if chatDto.categoryId != "":
|
||||
for category in channelGroup.categories:
|
||||
for category in community.categories:
|
||||
if category.id == chatDto.categoryId:
|
||||
categoryPosition = category.position
|
||||
break
|
||||
|
||||
items.add(self.addOrUpdateChat(
|
||||
chatDto,
|
||||
channelGroup,
|
||||
community,
|
||||
belongsToCommunity = chatDto.communityId.len > 0,
|
||||
events,
|
||||
settingsService,
|
||||
|
@ -392,7 +394,7 @@ proc reevaluateRequiresTokenPermissionToJoin(self: Module) =
|
|||
break
|
||||
self.view.setRequiresTokenPermissionToJoin(joinPermissionsChanged)
|
||||
|
||||
proc initCommunityTokenPermissionsModel(self: Module, channelGroup: ChannelGroupDto) =
|
||||
proc initCommunityTokenPermissionsModel(self: Module) =
|
||||
self.rebuildCommunityTokenPermissionsModel()
|
||||
|
||||
proc convertPubKeysToJson(self: Module, pubKeys: string): seq[string] =
|
||||
|
@ -419,7 +421,8 @@ method load*(self: Module) =
|
|||
|
||||
method onChatsLoaded*(
|
||||
self: Module,
|
||||
channelGroup: ChannelGroupDto,
|
||||
community: CommunityDto,
|
||||
chats: seq[ChatDto],
|
||||
events: UniqueUUIDEventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service,
|
||||
|
@ -431,7 +434,7 @@ method onChatsLoaded*(
|
|||
sharedUrlsService: shared_urls_service.Service,
|
||||
) =
|
||||
self.chatsLoaded = true
|
||||
self.buildChatSectionUI(channelGroup, events, settingsService, nodeConfigurationService,
|
||||
self.buildChatSectionUI(community, chats, events, settingsService, nodeConfigurationService,
|
||||
contactService, chatService, communityService, messageService, mailserversService, sharedUrlsService)
|
||||
|
||||
if(not self.controller.isCommunity()):
|
||||
|
@ -446,8 +449,8 @@ method onChatsLoaded*(
|
|||
requestToJoinState = RequestToJoinState.Requested
|
||||
|
||||
self.view.setRequestToJoinState(requestToJoinState)
|
||||
self.initCommunityTokenPermissionsModel(channelGroup)
|
||||
self.onCommunityCheckAllChannelsPermissionsResponse(channelGroup.channelPermissions)
|
||||
self.initCommunityTokenPermissionsModel()
|
||||
self.onCommunityCheckAllChannelsPermissionsResponse(community.channelPermissions)
|
||||
self.controller.asyncCheckPermissionsToJoin()
|
||||
|
||||
let activeChatId = self.controller.getActiveChatId()
|
||||
|
@ -589,7 +592,7 @@ proc updateBadgeNotifications(self: Module, chat: ChatDto, hasUnreadMessages: bo
|
|||
self.chatContentModules[chatId].onNotificationsUpdated(hasUnreadMessages, unviewedMentionsCount)
|
||||
|
||||
if chat.categoryId != "":
|
||||
let hasUnreadMessages = self.controller.chatsWithCategoryHaveUnreadMessages(chat.communityId, chat.categoryId)
|
||||
let hasUnreadMessages = self.controller.categoryHasUnreadMessages(chat.communityId, chat.categoryId)
|
||||
self.view.chatsModel().setCategoryHasUnreadMessages(chat.categoryId, hasUnreadMessages)
|
||||
|
||||
self.updateParentBadgeNotifications()
|
||||
|
@ -629,7 +632,7 @@ method chatsModel*(self: Module): chats_model.Model =
|
|||
proc addNewChat(
|
||||
self: Module,
|
||||
chatDto: ChatDto,
|
||||
channelGroup: ChannelGroupDto,
|
||||
community: CommunityDto,
|
||||
belongsToCommunity: bool,
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
|
@ -643,7 +646,7 @@ proc addNewChat(
|
|||
setChatAsActive: bool = true,
|
||||
insertIntoModel: bool = true,
|
||||
): chat_item.Item =
|
||||
let hasNotification =chatDto.unviewedMessagesCount > 0
|
||||
let hasNotification = chatDto.unviewedMessagesCount > 0
|
||||
let notificationsCount = chatDto.unviewedMentionsCount
|
||||
|
||||
var chatName = chatDto.name
|
||||
|
@ -672,12 +675,11 @@ proc addNewChat(
|
|||
var memberRole = self.getUserMemberRole(chatDto.members)
|
||||
|
||||
if chatDto.chatType != ChatType.PrivateGroupChat:
|
||||
memberRole = channelGroup.memberRole
|
||||
memberRole = community.memberRole
|
||||
|
||||
if memberRole == MemberRole.None and len(chatDto.communityId) != 0:
|
||||
memberRole = channelGroup.memberRole
|
||||
memberRole = community.memberRole
|
||||
if memberRole == MemberRole.None:
|
||||
let community = communityService.getCommunityById(chatDto.communityId)
|
||||
memberRole = community.memberRole
|
||||
|
||||
var categoryOpened = true
|
||||
|
@ -694,6 +696,16 @@ proc addNewChat(
|
|||
# preferable. Please fix-me in https://github.com/status-im/status-desktop/issues/14431
|
||||
self.view.chatsModel().changeCategoryOpened(category.id, category.categoryOpened)
|
||||
|
||||
var canPostReactions = true
|
||||
var hideIfPermissionsNotMet = false
|
||||
var viewersCanPostReactions = true
|
||||
if self.controller.isCommunity:
|
||||
let communityChat = community.getCommunityChat(chatDto.id)
|
||||
# Some properties are only available on CommunityChat (they are useless for normal chats)
|
||||
canPostReactions = communityChat.canPostReactions
|
||||
hideIfPermissionsNotMet = communityChat.hideIfPermissionsNotMet
|
||||
viewersCanPostReactions = communityChat.viewersCanPostReactions
|
||||
|
||||
result = chat_item.initItem(
|
||||
chatDto.id,
|
||||
chatName,
|
||||
|
@ -726,9 +738,9 @@ proc addNewChat(
|
|||
self.controller.checkChatHasPermissions(self.controller.getMySectionId(), chatDto.id)
|
||||
else:
|
||||
false,
|
||||
canPostReactions = chatDto.canPostReactions,
|
||||
viewersCanPostReactions = chatDto.viewersCanPostReactions,
|
||||
hideIfPermissionsNotMet = chatDto.hideIfPermissionsNotMet,
|
||||
canPostReactions = canPostReactions,
|
||||
viewersCanPostReactions = viewersCanPostReactions,
|
||||
hideIfPermissionsNotMet = hideIfPermissionsNotMet,
|
||||
viewOnlyPermissionsSatisfied = true, # will be updated in async call
|
||||
viewAndPostPermissionsSatisfied = true # will be updated in async call
|
||||
)
|
||||
|
@ -1382,7 +1394,7 @@ method setLoadingHistoryMessagesInProgress*(self: Module, isLoading: bool) =
|
|||
|
||||
proc addOrUpdateChat(self: Module,
|
||||
chat: ChatDto,
|
||||
channelGroup: ChannelGroupDto,
|
||||
community: CommunityDto,
|
||||
belongsToCommunity: bool,
|
||||
events: UniqueUUIDEventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
|
@ -1398,8 +1410,8 @@ proc addOrUpdateChat(self: Module,
|
|||
): chat_item.Item =
|
||||
|
||||
let sectionId = self.controller.getMySectionId()
|
||||
if(belongsToCommunity and sectionId != chat.communityId or
|
||||
not belongsToCommunity and sectionId != singletonInstance.userProfile.getPubKey()):
|
||||
if belongsToCommunity and sectionId != chat.communityId or
|
||||
not belongsToCommunity and sectionId != singletonInstance.userProfile.getPubKey():
|
||||
return
|
||||
|
||||
self.updateBadgeNotifications(chat, chat.unviewedMessagesCount > 0, chat.unviewedMentionsCount)
|
||||
|
@ -1424,7 +1436,7 @@ proc addOrUpdateChat(self: Module,
|
|||
|
||||
result = self.addNewChat(
|
||||
chat,
|
||||
channelGroup,
|
||||
community,
|
||||
belongsToCommunity,
|
||||
events.eventsEmitter(),
|
||||
settingsService,
|
||||
|
@ -1456,7 +1468,7 @@ method addOrUpdateChat*(self: Module,
|
|||
): chat_item.Item =
|
||||
result = self.addOrUpdateChat(
|
||||
chat,
|
||||
ChannelGroupDto(),
|
||||
CommunityDto(),
|
||||
belongsToCommunity,
|
||||
events,
|
||||
settingsService,
|
||||
|
|
|
@ -109,10 +109,8 @@ proc delete*(self: Controller) =
|
|||
discard
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_CHANNEL_GROUPS_LOADED) do(e:Args):
|
||||
let args = ChannelGroupsArgs(e)
|
||||
self.delegate.onChannelGroupsLoaded(
|
||||
args.channelGroups,
|
||||
self.events.on(SIGNAL_ACTIVE_CHATS_LOADED) do(e:Args):
|
||||
self.delegate.onChatsLoaded(
|
||||
self.events,
|
||||
self.settingsService,
|
||||
self.nodeConfigurationService,
|
||||
|
@ -145,7 +143,7 @@ proc init*(self: Controller) =
|
|||
self.networksService,
|
||||
)
|
||||
|
||||
self.events.on(SIGNAL_CHANNEL_GROUPS_LOADING_FAILED) do(e:Args):
|
||||
self.events.on(SIGNAL_CHATS_LOADING_FAILED) do(e:Args):
|
||||
self.delegate.onChatsLoadingFailed()
|
||||
|
||||
self.events.on(SIGNAL_ACTIVE_MAILSERVER_CHANGED) do(e:Args):
|
||||
|
@ -489,9 +487,6 @@ proc init*(self: Controller) =
|
|||
proc isConnected*(self: Controller): bool =
|
||||
return self.nodeService.isConnected()
|
||||
|
||||
proc getChannelGroups*(self: Controller): seq[ChannelGroupDto] =
|
||||
return self.chatService.getChannelGroups()
|
||||
|
||||
proc getActiveSectionId*(self: Controller): string =
|
||||
result = self.activeSectionId
|
||||
|
||||
|
@ -535,6 +530,9 @@ proc switchTo*(self: Controller, sectionId, chatId, messageId: string) =
|
|||
let data = ActiveSectionChatArgs(sectionId: sectionId, chatId: chatId, messageId: messageId)
|
||||
self.events.emit(SIGNAL_MAKE_SECTION_CHAT_ACTIVE, data)
|
||||
|
||||
proc getJoinedAndSpectatedCommunities*(self: Controller): seq[CommunityDto] =
|
||||
return self.communityService.getJoinedAndSpectatedCommunities()
|
||||
|
||||
proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
|
||||
return self.communityService.getCommunityById(communityId)
|
||||
|
||||
|
|
|
@ -84,9 +84,8 @@ method chatSectionDidLoad*(self: AccessInterface) {.base.} =
|
|||
method communitySectionDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method onChannelGroupsLoaded*(
|
||||
method onChatsLoaded*(
|
||||
self: AccessInterface,
|
||||
channelGroups: seq[ChannelGroupDto],
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service,
|
||||
|
|
|
@ -91,7 +91,7 @@ type
|
|||
view: View
|
||||
viewVariant: QVariant
|
||||
controller: Controller
|
||||
channelGroupModules: OrderedTable[string, chat_section_module.AccessInterface]
|
||||
chatSectionModules: OrderedTable[string, chat_section_module.AccessInterface]
|
||||
events: EventEmitter
|
||||
urlsManager: UrlsManager
|
||||
keycardService: keycard_service.Service
|
||||
|
@ -207,7 +207,7 @@ proc newModule*[T](
|
|||
result.keychainService = keychainService
|
||||
|
||||
# Submodules
|
||||
result.channelGroupModules = initOrderedTable[string, chat_section_module.AccessInterface]()
|
||||
result.chatSectionModules = initOrderedTable[string, chat_section_module.AccessInterface]()
|
||||
result.walletSectionModule = wallet_section_module.newModule(
|
||||
result, events, tokenService, collectibleService, currencyService,
|
||||
transactionService, walletAccountService,
|
||||
|
@ -246,9 +246,9 @@ method delete*[T](self: Module[T]) =
|
|||
self.gifsModule.delete
|
||||
self.activityCenterModule.delete
|
||||
self.communitiesModule.delete
|
||||
for cModule in self.channelGroupModules.values:
|
||||
for cModule in self.chatSectionModules.values:
|
||||
cModule.delete
|
||||
self.channelGroupModules.clear
|
||||
self.chatSectionModules.clear
|
||||
self.walletSectionModule.delete
|
||||
self.browserSectionModule.delete
|
||||
self.appSearchModule.delete
|
||||
|
@ -321,27 +321,24 @@ method onCommunityTokensDetailsLoaded[T](self: Module[T], communityId: string,
|
|||
)
|
||||
self.view.model().setTokenItems(communityId, communityTokensItems)
|
||||
|
||||
proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto): SectionItem =
|
||||
let isCommunity = channelGroup.channelGroupType == ChannelGroupType.Community
|
||||
var communityDetails: CommunityDto
|
||||
proc createCommunitySectionItem[T](self: Module[T], communityDetails: CommunityDto): SectionItem =
|
||||
var communityTokensItems: seq[TokenItem]
|
||||
if (isCommunity):
|
||||
communityDetails = self.controller.getCommunityById(channelGroup.id)
|
||||
if communityDetails.memberRole == MemberRole.Owner or communityDetails.memberRole == MemberRole.TokenMaster:
|
||||
self.controller.getCommunityTokensDetailsAsync(channelGroup.id)
|
||||
|
||||
# Get community members' revealed accounts
|
||||
# We will update the model later when we finish loading the accounts
|
||||
self.controller.asyncGetRevealedAccountsForAllMembers(channelGroup.id)
|
||||
if communityDetails.memberRole == MemberRole.Owner or communityDetails.memberRole == MemberRole.TokenMaster:
|
||||
self.controller.getCommunityTokensDetailsAsync(communityDetails.id)
|
||||
|
||||
# Get community members' revealed accounts
|
||||
# We will update the model later when we finish loading the accounts
|
||||
self.controller.asyncGetRevealedAccountsForAllMembers(communityDetails.id)
|
||||
|
||||
let (unviewedCount, notificationsCount) = self.controller.sectionUnreadMessagesAndMentionsCount(communityDetails.id)
|
||||
|
||||
let unviewedCount = channelGroup.unviewedMessagesCount
|
||||
let notificationsCount = channelGroup.unviewedMentionsCount
|
||||
let hasNotification = unviewedCount > 0 or notificationsCount > 0
|
||||
let active = self.getActiveSectionId() == channelGroup.id # We must pass on if the current item section is currently active to keep that property as it is
|
||||
let active = self.getActiveSectionId() == communityDetails.id # We must pass on if the current item section is currently active to keep that property as it is
|
||||
|
||||
|
||||
# Add members who were kicked from the community after the ownership change for auto-rejoin after they share addresses
|
||||
var members = channelGroup.members
|
||||
var members = communityDetails.members
|
||||
for requestForAutoRejoin in communityDetails.waitingForSharedAddressesRequestsToJoin:
|
||||
var chatMember = ChatMember()
|
||||
chatMember.id = requestForAutoRejoin.publicKey
|
||||
|
@ -349,7 +346,6 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
|||
chatMember.role = MemberRole.None
|
||||
members.add(chatMember)
|
||||
|
||||
|
||||
var bannedMembers = newSeq[MemberItem]()
|
||||
for memberId, memberState in communityDetails.pendingAndBannedMembers.pairs:
|
||||
let state = memberState.toMembershipRequestState()
|
||||
|
@ -360,32 +356,32 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
|||
discard
|
||||
|
||||
result = initItem(
|
||||
channelGroup.id,
|
||||
if isCommunity: SectionType.Community else: SectionType.Chat,
|
||||
if isCommunity: channelGroup.name else: conf.CHAT_SECTION_NAME,
|
||||
channelGroup.memberRole,
|
||||
if isCommunity: communityDetails.isControlNode else: false,
|
||||
channelGroup.description,
|
||||
channelGroup.introMessage,
|
||||
channelGroup.outroMessage,
|
||||
channelGroup.images.thumbnail,
|
||||
channelGroup.images.banner,
|
||||
icon = if (isCommunity): "" else: conf.CHAT_SECTION_ICON,
|
||||
channelGroup.color,
|
||||
if isCommunity: communityDetails.tags else: "",
|
||||
communityDetails.id,
|
||||
sectionType = SectionType.Community,
|
||||
communityDetails.name,
|
||||
communityDetails.memberRole,
|
||||
communityDetails.isControlNode,
|
||||
communityDetails.description,
|
||||
communityDetails.introMessage,
|
||||
communityDetails.outroMessage,
|
||||
communityDetails.images.thumbnail,
|
||||
communityDetails.images.banner,
|
||||
icon = "",
|
||||
communityDetails.color,
|
||||
communityDetails.tags,
|
||||
hasNotification,
|
||||
notificationsCount,
|
||||
active,
|
||||
enabled = true,
|
||||
if (isCommunity): communityDetails.joined else: true,
|
||||
if (isCommunity): communityDetails.canJoin else: true,
|
||||
if (isCommunity): communityDetails.spectated else: false,
|
||||
channelGroup.canManageUsers,
|
||||
if (isCommunity): communityDetails.canRequestAccess else: true,
|
||||
if (isCommunity): communityDetails.isMember else: true,
|
||||
channelGroup.permissions.access,
|
||||
channelGroup.permissions.ensOnly,
|
||||
channelGroup.muted,
|
||||
communityDetails.joined,
|
||||
communityDetails.canJoin,
|
||||
communityDetails.spectated,
|
||||
communityDetails.canManageUsers,
|
||||
communityDetails.canRequestAccess,
|
||||
communityDetails.isMember,
|
||||
communityDetails.permissions.access,
|
||||
communityDetails.permissions.ensOnly,
|
||||
communityDetails.muted,
|
||||
# members
|
||||
members.map(proc(member: ChatMember): MemberItem =
|
||||
let contactDetails = self.controller.getContactDetails(member.id)
|
||||
|
@ -400,30 +396,30 @@ proc createChannelGroupItem[T](self: Module[T], channelGroup: ChannelGroupDto):
|
|||
result = self.createMemberItem(member.id, "", state, member.role)
|
||||
),
|
||||
# pendingRequestsToJoin
|
||||
if (isCommunity): communityDetails.pendingRequestsToJoin.map(x => pending_request_item.initItem(
|
||||
communityDetails.pendingRequestsToJoin.map(x => pending_request_item.initItem(
|
||||
x.id,
|
||||
x.publicKey,
|
||||
x.chatId,
|
||||
x.communityId,
|
||||
x.state,
|
||||
x.our
|
||||
)) else: @[],
|
||||
)),
|
||||
communityDetails.settings.historyArchiveSupportEnabled,
|
||||
communityDetails.adminSettings.pinMessageAllMembersEnabled,
|
||||
bannedMembers,
|
||||
# pendingMemberRequests
|
||||
if (isCommunity): communityDetails.pendingRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem =
|
||||
communityDetails.pendingRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem =
|
||||
result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state), MemberRole.None)
|
||||
) else: @[],
|
||||
),
|
||||
# declinedMemberRequests
|
||||
if (isCommunity): communityDetails.declinedRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem =
|
||||
communityDetails.declinedRequestsToJoin.map(proc(requestDto: CommunityMembershipRequestDto): MemberItem =
|
||||
result = self.createMemberItem(requestDto.publicKey, requestDto.id, MembershipRequestState(requestDto.state), MemberRole.None)
|
||||
) else: @[],
|
||||
channelGroup.encrypted,
|
||||
),
|
||||
communityDetails.encrypted,
|
||||
communityTokensItems,
|
||||
channelGroup.pubsubTopic,
|
||||
channelGroup.pubsubTopicKey,
|
||||
channelGroup.shard.index,
|
||||
communityDetails.pubsubTopic,
|
||||
communityDetails.pubsubTopicKey,
|
||||
communityDetails.shard.index,
|
||||
)
|
||||
|
||||
proc connectForNotificationsOnly[T](self: Module[T]) =
|
||||
|
@ -623,9 +619,8 @@ method load*[T](
|
|||
else:
|
||||
self.setActiveSection(activeSection)
|
||||
|
||||
method onChannelGroupsLoaded*[T](
|
||||
method onChatsLoaded*[T](
|
||||
self: Module[T],
|
||||
channelGroups: seq[ChannelGroupDto],
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
nodeConfigurationService: node_configuration_service.Service,
|
||||
|
@ -643,17 +638,63 @@ method onChannelGroupsLoaded*[T](
|
|||
self.chatsLoaded = true
|
||||
if not self.communityDataLoaded:
|
||||
return
|
||||
|
||||
let myPubKey = singletonInstance.userProfile.getPubKey()
|
||||
|
||||
var activeSection: SectionItem
|
||||
var activeSectionId = singletonInstance.localAccountSensitiveSettings.getActiveSection()
|
||||
if activeSectionId == "" or activeSectionId == conf.SETTINGS_SECTION_ID:
|
||||
activeSectionId = singletonInstance.userProfile.getPubKey()
|
||||
activeSectionId = myPubKey
|
||||
|
||||
for channelGroup in channelGroups:
|
||||
self.channelGroupModules[channelGroup.id] = chat_section_module.newModule(
|
||||
# Create personal chat section
|
||||
self.chatSectionModules[myPubKey] = chat_section_module.newModule(
|
||||
self,
|
||||
events,
|
||||
sectionId = myPubKey,
|
||||
isCommunity = false,
|
||||
settingsService,
|
||||
nodeConfigurationService,
|
||||
contactsService,
|
||||
chatService,
|
||||
communityService,
|
||||
messageService,
|
||||
mailserversService,
|
||||
walletAccountService,
|
||||
tokenService,
|
||||
communityTokensService,
|
||||
sharedUrlsService,
|
||||
networkService
|
||||
)
|
||||
let (unviewedMessagesCount, unviewedMentionsCount) = self.controller.sectionUnreadMessagesAndMentionsCount(myPubKey)
|
||||
let personalChatSectionItem = initItem(
|
||||
myPubKey,
|
||||
sectionType = SectionType.Chat,
|
||||
name = conf.CHAT_SECTION_NAME,
|
||||
icon = conf.CHAT_SECTION_ICON,
|
||||
hasNotification = unviewedMessagesCount > 0 or unviewedMentionsCount > 0,
|
||||
notificationsCount = unviewedMentionsCount,
|
||||
active = self.getActiveSectionId() == myPubKey,
|
||||
enabled = true,
|
||||
joined = true,
|
||||
canJoin = true,
|
||||
canRequestAccess = true,
|
||||
isMember = true,
|
||||
muted = false,
|
||||
)
|
||||
self.view.model().addItem(personalChatSectionItem)
|
||||
if activeSectionId == personalChatSectionItem.id:
|
||||
activeSection = personalChatSectionItem
|
||||
|
||||
self.chatSectionModules[myPubKey].load()
|
||||
|
||||
let communities = self.controller.getJoinedAndSpectatedCommunities()
|
||||
# Create Community sections
|
||||
for community in communities:
|
||||
self.chatSectionModules[community.id] = chat_section_module.newModule(
|
||||
self,
|
||||
events,
|
||||
channelGroup.id,
|
||||
isCommunity = channelGroup.channelGroupType == ChannelGroupType.Community,
|
||||
community.id,
|
||||
isCommunity = true,
|
||||
settingsService,
|
||||
nodeConfigurationService,
|
||||
contactsService,
|
||||
|
@ -667,12 +708,12 @@ method onChannelGroupsLoaded*[T](
|
|||
sharedUrlsService,
|
||||
networkService
|
||||
)
|
||||
let channelGroupItem = self.createChannelGroupItem(channelGroup)
|
||||
self.view.model().addItem(channelGroupItem)
|
||||
if activeSectionId == channelGroupItem.id:
|
||||
activeSection = channelGroupItem
|
||||
let communitySectionItem = self.createCommunitySectionItem(community)
|
||||
self.view.model().addItem(communitySectionItem)
|
||||
if activeSectionId == communitySectionItem.id:
|
||||
activeSection = communitySectionItem
|
||||
|
||||
self.channelGroupModules[channelGroup.id].load()
|
||||
self.chatSectionModules[community.id].load()
|
||||
|
||||
# Set active section if it is one of the channel sections
|
||||
if not activeSection.isEmpty():
|
||||
|
@ -705,8 +746,7 @@ method onCommunityDataLoaded*[T](
|
|||
if not self.chatsLoaded:
|
||||
return
|
||||
|
||||
self.onChannelGroupsLoaded(
|
||||
self.controller.getChannelGroups(),
|
||||
self.onChatsLoaded(
|
||||
events,
|
||||
settingsService,
|
||||
nodeConfigurationService,
|
||||
|
@ -729,7 +769,7 @@ proc checkIfModuleDidLoad [T](self: Module[T]) =
|
|||
if self.moduleLoaded:
|
||||
return
|
||||
|
||||
for cModule in self.channelGroupModules.values:
|
||||
for cModule in self.chatSectionModules.values:
|
||||
if(not cModule.isLoaded()):
|
||||
return
|
||||
|
||||
|
@ -839,7 +879,7 @@ method setActiveSectionById*[T](self: Module[T], id: string) =
|
|||
self.setActiveSection(item)
|
||||
|
||||
proc notifySubModulesAboutChange[T](self: Module[T], sectionId: string) =
|
||||
for cModule in self.channelGroupModules.values:
|
||||
for cModule in self.chatSectionModules.values:
|
||||
cModule.onActiveSectionChange(sectionId)
|
||||
|
||||
# If there is a need other section may be notified the same way from here...
|
||||
|
@ -888,17 +928,17 @@ method setCurrentUserStatus*[T](self: Module[T], status: StatusType) =
|
|||
self.controller.setCurrentUserStatus(status)
|
||||
|
||||
proc getChatSectionModule*[T](self: Module[T]): chat_section_module.AccessInterface =
|
||||
return self.channelGroupModules[singletonInstance.userProfile.getPubKey()]
|
||||
return self.chatSectionModules[singletonInstance.userProfile.getPubKey()]
|
||||
|
||||
method getChatSectionModuleAsVariant*[T](self: Module[T]): QVariant =
|
||||
return self.getChatSectionModule().getModuleAsVariant()
|
||||
|
||||
method getCommunitySectionModule*[T](self: Module[T], communityId: string): QVariant =
|
||||
if(not self.channelGroupModules.contains(communityId)):
|
||||
if(not self.chatSectionModules.contains(communityId)):
|
||||
echo "main-module, unexisting community key: ", communityId
|
||||
return
|
||||
|
||||
return self.channelGroupModules[communityId].getModuleAsVariant()
|
||||
return self.chatSectionModules[communityId].getModuleAsVariant()
|
||||
|
||||
method rebuildChatSearchModel*[T](self: Module[T]) =
|
||||
var items: seq[chat_search_item.Item] = @[]
|
||||
|
@ -985,13 +1025,13 @@ method communityJoined*[T](
|
|||
networkService: network_service.Service,
|
||||
setActive: bool = false,
|
||||
) =
|
||||
if self.channelGroupModules.contains(community.id):
|
||||
if self.chatSectionModules.contains(community.id):
|
||||
# The community is already spectated
|
||||
return
|
||||
var firstCommunityJoined = false
|
||||
if (self.channelGroupModules.len == 1): # First one is personal chat section
|
||||
if (self.chatSectionModules.len == 1): # First one is personal chat section
|
||||
firstCommunityJoined = true
|
||||
self.channelGroupModules[community.id] = chat_section_module.newModule(
|
||||
self.chatSectionModules[community.id] = chat_section_module.newModule(
|
||||
self,
|
||||
events,
|
||||
community.id,
|
||||
|
@ -1009,10 +1049,9 @@ method communityJoined*[T](
|
|||
sharedUrlsService,
|
||||
networkService
|
||||
)
|
||||
let channelGroup = community.toChannelGroupDto()
|
||||
self.channelGroupModules[community.id].load()
|
||||
self.chatSectionModules[community.id].load()
|
||||
|
||||
let communitySectionItem = self.createChannelGroupItem(channelGroup)
|
||||
let communitySectionItem = self.createCommunitySectionItem(community)
|
||||
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
|
||||
self.view.model().addItem(communitySectionItem,
|
||||
|
@ -1022,11 +1061,12 @@ method communityJoined*[T](
|
|||
|
||||
if setActive:
|
||||
self.setActiveSection(communitySectionItem)
|
||||
if channelGroup.chats.len > 0:
|
||||
self.channelGroupModules[community.id].setActiveItem(channelGroup.chats[0].id)
|
||||
if(community.chats.len > 0):
|
||||
let chatId = community.chats[0].id
|
||||
self.chatSectionModules[community.id].setActiveItem(chatId)
|
||||
|
||||
method communityLeft*[T](self: Module[T], communityId: string) =
|
||||
if(not self.channelGroupModules.contains(communityId)):
|
||||
if(not self.chatSectionModules.contains(communityId)):
|
||||
echo "main-module, unexisting community key to leave: ", communityId
|
||||
return
|
||||
|
||||
|
@ -1039,24 +1079,23 @@ method communityLeft*[T](self: Module[T], communityId: string) =
|
|||
self.setActiveSection(item)
|
||||
|
||||
var moduleToDelete: chat_section_module.AccessInterface
|
||||
discard self.channelGroupModules.pop(communityId, moduleToDelete)
|
||||
discard self.chatSectionModules.pop(communityId, moduleToDelete)
|
||||
moduleToDelete.delete
|
||||
moduleToDelete = nil
|
||||
|
||||
method communityEdited*[T](
|
||||
self: Module[T],
|
||||
community: CommunityDto) =
|
||||
if(not self.channelGroupModules.contains(community.id)):
|
||||
if(not self.chatSectionModules.contains(community.id)):
|
||||
return
|
||||
let channelGroup = community.toChannelGroupDto()
|
||||
var channelGroupItem = self.createChannelGroupItem(channelGroup)
|
||||
var communitySectionItem = self.createCommunitySectionItem(community)
|
||||
# We need to calculate the unread counts because the community update doesn't come with it
|
||||
let (unviewedMessagesCount, unviewedMentionsCount) = self.controller.sectionUnreadMessagesAndMentionsCount(
|
||||
channelGroupItem.id
|
||||
communitySectionItem.id
|
||||
)
|
||||
channelGroupItem.setHasNotification(unviewedMessagesCount > 0)
|
||||
channelGroupItem.setNotificationsCount(unviewedMentionsCount)
|
||||
self.view.editItem(channelGroupItem)
|
||||
communitySectionItem.setHasNotification(unviewedMessagesCount > 0)
|
||||
communitySectionItem.setNotificationsCount(unviewedMentionsCount)
|
||||
self.view.editItem(communitySectionItem)
|
||||
|
||||
method onCommunityMuted*[T](
|
||||
self: Module[T],
|
||||
|
@ -1595,8 +1634,8 @@ method activateStatusDeepLink*[T](self: Module[T], statusDeepLink: string) =
|
|||
return
|
||||
|
||||
method onDeactivateChatLoader*[T](self: Module[T], sectionId: string, chatId: string) =
|
||||
if (sectionId.len > 0 and self.channelGroupModules.contains(sectionId)):
|
||||
self.channelGroupModules[sectionId].onDeactivateChatLoader(chatId)
|
||||
if (sectionId.len > 0 and self.chatSectionModules.contains(sectionId)):
|
||||
self.chatSectionModules[sectionId].onDeactivateChatLoader(chatId)
|
||||
|
||||
method windowActivated*[T](self: Module[T]) =
|
||||
self.controller.slowdownArchivesImport()
|
||||
|
@ -1646,12 +1685,12 @@ method checkIfAddressWasCopied*[T](self: Module[T], value: string) =
|
|||
self.addressWasShown(value)
|
||||
|
||||
method openSectionChatAndMessage*[T](self: Module[T], sectionId: string, chatId: string, messageId: string) =
|
||||
if sectionId in self.channelGroupModules:
|
||||
self.channelGroupModules[sectionId].openCommunityChatAndScrollToMessage(chatId, messageId)
|
||||
if sectionId in self.chatSectionModules:
|
||||
self.chatSectionModules[sectionId].openCommunityChatAndScrollToMessage(chatId, messageId)
|
||||
|
||||
method updateRequestToJoinState*[T](self: Module[T], sectionId: string, requestToJoinState: RequestToJoinState) =
|
||||
if sectionId in self.channelGroupModules:
|
||||
self.channelGroupModules[sectionId].updateRequestToJoinState(requestToJoinState)
|
||||
if sectionId in self.chatSectionModules:
|
||||
self.chatSectionModules[sectionId].updateRequestToJoinState(requestToJoinState)
|
||||
|
||||
proc createMemberItem*[T](self: Module[T], memberId: string, requestId: string, state: MembershipRequestState, role: MemberRole): MemberItem =
|
||||
let contactDetails = self.controller.getContactDetails(memberId)
|
||||
|
|
|
@ -105,7 +105,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
|
|||
result.devicesModule = devices_module.newModule(result, events, settingsService, devicesService)
|
||||
result.syncModule = sync_module.newModule(result, events, settingsService, nodeConfigurationService, mailserversService)
|
||||
result.wakuModule = waku_module.newModule(result, events, settingsService, nodeConfigurationService)
|
||||
result.notificationsModule = notifications_module.newModule(result, events, settingsService, chatService, contactsService)
|
||||
result.notificationsModule = notifications_module.newModule(result, events, settingsService, chatService, contactsService, communityService)
|
||||
result.ensUsernamesModule = ens_usernames_module.newModule(
|
||||
result, events, settingsService, ensService, walletAccountService, networkService, tokenService, keycardService
|
||||
)
|
||||
|
|
|
@ -17,23 +17,41 @@ type
|
|||
settingsService: settings_service.Service
|
||||
chatService: chat_service.Service
|
||||
contactService: contact_service.Service
|
||||
communityService: community_service.Service
|
||||
chatsLoaded: bool
|
||||
communitiesLoaded: bool
|
||||
|
||||
proc newController*(delegate: io_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
chatService: chat_service.Service,
|
||||
contactService: contact_service.Service): Controller =
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
chatService: chat_service.Service,
|
||||
contactService: contact_service.Service,
|
||||
communityService: community_service.Service,
|
||||
): Controller =
|
||||
result = Controller()
|
||||
result.delegate = delegate
|
||||
result.events = events
|
||||
result.settingsService = settingsService
|
||||
result.chatService = chatService
|
||||
result.contactService = contactService
|
||||
result.communityService = communityService
|
||||
result.chatsLoaded = false
|
||||
result.communitiesLoaded = false
|
||||
|
||||
proc delete*(self: Controller) =
|
||||
discard
|
||||
|
||||
proc init*(self: Controller) =
|
||||
self.events.on(SIGNAL_ACTIVE_CHATS_LOADED) do(e:Args):
|
||||
self.chatsLoaded = true
|
||||
if self.communitiesLoaded:
|
||||
self.delegate.initModel()
|
||||
|
||||
self.events.on(SIGNAL_COMMUNITY_DATA_LOADED) do(e:Args):
|
||||
self.communitiesLoaded = true
|
||||
if self.chatsLoaded:
|
||||
self.delegate.initModel()
|
||||
|
||||
self.events.on(SIGNAL_COMMUNITY_JOINED) do(e:Args):
|
||||
let args = CommunityArgs(e)
|
||||
if(args.error.len > 0):
|
||||
|
@ -95,11 +113,14 @@ proc setNotifSettingExemptions*(self: Controller, id: string, exemptions: Notifi
|
|||
proc removeNotifSettingExemptions*(self: Controller, id: string): bool =
|
||||
return self.settingsService.removeNotifSettingExemptions(id)
|
||||
|
||||
proc getChannelGroups*(self: Controller): seq[ChannelGroupDto] =
|
||||
return self.chatService.getChannelGroups()
|
||||
proc getChatsForPersonalSection*(self: Controller): seq[ChatDto] =
|
||||
return self.chatService.getChatsForPersonalSection()
|
||||
|
||||
proc getChatDetails*(self: Controller, chatId: string): ChatDto =
|
||||
return self.chatService.getChatById(chatId)
|
||||
|
||||
proc getContactDetails*(self: Controller, id: string): ContactDetails =
|
||||
return self.contactService.getContactDetails(id)
|
||||
|
||||
proc getJoinedAndSpectatedCommunities*(self: Controller): seq[CommunityDto] =
|
||||
return self.communityService.getJoinedAndSpectatedCommunities()
|
||||
|
|
|
@ -14,6 +14,9 @@ method load*(self: AccessInterface) {.base.} =
|
|||
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method initModel*(self: AccessInterface) {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
method isLoaded*(self: AccessInterface): bool {.base.} =
|
||||
raise newException(ValueError, "No implementation available")
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import ../../../../core/eventemitter
|
|||
import ../../../../../app_service/service/settings/service as settings_service
|
||||
import ../../../../../app_service/service/chat/service as chat_service
|
||||
import ../../../../../app_service/service/contacts/service as contact_service
|
||||
import ../../../../../app_service/service/community/service as community_service
|
||||
from ../../../../../app_service/service/community/dto/community import CommunityDto
|
||||
|
||||
export io_interface
|
||||
|
@ -24,15 +25,18 @@ type
|
|||
moduleLoaded: bool
|
||||
|
||||
proc newModule*(delegate: delegate_interface.AccessInterface,
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
chatService: chat_service.Service,
|
||||
contactService: contact_service.Service): Module =
|
||||
events: EventEmitter,
|
||||
settingsService: settings_service.Service,
|
||||
chatService: chat_service.Service,
|
||||
contactService: contact_service.Service,
|
||||
communityService: community_service.Service,
|
||||
): Module =
|
||||
result = Module()
|
||||
result.delegate = delegate
|
||||
result.view = view.newView(result)
|
||||
result.viewVariant = newQVariant(result.view)
|
||||
result.controller = controller.newController(result, events, settingsService, chatService, contactService)
|
||||
result.controller = controller.newController(result, events, settingsService, chatService, contactService,
|
||||
communityService)
|
||||
result.moduleLoaded = false
|
||||
|
||||
method delete*(self: Module) =
|
||||
|
@ -70,26 +74,34 @@ proc createChatItem(self: Module, chatDto: ChatDto): Item =
|
|||
|
||||
return self.createItem(chatDto.id, chatName, chatImage, chatDto.color, chatDto.joined, itemType)
|
||||
|
||||
proc initModel(self: Module) =
|
||||
let channelGroups = self.controller.getChannelGroups()
|
||||
method initModel(self: Module) =
|
||||
var items: seq[Item]
|
||||
for cg in channelGroups:
|
||||
if cg.channelGroupType == ChannelGroupType.Community:
|
||||
let item = self.createItem(cg.id, cg.name, cg.images.thumbnail, cg.color, joinedTimestamp = 0, item.Type.Community)
|
||||
items.add(item)
|
||||
elif cg.channelGroupType == ChannelGroupType.Personal:
|
||||
for c in cg.chats:
|
||||
if c.chatType != ChatType.OneToOne and c.chatType != ChatType.PrivateGroupChat:
|
||||
continue
|
||||
let item = self.createChatItem(c)
|
||||
items.add(item)
|
||||
# Add personal section
|
||||
let personalChats = self.controller.getChatsForPersonalSection()
|
||||
for c in personalChats:
|
||||
if c.chatType != ChatType.OneToOne and c.chatType != ChatType.PrivateGroupChat:
|
||||
continue
|
||||
let item = self.createChatItem(c)
|
||||
items.add(item)
|
||||
|
||||
# Add communities
|
||||
let communities = self.controller.getJoinedAndSpectatedCommunities()
|
||||
for community in communities:
|
||||
let item = self.createItem(
|
||||
community.id,
|
||||
community.name,
|
||||
community.images.thumbnail,
|
||||
community.color,
|
||||
joinedTimestamp = 0,
|
||||
item.Type.Community
|
||||
)
|
||||
items.add(item)
|
||||
|
||||
# Sort to get most recent first
|
||||
items.sort(comp, SortOrder.Descending)
|
||||
self.view.exemptionsModel().setItems(items)
|
||||
|
||||
method viewDidLoad*(self: Module) =
|
||||
self.initModel()
|
||||
self.moduleLoaded = true
|
||||
self.delegate.notificationsModuleDidLoad()
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
#################################################
|
||||
# Async get chats (channel groups)
|
||||
# Async get chats
|
||||
#################################################
|
||||
type
|
||||
AsyncGetChannelGroupsTaskArg = ref object of QObjectTaskArg
|
||||
|
||||
const asyncGetChannelGroupsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncGetChannelGroupsTaskArg](argEncoded)
|
||||
type
|
||||
AsyncGetActiveChatsTaskArg = ref object of QObjectTaskArg
|
||||
|
||||
const asyncGetActiveChatsTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
|
||||
let arg = decode[AsyncGetActiveChatsTaskArg](argEncoded)
|
||||
try:
|
||||
let response = status_chat.getChannelGroups()
|
||||
let response = status_chat.getActiveChats()
|
||||
|
||||
let responseJson = %*{
|
||||
"channelGroups": response.result,
|
||||
"chats": response.result,
|
||||
"error": "",
|
||||
}
|
||||
arg.finish(responseJson)
|
||||
|
|
|
@ -16,7 +16,7 @@ type ChatType* {.pure.}= enum
|
|||
Timeline {.deprecated.} = 5,
|
||||
CommunityChat = 6
|
||||
|
||||
type ChannelGroupType* {.pure.}= enum
|
||||
type ChatSectionType* {.pure.}= enum
|
||||
Unknown = "unknown",
|
||||
Personal = "personal",
|
||||
Community = "community"
|
||||
|
@ -93,35 +93,6 @@ type ChatDto* = object
|
|||
permissions*: Permission
|
||||
hideIfPermissionsNotMet*: bool
|
||||
|
||||
type ChannelGroupDto* = object
|
||||
id*: string
|
||||
channelGroupType*: ChannelGroupType
|
||||
memberRole*: MemberRole
|
||||
verified*: bool
|
||||
name*: string
|
||||
ensName*: string
|
||||
description*: string
|
||||
introMessage*: string
|
||||
outroMessage*: string
|
||||
chats*: seq[ChatDto]
|
||||
categories*: seq[Category]
|
||||
images*: Images
|
||||
permissions*: Permission
|
||||
members*: seq[ChatMember]
|
||||
canManageUsers*: bool
|
||||
color*: string
|
||||
muted*: bool
|
||||
historyArchiveSupportEnabled*: bool
|
||||
pinMessageAllMembersEnabled*: bool
|
||||
bannedMembersIds*: seq[string]
|
||||
encrypted*: bool
|
||||
unviewedMessagesCount*: int
|
||||
unviewedMentionsCount*: int
|
||||
channelPermissions*: CheckAllChannelsPermissionsResponseDto
|
||||
pubsubTopic*: string
|
||||
pubsubTopicKey*: string
|
||||
shard*: Shard
|
||||
|
||||
type ClearedHistoryDto* = object
|
||||
chatId*: string
|
||||
clearedAt*: int
|
||||
|
@ -324,74 +295,6 @@ proc toChatDto*(jsonObj: JsonNode): ChatDto =
|
|||
if (result.communityId != "" and not result.id.contains(result.communityId)):
|
||||
result.id = result.communityId & result.id
|
||||
|
||||
proc toChannelGroupDto*(jsonObj: JsonNode): ChannelGroupDto =
|
||||
result = ChannelGroupDto()
|
||||
|
||||
discard jsonObj.getProp("verified", result.verified)
|
||||
discard jsonObj.getProp("memberRole", result.memberRole)
|
||||
discard jsonObj.getProp("name", result.name)
|
||||
discard jsonObj.getProp("description", result.description)
|
||||
discard jsonObj.getProp("introMessage", result.introMessage)
|
||||
discard jsonObj.getProp("outroMessage", result.outroMessage)
|
||||
discard jsonObj.getProp("encrypted", result.encrypted)
|
||||
discard jsonObj.getProp("unviewedMessagesCount", result.unviewedMessagesCount)
|
||||
discard jsonObj.getProp("unviewedMentionsCount", result.unviewedMentionsCount)
|
||||
|
||||
result.channelGroupType = ChannelGroupType.Unknown
|
||||
var channelGroupTypeString: string
|
||||
if (jsonObj.getProp("channelGroupType", channelGroupTypeString)):
|
||||
result.channelGroupType = parseEnum[ChannelGroupType](channelGroupTypeString)
|
||||
|
||||
var chatsObj: JsonNode
|
||||
if(jsonObj.getProp("chats", chatsObj)):
|
||||
for _, chatObj in chatsObj:
|
||||
let chat = toChatDto(chatObj)
|
||||
if (chat.chatType == ChatType.Public):
|
||||
# Filter out public chats as we don't show them anymore
|
||||
continue
|
||||
result.chats.add(chat)
|
||||
|
||||
var categoriesObj: JsonNode
|
||||
if(jsonObj.getProp("categories", categoriesObj)):
|
||||
for _, categoryObj in categoriesObj:
|
||||
result.categories.add(toCategory(categoryObj))
|
||||
|
||||
var imagesObj: JsonNode
|
||||
if(jsonObj.getProp("images", imagesObj)):
|
||||
result.images = toImages(imagesObj)
|
||||
|
||||
var permissionObj: JsonNode
|
||||
if(jsonObj.getProp("permissions", permissionObj)):
|
||||
result.permissions = toPermission(permissionObj)
|
||||
|
||||
var membersObj: JsonNode
|
||||
if(jsonObj.getProp("members", membersObj) and membersObj.kind == JObject):
|
||||
for memberId, memberObj in membersObj:
|
||||
result.members.add(toChannelMember(memberObj, memberId, joined = true))
|
||||
|
||||
var bannedMembersIdsObj: JsonNode
|
||||
if(jsonObj.getProp("banList", bannedMembersIdsObj) and bannedMembersIdsObj.kind == JArray):
|
||||
for bannedMemberId in bannedMembersIdsObj:
|
||||
result.bannedMembersIds.add(bannedMemberId.getStr)
|
||||
|
||||
discard jsonObj.getProp("canManageUsers", result.canManageUsers)
|
||||
discard jsonObj.getProp("color", result.color)
|
||||
discard jsonObj.getProp("muted", result.muted)
|
||||
|
||||
var responseDto = CheckAllChannelsPermissionsResponseDto()
|
||||
responseDto.channels = initTable[string, CheckChannelPermissionsResponseDto]()
|
||||
result.channelPermissions = responseDto
|
||||
var checkChannelPermissionResponsesObj: JsonNode
|
||||
if(jsonObj.getProp("checkChannelPermissionResponses", checkChannelPermissionResponsesObj) and checkChannelPermissionResponsesObj.kind == JObject):
|
||||
|
||||
for channelId, permissionResponse in checkChannelPermissionResponsesObj:
|
||||
result.channelPermissions.channels[channelId] = permissionResponse.toCheckChannelPermissionsResponseDto()
|
||||
|
||||
discard jsonObj.getProp("pubsubTopic", result.pubsubTopic)
|
||||
discard jsonObj.getProp("pubsubTopicKey", result.pubsubTopicKey)
|
||||
|
||||
result.shard = jsonObj.getShard()
|
||||
|
||||
# To parse Community chats to ChatDto, we need to add the commuity ID and type
|
||||
proc toChatDto*(jsonObj: JsonNode, communityId: string): ChatDto =
|
||||
result = jsonObj.toChatDto()
|
||||
|
@ -433,3 +336,12 @@ proc updateMissingFields*(chatToUpdate: var ChatDto, oldChat: ChatDto) =
|
|||
chatToUpdate.viewersCanPostReactions = oldChat.viewersCanPostReactions
|
||||
chatToUpdate.categoryId = oldChat.categoryId
|
||||
chatToUpdate.members = oldChat.members
|
||||
|
||||
proc isOneToOne*(c: ChatDto): bool =
|
||||
return c.chatType == ChatType.OneToOne
|
||||
|
||||
proc isPrivateGroupChat*(c: ChatDto): bool =
|
||||
return c.chatType == ChatType.PrivateGroupChat
|
||||
|
||||
proc isActivePersonalChat*(c: ChatDto): bool =
|
||||
return c.active and (c.isOneToOne() or c.isPrivateGroupChat()) and c.communityId == ""
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import NimQml, Tables, json, sequtils, stew/shims/strformat, chronicles, os, std/algorithm, strutils, uuids, base64
|
||||
import NimQml, Tables, json, sequtils, stew/shims/strformat, chronicles, os, strutils, uuids, base64
|
||||
import std/[times, os]
|
||||
|
||||
import ../../../app/core/tasks/[qt, threadpool]
|
||||
|
@ -30,12 +30,6 @@ include ../../../app/core/tasks/common
|
|||
include async_tasks
|
||||
|
||||
type
|
||||
ChannelGroupsArgs* = ref object of Args
|
||||
channelGroups*: seq[ChannelGroupDto]
|
||||
|
||||
ChannelGroupArgs* = ref object of Args
|
||||
channelGroup*: ChannelGroupDto
|
||||
|
||||
ChatUpdateArgs* = ref object of Args
|
||||
chats*: seq[ChatDto]
|
||||
|
||||
|
@ -102,8 +96,8 @@ type
|
|||
error*: string
|
||||
|
||||
# Signals which may be emitted by this service:
|
||||
const SIGNAL_CHANNEL_GROUPS_LOADED* = "channelGroupsLoaded"
|
||||
const SIGNAL_CHANNEL_GROUPS_LOADING_FAILED* = "channelGroupsLoadingFailed"
|
||||
const SIGNAL_ACTIVE_CHATS_LOADED* = "activeChatsLoaded"
|
||||
const SIGNAL_CHATS_LOADING_FAILED* = "chatsLoadingFailed"
|
||||
const SIGNAL_CHAT_UPDATE* = "chatUpdate"
|
||||
const SIGNAL_CHAT_LEFT* = "channelLeft"
|
||||
const SIGNAL_SENDING_FAILED* = "messageSendingFailed"
|
||||
|
@ -131,7 +125,6 @@ QtObject:
|
|||
threadpool: ThreadPool
|
||||
events: EventEmitter
|
||||
chats: Table[string, ChatDto] # [chat_id, ChatDto]
|
||||
channelGroups: OrderedTable[string, ChannelGroupDto] # [chatGroup_id, ChannelGroupDto]
|
||||
contactService: contact_service.Service
|
||||
|
||||
proc delete*(self: Service) =
|
||||
|
@ -148,12 +141,9 @@ QtObject:
|
|||
result.threadpool = threadpool
|
||||
result.contactService = contactService
|
||||
result.chats = initTable[string, ChatDto]()
|
||||
result.channelGroups = initOrderedTable[string, ChannelGroupDto]()
|
||||
|
||||
# Forward declarations
|
||||
proc updateOrAddChat*(self: Service, chat: ChatDto)
|
||||
proc hydrateChannelGroups*(self: Service, data: JsonNode)
|
||||
proc updateOrAddChannelGroup*(self: Service, channelGroup: ChannelGroupDto, isCommunityChannelGroup: bool = false)
|
||||
proc processMessengerResponse*(self: Service, response: RpcResponse[JsonNode]): (seq[ChatDto], seq[MessageDto])
|
||||
|
||||
proc doConnect(self: Service) =
|
||||
|
@ -187,126 +177,63 @@ QtObject:
|
|||
for clearedHistoryDto in receivedData.clearedHistories:
|
||||
self.events.emit(SIGNAL_CHAT_HISTORY_CLEARED, ChatArgs(chatId: clearedHistoryDto.chatId))
|
||||
|
||||
# Handling community updates
|
||||
if (receivedData.communities.len > 0):
|
||||
for community in receivedData.communities:
|
||||
if community.joined:
|
||||
self.updateOrAddChannelGroup(community.toChannelGroupDto(), isCommunityChannelGroup = true)
|
||||
|
||||
self.events.on(SIGNAL_CHAT_REQUEST_UPDATE_AFTER_SEND) do(e: Args):
|
||||
var args = RpcResponseArgs(e)
|
||||
discard self.processMessengerResponse(args.response)
|
||||
|
||||
proc getChannelGroups*(self: Service): seq[ChannelGroupDto] =
|
||||
return toSeq(self.channelGroups.values)
|
||||
|
||||
proc loadChannelGroupById*(self: Service, channelGroupId: string) =
|
||||
try:
|
||||
let response = status_chat.getChannelGroupById(channelGroupId)
|
||||
self.hydrateChannelGroups(response.result)
|
||||
except Exception as e:
|
||||
error "error loadChannelGroupById: ", errorDescription = e.msg
|
||||
|
||||
proc asyncGetChannelGroups*(self: Service) =
|
||||
let arg = AsyncGetChannelGroupsTaskArg(
|
||||
tptr: cast[ByteAddress](asyncGetChannelGroupsTask),
|
||||
proc asyncGetActiveChat*(self: Service) =
|
||||
let arg = AsyncGetActiveChatsTaskArg(
|
||||
tptr: cast[ByteAddress](asyncGetActiveChatsTask),
|
||||
vptr: cast[ByteAddress](self.vptr),
|
||||
slot: "onAsyncGetChannelGroupsResponse",
|
||||
slot: "onAsyncGetActiveChatsResponse",
|
||||
)
|
||||
self.threadpool.start(arg)
|
||||
|
||||
proc sortPersonnalChatAsFirst[T, D](x, y: (T, D)): int =
|
||||
if (x[1].channelGroupType == Personal): return -1
|
||||
if (y[1].channelGroupType == Personal): return 1
|
||||
return 0
|
||||
|
||||
proc hydrateChannelGroups(self: Service, data: JsonNode) =
|
||||
var chats: seq[ChatDto] = @[]
|
||||
for (sectionId, section) in data.pairs:
|
||||
var channelGroup = section.toChannelGroupDto()
|
||||
channelGroup.id = sectionId
|
||||
self.channelGroups[sectionId] = channelGroup
|
||||
for (chatId, chat) in section["chats"].pairs:
|
||||
chats.add(chat.toChatDto())
|
||||
|
||||
# Make the personal channelGroup the first one
|
||||
self.channelGroups.sort(sortPersonnalChatAsFirst[string, ChannelGroupDto], SortOrder.Ascending)
|
||||
|
||||
for chat in chats:
|
||||
proc hydrateChats(self: Service, data: JsonNode) =
|
||||
for chatJson in data:
|
||||
let chat = chatJson.toChatDto()
|
||||
if chat.active and chat.chatType != chat_dto.ChatType.Unknown:
|
||||
if chat.chatType == chat_dto.ChatType.Public:
|
||||
# Deactivate old public chats
|
||||
discard status_chat.deactivateChat(chat.id)
|
||||
else:
|
||||
self.chats[chat.id] = chat
|
||||
|
||||
proc onAsyncGetChannelGroupsResponse*(self: Service, response: string) {.slot.} =
|
||||
proc onAsyncGetActiveChatsResponse*(self: Service, response: string) {.slot.} =
|
||||
try:
|
||||
let rpcResponseObj = response.parseJson
|
||||
|
||||
if (rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != ""):
|
||||
raise newException(CatchableError, rpcResponseObj{"error"}.getStr)
|
||||
|
||||
if(rpcResponseObj["channelGroups"].kind == JNull):
|
||||
raise newException(RpcException, "No channel groups returned")
|
||||
if rpcResponseObj["chats"].kind != JNull:
|
||||
self.hydrateChats(rpcResponseObj["chats"])
|
||||
|
||||
self.hydrateChannelGroups(rpcResponseObj["channelGroups"])
|
||||
self.events.emit(SIGNAL_CHANNEL_GROUPS_LOADED, ChannelGroupsArgs(channelGroups: self.getChannelGroups()))
|
||||
self.events.emit(SIGNAL_ACTIVE_CHATS_LOADED, Args())
|
||||
except Exception as e:
|
||||
let errDesription = e.msg
|
||||
error "error get channel groups: ", errDesription
|
||||
self.events.emit(SIGNAL_CHANNEL_GROUPS_LOADING_FAILED, Args())
|
||||
error "error get active chats: ", errDesription
|
||||
self.events.emit(SIGNAL_CHATS_LOADING_FAILED, Args())
|
||||
|
||||
proc init*(self: Service) =
|
||||
self.doConnect()
|
||||
|
||||
self.asyncGetChannelGroups()
|
||||
self.asyncGetActiveChat()
|
||||
|
||||
proc hasChannel*(self: Service, chatId: string): bool =
|
||||
self.chats.hasKey(chatId)
|
||||
|
||||
|
||||
proc getChatIndex*(self: Service, channelGroupId, chatId: string): int =
|
||||
var i = 0
|
||||
|
||||
if not self.channelGroups.contains(channelGroupId):
|
||||
warn "unknown channel group", channelGroupId
|
||||
return -1
|
||||
|
||||
for chat in self.channelGroups[channelGroupId].chats:
|
||||
if (chat.id == chatId):
|
||||
return i
|
||||
i.inc()
|
||||
return -1
|
||||
|
||||
proc chatsWithCategoryHaveUnreadMessages*(self: Service, communityId: string, categoryId: string): bool =
|
||||
if communityId == "" or categoryId == "":
|
||||
return false
|
||||
|
||||
if not self.channelGroups.contains(communityId):
|
||||
warn "unknown community", communityId
|
||||
return false
|
||||
|
||||
for chat in self.channelGroups[communityId].chats:
|
||||
if chat.categoryId != categoryId:
|
||||
continue
|
||||
if (not chat.muted and chat.unviewedMessagesCount > 0) or chat.unviewedMentionsCount > 0:
|
||||
return true
|
||||
return false
|
||||
|
||||
proc sectionUnreadMessagesAndMentionsCount*(self: Service, communityId: string):
|
||||
proc sectionUnreadMessagesAndMentionsCount*(self: Service, sectionId: string):
|
||||
tuple[unviewedMessagesCount: int, unviewedMentionsCount: int] =
|
||||
if communityId == "":
|
||||
return
|
||||
|
||||
if not self.channelGroups.contains(communityId):
|
||||
warn "unknown community", communityId
|
||||
return
|
||||
|
||||
result.unviewedMentionsCount = 0
|
||||
result.unviewedMessagesCount = 0
|
||||
|
||||
for chat in self.channelGroups[communityId].chats:
|
||||
let myPubKey = singletonInstance.userProfile.getPubKey()
|
||||
var seactionIdToFind = sectionId
|
||||
if sectionId == myPubKey:
|
||||
# If the section is the personal one (ID == pubKey), then we set the seactionIdToFind to ""
|
||||
# because personal chats have communityId == ""
|
||||
seactionIdToFind = ""
|
||||
for _, chat in self.chats:
|
||||
if chat.communityId != seactionIdToFind:
|
||||
continue
|
||||
result.unviewedMentionsCount += chat.unviewedMentionsCount
|
||||
# We count the unread messages if we are unmuted and it's not a mention, we want to show a badge on mentions
|
||||
if chat.unviewedMentionsCount == 0 and chat.muted:
|
||||
|
@ -328,49 +255,6 @@ QtObject:
|
|||
self.chats[chat.id].categoryId = categoryId
|
||||
self.events.emit(SIGNAL_CHAT_ADDED_OR_UPDATED, ChatArgs(communityId: chat.communityId, chatId: chat.id))
|
||||
|
||||
var channelGroupId = chat.communityId
|
||||
if (channelGroupId == ""):
|
||||
channelGroupId = singletonInstance.userProfile.getPubKey()
|
||||
|
||||
if not self.channelGroups.contains(channelGroupId):
|
||||
warn "unknown community for new channel update", channelGroupId
|
||||
return
|
||||
|
||||
let index = self.getChatIndex(channelGroupId, chat.id)
|
||||
if (index == -1):
|
||||
self.channelGroups[channelGroupId].chats.add(self.chats[chat.id])
|
||||
else:
|
||||
self.channelGroups[channelGroupId].chats[index] = self.chats[chat.id]
|
||||
|
||||
proc updateMissingFieldsInCommunityChat(self: Service, channelGroupId: string, newChat: ChatDto): ChatDto =
|
||||
|
||||
if not self.channelGroups.contains(channelGroupId):
|
||||
warn "unknown channel group", channelGroupId
|
||||
return
|
||||
|
||||
var chat = newChat
|
||||
for previousChat in self.channelGroups[channelGroupId].chats:
|
||||
if previousChat.id != newChat.id:
|
||||
continue
|
||||
chat.unviewedMessagesCount = previousChat.unviewedMessagesCount
|
||||
chat.unviewedMentionsCount = previousChat.unviewedMentionsCount
|
||||
chat.muted = previousChat.muted
|
||||
chat.highlight = previousChat.highlight
|
||||
break
|
||||
return chat
|
||||
|
||||
# Community channel groups have less info because they come from community signals
|
||||
proc updateOrAddChannelGroup*(self: Service, channelGroup: ChannelGroupDto, isCommunityChannelGroup: bool = false) =
|
||||
var newChannelGroup = channelGroup
|
||||
if isCommunityChannelGroup and self.channelGroups.contains(channelGroup.id):
|
||||
# We need to update missing fields in the chats seq before saving
|
||||
let newChats = channelGroup.chats.mapIt(self.updateMissingFieldsInCommunityChat(channelGroup.id, it))
|
||||
newChannelGroup.chats = newChats
|
||||
|
||||
self.channelGroups[channelGroup.id] = newChannelGroup
|
||||
for chat in newChannelGroup.chats:
|
||||
self.updateOrAddChat(chat)
|
||||
|
||||
proc updateChannelMembers*(self: Service, channel: ChatDto) =
|
||||
if not self.chats.hasKey(channel.id):
|
||||
return
|
||||
|
@ -380,12 +264,6 @@ QtObject:
|
|||
self.updateOrAddChat(chat)
|
||||
self.events.emit(SIGNAL_CHAT_MEMBERS_CHANGED, ChatMembersChangedArgs(chatId: chat.id, members: chat.members))
|
||||
|
||||
proc getChannelGroupById*(self: Service, channelGroupId: string): ChannelGroupDto =
|
||||
if not self.channelGroups.contains(channelGroupId):
|
||||
warn "Unknown channel group", channelGroupId
|
||||
return
|
||||
return self.channelGroups[channelGroupId]
|
||||
|
||||
proc parseChatResponse*(self: Service, response: RpcResponse[JsonNode]): (seq[ChatDto], seq[MessageDto]) =
|
||||
var chats: seq[ChatDto] = @[]
|
||||
var messages: seq[MessageDto] = @[]
|
||||
|
@ -460,6 +338,12 @@ QtObject:
|
|||
proc getChatsOfChatTypes*(self: Service, types: seq[chat_dto.ChatType]): seq[ChatDto] =
|
||||
return self.getAllChats().filterIt(it.chatType in types)
|
||||
|
||||
proc getChatsForPersonalSection*(self: Service): seq[ChatDto] =
|
||||
return self.getAllChats().filterIt(it.isActivePersonalChat())
|
||||
|
||||
proc getChatsForCommunity*(self: Service, communityId: string): seq[ChatDto] =
|
||||
return self.getAllChats().filterIt(it.communityId == communityId)
|
||||
|
||||
proc getChatById*(self: Service, chatId: string, showWarning: bool = true): ChatDto =
|
||||
if(not self.chats.contains(chatId)):
|
||||
if (showWarning):
|
||||
|
@ -527,11 +411,6 @@ QtObject:
|
|||
|
||||
discard status_chat.deactivateChat(chatId, preserveHistory = chat.chatType == chat_dto.ChatType.OneToOne)
|
||||
|
||||
var channelGroupId = chat.communityId
|
||||
if (channelGroupId == ""):
|
||||
channelGroupId = singletonInstance.userProfile.getPubKey()
|
||||
|
||||
self.channelGroups[channelGroupId].chats.delete(self.getChatIndex(channelGroupId, chatId))
|
||||
self.chats.del(chatId)
|
||||
self.events.emit(SIGNAL_CHAT_LEFT, ChatArgs(chatId: chatId))
|
||||
except Exception as e:
|
||||
|
@ -734,20 +613,11 @@ QtObject:
|
|||
var parsedImage = imageJson.parseJson
|
||||
parsedImage["imagePath"] = %singletonInstance.utils.formatImagePath(parsedImage["imagePath"].getStr)
|
||||
let response = status_chat.editChat(communityID, chatID, name, color, $parsedImage)
|
||||
if (not response.error.isNil):
|
||||
let msg = response.error.message & " chatId=" & chatId
|
||||
error "error while editing group chat details", msg
|
||||
return
|
||||
|
||||
let resultedChat = response.result.toChatDto()
|
||||
discard self.processMessengerResponse(response)
|
||||
|
||||
var chat = self.chats[chatID]
|
||||
chat.name = name
|
||||
chat.color = color
|
||||
chat.icon = resultedChat.icon
|
||||
self.updateOrAddChat(chat)
|
||||
|
||||
self.events.emit(SIGNAL_GROUP_CHAT_DETAILS_UPDATED, ChatUpdateDetailsArgs(id: chatID, newName: name, newColor: color, newImage: resultedChat.icon))
|
||||
let chat = self.chats[chatID]
|
||||
self.events.emit(SIGNAL_GROUP_CHAT_DETAILS_UPDATED, ChatUpdateDetailsArgs(id: chatID, newName: name, newColor: color, newImage: chat.icon))
|
||||
except Exception as e:
|
||||
error "error while updating group chat: ", msg = e.msg
|
||||
|
||||
|
@ -781,25 +651,6 @@ QtObject:
|
|||
except Exception as e:
|
||||
error "error while creating group chat", msg = e.msg
|
||||
|
||||
proc getMembers*(self: Service, communityID, chatId: string): seq[ChatMember] =
|
||||
try:
|
||||
var realChatId = chatId.replace(communityID, "")
|
||||
let response = status_chat.getMembers(communityID, realChatId)
|
||||
if response.result.kind == JNull:
|
||||
# No members. Could be a public chat
|
||||
return
|
||||
let myPubkey = singletonInstance.userProfile.getPubKey()
|
||||
result = @[]
|
||||
for (id, memberObj) in response.result.pairs:
|
||||
var member = toChatMember(memberObj, id)
|
||||
# Make yourself as the first result
|
||||
if (id == myPubkey):
|
||||
result.insert(member)
|
||||
else:
|
||||
result.add(member)
|
||||
except Exception as e:
|
||||
error "error while getting members", msg = e.msg, communityID, chatId
|
||||
|
||||
proc updateUnreadMessage*(self: Service, chatID: string, messagesCount:int, messagesWithMentionsCount:int) =
|
||||
var chat = self.getChatById(chatID)
|
||||
if chat.id == "":
|
||||
|
@ -842,7 +693,7 @@ QtObject:
|
|||
let communityId = rpcResponseObj{"communityId"}.getStr()
|
||||
let chatId = rpcResponseObj{"chatId"}.getStr()
|
||||
let checkChannelPermissionsResponse = rpcResponseObj["response"]["result"].toCheckChannelPermissionsResponseDto()
|
||||
self.channelGroups[communityId].channelPermissions.channels[chatId] = checkChannelPermissionsResponse
|
||||
|
||||
self.events.emit(SIGNAL_CHECK_CHANNEL_PERMISSIONS_RESPONSE, CheckChannelPermissionsResponseArgs(communityId: communityId, chatId: chatId, checkChannelPermissionsResponse: checkChannelPermissionsResponse))
|
||||
except Exception as e:
|
||||
let errMsg = e.msg
|
||||
|
@ -870,7 +721,7 @@ QtObject:
|
|||
raise newException(RpcException, error.message)
|
||||
|
||||
let checkAllChannelsPermissionsResponse = rpcResponseObj["response"]["result"].toCheckAllChannelsPermissionsResponseDto()
|
||||
self.channelGroups[communityId].channelPermissions = checkAllChannelsPermissionsResponse
|
||||
# TODO save it
|
||||
self.events.emit(SIGNAL_CHECK_ALL_CHANNELS_PERMISSIONS_RESPONSE, CheckAllChannelsPermissionsResponseArgs(communityId: communityId, checkAllChannelsPermissionsResponse: checkAllChannelsPermissionsResponse))
|
||||
except Exception as e:
|
||||
let errMsg = e.msg
|
||||
|
|
|
@ -548,39 +548,6 @@ proc getBannedMembersIds*(self: CommunityDto): seq[string] =
|
|||
bannedIds.add(memberId)
|
||||
return bannedIds
|
||||
|
||||
proc toChannelGroupDto*(communityDto: CommunityDto): ChannelGroupDto =
|
||||
ChannelGroupDto(
|
||||
id: communityDto.id,
|
||||
channelGroupType: ChannelGroupType.Community,
|
||||
name: communityDto.name,
|
||||
images: communityDto.images,
|
||||
chats: communityDto.chats,
|
||||
categories: communityDto.categories,
|
||||
# Community doesn't have an ensName yet. Add this when it is added in status-go
|
||||
# ensName: communityDto.ensName,
|
||||
memberRole: communityDto.memberRole,
|
||||
verified: communityDto.verified,
|
||||
description: communityDto.description,
|
||||
introMessage: communityDto.introMessage,
|
||||
outroMessage: communityDto.outroMessage,
|
||||
color: communityDto.color,
|
||||
# tags: communityDto.tags, NOTE: do we need tags here?
|
||||
permissions: communityDto.permissions,
|
||||
members: communityDto.members.map(m => ChatMember(
|
||||
id: m.id,
|
||||
joined: true,
|
||||
role: m.role
|
||||
)),
|
||||
canManageUsers: communityDto.canManageUsers,
|
||||
muted: communityDto.muted,
|
||||
historyArchiveSupportEnabled: communityDto.settings.historyArchiveSupportEnabled,
|
||||
bannedMembersIds: communityDto.getBannedMembersIds(),
|
||||
encrypted: communityDto.encrypted,
|
||||
shard: communityDto.shard,
|
||||
pubsubTopic: communityDto.pubsubTopic,
|
||||
pubsubTopicKey: communityDto.pubsubTopicKey,
|
||||
)
|
||||
|
||||
proc parseCommunitiesSettings*(response: JsonNode): seq[CommunitySettingsDto] =
|
||||
result = map(response["result"].getElems(),
|
||||
proc(x: JsonNode): CommunitySettingsDto = x.toCommunitySettingsDto())
|
||||
|
@ -628,15 +595,20 @@ proc toMembersRevealedAccounts*(membersRevealedAccountsObj: JsonNode): MembersRe
|
|||
for (pubkey, revealedAccountsObj) in membersRevealedAccountsObj.pairs:
|
||||
result[pubkey] = revealedAccountsObj.toRevealedAccounts()
|
||||
|
||||
proc getCommunityChats*(self: CommunityDto, chatsIds: seq[string]): seq[ChatDto] =
|
||||
proc getCommunityChats*(self: CommunityDto, chatIds: seq[string]): seq[ChatDto] =
|
||||
var chats: seq[ChatDto] = @[]
|
||||
for chatId in chatsIds:
|
||||
for chatId in chatIds:
|
||||
for communityChat in self.chats:
|
||||
if chatId == communityChat.id:
|
||||
chats.add(communityChat)
|
||||
break
|
||||
return chats
|
||||
|
||||
proc getCommunityChat*(self: CommunityDto, chatId: string): ChatDto =
|
||||
let chats = self.getCommunityChats(@[chatId])
|
||||
if chats.len > 0:
|
||||
return chats[0]
|
||||
|
||||
proc isOwner*(self: CommunityDto): bool =
|
||||
return self.memberRole == MemberRole.Owner
|
||||
|
||||
|
|
|
@ -306,10 +306,10 @@ QtObject:
|
|||
result.communityMetrics = initTable[string, CommunityMetricsDto]()
|
||||
result.communityInfoRequests = initTable[string, Time]()
|
||||
|
||||
proc getFilteredJoinedCommunities(self: Service): Table[string, CommunityDto] =
|
||||
proc getFilteredJoinedAndSpectatedCommunities(self: Service): Table[string, CommunityDto] =
|
||||
result = initTable[string, CommunityDto]()
|
||||
for communityId, community in self.communities.pairs:
|
||||
if community.joined:
|
||||
if community.joined or community.spectated:
|
||||
result[communityId] = community
|
||||
|
||||
proc getFilteredCuratedCommunities(self: Service): Table[string, CommunityDto] =
|
||||
|
@ -650,17 +650,6 @@ QtObject:
|
|||
chat.emoji != prevChat.emoji or chat.viewersCanPostReactions != prevChat.viewersCanPostReactions or
|
||||
chat.hideIfPermissionsNotMet != prevChat.hideIfPermissionsNotMet:
|
||||
var updatedChat = chat
|
||||
|
||||
# TODO improve this in https://github.com/status-im/status-desktop/issues/12595
|
||||
# Currently, status-go only sends canPostReactions on app start (getChannelGroups)
|
||||
# so here, we need to imply it. If viewersCanPostReactions is true, then everyone can post reactions
|
||||
# admins can also always post reactions
|
||||
if chat.viewersCanPostReactions or
|
||||
(not chat.viewersCanPostReactions and community.memberRole != MemberRole.None):
|
||||
updatedChat.canPostReactions = true
|
||||
elif not chat.viewersCanPostReactions and community.memberRole == MemberRole.None:
|
||||
updatedChat.canPostReactions = false
|
||||
|
||||
self.chatService.updateOrAddChat(updatedChat) # we have to update chats stored in the chat service.
|
||||
|
||||
let data = CommunityChatArgs(chat: updatedChat)
|
||||
|
@ -845,7 +834,7 @@ QtObject:
|
|||
if self.communities.hasKey(settings.id):
|
||||
self.communities[settings.id].settings = settings
|
||||
|
||||
# Non approver requests to join for all communities
|
||||
# Non approved requests to join for all communities
|
||||
let nonAprrovedRequestsToJoinObj = responseObj["nonAprrovedRequestsToJoin"]
|
||||
|
||||
if nonAprrovedRequestsToJoinObj{"result"}.kind != JNull:
|
||||
|
@ -874,8 +863,8 @@ QtObject:
|
|||
proc getCommunityTags*(self: Service): string =
|
||||
return self.communityTags
|
||||
|
||||
proc getJoinedCommunities*(self: Service): seq[CommunityDto] =
|
||||
return toSeq(self.getFilteredJoinedCommunities().values)
|
||||
proc getJoinedAndSpectatedCommunities*(self: Service): seq[CommunityDto] =
|
||||
return toSeq(self.getFilteredJoinedAndSpectatedCommunities().values)
|
||||
|
||||
proc getAllCommunities*(self: Service): seq[CommunityDto] =
|
||||
return toSeq(self.communities.values)
|
||||
|
@ -1056,13 +1045,9 @@ QtObject:
|
|||
|
||||
updatedCommunity.settings = communitySettings
|
||||
self.communities[communityId] = updatedCommunity
|
||||
self.chatService.loadChannelGroupById(communityId)
|
||||
|
||||
let ownerTokenNotification = self.activityCenterService.getNotificationForTypeAndCommunityId(notification.ActivityCenterNotificationType.OwnerTokenReceived, communityId)
|
||||
|
||||
self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[updatedCommunity]))
|
||||
self.events.emit(SIGNAL_COMMUNITY_SPECTATED, CommunityArgs(community: updatedCommunity, fromUserAction: true, isPendingOwnershipRequest: (ownerTokenNotification != nil)))
|
||||
|
||||
for k, chat in updatedCommunity.chats:
|
||||
var fullChatId = chat.id
|
||||
if not chat.id.startsWith(communityId):
|
||||
|
@ -1077,6 +1062,9 @@ QtObject:
|
|||
# TODO find a way to populate missing infos like the color
|
||||
self.chatService.updateOrAddChat(chatDto)
|
||||
self.messageService.asyncLoadInitialMessagesForChat(fullChatId)
|
||||
|
||||
self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[updatedCommunity]))
|
||||
self.events.emit(SIGNAL_COMMUNITY_SPECTATED, CommunityArgs(community: updatedCommunity, fromUserAction: true, isPendingOwnershipRequest: (ownerTokenNotification != nil)))
|
||||
except Exception as e:
|
||||
error "Error joining the community", msg = e.msg
|
||||
result = fmt"Error joining the community: {e.msg}"
|
||||
|
@ -1225,8 +1213,6 @@ QtObject:
|
|||
community.settings = communitySettings
|
||||
# add this to the communities list and communitiesSettings
|
||||
self.communities[community.id] = community
|
||||
# add new community channel group and chats to chat service
|
||||
self.chatService.updateOrAddChannelGroup(community.toChannelGroupDto())
|
||||
for chat in community.chats:
|
||||
self.chatService.updateOrAddChat(chat)
|
||||
|
||||
|
@ -2495,3 +2481,18 @@ QtObject:
|
|||
self.events.emit(SIGNAL_COMMUNITIES_UPDATE, CommunitiesArgs(communities: @[community]))
|
||||
except Exception as e:
|
||||
error "error promoting self to control node", msg = e.msg
|
||||
|
||||
proc categoryHasUnreadMessages*(self: Service, communityId: string, categoryId: string): bool =
|
||||
if communityId == "" or categoryId == "":
|
||||
return false
|
||||
|
||||
if not self.communities.contains(communityId):
|
||||
warn "unknown community", communityId
|
||||
return false
|
||||
|
||||
for chat in self.communities[communityId].chats:
|
||||
if chat.categoryId != categoryId:
|
||||
continue
|
||||
if (not chat.muted and chat.unviewedMessagesCount > 0) or chat.unviewedMentionsCount > 0:
|
||||
return true
|
||||
return false
|
||||
|
|
|
@ -35,13 +35,9 @@ proc saveChat*(
|
|||
}
|
||||
])
|
||||
|
||||
proc getChannelGroups*(): RpcResponse[JsonNode] =
|
||||
proc getActiveChats*(): RpcResponse[JsonNode] =
|
||||
let payload = %* []
|
||||
result = callPrivateRPC("chat_getChannelGroups", payload)
|
||||
|
||||
proc getChannelGroupById*(channelGroupId: string): RpcResponse[JsonNode] =
|
||||
let payload = %* [channelGroupId]
|
||||
result = callPrivateRPC("chat_getChannelGroupByID", payload)
|
||||
result = callPrivateRPC("activeChats".prefix, payload)
|
||||
|
||||
proc createOneToOneChat*(chatId: string, ensName: string = ""): RpcResponse[JsonNode] =
|
||||
let communityId = ""
|
||||
|
@ -146,9 +142,6 @@ proc createGroupChatFromInvitation*(groupName: string, chatId: string, adminPK:
|
|||
let payload = %* [groupName, chatId, adminPK]
|
||||
result = callPrivateRPC("createGroupChatFromInvitation".prefix, payload)
|
||||
|
||||
proc getMembers*(communityId, chatId: string): RpcResponse[JsonNode] =
|
||||
result = callPrivateRPC("chat_getMembers", %* [communityId, chatId])
|
||||
|
||||
proc editChat*(communityID: string, chatID: string, name: string, color: string, imageJson: string): RpcResponse[JsonNode] =
|
||||
let croppedImage = newCroppedImage(imageJson)
|
||||
let payload = %* [communityID, chatID, name, color, croppedImage]
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit dcc93dee965a39d9b4ee9dca79f546c497baa77e
|
||||
Subproject commit 8f50b578d1378c1e43bfa9645910d5e690b8c98b
|
Loading…
Reference in New Issue