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
proc startupDidLoad*(self: AppController)
proc userLoggedIn*(self: AppController): string
proc appReady*(self: AppController)
proc logout*(self: AppController)
proc finishAppLoading*(self: AppController)
proc storeDefaultKeyPairForNewKeycardUser*(self: AppController)
@ -458,13 +459,15 @@ proc load(self: AppController) =
proc userLoggedIn*(self: AppController): string =
try:
self.generalService.startMessenger()
self.statusFoundation.userLoggedIn()
return ""
except Exception as e:
let errDescription = e.msg
error "error: ", errDescription
return errDescription
proc appReady*(self: AppController) =
self.statusFoundation.appReady()
proc finishAppLoading*(self: AppController) =
self.load()

View File

@ -2,32 +2,18 @@ import NimQml, strutils, chronicles
import ../eventemitter
import ../../global/app_signals
import ../../../app_service/common/conversion
import ../../../app_service/service/accounts/utils
logScope:
topics = "urls-manager"
const StatusInternalLink* = "status-app"
const StatusExternalLink* = "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/"
const StatusInternalLink* = "status-app://"
const StatusExternalLink* = "https://status.app/"
QtObject:
type UrlsManager* = ref object of QObject
events: EventEmitter
protocolUriOnStart: string
loggedIn: bool
appReady: bool
proc setup(self: UrlsManager, urlSchemeEvent: StatusEvent,
singleInstance: SingleInstance) =
@ -46,58 +32,29 @@ QtObject:
result.setup(urlSchemeEvent, singleInstance)
result.events = events
result.protocolUriOnStart = protocolUriOnStart
result.loggedIn = false
result.appReady = false
proc prepareCommunityId(self: UrlsManager, communityId: string): string =
if isCompressedPubKey(communityId):
return changeCommunityKeyCompression(communityId)
return communityId
proc convertInternalLinkToExternal*(self: UrlsManager, statusDeepLink: string): string =
let idx = find(statusDeepLink, StatusInternalLink)
result = statusDeepLink
if idx != -1:
result = statusDeepLink[idx + StatusInternalLink.len .. ^1]
result = StatusExternalLink & result
proc onUrlActivated*(self: UrlsManager, urlRaw: string) {.slot.} =
if not self.loggedIn:
if not self.appReady:
self.protocolUriOnStart = urlRaw
return
var data = StatusUrlArgs()
let url = urlRaw.multiReplace((" ", ""))
.multiReplace(("\r\n", ""))
.multiReplace(("\n", ""))
let data = StatusUrlArgs(url: self.convertInternalLinkToExternal(url))
# Display user profile popup for user with `user_pk` or `ens_name`
if url.startsWith(UriFormatUserProfile):
data.action = StatusUrlAction.DisplayUserProfile
data.userId = url[UriFormatUserProfile.len .. url.len-1]
self.events.emit(SIGNAL_STATUS_URL_ACTIVATED, data)
# Open community with `community_key`
elif url.startsWith(UriFormatCommunity):
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
proc appReady*(self: UrlsManager) =
self.appReady = true
if self.protocolUriOnStart != "":
self.onUrlActivated(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,
protocolUriOnStart)
proc userLoggedIn*(self: StatusFoundation) =
self.urlsManager.userLoggedIn()
proc appReady*(self: StatusFoundation) =
self.urlsManager.appReady()

View File

