feat(sharding): add shard info args to requestCommunityInfo calls

Fixes #12015
This commit is contained in:
Jonathan Rainville 2023-11-08 14:59:45 -05:00
parent 6f39f8782b
commit d66c1f7b0d
37 changed files with 335 additions and 287 deletions

View File

@ -114,6 +114,7 @@ proc applyNecessaryActionsAfterLoggingIn(self: AppController)
# Startup Module Delegate Interface # Startup Module Delegate Interface
proc startupDidLoad*(self: AppController) proc startupDidLoad*(self: AppController)
proc userLoggedIn*(self: AppController): string proc userLoggedIn*(self: AppController): string
proc appReady*(self: AppController)
proc logout*(self: AppController) proc logout*(self: AppController)
proc finishAppLoading*(self: AppController) proc finishAppLoading*(self: AppController)
proc storeDefaultKeyPairForNewKeycardUser*(self: AppController) proc storeDefaultKeyPairForNewKeycardUser*(self: AppController)
@ -458,13 +459,15 @@ proc load(self: AppController) =
proc userLoggedIn*(self: AppController): string = proc userLoggedIn*(self: AppController): string =
try: try:
self.generalService.startMessenger() self.generalService.startMessenger()
self.statusFoundation.userLoggedIn()
return "" return ""
except Exception as e: except Exception as e:
let errDescription = e.msg let errDescription = e.msg
error "error: ", errDescription error "error: ", errDescription
return errDescription return errDescription
proc appReady*(self: AppController) =
self.statusFoundation.appReady()
proc finishAppLoading*(self: AppController) = proc finishAppLoading*(self: AppController) =
self.load() self.load()

View File

@ -2,32 +2,18 @@ import NimQml, strutils, chronicles
import ../eventemitter import ../eventemitter
import ../../global/app_signals import ../../global/app_signals
import ../../../app_service/common/conversion
import ../../../app_service/service/accounts/utils
logScope: logScope:
topics = "urls-manager" topics = "urls-manager"
const StatusInternalLink* = "status-app" const StatusInternalLink* = "status-app://"
const StatusExternalLink* = "status.app" const StatusExternalLink* = "https://status.app/"
const profileLinkPrefix* = "/u/"
const UriFormatUserProfile = StatusInternalLink & ":/" & profileLinkPrefix
const UriFormatCommunity = StatusInternalLink & "://c/"
const UriFormatCommunityChannel = StatusInternalLink & "://cc/"
# enable after MVP
#const UriFormatGroupChat = StatusInternalLink & "://g/"
#const UriFormatBrowser = StatusInternalLink & "://b/"
QtObject: QtObject:
type UrlsManager* = ref object of QObject type UrlsManager* = ref object of QObject
events: EventEmitter events: EventEmitter
protocolUriOnStart: string protocolUriOnStart: string
loggedIn: bool appReady: bool
proc setup(self: UrlsManager, urlSchemeEvent: StatusEvent, proc setup(self: UrlsManager, urlSchemeEvent: StatusEvent,
singleInstance: SingleInstance) = singleInstance: SingleInstance) =
@ -46,58 +32,29 @@ QtObject:
result.setup(urlSchemeEvent, singleInstance) result.setup(urlSchemeEvent, singleInstance)
result.events = events result.events = events
result.protocolUriOnStart = protocolUriOnStart result.protocolUriOnStart = protocolUriOnStart
result.loggedIn = false result.appReady = false
proc prepareCommunityId(self: UrlsManager, communityId: string): string = proc convertInternalLinkToExternal*(self: UrlsManager, statusDeepLink: string): string =
if isCompressedPubKey(communityId): let idx = find(statusDeepLink, StatusInternalLink)
return changeCommunityKeyCompression(communityId) result = statusDeepLink
return communityId if idx != -1:
result = statusDeepLink[idx + StatusInternalLink.len .. ^1]
result = StatusExternalLink & result
proc onUrlActivated*(self: UrlsManager, urlRaw: string) {.slot.} = proc onUrlActivated*(self: UrlsManager, urlRaw: string) {.slot.} =
if not self.loggedIn: if not self.appReady:
self.protocolUriOnStart = urlRaw self.protocolUriOnStart = urlRaw
return return
var data = StatusUrlArgs()
let url = urlRaw.multiReplace((" ", "")) let url = urlRaw.multiReplace((" ", ""))
.multiReplace(("\r\n", "")) .multiReplace(("\r\n", ""))
.multiReplace(("\n", "")) .multiReplace(("\n", ""))
let data = StatusUrlArgs(url: self.convertInternalLinkToExternal(url))
# Display user profile popup for user with `user_pk` or `ens_name` self.events.emit(SIGNAL_STATUS_URL_ACTIVATED, data)
if url.startsWith(UriFormatUserProfile):
data.action = StatusUrlAction.DisplayUserProfile
data.userId = url[UriFormatUserProfile.len .. url.len-1]
# Open community with `community_key` proc appReady*(self: UrlsManager) =
elif url.startsWith(UriFormatCommunity): self.appReady = true
data.action = StatusUrlAction.OpenCommunity
data.communityId = self.prepareCommunityId(url[UriFormatCommunity.len .. url.len-1])
# Open community which has a channel with `channel_key` and makes that channel active
elif url.startsWith(UriFormatCommunityChannel):
data.action = StatusUrlAction.OpenCommunityChannel
data.chatId = url[UriFormatCommunityChannel.len .. url.len-1]
# Open `url` in the app's browser
# Enable after MVP
#elif url.startsWith(UriFormatBrowser):
# data.action = StatusUrlAction.OpenLinkInBrowser
# data.url = url[UriFormatBrowser.len .. url.len-1]
else:
info "Unsupported deep link structure: ", url
return
self.events.emit(SIGNAL_STATUS_URL_REQUESTED, data)
proc userLoggedIn*(self: UrlsManager) =
self.loggedIn = true
if self.protocolUriOnStart != "": if self.protocolUriOnStart != "":
self.onUrlActivated(self.protocolUriOnStart) self.onUrlActivated(self.protocolUriOnStart)
self.protocolUriOnStart = "" self.protocolUriOnStart = ""
proc convertExternalLinkToInternal*(self: UrlsManager, statusDeepLink: string): string =
let idx = find(statusDeepLink, StatusExternalLink)
result = statusDeepLink
if idx != -1:
result = statusDeepLink[idx + StatusExternalLink.len .. ^1]
result = StatusInternalLink & ":/" & result

View File

@ -34,5 +34,5 @@ proc initUrlSchemeManager*(self: StatusFoundation, urlSchemeEvent: StatusEvent,
self.urlsManager = newUrlsManager(self.events, urlSchemeEvent, singleInstance, self.urlsManager = newUrlsManager(self.events, urlSchemeEvent, singleInstance,
protocolUriOnStart) protocolUriOnStart)
proc userLoggedIn*(self: StatusFoundation) = proc appReady*(self: StatusFoundation) =
self.urlsManager.userLoggedIn() self.urlsManager.appReady()

View File

@ -39,4 +39,4 @@ type
url*: string url*: string
userId*: string # can be public key or ens name userId*: string # can be public key or ens name
const SIGNAL_STATUS_URL_REQUESTED* = "statusUrlRequested" const SIGNAL_STATUS_URL_ACTIVATED* = "statusUrlActivated"

View File

@ -35,9 +35,10 @@ type
proc getChatDetails*(self: Controller): ChatDto proc getChatDetails*(self: Controller): ChatDto
proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string, proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
belongsToCommunity: bool, isUsersListAvailable: bool, settingsService: settings_service.Service, belongsToCommunity: bool, isUsersListAvailable: bool, settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service, contactService: contact_service.Service, chatService: chat_service.Service, nodeConfigurationService: node_configuration_service.Service, contactService: contact_service.Service,
communityService: community_service.Service, messageService: message_service.Service): Controller = chatService: chat_service.Service, communityService: community_service.Service,
messageService: message_service.Service): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
result.events = initUniqueUUIDEventEmitter(events) result.events = initUniqueUUIDEventEmitter(events)

View File

@ -9,8 +9,9 @@ import ../../../../../../app_service/service/chat/service as chat_service
import ../../../../../../app_service/service/message/service as message_service import ../../../../../../app_service/service/message/service as message_service
import ../../../../../../app_service/service/mailservers/service as mailservers_service import ../../../../../../app_service/service/mailservers/service as mailservers_service
import ../../../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../../../app_service/service/shared_urls/service as shared_urls_service
import ../../../../../../app_service/common/types
import ../../../../../global/app_signals import ../../../../../global/app_signals
import ../../../../../core/signals/types
import ../../../../../core/eventemitter import ../../../../../core/eventemitter
import ../../../../../core/unique_event_emitter import ../../../../../core/unique_event_emitter
@ -31,11 +32,12 @@ type
chatService: chat_service.Service chatService: chat_service.Service
messageService: message_service.Service messageService: message_service.Service
mailserversService: mailservers_service.Service mailserversService: mailservers_service.Service
sharedUrlsService: shared_urls_service.Service
proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string, proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service, belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service,
chatService: chat_service.Service, messageService: message_service.Service, mailserversService: mailservers_service.Service): chatService: chat_service.Service, messageService: message_service.Service,
Controller = mailserversService: mailservers_service.Service, sharedUrlsService: shared_urls_service.Service): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
result.events = initUniqueUUIDEventEmitter(events) result.events = initUniqueUUIDEventEmitter(events)
@ -48,6 +50,7 @@ proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter
result.chatService = chatService result.chatService = chatService
result.messageService = messageService result.messageService = messageService
result.mailserversService = mailserversService result.mailserversService = mailserversService
result.sharedUrlsService = sharedUrlsService
proc delete*(self: Controller) = proc delete*(self: Controller) =
self.events.disconnect() self.events.disconnect()
@ -240,8 +243,10 @@ proc getCommunityDetails*(self: Controller): CommunityDto =
proc getCommunityById*(self: Controller, communityId: string): CommunityDto = proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
return self.communityService.getCommunityById(communityId) return self.communityService.getCommunityById(communityId)
proc requestCommunityInfo*(self: Controller, communityId: string, useDataabse: bool, requiredTimeSinceLastRequest: Duration) = proc requestCommunityInfo*(self: Controller, communityId: string, shard: Shard, useDatabase: bool,
self.communityService.requestCommunityInfo(communityId, false, useDataabse, requiredTimeSinceLastRequest) requiredTimeSinceLastRequest: Duration) =
self.communityService.requestCommunityInfo(communityId, shard, importing = false,
useDatabase, requiredTimeSinceLastRequest)
proc getOneToOneChatNameAndImage*(self: Controller): proc getOneToOneChatNameAndImage*(self: Controller):
tuple[name: string, image: string, largeImage: string] = tuple[name: string, image: string, largeImage: string] =
@ -325,3 +330,6 @@ proc resendChatMessage*(self: Controller, messageId: string): string =
proc asyncGetMessageById*(self: Controller, messageId: string): UUID = proc asyncGetMessageById*(self: Controller, messageId: string): UUID =
return self.messageService.asyncGetMessageById(messageId) return self.messageService.asyncGetMessageById(messageId)
proc parseSharedUrl*(self: Controller, url: string): UrlDataDto =
return self.sharedUrlsService.parseSharedUrl(url)

View File

@ -1,4 +1,4 @@
import NimQml, chronicles, sequtils, uuids, sets, times import NimQml, chronicles, sequtils, uuids, sets, times, tables
import io_interface import io_interface
import ../io_interface as delegate_interface import ../io_interface as delegate_interface
import view, controller import view, controller
@ -15,6 +15,7 @@ import ../../../../../../app_service/service/community/service as community_serv
import ../../../../../../app_service/service/chat/service as chat_service import ../../../../../../app_service/service/chat/service as chat_service
import ../../../../../../app_service/service/message/service as message_service import ../../../../../../app_service/service/message/service as message_service
import ../../../../../../app_service/service/mailservers/service as mailservers_service import ../../../../../../app_service/service/mailservers/service as mailservers_service
import ../../../../../../app_service/service/shared_urls/service as shared_urls_service
import ../../../../../../app_service/common/types import ../../../../../../app_service/common/types
export io_interface export io_interface
@ -45,15 +46,16 @@ type
getMessageRequestId: UUID getMessageRequestId: UUID
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string, proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service, belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service,
chatService: chat_service.Service, messageService: message_service.Service, mailserversService: mailservers_service.Service): chatService: chat_service.Service, messageService: message_service.Service,
mailserversService: mailservers_service.Service, sharedUrlsService: shared_urls_service.Service):
Module = Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.view = view.newView(result) result.view = view.newView(result)
result.viewVariant = newQVariant(result.view) result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity, contactService, result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity, contactService,
communityService, chatService, messageService, mailserversService) communityService, chatService, messageService, mailserversService, sharedUrlsService)
result.moduleLoaded = false result.moduleLoaded = false
result.initialMessagesLoaded = false result.initialMessagesLoaded = false
result.firstUnseenMessageState = (false, false, false) result.firstUnseenMessageState = (false, false, false)
@ -805,7 +807,7 @@ proc updateLinkPreviewsContacts(self: Module, item: Item, requestFromMailserver:
self.controller.requestContactInfo(contactId) self.controller.requestContactInfo(contactId)
proc updateLinkPreviewsCommunities(self: Module, item: Item, requestFromMailserver: bool) = proc updateLinkPreviewsCommunities(self: Module, item: Item, requestFromMailserver: bool) =
for communityId in item.linkPreviewModel.getCommunityIds().items: for communityId, url in item.linkPreviewModel.getCommunityLinks().pairs:
let community = self.controller.getCommunityById(communityId) let community = self.controller.getCommunityById(communityId)
if community.id != "": if community.id != "":
@ -815,6 +817,7 @@ proc updateLinkPreviewsCommunities(self: Module, item: Item, requestFromMailserv
continue continue
debug "updateLinkPreviewsCommunites: requesting from mailserver", communityId debug "updateLinkPreviewsCommunites: requesting from mailserver", communityId
let urlData = self.controller.parseSharedUrl(url)
item.linkPreviewModel.onCommunityInfoRequested(communityId) item.linkPreviewModel.onCommunityInfoRequested(communityId)
self.controller.requestCommunityInfo(communityId, false, initDuration(minutes = 10)) self.controller.requestCommunityInfo(communityId, urlData.community.shard, useDatabase = false, initDuration(minutes = 10))

View File

@ -23,6 +23,7 @@ import ../../../../../app_service/service/community/service as community_service
import ../../../../../app_service/service/gif/service as gif_service import ../../../../../app_service/service/gif/service as gif_service
import ../../../../../app_service/service/message/service as message_service import ../../../../../app_service/service/message/service as message_service
import ../../../../../app_service/service/mailservers/service as mailservers_service import ../../../../../app_service/service/mailservers/service as mailservers_service
import ../../../../../app_service/service/shared_urls/service as shared_urls_service
import ../../../../../app_service/common/types import ../../../../../app_service/common/types
export io_interface export io_interface
@ -42,23 +43,25 @@ type
moduleLoaded: bool moduleLoaded: bool
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string, proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
belongsToCommunity: bool, isUsersListAvailable: bool, settingsService: settings_service.Service, belongsToCommunity: bool, isUsersListAvailable: bool, settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service, contactService: contact_service.Service, chatService: chat_service.Service, nodeConfigurationService: node_configuration_service.Service, contactService: contact_service.Service,
communityService: community_service.Service, messageService: message_service.Service, gifService: gif_service.Service, chatService: chat_service.Service, communityService: community_service.Service,
mailserversService: mailservers_service.Service): messageService: message_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, sharedUrlsService: shared_urls_service.Service):
Module = Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.view = view.newView(result) result.view = view.newView(result)
result.viewVariant = newQVariant(result.view) result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity, result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity,
isUsersListAvailable, settingsService, nodeConfigurationService, contactService, chatService, communityService, messageService) isUsersListAvailable, settingsService, nodeConfigurationService, contactService, chatService, communityService,
messageService)
result.moduleLoaded = false result.moduleLoaded = false
result.inputAreaModule = input_area_module.newModule(result, events, sectionId, chatId, belongsToCommunity, result.inputAreaModule = input_area_module.newModule(result, events, sectionId, chatId, belongsToCommunity,
chatService, communityService, gifService, messageService, settingsService) chatService, communityService, gifService, messageService, settingsService)
result.messagesModule = messages_module.newModule(result, events, sectionId, chatId, belongsToCommunity, result.messagesModule = messages_module.newModule(result, events, sectionId, chatId, belongsToCommunity,
contactService, communityService, chatService, messageService, mailserversService) contactService, communityService, chatService, messageService, mailserversService, sharedUrlsService)
result.usersModule = users_module.newModule(events, sectionId, chatId, belongsToCommunity, result.usersModule = users_module.newModule(events, sectionId, chatId, belongsToCommunity,
isUsersListAvailable, contactService, chat_service, communityService, messageService) isUsersListAvailable, contactService, chat_service, communityService, messageService)

View File