@ -39,4 +39,4 @@ type
url*: string
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 newController*(delegate: io_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
belongsToCommunity: bool, isUsersListAvailable: bool, 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): Controller =
belongsToCommunity: bool, isUsersListAvailable: bool, 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): Controller =
result = Controller()
result.delegate = delegate
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/mailservers/service as mailservers_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 ../../../../../core/signals/types
import ../../../../../core/eventemitter
import ../../../../../core/unique_event_emitter
@ -31,11 +32,12 @@ type
chatService: chat_service.Service
messageService: message_service.Service
mailserversService: mailservers_service.Service
sharedUrlsService: shared_urls_service.Service
proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service,
chatService: chat_service.Service, messageService: message_service.Service, mailserversService: mailservers_service.Service):
Controller =
belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service,
chatService: chat_service.Service, messageService: message_service.Service,
mailserversService: mailservers_service.Service, sharedUrlsService: shared_urls_service.Service): Controller =
result = Controller()
result.delegate = delegate
result.events = initUniqueUUIDEventEmitter(events)
@ -48,6 +50,7 @@ proc newController*(delegate: io_interface.AccessInterface, events: EventEmitter
result.chatService = chatService
result.messageService = messageService
result.mailserversService = mailserversService
result.sharedUrlsService = sharedUrlsService
proc delete*(self: Controller) =
self.events.disconnect()
@ -240,8 +243,10 @@ proc getCommunityDetails*(self: Controller): CommunityDto =
proc getCommunityById*(self: Controller, communityId: string): CommunityDto =
return self.communityService.getCommunityById(communityId)
proc requestCommunityInfo*(self: Controller, communityId: string, useDataabse: bool, requiredTimeSinceLastRequest: Duration) =
self.communityService.requestCommunityInfo(communityId, false, useDataabse, requiredTimeSinceLastRequest)
proc requestCommunityInfo*(self: Controller, communityId: string, shard: Shard, useDatabase: bool,
requiredTimeSinceLastRequest: Duration) =
self.communityService.requestCommunityInfo(communityId, shard, importing = false,
useDatabase, requiredTimeSinceLastRequest)
proc getOneToOneChatNameAndImage*(self: Controller):
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 =
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 as delegate_interface
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/message/service as message_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
export io_interface
@ -45,15 +46,16 @@ type
getMessageRequestId: UUID
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service,
chatService: chat_service.Service, messageService: message_service.Service, mailserversService: mailservers_service.Service):
belongsToCommunity: bool, contactService: contact_service.Service, communityService: community_service.Service,
chatService: chat_service.Service, messageService: message_service.Service,
mailserversService: mailservers_service.Service, sharedUrlsService: shared_urls_service.Service):
Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, sectionId, chatId, belongsToCommunity, contactService,
communityService, chatService, messageService, mailserversService)
communityService, chatService, messageService, mailserversService, sharedUrlsService)
result.moduleLoaded = false
result.initialMessagesLoaded = false
result.firstUnseenMessageState = (false, false, false)
@ -805,7 +807,7 @@ proc updateLinkPreviewsContacts(self: Module, item: Item, requestFromMailserver:
self.controller.requestContactInfo(contactId)
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)
if community.id != "":
@ -815,6 +817,7 @@ proc updateLinkPreviewsCommunities(self: Module, item: Item, requestFromMailserv
continue
debug "updateLinkPreviewsCommunites: requesting from mailserver", communityId
let urlData = self.controller.parseSharedUrl(url)
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/message/service as message_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
export io_interface
@ -42,23 +43,25 @@ type
moduleLoaded: bool
proc newModule*(delegate: delegate_interface.AccessInterface, events: EventEmitter, sectionId: string, chatId: string,
belongsToCommunity: bool, isUsersListAvailable: bool, 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):
belongsToCommunity: bool, isUsersListAvailable: bool, 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, sharedUrlsService: shared_urls_service.Service):
Module =
result = Module()
result.delegate = delegate
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
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.inputAreaModule = input_area_module.newModule(result, events, sectionId, chatId, belongsToCommunity,
chatService, communityService, gifService, messageService, settingsService)
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,
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/community_tokens/service as community_tokens_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 ../../../core/signals/types
@ -40,16 +41,17 @@ type
walletAccountService: wallet_account_service.Service
tokenService: token_service.Service
communityTokensService: community_tokens_service.Service
sharedUrlsService: shared_urls_service.Service
proc newController*(delegate: io_interface.AccessInterface, sectionId: string, isCommunity: bool, 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,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service): Controller =
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,
walletAccountService: wallet_account_service.Service, tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: shared_urls_service.Service): Controller =
result = Controller()
result.delegate = delegate
result.sectionId = sectionId
@ -67,6 +69,7 @@ proc newController*(delegate: io_interface.AccessInterface, sectionId: string, i
result.walletAccountService = walletAccountService
result.tokenService = tokenService
result.communityTokensService = communityTokensService
result.sharedUrlsService = sharedUrlsService
proc delete*(self: Controller) =
self.events.disconnect()
@ -158,14 +161,14 @@ proc init*(self: Controller) =
let belongsToCommunity = chat.communityId.len > 0
discard self.delegate.addOrUpdateChat(chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
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):
var args = CreatedChatArgs(e)
let belongsToCommunity = args.chat.communityId.len > 0
discard self.delegate.addOrUpdateChat(args.chat, belongsToCommunity, self.events, self.settingsService, self.nodeConfigurationService,
self.contactService, self.chatService, self.communityService, self.messageService, self.gifService,
self.mailserversService, setChatAsActive = true)
self.mailserversService, self.sharedUrlsService, setChatAsActive = true)
if (self.isCommunitySection):
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
discard self.delegate.addOrUpdateChat(args.chat, belongsToCommunity, self.events, self.settingsService,
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):
let args = CommunityMetricsArgs(e)
@ -420,6 +423,7 @@ proc getChatsAndBuildUI*(self: Controller) =
self.messageService,
self.gifService,
self.mailserversService,
self.sharedUrlsService,
)
proc sectionUnreadMessagesAndMentionsCount*(self: Controller, communityId: string):
@ -464,7 +468,7 @@ proc createOneToOneChat*(self: Controller, communityID: string, chatId: string,
if(response.success):
discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
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) =
self.chatService.switchToOrCreateOneToOneChat(chatId, ensName)
@ -534,14 +538,14 @@ proc createGroupChat*(self: Controller, communityID: string, groupName: string,
if(response.success):
discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
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) =
let response = self.chatService.createGroupChatFromInvitation(groupName, chatId, adminPK)
if(response.success):
discard self.delegate.addOrUpdateChat(response.chatDto, false, self.events, self.settingsService, self.nodeConfigurationService,
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) =
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/gif/service as gif_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 item as chat_item
@ -21,30 +22,22 @@ type
method delete*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method load*(self: AccessInterface,
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.} =
method load*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onChatsLoaded*(self: AccessInterface,
channelGroup: ChannelGroupDto,
events: UniqueUUIDEventEmitter,
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.} =
channelGroup: ChannelGroupDto,
events: UniqueUUIDEventEmitter,
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,
sharedUrlsService: shared_urls_service.Service,
) {.base.} =
raise newException(ValueError, "No implementation available rip")
method isLoaded*(self: AccessInterface): bool {.base.} =
@ -72,10 +65,11 @@ method makeChatWithIdActive*(self: AccessInterface, chatId: string) {.base.} =
raise newException(ValueError, "No implementation available")
method addNewChat*(self: AccessInterface, chatDto: ChatDto, belongsToCommunity: bool, events: EventEmitter,
settingsService: settings_service.Service, contactService: contact_service.Service,
chatService: chat_service.Service, communityService: community_service.Service,
messageService: message_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, setChatAsActive: bool = true, insertIntoModel: bool = true): Item {.base.} =
settingsService: settings_service.Service, contactService: contact_service.Service,
chatService: chat_service.Service, communityService: community_service.Service,
messageService: message_service.Service, gifService: gif_service.Service,
mailserversService: mailservers_service.Service, sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true, insertIntoModel: bool = true): Item {.base.} =
raise newException(ValueError, "No implementation available")
method doesCatOrChatExist*(self: AccessInterface, chatId: string): bool {.base.} =
@ -96,6 +90,7 @@ method addOrUpdateChat*(self: AccessInterface,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true,
insertIntoModel: bool = true
): 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/token/service as token_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/contacts/dto/contacts as contacts_dto
import ../../../../app_service/service/community/dto/community as community_dto
@ -54,7 +55,8 @@ type
chatsLoaded: bool
# Forward declaration
proc buildChatSectionUI(self: Module,
proc buildChatSectionUI(
self: Module,
channelGroup: ChannelGroupDto,
events: UniqueUUIDEventEmitter,
settingsService: settings_service.Service,
@ -64,7 +66,9 @@ proc buildChatSectionUI(self: Module,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service)
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
)
proc reevaluateRequiresTokenPermissionToJoin(self: Module)
@ -81,6 +85,7 @@ proc addOrUpdateChat(self: Module,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true,
insertIntoModel: bool = true,
): Item
@ -101,11 +106,13 @@ proc newModule*(
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: shared_urls_service.Service,
): Module =
result = Module()
result.delegate = delegate
result.controller = controller.newController(result, sectionId, isCommunity, events, settingsService, nodeConfigurationService,
contactService, chatService, communityService, messageService, gifService, mailserversService, walletAccountService, tokenService, communityTokensService)
result.controller = controller.newController(result, sectionId, isCommunity, events, settingsService,
nodeConfigurationService, contactService, chatService, communityService, messageService, gifService,
mailserversService, walletAccountService, tokenService, communityTokensService, sharedUrlsService)
result.view = view.newView(result)
result.viewVariant = newQVariant(result.view)
result.moduleLoaded = false
@ -133,18 +140,25 @@ proc getUserMemberRole(self: Module, members: seq[ChatMember]): MemberRole =
return m.role
return MemberRole.None
proc addSubmodule(self: Module, chatId: string, belongToCommunity: bool, isUsersListAvailable: bool, 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) =
proc addSubmodule(
self: Module,
chatId: string,
belongToCommunity: bool,
isUsersListAvailable: bool,
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,
sharedUrlsService: shared_urls_service.Service,
) =
self.chatContentModules[chatId] = chat_content_module.newModule(self, events, self.controller.getMySectionId(), chatId,
belongToCommunity, isUsersListAvailable, settingsService, nodeConfigurationService, contactService, chatService, communityService,
messageService, gifService, mailserversService)
messageService, gifService, mailserversService, sharedUrlsService)
proc removeSubmodule(self: Module, chatId: string) =
if(not self.chatContentModules.contains(chatId)):
@ -187,7 +201,9 @@ proc buildChatSectionUI(
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service) =
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
) =
var selectedItemId = ""
let sectionLastOpenChat = singletonInstance.localAccountSensitiveSettings.getSectionLastOpenChat(self.controller.getMySectionId())
@ -226,6 +242,7 @@ proc buildChatSectionUI(
messageService,
gifService,
mailserversService,
sharedUrlsService,
setChatAsActive = false,
insertIntoModel = false
))
@ -301,18 +318,7 @@ method clearListOfMyContacts*(self: Module) =
self.view.listOfMyContacts().clear()
method load*(
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) =
method load*(self: Module) =
self.controller.init()
self.view.load()
@ -328,10 +334,11 @@ method onChatsLoaded*(
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
) =
self.chatsLoaded = true
self.buildChatSectionUI(channelGroup, events, settingsService, nodeConfigurationService,
contactService, chatService, communityService, messageService, gifService, mailserversService)
contactService, chatService, communityService, messageService, gifService, mailserversService, sharedUrlsService)
if(not self.controller.isCommunity()):
# 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
if self.chatsLoaded:
# update model of this module (appropriate chat from the chats list (chats model))
self.view.chatsModel().updateNotificationsForItemById(chatId, hasUnreadMessages, unviewedMentionsCount)
# update child module
if (self.chatContentModules.contains(chatId)):
self.chatContentModules[chatId].onNotificationsUpdated(hasUnreadMessages, unviewedMentionsCount)
# Update category
if chat.categoryId != "":
let hasUnreadMessages = self.controller.chatsWithCategoryHaveUnreadMessages(chat.communityId, chat.categoryId)
self.view.chatsModel().setCategoryHasUnreadMessages(chat.categoryId, hasUnreadMessages)
# update parent module
self.updateParentBadgeNotifications()
method updateLastMessageTimestamp*(self: Module, chatId: string, lastMessageTimestamp: int) =
@ -527,6 +532,7 @@ method addNewChat*(
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true,
insertIntoModel: bool = true,
): Item =
@ -626,6 +632,7 @@ method addNewChat*(
messageService,
gifService,
mailserversService,
sharedUrlsService,
)
self.chatContentModules[chatDto.id].load(result)
@ -1188,6 +1195,7 @@ proc addOrUpdateChat(self: Module,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true,
insertIntoModel: bool = true,
): Item =
@ -1233,6 +1241,7 @@ proc addOrUpdateChat(self: Module,
messageService,
gifService,
mailserversService,
sharedUrlsService,
setChatAsActive,
insertIntoModel,
)
@ -1249,6 +1258,7 @@ method addOrUpdateChat*(self: Module,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
sharedUrlsService: shared_urls_service.Service,
setChatAsActive: bool = true,
insertIntoModel: bool = true,
): Item =
@ -1265,6 +1275,7 @@ method addOrUpdateChat*(self: Module,
messageService,
gifService,
mailserversService,
sharedUrlsService,
setChatAsActive,
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/wallet_account/service as wallet_account_service
import app_service/service/keycard/service as keycard_service
import app_service/common/types
import backend/collectibles as backend_collectibles
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] =
return self.chatService.getChatsByIds(chatIds)
proc requestCommunityInfo*(self: Controller, communityId: string, importing: bool) =
self.communityService.requestCommunityInfo(communityId, importing)
proc requestCommunityInfo*(self: Controller, communityId: string, shard: Shard, importing: bool) =
self.communityService.requestCommunityInfo(communityId, shard, importing)
proc importCommunity*(self: Controller, communityKey: string) =
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/chat/service as chat_service
import ../../../../app_service/service/community_tokens/dto/community_token
import app_service/common/types
import ../../shared_models/section_item
type
@ -68,7 +69,10 @@ method isCommunityRequestPending*(self: AccessInterface, communityId: string): b
method cancelRequestToJoinCommunity*(self: AccessInterface, communityId: string) {.base.} =
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")
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) =
self.controller.cancelRequestToJoinCommunity(communityId)
method requestCommunityInfo*(self: Module, communityId: string, importing: bool) =
self.controller.requestCommunityInfo(communityId, importing)
method requestCommunityInfo*(self: Module, communityId: string, shardCluster: int, shardIndex: int, importing: bool) =
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 =
self.controller.isUserMemberOfCommunity(communityId)