@ -14,6 +14,7 @@ import ../../../../app_service/service/wallet_account/service as wallet_account_
import ../../../../app_service/service/token/service as token_service import ../../../../app_service/service/token/service as token_service
import ../../../../app_service/service/community_tokens/service as community_tokens_service import ../../../../app_service/service/community_tokens/service as community_tokens_service
import ../../../../app_service/service/visual_identity/service as procs_from_visual_identity_service import ../../../../app_service/service/visual_identity/service as procs_from_visual_identity_service
import ../../../../app_service/service/shared_urls/service as shared_urls_service
import backend/collectibles as backend_collectibles import backend/collectibles as backend_collectibles
import ../../../core/signals/types import ../../../core/signals/types
@ -40,16 +41,17 @@ type
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
tokenService: token_service.Service tokenService: token_service.Service
communityTokensService: community_tokens_service.Service communityTokensService: community_tokens_service.Service
sharedUrlsService: shared_urls_service.Service
proc newController*(delegate: io_interface.AccessInterface, sectionId: string, isCommunity: bool, events: EventEmitter, proc newController*(delegate: io_interface.AccessInterface, sectionId: string, isCommunity: bool, events: EventEmitter,
settingsService: settings_service.Service, nodeConfigurationService: node_configuration_service.Service, settingsService: settings_service.Service, nodeConfigurationService: node_configuration_service.Service,
contactService: contact_service.Service, chatService: chat_service.Service, communityService: community_service.Service, contactService: contact_service.Service, chatService: chat_service.Service,
messageService: message_service.Service, gifService: gif_service.Service, communityService: community_service.Service, messageService: message_service.Service,
mailserversService: mailservers_service.Service, gifService: gif_service.Service, mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service, tokenService: token_service.Service,
tokenService: token_service.Service, communityTokensService: community_tokens_service.Service,
communityTokensService: community_tokens_service.Service): Controller = sharedUrlsService: shared_urls_service.Service): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
result.sectionId = sectionId result.sectionId = sectionId
@ -67,6 +69,7 @@ proc newController*(delegate: io_interface.AccessInterface, sectionId: string, i
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.tokenService = tokenService result.tokenService = tokenService
result.communityTokensService = communityTokensService result.communityTokensService = communityTokensService
result.sharedUrlsService = sharedUrlsService
proc delete*(self: Controller) = proc delete*(self: Controller) =
self.events.disconnect() self.events.disconnect()
@ -158,14 +161,14 @@ proc init*(self: Controller) =
let belongsToCommunity = chat.communityId.len > 0 let belongsToCommunity = chat.communityId.len > 0
discard self.delegate.addOrUpdateChat(chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService, discard self.delegate.addOrUpdateChat(chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.gifService, self.contactService, self.chatService, self.communityService, self.messageService, self.gifService,
self.mailserversService, setChatAsActive = false) self.mailserversService, self.sharedUrlsService, setChatAsActive = false)
self.events.on(SIGNAL_CHAT_CREATED) do(e: Args): self.events.on(SIGNAL_CHAT_CREATED) do(e: Args):
var args = CreatedChatArgs(e) var args = CreatedChatArgs(e)
let belongsToCommunity = args.chat.communityId.len > 0 let belongsToCommunity = args.chat.communityId.len > 0
discard self.delegate.addOrUpdateChat(args.chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService, discard self.delegate.addOrUpdateChat(args.chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.gifService, self.contactService, self.chatService, self.communityService, self.messageService, self.gifService,
self.mailserversService, setChatAsActive = true) self.mailserversService, self.sharedUrlsService, setChatAsActive = true)
if (self.isCommunitySection): if (self.isCommunitySection):
self.events.on(SIGNAL_COMMUNITY_CHANNEL_CREATED) do(e:Args): self.events.on(SIGNAL_COMMUNITY_CHANNEL_CREATED) do(e:Args):
@ -173,7 +176,7 @@ proc init*(self: Controller) =
let belongsToCommunity = args.chat.communityId.len > 0 let belongsToCommunity = args.chat.communityId.len > 0
discard self.delegate.addOrUpdateChat(args.chat, belongsToCommunity, self.events, self.settingsService, discard self.delegate.addOrUpdateChat(args.chat, belongsToCommunity, self.events, self.settingsService,
self.nodeConfigurationService, self.contactService, self.chatService, self.communityService, self.nodeConfigurationService, self.contactService, self.chatService, self.communityService,
self.messageService, self.gifService, self.mailserversService, setChatAsActive = true) self.messageService, self.gifService, self.mailserversService, self.sharedUrlsService, setChatAsActive = true)
self.events.on(SIGNAL_COMMUNITY_METRICS_UPDATED) do(e: Args): self.events.on(SIGNAL_COMMUNITY_METRICS_UPDATED) do(e: Args):
let args = CommunityMetricsArgs(e) let args = CommunityMetricsArgs(e)
@ -420,6 +423,7 @@ proc getChatsAndBuildUI*(self: Controller) =
self.messageService, self.messageService,
self.gifService, self.gifService,
self.mailserversService, self.mailserversService,
self.sharedUrlsService,
) )
proc sectionUnreadMessagesAndMentionsCount*(self: Controller, communityId: string): proc sectionUnreadMessagesAndMentionsCount*(self: Controller, communityId: string):
@ -464,7 +468,7 @@ proc createOneToOneChat*(self: Controller, communityID: string, chatId: string,
if(response.success): if(response.success):
discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService, discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.contactService, self.chatService, self.communityService, self.messageService,
self.gifService, self.mailserversService) self.gifService, self.mailserversService, self.sharedUrlsService)
proc switchToOrCreateOneToOneChat*(self: Controller, chatId: string, ensName: string) = proc switchToOrCreateOneToOneChat*(self: Controller, chatId: string, ensName: string) =
self.chatService.switchToOrCreateOneToOneChat(chatId, ensName) self.chatService.switchToOrCreateOneToOneChat(chatId, ensName)
@ -534,14 +538,14 @@ proc createGroupChat*(self: Controller, communityID: string, groupName: string,
if(response.success): if(response.success):
discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService, discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.contactService, self.chatService, self.communityService, self.messageService,
self.gifService, self.mailserversService) self.gifService, self.mailserversService, self.sharedUrlsService)
proc joinGroupChatFromInvitation*(self: Controller, groupName: string, chatId: string, adminPK: string) = proc joinGroupChatFromInvitation*(self: Controller, groupName: string, chatId: string, adminPK: string) =
let response = self.chatService.createGroupChatFromInvitation(groupName, chatId, adminPK) let response = self.chatService.createGroupChatFromInvitation(groupName, chatId, adminPK)
if(response.success): if(response.success):
discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService, discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.contactService, self.chatService, self.communityService, self.messageService,
self.gifService, self.mailserversService) self.gifService, self.mailserversService, self.sharedUrlsService)
proc acceptRequestToJoinCommunity*(self: Controller, requestId: string, communityId: string) = proc acceptRequestToJoinCommunity*(self: Controller, requestId: string, communityId: string) =
self.communityService.asyncAcceptRequestToJoinCommunity(communityId, requestId) self.communityService.asyncAcceptRequestToJoinCommunity(communityId, requestId)

View File

@ -8,6 +8,7 @@ import ../../../../app_service/service/community/service as community_service
import ../../../../app_service/service/message/service as message_service import ../../../../app_service/service/message/service as message_service
import ../../../../app_service/service/gif/service as gif_service import ../../../../app_service/service/gif/service as gif_service
import ../../../../app_service/service/mailservers/service as mailservers_service import ../../../../app_service/service/mailservers/service as mailservers_service
import ../../../../app_service/service/shared_urls/service as shared_urls_service
import model as chats_model import model as chats_model
import item as chat_item import item as chat_item
@ -21,30 +22,22 @@ type
method delete*(self: AccessInterface) {.base.} = method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method load*(self: AccessInterface, method load*(self: AccessInterface) {.base.} =
channelGroup: ChannelGroupDto,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactService: contact_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onChatsLoaded*(self: AccessInterface, method onChatsLoaded*(self: AccessInterface,
channelGroup: ChannelGroupDto, channelGroup: ChannelGroupDto,
events: UniqueUUIDEventEmitter, events: UniqueUUIDEventEmitter,
settingsService: settings_service.Service, settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service, nodeConfigurationService: node_configuration_service.Service,
contactService: contact_service.Service, contactService: contact_service.Service,
chatService: chat_service.Service, chatService: chat_service.Service,
communityService: community_service.Service, communityService: community_service.Service,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service) {.base.} = mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
) {.base.} =
raise newException(ValueError, "No implementation available rip") raise newException(ValueError, "No implementation available rip")
method isLoaded*(self: AccessInterface): bool {.base.} = method isLoaded*(self: AccessInterface): bool {.base.} =
@ -72,10 +65,11 @@ method makeChatWithIdActive*(self: AccessInterface, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method addNewChat*(self: AccessInterface, chatDto: ChatDto, belongsToCommunity: bool, events: EventEmitter, method addNewChat*(self: AccessInterface, chatDto: ChatDto, belongsToCommunity: bool, events: EventEmitter,
settingsService: settings_service.Service, contactService: contact_service.Service, settingsService: settings_service.Service, contactService: contact_service.Service,
chatService: chat_service.Service, communityService: community_service.Service, chatService: chat_service.Service, communityService: community_service.Service,
messageService: message_service.Service, gifService: gif_service.Service, messageService: message_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, setChatAsActive: bool = true, insertIntoModel: bool = true): Item {.base.} = mailserversService: mailservers_service.Service, sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true, insertIntoModel: bool = true): Item {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method doesCatOrChatExist*(self: AccessInterface, chatId: string): bool {.base.} = method doesCatOrChatExist*(self: AccessInterface, chatId: string): bool {.base.} =
@ -96,6 +90,7 @@ method addOrUpdateChat*(self: AccessInterface,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true, setChatAsActive: bool = true,
insertIntoModel: bool = true insertIntoModel: bool = true
): Item {.base.} = ): Item {.base.} =

View File

@ -33,6 +33,7 @@ import ../../../../app_service/service/gif/service as gif_service
import ../../../../app_service/service/wallet_account/service as wallet_account_service import ../../../../app_service/service/wallet_account/service as wallet_account_service
import ../../../../app_service/service/token/service as token_service import ../../../../app_service/service/token/service as token_service
import ../../../../app_service/service/community_tokens/service as community_tokens_service import ../../../../app_service/service/community_tokens/service as community_tokens_service
import ../../../../app_service/service/shared_urls/service as shared_urls_service
import ../../../../app_service/service/visual_identity/service as visual_identity import ../../../../app_service/service/visual_identity/service as visual_identity
import ../../../../app_service/service/contacts/dto/contacts as contacts_dto import ../../../../app_service/service/contacts/dto/contacts as contacts_dto
import ../../../../app_service/service/community/dto/community as community_dto import ../../../../app_service/service/community/dto/community as community_dto
@ -54,7 +55,8 @@ type
chatsLoaded: bool chatsLoaded: bool
# Forward declaration # Forward declaration
proc buildChatSectionUI(self: Module, proc buildChatSectionUI(
self: Module,
channelGroup: ChannelGroupDto, channelGroup: ChannelGroupDto,
events: UniqueUUIDEventEmitter, events: UniqueUUIDEventEmitter,
settingsService: settings_service.Service, settingsService: settings_service.Service,
@ -64,7 +66,9 @@ proc buildChatSectionUI(self: Module,
communityService: community_service.Service, communityService: community_service.Service,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service) mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
)
proc reevaluateRequiresTokenPermissionToJoin(self: Module) proc reevaluateRequiresTokenPermissionToJoin(self: Module)
@ -81,6 +85,7 @@ proc addOrUpdateChat(self: Module,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true, setChatAsActive: bool = true,
insertIntoModel: bool = true, insertIntoModel: bool = true,
): Item ): Item
@ -101,11 +106,13 @@ proc newModule*(
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service, communityTokensService: community_tokens_service.Service,
sharedUrlsService: shared_urls_service.Service,
): Module = ): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.controller = controller.newController(result, sectionId, isCommunity, events, settingsService, nodeConfigurationService, result.controller = controller.newController(result, sectionId, isCommunity, events, settingsService,
contactService, chatService, communityService, messageService, gifService, mailserversService, walletAccountService, tokenService, communityTokensService) nodeConfigurationService, contactService, chatService, communityService, messageService, gifService,
mailserversService, walletAccountService, tokenService, communityTokensService, sharedUrlsService)
result.view = view.newView(result) result.view = view.newView(result)
result.viewVariant = newQVariant(result.view) result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false result.moduleLoaded = false
@ -133,18 +140,25 @@ proc getUserMemberRole(self: Module, members: seq[ChatMember]): MemberRole =
return m.role return m.role
return MemberRole.None return MemberRole.None
proc addSubmodule(self: Module, chatId: string, belongToCommunity: bool, isUsersListAvailable: bool, events: EventEmitter, proc addSubmodule(
settingsService: settings_service.Service, self: Module,
nodeConfigurationService: node_configuration_service.Service, chatId: string,
contactService: contact_service.Service, belongToCommunity: bool,
chatService: chat_service.Service, isUsersListAvailable: bool,
communityService: community_service.Service, events: EventEmitter,
messageService: message_service.Service, settingsService: settings_service.Service,
gifService: gif_service.Service, nodeConfigurationService: node_configuration_service.Service,
mailserversService: mailservers_service.Service) = contactService: contact_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
) =
self.chatContentModules[chatId] = chat_content_module.newModule(self, events, self.controller.getMySectionId(), chatId, self.chatContentModules[chatId] = chat_content_module.newModule(self, events, self.controller.getMySectionId(), chatId,
belongToCommunity, isUsersListAvailable, settingsService, nodeConfigurationService, contactService, chatService, communityService, belongToCommunity, isUsersListAvailable, settingsService, nodeConfigurationService, contactService, chatService, communityService,
messageService, gifService, mailserversService) messageService, gifService, mailserversService, sharedUrlsService)
proc removeSubmodule(self: Module, chatId: string) = proc removeSubmodule(self: Module, chatId: string) =
if(not self.chatContentModules.contains(chatId)): if(not self.chatContentModules.contains(chatId)):
@ -187,7 +201,9 @@ proc buildChatSectionUI(
communityService: community_service.Service, communityService: community_service.Service,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service) = mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
) =
var selectedItemId = "" var selectedItemId = ""
let sectionLastOpenChat = singletonInstance.localAccountSensitiveSettings.getSectionLastOpenChat(self.controller.getMySectionId()) let sectionLastOpenChat = singletonInstance.localAccountSensitiveSettings.getSectionLastOpenChat(self.controller.getMySectionId())
@ -226,6 +242,7 @@ proc buildChatSectionUI(
messageService, messageService,
gifService, gifService,
mailserversService, mailserversService,
sharedUrlsService,
setChatAsActive = false, setChatAsActive = false,
insertIntoModel = false insertIntoModel = false
)) ))
@ -301,18 +318,7 @@ method clearListOfMyContacts*(self: Module) =
self.view.listOfMyContacts().clear() self.view.listOfMyContacts().clear()
method load*( method load*(self: Module) =
self: Module,
channelGroup: ChannelGroupDto,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactService: contact_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service) =
self.controller.init() self.controller.init()
self.view.load() self.view.load()
@ -328,10 +334,11 @@ method onChatsLoaded*(
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
) = ) =
self.chatsLoaded = true self.chatsLoaded = true
self.buildChatSectionUI(channelGroup, events, settingsService, nodeConfigurationService, self.buildChatSectionUI(channelGroup, events, settingsService, nodeConfigurationService,
contactService, chatService, communityService, messageService, gifService, mailserversService) contactService, chatService, communityService, messageService, gifService, mailserversService, sharedUrlsService)
if(not self.controller.isCommunity()): if(not self.controller.isCommunity()):
# we do this only in case of chat section (not in case of communities) # we do this only in case of chat section (not in case of communities)
@ -471,17 +478,15 @@ proc updateBadgeNotifications(self: Module, chat: ChatDto, hasUnreadMessages: bo
let chatId = chat.id let chatId = chat.id
if self.chatsLoaded: if self.chatsLoaded:
# update model of this module (appropriate chat from the chats list (chats model))
self.view.chatsModel().updateNotificationsForItemById(chatId, hasUnreadMessages, unviewedMentionsCount) self.view.chatsModel().updateNotificationsForItemById(chatId, hasUnreadMessages, unviewedMentionsCount)
# update child module
if (self.chatContentModules.contains(chatId)): if (self.chatContentModules.contains(chatId)):
self.chatContentModules[chatId].onNotificationsUpdated(hasUnreadMessages, unviewedMentionsCount) self.chatContentModules[chatId].onNotificationsUpdated(hasUnreadMessages, unviewedMentionsCount)
# Update category
if chat.categoryId != "": if chat.categoryId != "":
let hasUnreadMessages = self.controller.chatsWithCategoryHaveUnreadMessages(chat.communityId, chat.categoryId) let hasUnreadMessages = self.controller.chatsWithCategoryHaveUnreadMessages(chat.communityId, chat.categoryId)
self.view.chatsModel().setCategoryHasUnreadMessages(chat.categoryId, hasUnreadMessages) self.view.chatsModel().setCategoryHasUnreadMessages(chat.categoryId, hasUnreadMessages)
# update parent module
self.updateParentBadgeNotifications() self.updateParentBadgeNotifications()
method updateLastMessageTimestamp*(self: Module, chatId: string, lastMessageTimestamp: int) = method updateLastMessageTimestamp*(self: Module, chatId: string, lastMessageTimestamp: int) =
@ -527,6 +532,7 @@ method addNewChat*(
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true, setChatAsActive: bool = true,
insertIntoModel: bool = true, insertIntoModel: bool = true,
): Item = ): Item =
@ -626,6 +632,7 @@ method addNewChat*(
messageService, messageService,
gifService, gifService,
mailserversService, mailserversService,
sharedUrlsService,
) )
self.chatContentModules[chatDto.id].load(result) self.chatContentModules[chatDto.id].load(result)
@ -1188,6 +1195,7 @@ proc addOrUpdateChat(self: Module,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true, setChatAsActive: bool = true,
insertIntoModel: bool = true, insertIntoModel: bool = true,
): Item = ): Item =
@ -1233,6 +1241,7 @@ proc addOrUpdateChat(self: Module,
messageService, messageService,
gifService, gifService,
mailserversService, mailserversService,
sharedUrlsService,
setChatAsActive, setChatAsActive,
insertIntoModel, insertIntoModel,
) )
@ -1249,6 +1258,7 @@ method addOrUpdateChat*(self: Module,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true, setChatAsActive: bool = true,
insertIntoModel: bool = true, insertIntoModel: bool = true,
): Item = ): Item =
@ -1265,6 +1275,7 @@ method addOrUpdateChat*(self: Module,
messageService, messageService,
gifService, gifService,
mailserversService, mailserversService,
sharedUrlsService,
setChatAsActive, setChatAsActive,
insertIntoModel, insertIntoModel,
) )

View File

@ -12,6 +12,7 @@ import app_service/service/community_tokens/service as community_tokens_service
import app_service/service/token/service as token_service import app_service/service/token/service as token_service
import app_service/service/wallet_account/service as wallet_account_service import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/keycard/service as keycard_service import app_service/service/keycard/service as keycard_service
import app_service/common/types
import backend/collectibles as backend_collectibles import backend/collectibles as backend_collectibles
import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module import app/modules/shared_modules/keycard_popup/io_interface as keycard_shared_module
@ -328,8 +329,8 @@ proc reorderCommunityChat*(
proc getChatDetailsByIds*(self: Controller, chatIds: seq[string]): seq[ChatDto] = proc getChatDetailsByIds*(self: Controller, chatIds: seq[string]): seq[ChatDto] =
return self.chatService.getChatsByIds(chatIds) return self.chatService.getChatsByIds(chatIds)
proc requestCommunityInfo*(self: Controller, communityId: string, importing: bool) = proc requestCommunityInfo*(self: Controller, communityId: string, shard: Shard, importing: bool) =
self.communityService.requestCommunityInfo(communityId, importing) self.communityService.requestCommunityInfo(communityId, shard, importing)
proc importCommunity*(self: Controller, communityKey: string) = proc importCommunity*(self: Controller, communityKey: string) =
self.communityService.asyncImportCommunity(communityKey) self.communityService.asyncImportCommunity(communityKey)

View File

@ -2,6 +2,7 @@ import tables
import ../../../../app_service/service/community/service as community_service import ../../../../app_service/service/community/service as community_service
import ../../../../app_service/service/chat/service as chat_service import ../../../../app_service/service/chat/service as chat_service
import ../../../../app_service/service/community_tokens/dto/community_token import ../../../../app_service/service/community_tokens/dto/community_token
import app_service/common/types
import ../../shared_models/section_item import ../../shared_models/section_item
type type
@ -68,7 +69,10 @@ method isCommunityRequestPending*(self: AccessInterface, communityId: string): b
method cancelRequestToJoinCommunity*(self: AccessInterface, communityId: string) {.base.} = method cancelRequestToJoinCommunity*(self: AccessInterface, communityId: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method requestCommunityInfo*(self: AccessInterface, communityId: string, importing: bool) {.base.} = method requestCommunityInfo*(self: AccessInterface, communityId: string, shardCluster: int, shardIndex: int, importing: bool) {.base.} =
raise newException(ValueError, "No implementation available")
method requestCommunityInfo*(self: AccessInterface, communityId: string, shard: Shard, importing: bool) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method importCommunity*(self: AccessInterface, communityKey: string) {.base.} = method importCommunity*(self: AccessInterface, communityKey: string) {.base.} =

View File

@ -382,8 +382,17 @@ method discordCategoriesAndChannelsExtracted*(self: Module, categories: seq[Disc
method cancelRequestToJoinCommunity*(self: Module, communityId: string) = method cancelRequestToJoinCommunity*(self: Module, communityId: string) =
self.controller.cancelRequestToJoinCommunity(communityId) self.controller.cancelRequestToJoinCommunity(communityId)
method requestCommunityInfo*(self: Module, communityId: string, importing: bool) = method requestCommunityInfo*(self: Module, communityId: string, shardCluster: int, shardIndex: int, importing: bool) =
self.controller.requestCommunityInfo(communityId, importing) let shard = Shard(
cluster: shardCluster,
index: shardIndex,
)
self.controller.requestCommunityInfo(communityId, shard, importing)
method requestCommunityInfo*(self: Module, communityId: string, shard: Shard, importing: bool) =
let cluster = if shard == nil: -1 else: shard.cluster
let index = if shard == nil: -1 else: shard.index
self.requestCommunityInfo(communityId, cluster, index, importing)
method isUserMemberOfCommunity*(self: Module, communityId: string): bool = method isUserMemberOfCommunity*(self: Module, communityId: string): bool =
self.controller.isUserMemberOfCommunity(communityId) self.controller.isUserMemberOfCommunity(communityId)

View File

@ -568,7 +568,8 @@ QtObject:
self.delegate.cancelRequestToJoinCommunity(communityId) self.delegate.cancelRequestToJoinCommunity(communityId)
proc requestCommunityInfo*(self: View, communityId: string, importing: bool) {.slot.} = proc requestCommunityInfo*(self: View, communityId: string, importing: bool) {.slot.} =
self.delegate.requestCommunityInfo(communityId, importing) # TODO update the slot to accept the shard arguments when it's available from the QML
self.delegate.requestCommunityInfo(communityId, shardCluster = -1, shardIndex = -1, importing)
proc getCommunityDetails*(self: View, communityId: string): string {.slot.} = proc getCommunityDetails*(self: View, communityId: string): string {.slot.} =
let communityItem = self.model.getItemById(communityId) let communityItem = self.model.getItemById(communityId)

View File

@ -22,6 +22,7 @@ import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/token/service as token_service import app_service/service/token/service as token_service
import app_service/service/network/service as networks_service import app_service/service/network/service as networks_service
import app_service/service/visual_identity/service as procs_from_visual_identity_service import app_service/service/visual_identity/service as procs_from_visual_identity_service
import app_service/service/shared_urls/service as urls_service
import app_service/service/community_tokens/community_collectible_owner import app_service/service/community_tokens/community_collectible_owner
@ -58,6 +59,7 @@ type
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
tokenService: token_service.Service tokenService: token_service.Service
networksService: networks_service.Service networksService: networks_service.Service
sharedUrlsService: urls_service.Service
# Forward declaration # Forward declaration
proc setActiveSection*(self: Controller, sectionId: string, skipSavingInSettings: bool = false) proc setActiveSection*(self: Controller, sectionId: string, skipSavingInSettings: bool = false)
@ -80,7 +82,8 @@ proc newController*(delegate: io_interface.AccessInterface,
communityTokensService: community_tokens_service.Service, communityTokensService: community_tokens_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
networksService: networks_service.Service networksService: networks_service.Service,
sharedUrlsService: urls_service.Service
): ):
Controller = Controller =
result = Controller() result = Controller()
@ -101,6 +104,7 @@ proc newController*(delegate: io_interface.AccessInterface,
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.tokenService = tokenService result.tokenService = tokenService
result.networksService = networksService result.networksService = networksService
result.sharedUrlsService = sharedUrlsService
proc delete*(self: Controller) = proc delete*(self: Controller) =
discard discard
@ -121,7 +125,8 @@ proc init*(self: Controller) =
self.mailserversService, self.mailserversService,
self.walletAccountService, self.walletAccountService,
self.tokenService, self.tokenService,
self.communityTokensService self.communityTokensService,
self.sharedUrlsService,
) )
self.events.on(SIGNAL_COMMUNITY_DATA_LOADED) do(e:Args): self.events.on(SIGNAL_COMMUNITY_DATA_LOADED) do(e:Args):
@ -137,7 +142,8 @@ proc init*(self: Controller) =
self.mailserversService, self.mailserversService,
self.walletAccountService, self.walletAccountService,
self.tokenService, self.tokenService,
self.communityTokensService self.communityTokensService,
self.sharedUrlsService,
) )
self.events.on(SIGNAL_CHANNEL_GROUPS_LOADING_FAILED) do(e:Args): self.events.on(SIGNAL_CHANNEL_GROUPS_LOADING_FAILED) do(e:Args):
@ -173,6 +179,7 @@ proc init*(self: Controller) =
self.walletAccountService, self.walletAccountService,
self.tokenService, self.tokenService,
self.communityTokensService, self.communityTokensService,
self.sharedUrlsService,
setActive = args.fromUserAction setActive = args.fromUserAction
) )
@ -192,6 +199,7 @@ proc init*(self: Controller) =
self.walletAccountService, self.walletAccountService,
self.tokenService, self.tokenService,
self.communityTokensService, self.communityTokensService,
self.sharedUrlsService,
setActive = args.fromUserAction setActive = args.fromUserAction
) )
self.delegate.onFinaliseOwnershipStatusChanged(args.isPendingOwnershipRequest, args.community.id) self.delegate.onFinaliseOwnershipStatusChanged(args.isPendingOwnershipRequest, args.community.id)
@ -217,6 +225,7 @@ proc init*(self: Controller) =
self.walletAccountService, self.walletAccountService,
self.tokenService, self.tokenService,
self.communityTokensService, self.communityTokensService,
self.sharedUrlsService,
setActive = true setActive = true
) )
@ -238,6 +247,7 @@ proc init*(self: Controller) =
self.walletAccountService, self.walletAccountService,
self.tokenService, self.tokenService,
self.communityTokensService, self.communityTokensService,
self.sharedUrlsService,
setActive = false setActive = false
) )
@ -277,9 +287,9 @@ proc init*(self: Controller) =
var args = ActiveSectionChatArgs(e) var args = ActiveSectionChatArgs(e)
self.setActiveSection(args.sectionId) self.setActiveSection(args.sectionId)
self.events.on(SIGNAL_STATUS_URL_REQUESTED) do(e: Args): self.events.on(SIGNAL_STATUS_URL_ACTIVATED) do(e: Args):
var args = StatusUrlArgs(e) var args = StatusUrlArgs(e)
self.delegate.onStatusUrlRequested(args.action, args.communityId, args.chatId, args.url, args.userId) self.delegate.activateStatusDeepLink(args.url)
self.events.on(SIGNAL_OS_NOTIFICATION_CLICKED) do(e: Args): self.events.on(SIGNAL_OS_NOTIFICATION_CLICKED) do(e: Args):
var args = ClickedNotificationArgs(e) var args = ClickedNotificationArgs(e)