View File

@ -568,7 +568,8 @@ QtObject:
self.delegate.cancelRequestToJoinCommunity(communityId)
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.} =
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/network/service as networks_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
@ -58,6 +59,7 @@ type
walletAccountService: wallet_account_service.Service
tokenService: token_service.Service
networksService: networks_service.Service
sharedUrlsService: urls_service.Service
# Forward declaration
proc setActiveSection*(self: Controller, sectionId: string, skipSavingInSettings: bool = false)
@ -80,7 +82,8 @@ proc newController*(delegate: io_interface.AccessInterface,
communityTokensService: community_tokens_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
networksService: networks_service.Service
networksService: networks_service.Service,
sharedUrlsService: urls_service.Service
):
Controller =
result = Controller()
@ -101,6 +104,7 @@ proc newController*(delegate: io_interface.AccessInterface,
result.walletAccountService = walletAccountService
result.tokenService = tokenService
result.networksService = networksService
result.sharedUrlsService = sharedUrlsService
proc delete*(self: Controller) =
discard
@ -121,7 +125,8 @@ proc init*(self: Controller) =
self.mailserversService,
self.walletAccountService,
self.tokenService,
self.communityTokensService
self.communityTokensService,
self.sharedUrlsService,
)
self.events.on(SIGNAL_COMMUNITY_DATA_LOADED) do(e:Args):
@ -137,7 +142,8 @@ proc init*(self: Controller) =
self.mailserversService,
self.walletAccountService,
self.tokenService,
self.communityTokensService
self.communityTokensService,
self.sharedUrlsService,
)
self.events.on(SIGNAL_CHANNEL_GROUPS_LOADING_FAILED) do(e:Args):
@ -173,6 +179,7 @@ proc init*(self: Controller) =
self.walletAccountService,
self.tokenService,
self.communityTokensService,
self.sharedUrlsService,
setActive = args.fromUserAction
)
@ -192,6 +199,7 @@ proc init*(self: Controller) =
self.walletAccountService,
self.tokenService,
self.communityTokensService,
self.sharedUrlsService,
setActive = args.fromUserAction
)
self.delegate.onFinaliseOwnershipStatusChanged(args.isPendingOwnershipRequest, args.community.id)
@ -217,6 +225,7 @@ proc init*(self: Controller) =
self.walletAccountService,
self.tokenService,
self.communityTokensService,
self.sharedUrlsService,
setActive = true
)
@ -238,6 +247,7 @@ proc init*(self: Controller) =
self.walletAccountService,
self.tokenService,
self.communityTokensService,
self.sharedUrlsService,
setActive = false
)
@ -277,9 +287,9 @@ proc init*(self: Controller) =
var args = ActiveSectionChatArgs(e)
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)
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):
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/community_tokens/service as community_tokens_service
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/core/eventemitter
@ -75,38 +76,40 @@ method communitySectionDidLoad*(self: AccessInterface) {.base.} =
raise newException(ValueError, "No implementation available")
method onChannelGroupsLoaded*(
self: AccessInterface,
channelGroups: seq[ChannelGroupDto],
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service)
{.base.} =
self: AccessInterface,
channelGroups: seq[ChannelGroupDto],
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
) {.base.} =
raise newException(ValueError, "No implementation available")
method onCommunityDataLoaded*(
self: AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service)
{.base.} =
self: AccessInterface,
events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
){.base.} =
raise newException(ValueError, "No implementation available")
method onChatsLoadingFailed*(self: AccessInterface) {.base.} =
@ -145,18 +148,20 @@ method communitySpectated*(self: AccessInterface, communityId: string) {.base.}
raise newException(ValueError, "No implementation available")
method communityJoined*(self: AccessInterface, community: CommunityDto, events: EventEmitter,
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
setActive: bool = false) {.base.} =
settingsService: settings_service.Service,
nodeConfigurationService: node_configuration_service.Service,
contactsService: contacts_service.Service,
chatService: chat_service.Service,
communityService: community_service.Service,
messageService: message_service.Service,
gifService: gif_service.Service,
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
setActive: bool = false,
) {.base.} =
raise newException(ValueError, "No implementation available")
method communityEdited*(self: AccessInterface, community: CommunityDto) {.base.} =
@ -260,7 +265,7 @@ method isConnected*(self: AccessInterface): bool {.base.} =
raise newException(ValueError, "No implementation available")
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")
method getVerificationRequestFrom*(self: AccessInterface, publicKey: string): VerificationRequest {.base.} =