View File

@ -13,7 +13,8 @@ import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/token/service as token_service import app_service/service/token/service as token_service
import app_service/service/community_tokens/service as community_tokens_service import app_service/service/community_tokens/service as community_tokens_service
import app_service/service/community_tokens/community_collectible_owner import app_service/service/community_tokens/community_collectible_owner
from app_service/common/types import StatusType, ContractTransactionStatus, MembershipRequestState import app_service/service/shared_urls/service as urls_service
from app_service/common/types import StatusType, ContractTransactionStatus, MembershipRequestState, Shard
import app/global/app_signals import app/global/app_signals
import app/core/eventemitter import app/core/eventemitter
@ -75,38 +76,40 @@ method communitySectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onChannelGroupsLoaded*( method onChannelGroupsLoaded*(
self: AccessInterface, self: AccessInterface,
channelGroups: seq[ChannelGroupDto], channelGroups: seq[ChannelGroupDto],
events: EventEmitter, events: EventEmitter,
settingsService: settings_service.Service, settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service, nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service, contactsService: contacts_service.Service,
chatService: chat_service.Service, chatService: chat_service.Service,
communityService: community_service.Service, communityService: community_service.Service,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service) communityTokensService: community_tokens_service.Service,
{.base.} = sharedUrlsService: urls_service.Service,
) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onCommunityDataLoaded*( method onCommunityDataLoaded*(
self: AccessInterface, self: AccessInterface,
events: EventEmitter, events: EventEmitter,
settingsService: settings_service.Service, settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service, nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service, contactsService: contacts_service.Service,
chatService: chat_service.Service, chatService: chat_service.Service,
communityService: community_service.Service, communityService: community_service.Service,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service) communityTokensService: community_tokens_service.Service,
{.base.} = sharedUrlsService: urls_service.Service,
){.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onChatsLoadingFailed*(self: AccessInterface) {.base.} = method onChatsLoadingFailed*(self: AccessInterface) {.base.} =
@ -145,18 +148,20 @@ method communitySpectated*(self: AccessInterface, communityId: string) {.base.}
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method communityJoined*(self: AccessInterface, community: CommunityDto, events: EventEmitter, method communityJoined*(self: AccessInterface, community: CommunityDto, events: EventEmitter,
settingsService: settings_service.Service, settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service, nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service, contactsService: contacts_service.Service,
chatService: chat_service.Service, chatService: chat_service.Service,
communityService: community_service.Service, communityService: community_service.Service,
messageService: message_service.Service, messageService: message_service.Service,
gifService: gif_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service, communityTokensService: community_tokens_service.Service,
setActive: bool = false) {.base.} = sharedUrlsService: urls_service.Service,
setActive: bool = false,
) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method communityEdited*(self: AccessInterface, community: CommunityDto) {.base.} = method communityEdited*(self: AccessInterface, community: CommunityDto) {.base.} =
@ -260,7 +265,7 @@ method isConnected*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method onStatusUrlRequested*(self: AccessInterface, action: StatusUrlAction, communityId: string, chatId: string, method onStatusUrlRequested*(self: AccessInterface, action: StatusUrlAction, communityId: string, chatId: string,
url: string, userId: string) {.base.} = url: string, userId: string, shard: Shard) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method getVerificationRequestFrom*(self: AccessInterface, publicKey: string): VerificationRequest {.base.} = method getVerificationRequestFrom*(self: AccessInterface, publicKey: string): VerificationRequest {.base.} =

View File

@ -75,10 +75,8 @@ import ../../core/custom_urls/urls_manager
export io_interface export io_interface
const COMMUNITY_PERMISSION_ACCESS_ON_REQUEST = 3
const TOAST_MESSAGE_VISIBILITY_DURATION_IN_MS = 5000 # 5 seconds const TOAST_MESSAGE_VISIBILITY_DURATION_IN_MS = 5000 # 5 seconds
const STATUS_URL_ENS_RESOLVE_REASON = "StatusUrl" const STATUS_URL_ENS_RESOLVE_REASON = "StatusUrl"
const MAX_MEMBERS_IN_GROUP_CHAT_WITHOUT_ADMIN = 19
type type
SpectateRequest = object SpectateRequest = object
@ -118,10 +116,12 @@ type
chatsLoaded: bool chatsLoaded: bool
communityDataLoaded: bool communityDataLoaded: bool
pendingSpectateRequest: SpectateRequest pendingSpectateRequest: SpectateRequest
statusDeepLinkToActivate: string
# Forward declaration # Forward declaration
method calculateProfileSectionHasNotification*[T](self: Module[T]): bool method calculateProfileSectionHasNotification*[T](self: Module[T]): bool
proc switchToContactOrDisplayUserProfile[T](self: Module[T], publicKey: string) proc switchToContactOrDisplayUserProfile[T](self: Module[T], publicKey: string)
method activateStatusDeepLink*[T](self: Module[T], statusDeepLink: string)
proc newModule*[T]( proc newModule*[T](
delegate: T, delegate: T,
@ -183,6 +183,7 @@ proc newModule*[T](
walletAccountService, walletAccountService,
tokenService, tokenService,
networkService, networkService,
sharedUrlsService,
) )
result.moduleLoaded = false result.moduleLoaded = false
result.chatsLoaded = false result.chatsLoaded = false
@ -650,7 +651,8 @@ method onChannelGroupsLoaded*[T](
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
) = ) =
self.chatsLoaded = true self.chatsLoaded = true
if not self.communityDataLoaded: if not self.communityDataLoaded:
@ -676,15 +678,15 @@ method onChannelGroupsLoaded*[T](
mailserversService, mailserversService,
walletAccountService, walletAccountService,
tokenService, tokenService,
communityTokensService communityTokensService,
sharedUrlsService,
) )
let channelGroupItem = self.createChannelGroupItem(channelGroup) let channelGroupItem = self.createChannelGroupItem(channelGroup)
self.view.model().addItem(channelGroupItem) self.view.model().addItem(channelGroupItem)
if activeSectionId == channelGroupItem.id: if activeSectionId == channelGroupItem.id:
activeSection = channelGroupItem activeSection = channelGroupItem
self.channelGroupModules[channelGroup.id].load(channelGroup, events, settingsService, nodeConfigurationService, self.channelGroupModules[channelGroup.id].load()
contactsService, chatService, communityService, messageService, gifService, mailserversService)
# Set active section if it is one of the channel sections # Set active section if it is one of the channel sections
if not activeSection.isEmpty(): if not activeSection.isEmpty():
@ -694,6 +696,8 @@ method onChannelGroupsLoaded*[T](
self.view.model().removeItem(LOADING_SECTION_ID) self.view.model().removeItem(LOADING_SECTION_ID)
self.view.sectionsLoaded() self.view.sectionsLoaded()
if self.statusDeepLinkToActivate != "":
self.activateStatusDeepLink(self.statusDeepLinkToActivate)
method onCommunityDataLoaded*[T]( method onCommunityDataLoaded*[T](
self: Module[T], self: Module[T],
@ -708,7 +712,8 @@ method onCommunityDataLoaded*[T](
mailserversService: mailservers_service.Service, mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
) = ) =
self.communityDataLoaded = true self.communityDataLoaded = true
if not self.chatsLoaded: if not self.chatsLoaded:
@ -727,7 +732,8 @@ method onCommunityDataLoaded*[T](
mailserversService, mailserversService,
walletAccountService, walletAccountService,
tokenService, tokenService,
communityTokensService communityTokensService,
sharedUrlsService,
) )
method onChatsLoadingFailed*[T](self: Module[T]) = method onChatsLoadingFailed*[T](self: Module[T]) =
@ -977,7 +983,8 @@ method communityJoined*[T](
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service, tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service, communityTokensService: community_tokens_service.Service,
setActive: bool = false sharedUrlsService: urls_service.Service,
setActive: bool = false,
) = ) =
if self.channelGroupModules.contains(community.id): if self.channelGroupModules.contains(community.id):
# The community is already spectated # The community is already spectated
@ -1000,11 +1007,11 @@ method communityJoined*[T](
mailserversService, mailserversService,
walletAccountService, walletAccountService,
tokenService, tokenService,
communityTokensService communityTokensService,
sharedUrlsService,
) )
let channelGroup = community.toChannelGroupDto() let channelGroup = community.toChannelGroupDto()
self.channelGroupModules[community.id].load(channelGroup, events, settingsService, nodeConfigurationService, contactsService, self.channelGroupModules[community.id].load()
chatService, communityService, messageService, gifService, mailserversService)
let communitySectionItem = self.createChannelGroupItem(channelGroup) let communitySectionItem = self.createChannelGroupItem(channelGroup)
if (firstCommunityJoined): if (firstCommunityJoined):
@ -1332,9 +1339,6 @@ method ephemeralNotificationClicked*[T](self: Module[T], id: int64) =
method onMyRequestAdded*[T](self: Module[T]) = method onMyRequestAdded*[T](self: Module[T]) =
self.displayEphemeralNotification("Your Request has been submitted", "" , "checkmark-circle", false, EphemeralNotificationType.Success.int, "") self.displayEphemeralNotification("Your Request has been submitted", "" , "checkmark-circle", false, EphemeralNotificationType.Success.int, "")
proc getCommunityIdFromFullChatId(fullChatId: string): string =
const communityIdLength = 68
return fullChatId.substr(0, communityIdLength-1)
proc switchToContactOrDisplayUserProfile[T](self: Module[T], publicKey: string) = proc switchToContactOrDisplayUserProfile[T](self: Module[T], publicKey: string) =
let contact = self.controller.getContact(publicKey) let contact = self.controller.getContact(publicKey)
@ -1344,7 +1348,7 @@ proc switchToContactOrDisplayUserProfile[T](self: Module[T], publicKey: string)
self.view.emitDisplayUserProfileSignal(publicKey) self.view.emitDisplayUserProfileSignal(publicKey)
method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, communityId: string, channelId: string, method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, communityId: string, channelId: string,
url: string, userId: string) = url: string, userId: string, shard: Shard) =
case action: case action:
of StatusUrlAction.DisplayUserProfile: of StatusUrlAction.DisplayUserProfile:
@ -1360,7 +1364,7 @@ method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, commun
# request community info and then spectate # request community info and then spectate
self.pendingSpectateRequest.communityId = communityId self.pendingSpectateRequest.communityId = communityId
self.pendingSpectateRequest.channelUuid = "" self.pendingSpectateRequest.channelUuid = ""
self.communitiesModule.requestCommunityInfo(communityId, importing = false) self.communitiesModule.requestCommunityInfo(communityId, shard, importing = false)
return return
self.controller.switchTo(communityId, "", "") self.controller.switchTo(communityId, "", "")
@ -1372,7 +1376,7 @@ method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, commun
if item.isEmpty(): if item.isEmpty():
self.pendingSpectateRequest.communityId = communityId self.pendingSpectateRequest.communityId = communityId
self.pendingSpectateRequest.channelUuid = channelId self.pendingSpectateRequest.channelUuid = channelId
self.communitiesModule.requestCommunityInfo(communityId, importing = false) self.communitiesModule.requestCommunityInfo(communityId, shard, importing = false)
return return
self.controller.switchTo(communityId, chatId, "") self.controller.switchTo(communityId, chatId, "")
@ -1511,18 +1515,21 @@ method checkAndPerformProfileMigrationIfNeeded*[T](self: Module[T]) =
method activateStatusDeepLink*[T](self: Module[T], statusDeepLink: string) = method activateStatusDeepLink*[T](self: Module[T], statusDeepLink: string) =
if not self.chatsLoaded:
self.statusDeepLinkToActivate = statusDeepLink
return
let urlData = self.sharedUrlsModule.parseSharedUrl(statusDeepLink) let urlData = self.sharedUrlsModule.parseSharedUrl(statusDeepLink)
if urlData.channel.uuid != "": if urlData.channel.uuid != "":
self.onStatusUrlRequested(StatusUrlAction.OpenCommunityChannel, urlData.community.communityId, urlData.channel.uuid, "", "") self.onStatusUrlRequested(StatusUrlAction.OpenCommunityChannel, urlData.community.communityId, urlData.channel.uuid,
url="", userId="", urlData.community.shard)
return return
if urlData.community.communityId != "": if urlData.community.communityId != "":
self.onStatusUrlRequested(StatusUrlAction.OpenCommunity, urlData.community.communityId, "", "", "") self.onStatusUrlRequested(StatusUrlAction.OpenCommunity, urlData.community.communityId, channelId="", url="", userId="", urlData.community.shard)
return return
if urlData.contact.publicKey != "": if urlData.contact.publicKey != "":
self.onStatusUrlRequested(StatusUrlAction.DisplayUserProfile, "", "", "", urlData.contact.publicKey) self.onStatusUrlRequested(StatusUrlAction.DisplayUserProfile, communityId="", channelId="", url="",
urlData.contact.publicKey, urlData.community.shard)
return return
let linkToActivate = self.urlsManager.convertExternalLinkToInternal(statusDeepLink)
self.urlsManager.onUrlActivated(linkToActivate)
method onDeactivateChatLoader*[T](self: Module[T], sectionId: string, chatId: string) = method onDeactivateChatLoader*[T](self: Module[T], sectionId: string, chatId: string) =
if (sectionId.len > 0 and self.channelGroupModules.contains(sectionId)): if (sectionId.len > 0 and self.channelGroupModules.contains(sectionId)):