View File

@ -75,10 +75,8 @@ import ../../core/custom_urls/urls_manager
export io_interface
const COMMUNITY_PERMISSION_ACCESS_ON_REQUEST = 3
const TOAST_MESSAGE_VISIBILITY_DURATION_IN_MS = 5000 # 5 seconds
const STATUS_URL_ENS_RESOLVE_REASON = "StatusUrl"
const MAX_MEMBERS_IN_GROUP_CHAT_WITHOUT_ADMIN = 19
type
SpectateRequest = object
@ -118,10 +116,12 @@ type
chatsLoaded: bool
communityDataLoaded: bool
pendingSpectateRequest: SpectateRequest
statusDeepLinkToActivate: string
# Forward declaration
method calculateProfileSectionHasNotification*[T](self: Module[T]): bool
proc switchToContactOrDisplayUserProfile[T](self: Module[T], publicKey: string)
method activateStatusDeepLink*[T](self: Module[T], statusDeepLink: string)
proc newModule*[T](
delegate: T,
@ -183,6 +183,7 @@ proc newModule*[T](
walletAccountService,
tokenService,
networkService,
sharedUrlsService,
)
result.moduleLoaded = false
result.chatsLoaded = false
@ -650,7 +651,8 @@ method onChannelGroupsLoaded*[T](
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
) =
self.chatsLoaded = true
if not self.communityDataLoaded:
@ -676,15 +678,15 @@ method onChannelGroupsLoaded*[T](
mailserversService,
walletAccountService,
tokenService,
communityTokensService
communityTokensService,
sharedUrlsService,
)
let channelGroupItem = self.createChannelGroupItem(channelGroup)
self.view.model().addItem(channelGroupItem)
if activeSectionId == channelGroupItem.id:
activeSection = channelGroupItem
self.channelGroupModules[channelGroup.id].load(channelGroup, events, settingsService, nodeConfigurationService,
contactsService, chatService, communityService, messageService, gifService, mailserversService)
self.channelGroupModules[channelGroup.id].load()
# Set active section if it is one of the channel sections
if not activeSection.isEmpty():
@ -694,6 +696,8 @@ method onChannelGroupsLoaded*[T](
self.view.model().removeItem(LOADING_SECTION_ID)
self.view.sectionsLoaded()
if self.statusDeepLinkToActivate != "":
self.activateStatusDeepLink(self.statusDeepLinkToActivate)
method onCommunityDataLoaded*[T](
self: Module[T],
@ -708,7 +712,8 @@ method onCommunityDataLoaded*[T](
mailserversService: mailservers_service.Service,
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service
communityTokensService: community_tokens_service.Service,
sharedUrlsService: urls_service.Service,
) =
self.communityDataLoaded = true
if not self.chatsLoaded:
@ -727,7 +732,8 @@ method onCommunityDataLoaded*[T](
mailserversService,
walletAccountService,
tokenService,
communityTokensService
communityTokensService,
sharedUrlsService,
)
method onChatsLoadingFailed*[T](self: Module[T]) =
@ -977,7 +983,8 @@ method communityJoined*[T](
walletAccountService: wallet_account_service.Service,
tokenService: token_service.Service,
communityTokensService: community_tokens_service.Service,
setActive: bool = false
sharedUrlsService: urls_service.Service,
setActive: bool = false,
) =
if self.channelGroupModules.contains(community.id):
# The community is already spectated
@ -1000,11 +1007,11 @@ method communityJoined*[T](
mailserversService,
walletAccountService,
tokenService,
communityTokensService
communityTokensService,
sharedUrlsService,
)
let channelGroup = community.toChannelGroupDto()
self.channelGroupModules[community.id].load(channelGroup, events, settingsService, nodeConfigurationService, contactsService,
chatService, communityService, messageService, gifService, mailserversService)
self.channelGroupModules[community.id].load()
let communitySectionItem = self.createChannelGroupItem(channelGroup)
if (firstCommunityJoined):
@ -1332,9 +1339,6 @@ method ephemeralNotificationClicked*[T](self: Module[T], id: int64) =
method onMyRequestAdded*[T](self: Module[T]) =
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) =
let contact = self.controller.getContact(publicKey)
@ -1344,7 +1348,7 @@ proc switchToContactOrDisplayUserProfile[T](self: Module[T], publicKey: string)
self.view.emitDisplayUserProfileSignal(publicKey)
method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, communityId: string, channelId: string,
url: string, userId: string) =
url: string, userId: string, shard: Shard) =
case action:
of StatusUrlAction.DisplayUserProfile:
@ -1360,7 +1364,7 @@ method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, commun
# request community info and then spectate
self.pendingSpectateRequest.communityId = communityId
self.pendingSpectateRequest.channelUuid = ""
self.communitiesModule.requestCommunityInfo(communityId, importing = false)
self.communitiesModule.requestCommunityInfo(communityId, shard, importing = false)
return
self.controller.switchTo(communityId, "", "")
@ -1372,7 +1376,7 @@ method onStatusUrlRequested*[T](self: Module[T], action: StatusUrlAction, commun
if item.isEmpty():
self.pendingSpectateRequest.communityId = communityId
self.pendingSpectateRequest.channelUuid = channelId
self.communitiesModule.requestCommunityInfo(communityId, importing = false)
self.communitiesModule.requestCommunityInfo(communityId, shard, importing = false)
return
self.controller.switchTo(communityId, chatId, "")
@ -1511,18 +1515,21 @@ method checkAndPerformProfileMigrationIfNeeded*[T](self: Module[T]) =
method activateStatusDeepLink*[T](self: Module[T], statusDeepLink: string) =
if not self.chatsLoaded:
self.statusDeepLinkToActivate = statusDeepLink
return
let urlData = self.sharedUrlsModule.parseSharedUrl(statusDeepLink)
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
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
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
let linkToActivate = self.urlsManager.convertExternalLinkToInternal(statusDeepLink)
self.urlsManager.onUrlActivated(linkToActivate)
method onDeactivateChatLoader*[T](self: Module[T], sectionId: string, chatId: string) =
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/wallet_account/service as wallet_account_service
import app_service/common/social_links
import app_service/common/types
import app_service/service/profile/dto/profile_showcase_preferences
@ -100,5 +101,5 @@ proc requestProfileShowcasePreferences*(self: Controller) =
proc requestProfileShowcaseForContact*(self: Controller, contactId: string) =
self.profileService.requestProfileShowcaseForContact(contactId)
proc requestCommunityInfo*(self: Controller, communityId: string) =
self.communityService.requestCommunityInfo(communityId)
proc requestCommunityInfo*(self: Controller, communityId: string, shard: Shard) =
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/profile/dto/profile_showcase
import app_service/service/profile/dto/profile_showcase_preferences
import app_service/common/types
import app_service/common/social_links
import app/modules/shared_models/social_links_model
@ -145,13 +146,13 @@ method updateProfileShowcase(self: Module, profileShowcase: ProfileShowcaseDto)
var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[]
var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[]
var profileCollectibleItems: seq[ProfileShowcaseCollectibleItem] = @[]
var profileAssetItems: seq[ProfileShowcaseAssetItem] = @[]
for communityEntry in profileShowcase.communities:
let community = self.controller.getCommunityById(communityEntry.communityId)
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(
communityEntry.communityId, ProfileShowcaseVisibility.ToEveryone, communityEntry.order))
else:
@ -186,15 +187,12 @@ method updateProfileShowcasePreferences(self: Module, preferences: ProfileShowca
var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[]
var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[]
var profileCollectibleItems: seq[ProfileShowcaseCollectibleItem] = @[]
var profileAssetItems: seq[ProfileShowcaseAssetItem] = @[]
for communityEntry in preferences.communities:
let community = self.controller.getCommunityById(communityEntry.communityId)
if community.id == "":
self.controller.requestCommunityInfo(communityEntry.communityId)
profileCommunityItems.add(initProfileShowcaseCommunityLoadingItem(
communityEntry.communityId, communityEntry.showcaseVisibility, communityEntry.order))
warn "Unknown community added to our own profile showcase" , communityId = communityEntry.communityId
else:
profileCommunityItems.add(initProfileShowcaseCommunityItem(
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 as delegate_interface

View File

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

View File

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

View File

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

View File

@ -76,14 +76,10 @@ type
InProgress,
Completed
type Shard* = object
type Shard* = ref object
cluster*: 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
type NewTokenType* {.pure.} = enum
Native = 0

View File

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

View File

@ -54,11 +54,13 @@ type
communityId: string
importing: bool
tryDatabase: bool
shardCluster: int
shardIndex: int
const asyncRequestCommunityInfoTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncRequestCommunityInfoTaskArg](argEncoded)
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(%* {
"communityId": arg.communityId,
"importing": arg.importing,

View File

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

View File

@ -1823,7 +1823,8 @@ QtObject:
)
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:
info "requestCommunityInfo: skipping as already requested", communityId
@ -1847,7 +1848,9 @@ QtObject:
slot: "asyncCommunityInfoLoaded",
communityId: communityId,
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)

View File

@ -11,6 +11,7 @@ type CommunityUrlDataDto* = object
color*: string
tagIndices*: seq[int]
communityId*: string
shard*: Shard
type CommunityChannelUrlDataDto* = object
emoji*: string
@ -29,6 +30,15 @@ type UrlDataDto* = object
channel*: CommunityChannelUrlDataDto
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 =
result = CommunityUrlDataDto()
discard jsonObj.getProp("displayName", result.displayName)
@ -42,6 +52,8 @@ proc toCommunityUrlDataDto*(jsonObj: JsonNode): CommunityUrlDataDto =
discard jsonObj.getProp("communityId", result.communityId)
result.shard = jsonObj.getShard()
proc toCommunityChannelUrlDataDto*(jsonObj: JsonNode): CommunityChannelUrlDataDto =
result = CommunityChannelUrlDataDto()
discard jsonObj.getProp("displayName", result.displayName)
@ -71,14 +83,19 @@ proc toUrlDataDto*(jsonObj: JsonNode): UrlDataDto =
if (jsonObj.getProp("contact", contactObj)):
result.contact = contactObj.toContactUrlDataDto()
proc `$`*(communityUrlDataDto: CommunityUrlDataDto): string =
proc toJsonNode*(communityUrlDataDto: CommunityUrlDataDto): JsonNode =
var jsonObj = newJObject()
jsonObj["displayName"] = %* communityUrlDataDto.displayName
jsonObj["description"] = %* communityUrlDataDto.description
jsonObj["membersCount"] = %* communityUrlDataDto.membersCount
jsonObj["color"] = %* communityUrlDataDto.color
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 =
var jsonObj = newJObject()

View File

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

View File

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

View File

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

View File

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

View File

@ -145,14 +145,6 @@ QtObject {
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() {
return aboutModuleInst.getCurrentVersion()
}

View File

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

View File

@ -45,7 +45,8 @@ Control {
const communityJson = root.store.getSectionByIdJson(communityId)
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
}