View File

@ -8,6 +8,7 @@ import app_service/service/settings/service as settings_service
import app_service/service/community/service as community_service import app_service/service/community/service as community_service
import app_service/service/wallet_account/service as wallet_account_service import app_service/service/wallet_account/service as wallet_account_service
import app_service/common/social_links import app_service/common/social_links
import app_service/common/types
import app_service/service/profile/dto/profile_showcase_preferences import app_service/service/profile/dto/profile_showcase_preferences
@ -100,5 +101,5 @@ proc requestProfileShowcasePreferences*(self: Controller) =
proc requestProfileShowcaseForContact*(self: Controller, contactId: string) = proc requestProfileShowcaseForContact*(self: Controller, contactId: string) =
self.profileService.requestProfileShowcaseForContact(contactId) self.profileService.requestProfileShowcaseForContact(contactId)
proc requestCommunityInfo*(self: Controller, communityId: string) = proc requestCommunityInfo*(self: Controller, communityId: string, shard: Shard) =
self.communityService.requestCommunityInfo(communityId) self.communityService.requestCommunityInfo(communityId, shard)

View File

@ -11,6 +11,7 @@ import app_service/service/community/service as community_service
import app_service/service/wallet_account/service as wallet_account_service import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/profile/dto/profile_showcase import app_service/service/profile/dto/profile_showcase
import app_service/service/profile/dto/profile_showcase_preferences import app_service/service/profile/dto/profile_showcase_preferences
import app_service/common/types
import app_service/common/social_links import app_service/common/social_links
import app/modules/shared_models/social_links_model import app/modules/shared_models/social_links_model
@ -145,13 +146,13 @@ method updateProfileShowcase(self: Module, profileShowcase: ProfileShowcaseDto)
var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[] var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[]
var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[] var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[]
var profileCollectibleItems: seq[ProfileShowcaseCollectibleItem] = @[]
var profileAssetItems: seq[ProfileShowcaseAssetItem] = @[] var profileAssetItems: seq[ProfileShowcaseAssetItem] = @[]
for communityEntry in profileShowcase.communities: for communityEntry in profileShowcase.communities:
let community = self.controller.getCommunityById(communityEntry.communityId) let community = self.controller.getCommunityById(communityEntry.communityId)
if community.id == "": if community.id == "":
self.controller.requestCommunityInfo(communityEntry.communityId) # Fetch the community, however, we do not the shard info, so hopefully we can fetch it
self.controller.requestCommunityInfo(communityEntry.communityId, shard = nil)
profileCommunityItems.add(initProfileShowcaseCommunityLoadingItem( profileCommunityItems.add(initProfileShowcaseCommunityLoadingItem(
communityEntry.communityId, ProfileShowcaseVisibility.ToEveryone, communityEntry.order)) communityEntry.communityId, ProfileShowcaseVisibility.ToEveryone, communityEntry.order))
else: else:
@ -186,15 +187,12 @@ method updateProfileShowcasePreferences(self: Module, preferences: ProfileShowca
var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[] var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[]
var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[] var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[]
var profileCollectibleItems: seq[ProfileShowcaseCollectibleItem] = @[]
var profileAssetItems: seq[ProfileShowcaseAssetItem] = @[] var profileAssetItems: seq[ProfileShowcaseAssetItem] = @[]
for communityEntry in preferences.communities: for communityEntry in preferences.communities:
let community = self.controller.getCommunityById(communityEntry.communityId) let community = self.controller.getCommunityById(communityEntry.communityId)
if community.id == "": if community.id == "":
self.controller.requestCommunityInfo(communityEntry.communityId) warn "Unknown community added to our own profile showcase" , communityId = communityEntry.communityId
profileCommunityItems.add(initProfileShowcaseCommunityLoadingItem(
communityEntry.communityId, communityEntry.showcaseVisibility, communityEntry.order))
else: else:
profileCommunityItems.add(initProfileShowcaseCommunityItem( profileCommunityItems.add(initProfileShowcaseCommunityItem(
community, communityEntry.showcaseVisibility, communityEntry.order)) community, communityEntry.showcaseVisibility, communityEntry.order))

View File

@ -1,4 +1,4 @@
import NimQml, sequtils, stint import NimQml, sequtils, stint, json
import io_interface, view, controller import io_interface, view, controller
import ../io_interface as delegate_interface import ../io_interface as delegate_interface

View File

@ -296,11 +296,11 @@ QtObject:
if contactId != "": if contactId != "":
result.incl(contactId) result.incl(contactId)
proc getCommunityIds*(self: Model): HashSet[string] = proc getCommunityLinks*(self: Model): Table[string, string] =
for item in self.items: for item in self.items:
let communityId = item.linkPreview.getCommunityId() let communityId = item.linkPreview.getCommunityId()
if communityId != "": if communityId != "":
result.incl(communityId) result[communityId] = item.linkPreview.url
proc setItemLoadingLocalData(self: Model, row: int, item: Item, value: bool) = proc setItemLoadingLocalData(self: Model, row: int, item: Item, value: bool) =
if item.loadingLocalData == value: if item.loadingLocalData == value:

View File

@ -218,6 +218,7 @@ type
c.startupDidLoad() c.startupDidLoad()
c.userLoggedIn() c.userLoggedIn()
c.finishAppLoading() c.finishAppLoading()
c.appReady()
c.storeDefaultKeyPairForNewKeycardUser() c.storeDefaultKeyPairForNewKeycardUser()
c.syncKeycardBasedOnAppWalletStateAfterLogin() c.syncKeycardBasedOnAppWalletStateAfterLogin()
c.applyKeycardReplacementAfterLogin() c.applyKeycardReplacementAfterLogin()

View File

@ -326,10 +326,11 @@ method emitObtainingPasswordSuccess*[T](self: Module[T], password: string) =
method finishAppLoading*[T](self: Module[T]) = method finishAppLoading*[T](self: Module[T]) =
self.delegate.finishAppLoading() self.delegate.finishAppLoading()
self.delegate.appReady()
method checkFetchingStatusAndProceed*[T](self: Module[T]) = method checkFetchingStatusAndProceed*[T](self: Module[T]) =
if self.view.fetchingDataModel().isEntityLoaded(FetchingFromWakuProfile): if self.view.fetchingDataModel().isEntityLoaded(FetchingFromWakuProfile):
self.delegate.finishAppLoading() self.finishAppLoading()
return return
let currStateObj = self.view.currentStartupStateObj() let currStateObj = self.view.currentStartupStateObj()
if currStateObj.isNil: if currStateObj.isNil:
@ -431,7 +432,7 @@ method onNodeLogin*[T](self: Module[T], error: string) =
if currStateObj.flowType() != FlowType.AppLogin: if currStateObj.flowType() != FlowType.AppLogin:
let images = self.controller.storeIdentityImage() let images = self.controller.storeIdentityImage()
self.accountsService.updateLoggedInAccount(self.getDisplayName, images) self.accountsService.updateLoggedInAccount(self.getDisplayName, images)
self.delegate.finishAppLoading() self.finishAppLoading()
else: else:
self.moveToStartupState() self.moveToStartupState()
if currStateObj.flowType() == state.FlowType.AppLogin: if currStateObj.flowType() == state.FlowType.AppLogin:

View File

@ -76,14 +76,10 @@ type
InProgress, InProgress,
Completed Completed
type Shard* = object type Shard* = ref object
cluster*: int cluster*: int
index*: int index*: int
proc initShard*(cluster: int = -1, index: int = -1): Shard =
result.cluster = cluster
result.index = index
# ToDo: Will be streamlined to single TokenType under https://github.com/status-im/status-desktop/pull/12654/files # ToDo: Will be streamlined to single TokenType under https://github.com/status-im/status-desktop/pull/12654/files
type NewTokenType* {.pure.} = enum type NewTokenType* {.pure.} = enum
Native = 0 Native = 0

View File

@ -2,6 +2,7 @@
import json, strformat, strutils, tables import json, strformat, strutils, tables
import ../../community/dto/community import ../../community/dto/community
import ../../shared_urls/dto/url_data
include ../../../common/json_utils include ../../../common/json_utils
import ../../../../app_service/common/types import ../../../../app_service/common/types
@ -380,12 +381,7 @@ proc toChannelGroupDto*(jsonObj: JsonNode): ChannelGroupDto =
discard jsonObj.getProp("pubsubTopic", result.pubsubTopic) discard jsonObj.getProp("pubsubTopic", result.pubsubTopic)
discard jsonObj.getProp("pubsubTopicKey", result.pubsubTopicKey) discard jsonObj.getProp("pubsubTopicKey", result.pubsubTopicKey)
var shardObj: JsonNode result.shard = jsonObj.getShard()
if(jsonObj.getProp("shard", shardObj)):
var shard = initShard()
discard shardObj.getProp("cluster", shard.cluster)
discard shardObj.getProp("index", shard.index)
result.shard = shard
# To parse Community chats to ChatDto, we need to add the commuity ID and type # To parse Community chats to ChatDto, we need to add the commuity ID and type
proc toChatDto*(jsonObj: JsonNode, communityId: string): ChatDto = proc toChatDto*(jsonObj: JsonNode, communityId: string): ChatDto =

View File

@ -54,11 +54,13 @@ type
communityId: string communityId: string
importing: bool importing: bool
tryDatabase: bool tryDatabase: bool
shardCluster: int
shardIndex: int
const asyncRequestCommunityInfoTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} = const asyncRequestCommunityInfoTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncRequestCommunityInfoTaskArg](argEncoded) let arg = decode[AsyncRequestCommunityInfoTaskArg](argEncoded)
try: try:
let response = status_go.requestCommunityInfo(arg.communityId, arg.tryDatabase) let response = status_go.requestCommunityInfo(arg.communityId, arg.tryDatabase, arg.shardCluster, arg.shardIndex)
arg.finish(%* { arg.finish(%* {
"communityId": arg.communityId, "communityId": arg.communityId,
"importing": arg.importing, "importing": arg.importing,

View File

@ -8,6 +8,7 @@ include ../../../common/json_utils
import ../../../common/conversion import ../../../common/conversion
import ../../chat/dto/chat import ../../chat/dto/chat
import ../../shared_urls/dto/url_data
import ../../../../app_service/common/types import ../../../../app_service/common/types
type RequestToJoinType* {.pure.}= enum type RequestToJoinType* {.pure.}= enum
@ -461,12 +462,7 @@ proc toCommunityDto*(jsonObj: JsonNode): CommunityDto =
discard jsonObj.getProp("pubsubTopic", result.pubsubTopic) discard jsonObj.getProp("pubsubTopic", result.pubsubTopic)
discard jsonObj.getProp("pubsubTopicKey", result.pubsubTopicKey) discard jsonObj.getProp("pubsubTopicKey", result.pubsubTopicKey)
var shardObj: JsonNode result.shard = jsonObj.getShard()
if(jsonObj.getProp("shard", shardObj)):
var shard = initShard()
discard shardObj.getProp("cluster", shard.cluster)
discard shardObj.getProp("index", shard.index)
result.shard = shard
proc toMembershipRequestState*(state: CommunityMemberPendingBanOrKick): MembershipRequestState = proc toMembershipRequestState*(state: CommunityMemberPendingBanOrKick): MembershipRequestState =
case state: case state:

View File

@ -1823,7 +1823,8 @@ QtObject:
) )
self.threadpool.start(arg) self.threadpool.start(arg)
proc requestCommunityInfo*(self: Service, communityId: string, importing = false, tryDatabase = true, requiredTimeSinceLastRequest = initDuration(0, 0)) = proc requestCommunityInfo*(self: Service, communityId: string, shard: Shard, importing = false, tryDatabase = true,
requiredTimeSinceLastRequest = initDuration(0, 0)) =
if communityId in self.requestedCommunityIds: if communityId in self.requestedCommunityIds:
info "requestCommunityInfo: skipping as already requested", communityId info "requestCommunityInfo: skipping as already requested", communityId
@ -1847,7 +1848,9 @@ QtObject:
slot: "asyncCommunityInfoLoaded", slot: "asyncCommunityInfoLoaded",
communityId: communityId, communityId: communityId,
importing: importing, importing: importing,
tryDatabase: tryDatabase tryDatabase: tryDatabase,
shardCluster: if shard == nil: -1 else: shard.cluster,
shardIndex: if shard == nil: -1 else: shard.index,
) )
self.threadpool.start(arg) self.threadpool.start(arg)

View File

@ -11,6 +11,7 @@ type CommunityUrlDataDto* = object
color*: string color*: string
tagIndices*: seq[int] tagIndices*: seq[int]
communityId*: string communityId*: string
shard*: Shard
type CommunityChannelUrlDataDto* = object type CommunityChannelUrlDataDto* = object
emoji*: string emoji*: string
@ -29,6 +30,15 @@ type UrlDataDto* = object
channel*: CommunityChannelUrlDataDto channel*: CommunityChannelUrlDataDto
contact*: ContactUrlDataDto contact*: ContactUrlDataDto
proc getShard*(jsonObj: JsonNode): Shard =
var shardObj: JsonNode
if (jsonObj.getProp("shard", shardObj)):
result = Shard()
discard shardObj.getProp("cluster", result.cluster)
discard shardObj.getProp("index", result.index)
else:
result = nil
proc toCommunityUrlDataDto*(jsonObj: JsonNode): CommunityUrlDataDto = proc toCommunityUrlDataDto*(jsonObj: JsonNode): CommunityUrlDataDto =
result = CommunityUrlDataDto() result = CommunityUrlDataDto()
discard jsonObj.getProp("displayName", result.displayName) discard jsonObj.getProp("displayName", result.displayName)
@ -42,6 +52,8 @@ proc toCommunityUrlDataDto*(jsonObj: JsonNode): CommunityUrlDataDto =
discard jsonObj.getProp("communityId", result.communityId) discard jsonObj.getProp("communityId", result.communityId)
result.shard = jsonObj.getShard()
proc toCommunityChannelUrlDataDto*(jsonObj: JsonNode): CommunityChannelUrlDataDto = proc toCommunityChannelUrlDataDto*(jsonObj: JsonNode): CommunityChannelUrlDataDto =
result = CommunityChannelUrlDataDto() result = CommunityChannelUrlDataDto()
discard jsonObj.getProp("displayName", result.displayName) discard jsonObj.getProp("displayName", result.displayName)
@ -62,7 +74,7 @@ proc toUrlDataDto*(jsonObj: JsonNode): UrlDataDto =
var communityObj: JsonNode var communityObj: JsonNode
if (jsonObj.getProp("community", communityObj)): if (jsonObj.getProp("community", communityObj)):
result.community = communityObj.toCommunityUrlDataDto() result.community = communityObj.toCommunityUrlDataDto()
var communityChannelObj: JsonNode var communityChannelObj: JsonNode
if (jsonObj.getProp("channel", communityChannelObj)): if (jsonObj.getProp("channel", communityChannelObj)):
result.channel = communityChannelObj.toCommunityChannelUrlDataDto() result.channel = communityChannelObj.toCommunityChannelUrlDataDto()
@ -71,14 +83,19 @@ proc toUrlDataDto*(jsonObj: JsonNode): UrlDataDto =
if (jsonObj.getProp("contact", contactObj)): if (jsonObj.getProp("contact", contactObj)):
result.contact = contactObj.toContactUrlDataDto() result.contact = contactObj.toContactUrlDataDto()
proc `$`*(communityUrlDataDto: CommunityUrlDataDto): string = proc toJsonNode*(communityUrlDataDto: CommunityUrlDataDto): JsonNode =
var jsonObj = newJObject() var jsonObj = newJObject()
jsonObj["displayName"] = %* communityUrlDataDto.displayName jsonObj["displayName"] = %* communityUrlDataDto.displayName
jsonObj["description"] = %* communityUrlDataDto.description jsonObj["description"] = %* communityUrlDataDto.description
jsonObj["membersCount"] = %* communityUrlDataDto.membersCount jsonObj["membersCount"] = %* communityUrlDataDto.membersCount
jsonObj["color"] = %* communityUrlDataDto.color jsonObj["color"] = %* communityUrlDataDto.color
jsonObj["communityId"] = %* communityUrlDataDto.communityId jsonObj["communityId"] = %* communityUrlDataDto.communityId
return $jsonObj jsonObj["shardCluster"] = %* communityUrlDataDto.shard.cluster
jsonObj["shardIndex"] = %* communityUrlDataDto.shard.index
return jsonObj
proc `$`*(communityUrlDataDto: CommunityUrlDataDto): string =
return $(communityUrlDataDto.toJsonNode())
proc `$`*(communityChannelUrlDataDto: CommunityChannelUrlDataDto): string = proc `$`*(communityChannelUrlDataDto: CommunityChannelUrlDataDto): string =
var jsonObj = newJObject() var jsonObj = newJObject()

View File

@ -433,12 +433,24 @@ proc collectCommunityMetrics*(communityId: string, metricsType: int, intervals:
"intervals": intervals "intervals": intervals
}]) }])
proc requestCommunityInfo*(communityId: string, tryDatabase: bool): RpcResponse[JsonNode] {.raises: [Exception].} = proc requestCommunityInfo*(communityId: string, tryDatabase: bool, shardCluster: int, shardIndex: int): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("fetchCommunity".prefix, %*[{ if shardCluster != -1 and shardIndex != -1:
"communityKey": communityId, result = callPrivateRPC("fetchCommunity".prefix,%*[{
"tryDatabase": tryDatabase, "communityKey": communityId,
"waitForResponse": true "tryDatabase": tryDatabase,
}]) "shard": {
"shardCluster": shardCluster,
"shardIndex": shardIndex,
},
"waitForResponse": true
}])
else:
result = callPrivateRPC("fetchCommunity".prefix, %*[{
"communityKey": communityId,
"tryDatabase": tryDatabase,
"shard": nil,
"waitForResponse": true
}])
proc importCommunity*(communityKey: string): RpcResponse[JsonNode] {.raises: [Exception].} = proc importCommunity*(communityKey: string): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("importCommunity".prefix, %*[communityKey]) result = callPrivateRPC("importCommunity".prefix, %*[communityKey])

View File

@ -370,6 +370,7 @@ Control {
} }
Loader { Loader {
id: invitationBubbleLoader id: invitationBubbleLoader
// TODO remove this component in #12570
active: root.messageDetails.contentType === StatusMessage.ContentType.Invitation && !editMode active: root.messageDetails.contentType === StatusMessage.ContentType.Invitation && !editMode
visible: active visible: active
} }

View File

@ -451,8 +451,8 @@ QtObject {
chatCommunitySectionModule.collectCommunityMetricsMessagesCount(intervals) chatCommunitySectionModule.collectCommunityMetricsMessagesCount(intervals)
} }
function requestCommunityInfo(id, importing = false) { function requestCommunityInfo(id, shardCluster, shardIndex, importing = false) {
communitiesModuleInst.requestCommunityInfo(id, importing) communitiesModuleInst.requestCommunityInfo(id, shardCluster, shardIndex, importing)
} }
function getCommunityDetailsAsJson(id) { function getCommunityDetailsAsJson(id) {

View File

@ -102,13 +102,13 @@ QtObject {
return root.communitiesModuleInst.getCommunityPublicKeyFromPrivateKey(privateKey); return root.communitiesModuleInst.getCommunityPublicKeyFromPrivateKey(privateKey);
} }
function requestCommunityInfo(communityKey, importing = false) { function requestCommunityInfo(communityKey, shardCluster, shardIndex, importing = false) {
const publicKey = Utils.isCompressedPubKey(communityKey) const publicKey = Utils.isCompressedPubKey(communityKey)
? Utils.changeCommunityKeyCompression(communityKey) ? Utils.changeCommunityKeyCompression(communityKey)
: communityKey : communityKey
if (importing) if (importing)
root.mainModuleInst.setCommunityIdToSpectate(publicKey) root.mainModuleInst.setCommunityIdToSpectate(publicKey)
root.communitiesModuleInst.requestCommunityInfo(publicKey, importing) root.communitiesModuleInst.requestCommunityInfo(publicKey, shardCluster, shardIndex, importing)
} }
property var communitiesList: communitiesModuleInst.model property var communitiesList: communitiesModuleInst.model

View File

@ -145,14 +145,6 @@ QtObject {
root.communitiesModuleInst.importCommunity(communityKey); root.communitiesModuleInst.importCommunity(communityKey);
} }
function requestCommunityInfo(communityKey, importing = false) {
const publicKey = Utils.isCompressedPubKey(communityKey)
? Utils.changeCommunityKeyCompression(communityKey)
: communityKey
root.mainModuleInst.setCommunityIdToSpectate(publicKey)
root.communitiesModuleInst.requestCommunityInfo(publicKey, importing)
}
function getCurrentVersion() { function getCurrentVersion() {
return aboutModuleInst.getCurrentVersion() return aboutModuleInst.getCurrentVersion()
} }

View File

@ -36,10 +36,19 @@ StatusDialog {
readonly property string inputErrorMessage: isInputValid ? "" : qsTr("Invalid key") readonly property string inputErrorMessage: isInputValid ? "" : qsTr("Invalid key")
readonly property string errorMessage: importErrorMessage || inputErrorMessage readonly property string errorMessage: importErrorMessage || inputErrorMessage
readonly property string inputKey: keyInput.text.trim() readonly property string inputKey: keyInput.text.trim()
property int shardCluster: -1
property int shardIndex: -1
readonly property string publicKey: { readonly property string publicKey: {
if (Utils.isStatusDeepLink(inputKey)) { if (Utils.isStatusDeepLink(inputKey)) {
d.shardCluster = -1
d.shardIndex = -1
const linkData = Utils.getCommunityDataFromSharedLink(inputKey) const linkData = Utils.getCommunityDataFromSharedLink(inputKey)
return !linkData ? "" : linkData.communityId if (!linkData) {
return ""
}
d.shardCluster = linkData.shardCluster
d.shardIndex = linkData.shardIndex
return linkData.communityId
} }
if (!Utils.isCommunityPublicKey(inputKey)) if (!Utils.isCommunityPublicKey(inputKey))
return "" return ""
@ -67,7 +76,7 @@ StatusDialog {
} }
if (requestIfNotFound) { if (requestIfNotFound) {
root.store.requestCommunityInfo(publicKey, false) root.store.requestCommunityInfo(publicKey, shardCluster, shardIndex, false)
d.communityInfoRequested = true d.communityInfoRequested = true
d.communityDetails = null d.communityDetails = null
} }

View File

@ -45,7 +45,8 @@ Control {
const communityJson = root.store.getSectionByIdJson(communityId) const communityJson = root.store.getSectionByIdJson(communityId)
if (!communityJson) { if (!communityJson) {
root.store.requestCommunityInfo(communityId) // we don't have the shard info, so we will try to fetch it on waku
root.store.requestCommunityInfo(communityId, -1, -1)
return null return null
} }