parent
b9fbb7c50c
commit
43a5d7eeeb
|
@ -33,6 +33,7 @@ import ../../app_service/service/gif/service as gif_service
|
||||||
import ../../app_service/service/ens/service as ens_service
|
import ../../app_service/service/ens/service as ens_service
|
||||||
import ../../app_service/service/community_tokens/service as tokens_service
|
import ../../app_service/service/community_tokens/service as tokens_service
|
||||||
import ../../app_service/service/network_connection/service as network_connection_service
|
import ../../app_service/service/network_connection/service as network_connection_service
|
||||||
|
import ../../app_service/service/shared_urls/service as shared_urls_service
|
||||||
|
|
||||||
import ../modules/shared_modules/keycard_popup/module as keycard_shared_module
|
import ../modules/shared_modules/keycard_popup/module as keycard_shared_module
|
||||||
import ../modules/startup/module as startup_module
|
import ../modules/startup/module as startup_module
|
||||||
|
@ -99,6 +100,7 @@ type
|
||||||
ensService: ens_service.Service
|
ensService: ens_service.Service
|
||||||
tokensService: tokens_service.Service
|
tokensService: tokens_service.Service
|
||||||
networkConnectionService: network_connection_service.Service
|
networkConnectionService: network_connection_service.Service
|
||||||
|
sharedUrlsService: shared_urls_service.Service
|
||||||
|
|
||||||
# Modules
|
# Modules
|
||||||
startupModule: startup_module.AccessInterface
|
startupModule: startup_module.AccessInterface
|
||||||
|
@ -228,7 +230,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
result.transactionService, result.tokenService, result.settingsService, result.walletAccountService)
|
result.transactionService, result.tokenService, result.settingsService, result.walletAccountService)
|
||||||
result.providerService = provider_service.newService(statusFoundation.events, statusFoundation.threadpool, result.ensService)
|
result.providerService = provider_service.newService(statusFoundation.events, statusFoundation.threadpool, result.ensService)
|
||||||
result.networkConnectionService = network_connection_service.newService(statusFoundation.events, result.walletAccountService, result.networkService, result.nodeService)
|
result.networkConnectionService = network_connection_service.newService(statusFoundation.events, result.walletAccountService, result.networkService, result.nodeService)
|
||||||
|
result.sharedUrlsService = shared_urls_service.newService(statusFoundation.events, statusFoundation.threadpool)
|
||||||
# Modules
|
# Modules
|
||||||
result.startupModule = startup_module.newModule[AppController](
|
result.startupModule = startup_module.newModule[AppController](
|
||||||
result,
|
result,
|
||||||
|
@ -277,7 +279,8 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
|
||||||
result.networkService,
|
result.networkService,
|
||||||
result.generalService,
|
result.generalService,
|
||||||
result.keycardService,
|
result.keycardService,
|
||||||
result.networkConnectionService
|
result.networkConnectionService,
|
||||||
|
result.sharedUrlsService
|
||||||
)
|
)
|
||||||
|
|
||||||
# Do connections
|
# Do connections
|
||||||
|
|
|
@ -25,6 +25,8 @@ import communities/module as communities_module
|
||||||
import node_section/module as node_section_module
|
import node_section/module as node_section_module
|
||||||
import communities/tokens/models/token_item
|
import communities/tokens/models/token_item
|
||||||
import network_connection/module as network_connection_module
|
import network_connection/module as network_connection_module
|
||||||
|
import shared_urls/module as shared_urls_module
|
||||||
|
|
||||||
import ../../../app_service/service/contacts/dto/contacts
|
import ../../../app_service/service/contacts/dto/contacts
|
||||||
|
|
||||||
import ../../../app_service/service/keychain/service as keychain_service
|
import ../../../app_service/service/keychain/service as keychain_service
|
||||||
|
@ -59,6 +61,7 @@ import ../../../app_service/service/community_tokens/service as community_tokens
|
||||||
import ../../../app_service/service/network/service as network_service
|
import ../../../app_service/service/network/service as network_service
|
||||||
import ../../../app_service/service/general/service as general_service
|
import ../../../app_service/service/general/service as general_service
|
||||||
import ../../../app_service/service/keycard/service as keycard_service
|
import ../../../app_service/service/keycard/service as keycard_service
|
||||||
|
import ../../../app_service/service/shared_urls/service as urls_service
|
||||||
import ../../../app_service/service/network_connection/service as network_connection_service
|
import ../../../app_service/service/network_connection/service as network_connection_service
|
||||||
import ../../../app_service/common/types
|
import ../../../app_service/common/types
|
||||||
import ../../../app_service/common/social_links
|
import ../../../app_service/common/social_links
|
||||||
|
@ -102,6 +105,7 @@ type
|
||||||
keycardSharedModule: keycard_shared_module.AccessInterface
|
keycardSharedModule: keycard_shared_module.AccessInterface
|
||||||
keycardSharedModuleKeycardSyncPurpose: keycard_shared_module.AccessInterface
|
keycardSharedModuleKeycardSyncPurpose: keycard_shared_module.AccessInterface
|
||||||
networkConnectionModule: network_connection_module.AccessInterface
|
networkConnectionModule: network_connection_module.AccessInterface
|
||||||
|
sharedUrlsModule: shared_urls_module.AccessInterface
|
||||||
moduleLoaded: bool
|
moduleLoaded: bool
|
||||||
chatsLoaded: bool
|
chatsLoaded: bool
|
||||||
communityDataLoaded: bool
|
communityDataLoaded: bool
|
||||||
|
@ -147,7 +151,8 @@ proc newModule*[T](
|
||||||
networkService: network_service.Service,
|
networkService: network_service.Service,
|
||||||
generalService: general_service.Service,
|
generalService: general_service.Service,
|
||||||
keycardService: keycard_service.Service,
|
keycardService: keycard_service.Service,
|
||||||
networkConnectionService: network_connection_service.Service
|
networkConnectionService: network_connection_service.Service,
|
||||||
|
sharedUrlsService: urls_service.Service
|
||||||
): Module[T] =
|
): Module[T] =
|
||||||
result = Module[T]()
|
result = Module[T]()
|
||||||
result.delegate = delegate
|
result.delegate = delegate
|
||||||
|
@ -214,6 +219,7 @@ proc newModule*[T](
|
||||||
messageService)
|
messageService)
|
||||||
result.nodeSectionModule = node_section_module.newModule(result, events, settingsService, nodeService, nodeConfigurationService)
|
result.nodeSectionModule = node_section_module.newModule(result, events, settingsService, nodeService, nodeConfigurationService)
|
||||||
result.networkConnectionModule = network_connection_module.newModule(result, events, networkConnectionService)
|
result.networkConnectionModule = network_connection_module.newModule(result, events, networkConnectionService)
|
||||||
|
result.sharedUrlsModule = shared_urls_module.newModule(result, events, sharedUrlsService)
|
||||||
|
|
||||||
method delete*[T](self: Module[T]) =
|
method delete*[T](self: Module[T]) =
|
||||||
self.controller.delete
|
self.controller.delete
|
||||||
|
@ -233,6 +239,7 @@ method delete*[T](self: Module[T]) =
|
||||||
if not self.keycardSharedModuleKeycardSyncPurpose.isNil:
|
if not self.keycardSharedModuleKeycardSyncPurpose.isNil:
|
||||||
self.keycardSharedModuleKeycardSyncPurpose.delete
|
self.keycardSharedModuleKeycardSyncPurpose.delete
|
||||||
self.networkConnectionModule.delete
|
self.networkConnectionModule.delete
|
||||||
|
self.sharedUrlsModule.delete
|
||||||
self.view.delete
|
self.view.delete
|
||||||
self.viewVariant.delete
|
self.viewVariant.delete
|
||||||
|
|
||||||
|
@ -521,6 +528,7 @@ method load*[T](
|
||||||
# Load wallet last as it triggers events that are listened by other modules
|
# Load wallet last as it triggers events that are listened by other modules
|
||||||
self.walletSectionModule.load()
|
self.walletSectionModule.load()
|
||||||
self.networkConnectionModule.load()
|
self.networkConnectionModule.load()
|
||||||
|
self.sharedUrlsModule.load()
|
||||||
|
|
||||||
# Set active section on app start
|
# Set active section on app start
|
||||||
# If section is empty or profile then open the loading section until chats are loaded
|
# If section is empty or profile then open the loading section until chats are loaded
|
||||||
|
@ -1250,6 +1258,16 @@ method onDisplayKeycardSharedModuleFlow*[T](self: Module[T]) =
|
||||||
self.view.emitDisplayKeycardSharedModuleFlow()
|
self.view.emitDisplayKeycardSharedModuleFlow()
|
||||||
|
|
||||||
method activateStatusDeepLink*[T](self: Module[T], statusDeepLink: string) =
|
method activateStatusDeepLink*[T](self: Module[T], statusDeepLink: string) =
|
||||||
|
let urlData = self.sharedUrlsModule.parseSharedUrl(statusDeepLink)
|
||||||
|
if urlData.community.communityId != "":
|
||||||
|
self.onStatusUrlRequested(StatusUrlAction.OpenCommunity, urlData.community.communityId, "", "", "")
|
||||||
|
return
|
||||||
|
if urlData.contact.publicKey != "":
|
||||||
|
self.onStatusUrlRequested(StatusUrlAction.DisplayUserProfile, "", "", "", urlData.contact.publicKey)
|
||||||
|
return
|
||||||
|
if urlData.channel.uuid != "":
|
||||||
|
self.onStatusUrlRequested(StatusUrlAction.OpenCommunityChannel, "", urlData.channel.uuid, "", "")
|
||||||
|
return
|
||||||
let linkToActivate = self.urlsManager.convertExternalLinkToInternal(statusDeepLink)
|
let linkToActivate = self.urlsManager.convertExternalLinkToInternal(statusDeepLink)
|
||||||
self.urlsManager.onUrlActivated(linkToActivate)
|
self.urlsManager.onUrlActivated(linkToActivate)
|
||||||
|
|
||||||
|
@ -1262,3 +1280,4 @@ method windowActivated*[T](self: Module[T]) =
|
||||||
|
|
||||||
method windowDeactivated*[T](self: Module[T]) =
|
method windowDeactivated*[T](self: Module[T]) =
|
||||||
self.controller.speedupArchivesImport()
|
self.controller.speedupArchivesImport()
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
import stint
|
||||||
|
import ./io_interface
|
||||||
|
|
||||||
|
import ../../../core/signals/types
|
||||||
|
import ../../../core/eventemitter
|
||||||
|
import ../../../../app_service/service/shared_urls/service as urls_service
|
||||||
|
|
||||||
|
type
|
||||||
|
Controller* = ref object of RootObj
|
||||||
|
delegate: io_interface.AccessInterface
|
||||||
|
events: EventEmitter
|
||||||
|
sharedUrlsService: urls_service.Service
|
||||||
|
|
||||||
|
proc newController*(
|
||||||
|
delegate: io_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
|
sharedUrlsService: urls_service.Service,
|
||||||
|
): Controller =
|
||||||
|
result = Controller()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.events = events
|
||||||
|
result.sharedUrlsService = sharedUrlsService
|
||||||
|
|
||||||
|
proc delete*(self: Controller) =
|
||||||
|
discard
|
||||||
|
|
||||||
|
proc parseCommunitySharedUrl*(self: Controller, url: string): CommunityUrlDataDto =
|
||||||
|
let data = self.sharedUrlsService.parseSharedUrl(url)
|
||||||
|
return data.community
|
||||||
|
|
||||||
|
proc parseCommunityChannelSharedUrl*(self: Controller, url: string): CommunityChannelUrlDataDto =
|
||||||
|
let data = self.sharedUrlsService.parseSharedUrl(url)
|
||||||
|
return data.channel
|
||||||
|
|
||||||
|
proc parseContactSharedUrl*(self: Controller, url: string): ContactUrlDataDto =
|
||||||
|
let data = self.sharedUrlsService.parseSharedUrl(url)
|
||||||
|
return data.contact
|
||||||
|
|
||||||
|
proc parseSharedUrl*(self: Controller, url: string): UrlDataDto =
|
||||||
|
return self.sharedUrlsService.parseSharedUrl(url)
|
|
@ -0,0 +1,32 @@
|
||||||
|
import NimQml, stint
|
||||||
|
|
||||||
|
import ../../../../app_service/service/shared_urls/service as urls_service
|
||||||
|
|
||||||
|
type
|
||||||
|
AccessInterface* {.pure inheritable.} = ref object of RootObj
|
||||||
|
|
||||||
|
method delete*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method load*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method viewDidLoad*(self: AccessInterface) {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method parseCommunitySharedUrl*(self: AccessInterface, url: string): string {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method parseCommunityChannelSharedUrl*(self: AccessInterface, url: string): string {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method parseContactSharedUrl*(self: AccessInterface, url: string): string {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
method parseSharedUrl*(self: AccessInterface, url: string): UrlDataDto {.base.} =
|
||||||
|
raise newException(ValueError, "No implementation available")
|
||||||
|
|
||||||
|
# This way (using concepts) is used only for the modules managed by AppController
|
||||||
|
type
|
||||||
|
DelegateInterface* = concept c
|
||||||
|
c.mainDidLoad()
|
|
@ -0,0 +1,65 @@
|
||||||
|
import NimQml, sequtils, stint
|
||||||
|
|
||||||
|
import io_interface, view, controller
|
||||||
|
import ../io_interface as delegate_interface
|
||||||
|
|
||||||
|
import ../../../../app_service/service/shared_urls/service as urls_service
|
||||||
|
|
||||||
|
import ../../../global/global_singleton
|
||||||
|
import ../../../core/eventemitter
|
||||||
|
|
||||||
|
export io_interface
|
||||||
|
|
||||||
|
type
|
||||||
|
Module* = ref object of io_interface.AccessInterface
|
||||||
|
delegate: delegate_interface.AccessInterface
|
||||||
|
controller: Controller
|
||||||
|
view: View
|
||||||
|
viewVariant: QVariant
|
||||||
|
moduleLoaded: bool
|
||||||
|
|
||||||
|
proc newModule*(
|
||||||
|
delegate: delegate_interface.AccessInterface,
|
||||||
|
events: EventEmitter,
|
||||||
|
sharedUrlsService: urls_service.Service,
|
||||||
|
): Module =
|
||||||
|
result = Module()
|
||||||
|
result.delegate = delegate
|
||||||
|
result.view = newView(result)
|
||||||
|
result.viewVariant = newQVariant(result.view)
|
||||||
|
result.controller = controller.newController(
|
||||||
|
result,
|
||||||
|
events,
|
||||||
|
sharedUrlsService,
|
||||||
|
)
|
||||||
|
result.moduleLoaded = false
|
||||||
|
|
||||||
|
method delete*(self: Module) =
|
||||||
|
self.view.delete
|
||||||
|
self.viewVariant.delete
|
||||||
|
self.controller.delete
|
||||||
|
|
||||||
|
method load*(self: Module) =
|
||||||
|
singletonInstance.engine.setRootContextProperty("sharedUrlsModule", self.viewVariant)
|
||||||
|
self.view.load()
|
||||||
|
|
||||||
|
method isLoaded*(self: Module): bool =
|
||||||
|
return self.moduleLoaded
|
||||||
|
|
||||||
|
method viewDidLoad*(self: Module) =
|
||||||
|
self.moduleLoaded = true
|
||||||
|
|
||||||
|
method parseSharedUrl*(self: Module, url: string): UrlDataDto =
|
||||||
|
return self.controller.parseSharedUrl(url)
|
||||||
|
|
||||||
|
method parseCommunitySharedUrl*(self: Module, url: string): string =
|
||||||
|
let communityData = self.controller.parseCommunitySharedUrl(url)
|
||||||
|
return $communityData
|
||||||
|
|
||||||
|
method parseCommunityChannelSharedUrl*(self: Module, url: string): string =
|
||||||
|
let channelData = self.controller.parseCommunityChannelSharedUrl(url)
|
||||||
|
return $channelData
|
||||||
|
|
||||||
|
method parseContactSharedUrl*(self: Module, url: string): string =
|
||||||
|
let contactData = self.controller.parseContactSharedUrl(url)
|
||||||
|
return $contactData
|
|
@ -0,0 +1,28 @@
|
||||||
|
import NimQml, json, strutils, sequtils
|
||||||
|
|
||||||
|
import ./io_interface
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type
|
||||||
|
View* = ref object of QObject
|
||||||
|
delegate: io_interface.AccessInterface
|
||||||
|
|
||||||
|
proc delete*(self: View) =
|
||||||
|
self.QObject.delete
|
||||||
|
|
||||||
|
proc newView*(delegate: io_interface.AccessInterface): View =
|
||||||
|
new(result, delete)
|
||||||
|
result.QObject.setup
|
||||||
|
result.delegate = delegate
|
||||||
|
|
||||||
|
proc load*(self: View) =
|
||||||
|
self.delegate.viewDidLoad()
|
||||||
|
|
||||||
|
proc parseCommunitySharedUrl*(self: View, url: string): string {.slot.} =
|
||||||
|
return self.delegate.parseCommunitySharedUrl(url)
|
||||||
|
|
||||||
|
proc parseCommunityChannelSharedUrl*(self: View, url: string): string {.slot.} =
|
||||||
|
return self.delegate.parseCommunityChannelSharedUrl(url)
|
||||||
|
|
||||||
|
proc parseContactSharedUrl*(self: View, url: string): string {.slot.} =
|
||||||
|
return self.delegate.parseContactSharedUrl(url)
|
|
@ -273,4 +273,4 @@ QtObject:
|
||||||
|
|
||||||
## Signals for in app (ephemeral) notifications
|
## Signals for in app (ephemeral) notifications
|
||||||
proc showToastAccountAdded*(self: View, name: string) {.signal.}
|
proc showToastAccountAdded*(self: View, name: string) {.signal.}
|
||||||
proc showToastKeypairRenamed*(self: View, oldName: string, newName: string) {.signal.}
|
proc showToastKeypairRenamed*(self: View, oldName: string, newName: string) {.signal.}
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
{.used.}
|
||||||
|
|
||||||
|
import json, strformat, strutils
|
||||||
|
|
||||||
|
include ../../../common/json_utils
|
||||||
|
|
||||||
|
type CommunityUrlDataDto* = object
|
||||||
|
displayName*: string
|
||||||
|
description*: string
|
||||||
|
membersCount*: int
|
||||||
|
color*: string
|
||||||
|
tagIndices*: seq[int]
|
||||||
|
communityId*: string
|
||||||
|
|
||||||
|
type CommunityChannelUrlDataDto* = object
|
||||||
|
emoji*: string
|
||||||
|
displayName*: string
|
||||||
|
description*: string
|
||||||
|
color*: string
|
||||||
|
uuid*: string
|
||||||
|
|
||||||
|
type ContactUrlDataDto* = object
|
||||||
|
displayName*: string
|
||||||
|
description*: string
|
||||||
|
publicKey*: string
|
||||||
|
|
||||||
|
type UrlDataDto* = object
|
||||||
|
community*: CommunityUrlDataDto
|
||||||
|
channel*: CommunityChannelUrlDataDto
|
||||||
|
contact*: ContactUrlDataDto
|
||||||
|
|
||||||
|
proc toCommunityUrlDataDto*(jsonObj: JsonNode): CommunityUrlDataDto =
|
||||||
|
result = CommunityUrlDataDto()
|
||||||
|
discard jsonObj.getProp("displayName", result.displayName)
|
||||||
|
discard jsonObj.getProp("description", result.description)
|
||||||
|
discard jsonObj.getProp("membersCount", result.membersCount)
|
||||||
|
discard jsonObj.getProp("color", result.color)
|
||||||
|
var tagIndicesObj: JsonNode
|
||||||
|
if (jsonObj.getProp("tagIndices", tagIndicesObj) and tagIndicesObj.kind == JArray):
|
||||||
|
for tagIndex in tagIndicesObj:
|
||||||
|
result.tagIndices.add(tagIndex.getInt)
|
||||||
|
|
||||||
|
discard jsonObj.getProp("communityId", result.communityId)
|
||||||
|
|
||||||
|
proc toCommunityChannelUrlDataDto*(jsonObj: JsonNode): CommunityChannelUrlDataDto =
|
||||||
|
result = CommunityChannelUrlDataDto()
|
||||||
|
discard jsonObj.getProp("displayName", result.displayName)
|
||||||
|
discard jsonObj.getProp("description", result.description)
|
||||||
|
discard jsonObj.getProp("emoji", result.emoji)
|
||||||
|
discard jsonObj.getProp("color", result.color)
|
||||||
|
discard jsonObj.getProp("uuid", result.uuid)
|
||||||
|
|
||||||
|
proc toContactUrlDataDto*(jsonObj: JsonNode): ContactUrlDataDto =
|
||||||
|
result = ContactUrlDataDto()
|
||||||
|
discard jsonObj.getProp("displayName", result.displayName)
|
||||||
|
discard jsonObj.getProp("description", result.description)
|
||||||
|
discard jsonObj.getProp("publicKey", result.publicKey)
|
||||||
|
|
||||||
|
proc toUrlDataDto*(jsonObj: JsonNode): UrlDataDto =
|
||||||
|
result = UrlDataDto()
|
||||||
|
|
||||||
|
var communityObj: JsonNode
|
||||||
|
if (jsonObj.getProp("community", communityObj)):
|
||||||
|
result.community = communityObj.toCommunityUrlDataDto()
|
||||||
|
|
||||||
|
var communityChannelObj: JsonNode
|
||||||
|
if (jsonObj.getProp("channel", communityChannelObj)):
|
||||||
|
result.channel = communityChannelObj.toCommunityChannelUrlDataDto()
|
||||||
|
|
||||||
|
var contactObj: JsonNode
|
||||||
|
if (jsonObj.getProp("contact", contactObj)):
|
||||||
|
result.contact = contactObj.toContactUrlDataDto()
|
||||||
|
|
||||||
|
proc `$`*(communityUrlDataDto: CommunityUrlDataDto): string =
|
||||||
|
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
|
||||||
|
|
||||||
|
proc `$`*(communityChannelUrlDataDto: CommunityChannelUrlDataDto): string =
|
||||||
|
var jsonObj = newJObject()
|
||||||
|
jsonObj["displayName"] = %* communityChannelUrlDataDto.displayName
|
||||||
|
jsonObj["description"] = %* communityChannelUrlDataDto.description
|
||||||
|
jsonObj["emoji"] = %* communityChannelUrlDataDto.emoji
|
||||||
|
jsonObj["color"] = %* communityChannelUrlDataDto.color
|
||||||
|
jsonObj["uuid"] = %* communityChannelUrlDataDto.uuid
|
||||||
|
return $jsonObj
|
||||||
|
|
||||||
|
proc `$`*(contactUrlDataDto: ContactUrlDataDto): string =
|
||||||
|
var jsonObj = newJObject()
|
||||||
|
jsonObj["displayName"] = %* contactUrlDataDto.displayName
|
||||||
|
jsonObj["description"] = %* contactUrlDataDto.description
|
||||||
|
jsonObj["publicKey"] = %* contactUrlDataDto.publicKey
|
||||||
|
return $jsonObj
|
|
@ -0,0 +1,34 @@
|
||||||
|
import NimQml, os, json, chronicles
|
||||||
|
|
||||||
|
import ../../../backend/general as status_general
|
||||||
|
import ../../../constants as app_constants
|
||||||
|
import ../../../app/core/eventemitter
|
||||||
|
import ../../../app/core/tasks/[qt, threadpool]
|
||||||
|
|
||||||
|
import ./dto/url_data as url_data_dto
|
||||||
|
|
||||||
|
export url_data_dto
|
||||||
|
|
||||||
|
logScope:
|
||||||
|
topics = "shared-urls-app-service"
|
||||||
|
|
||||||
|
QtObject:
|
||||||
|
type Service* = ref object of QObject
|
||||||
|
events: EventEmitter
|
||||||
|
threadpool: ThreadPool
|
||||||
|
|
||||||
|
proc newService*(events: EventEmitter, threadpool: ThreadPool): Service =
|
||||||
|
result = Service()
|
||||||
|
result.QObject.setup
|
||||||
|
result.events = events
|
||||||
|
|
||||||
|
proc parseSharedUrl*(self: Service, url: string): UrlDataDto =
|
||||||
|
try:
|
||||||
|
let response = status_general.parseSharedUrl(url)
|
||||||
|
if(response.result.contains("error")):
|
||||||
|
let errMsg = response.result["error"].getStr()
|
||||||
|
error "error while pasring shared url: ", errDesription = errMsg
|
||||||
|
return
|
||||||
|
return response.result.toUrlDataDto()
|
||||||
|
except Exception as e:
|
||||||
|
error "error while parsing shared url: ", msg = e.msg
|
|
@ -81,4 +81,7 @@ proc initKeystore*(keystoreDir: string): RpcResponse[JsonNode] {.raises: [Except
|
||||||
|
|
||||||
proc backupData*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
proc backupData*(): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
let payload = %* []
|
let payload = %* []
|
||||||
result = callPrivateRPC("backupData".prefix, payload)
|
result = callPrivateRPC("backupData".prefix, payload)
|
||||||
|
|
||||||
|
proc parseSharedUrl*(url: string): RpcResponse[JsonNode] {.raises: [Exception].} =
|
||||||
|
result = callPrivateRPC("parseSharedURL".prefix, %*[url])
|
|
@ -439,7 +439,7 @@ QtObject {
|
||||||
title: "Status",
|
title: "Status",
|
||||||
callback: null,
|
callback: null,
|
||||||
fetching: true,
|
fetching: true,
|
||||||
communityId: ""
|
communityData: null
|
||||||
}
|
}
|
||||||
|
|
||||||
// User profile
|
// User profile
|
||||||
|
@ -455,26 +455,28 @@ QtObject {
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
// Community
|
// Community
|
||||||
result.communityId = Utils.getCommunityIdFromShareLink(link)
|
result.communityData = Utils.getCommunityDataFromSharedLink(link)
|
||||||
if(!result.communityId) return result
|
if(!result.communityData) return result
|
||||||
|
|
||||||
const communityName = getSectionNameById(result.communityId)
|
const communityName = getSectionNameById(result.communityData.communityId)
|
||||||
if (!communityName) {
|
if (!communityName) {
|
||||||
// Unknown community, fetch the info if possible
|
// Unknown community, fetch the info if possible
|
||||||
root.requestCommunityInfo(result.communityId)
|
root.requestCommunityInfo(result.communityData.communityId)
|
||||||
|
|
||||||
|
result.title = qsTr("Join the %1 community").arg(result.communityData.displayName)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
result.title = qsTr("Join the %1 community").arg(communityName)
|
result.title = qsTr("Join the %1 community").arg(communityName)
|
||||||
result.fetching = false
|
result.fetching = false
|
||||||
result.callback = function () {
|
result.callback = function () {
|
||||||
const isUserMemberOfCommunity = isUserMemberOfCommunity(result.communityId)
|
const isUserMemberOfCommunity = isUserMemberOfCommunity(result.communityData.communityId)
|
||||||
if (isUserMemberOfCommunity) {
|
if (isUserMemberOfCommunity) {
|
||||||
setActiveCommunity(result.communityId)
|
setActiveCommunity(result.communityData.communityId)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
const userCanJoin = userCanJoin(result.communityId)
|
const userCanJoin = userCanJoin(result.communityData.communityId)
|
||||||
// TODO find what to do when you can't join
|
// TODO find what to do when you can't join
|
||||||
if (userCanJoin) {
|
if (userCanJoin) {
|
||||||
requestToJoinCommunityWithAuthentication(userProfileInst.preferredName) // FIXME what addresses to share?
|
requestToJoinCommunityWithAuthentication(userProfileInst.preferredName) // FIXME what addresses to share?
|
||||||
|
@ -493,7 +495,7 @@ QtObject {
|
||||||
return {
|
return {
|
||||||
site: Constants.externalStatusLinkWithHttps,
|
site: Constants.externalStatusLinkWithHttps,
|
||||||
title: result.title,
|
title: result.title,
|
||||||
communityId: result.communityId,
|
communityData: result.communityData,
|
||||||
fetching: result.fetching,
|
fetching: result.fetching,
|
||||||
thumbnailUrl: Style.png("status"),
|
thumbnailUrl: Style.png("status"),
|
||||||
contentType: "",
|
contentType: "",
|
||||||
|
|
|
@ -63,10 +63,17 @@ MembersSelectorBase {
|
||||||
property ListModel selectedMembers: ListModel {}
|
property ListModel selectedMembers: ListModel {}
|
||||||
|
|
||||||
function lookupContact(value) {
|
function lookupContact(value) {
|
||||||
|
let contactObj = Utils.parseContactUrl(value)
|
||||||
|
|
||||||
|
if (contactObj) {
|
||||||
|
processContact(contactObj)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
value = Utils.dropUserLinkPrefix(value.trim())
|
value = Utils.dropUserLinkPrefix(value.trim())
|
||||||
|
|
||||||
if (Utils.isChatKey(value)) {
|
if (Utils.isChatKey(value)) {
|
||||||
processContact(value)
|
processContact({publicKey: value})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,12 +85,19 @@ MembersSelectorBase {
|
||||||
root.suggestionsDialog.forceHide = false
|
root.suggestionsDialog.forceHide = false
|
||||||
}
|
}
|
||||||
|
|
||||||
function processContact(publicKey) {
|
function processContact(contactData) {
|
||||||
const contactDetails = Utils.getContactDetailsAsJson(publicKey, false)
|
// Open contact request if we have data from url
|
||||||
|
if (contactData.publicKey !== "" && contactData.displayName !== "") {
|
||||||
|
Global.openContactRequestPopupWithContactData(contactData,
|
||||||
|
popup => popup.closed.connect(root.rejected))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const contactDetails = Utils.getContactDetailsAsJson(contactData.publicKey, false)
|
||||||
if (contactDetails.publicKey === "") {
|
if (contactDetails.publicKey === "") {
|
||||||
// not a valid key given
|
// not a valid key given
|
||||||
root.suggestionsDialog.forceHide = false
|
root.suggestionsDialog.forceHide = false
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,6 +35,7 @@ QtObject {
|
||||||
Global.openIncomingIDRequestPopup.connect(openIncomingIDRequestPopup)
|
Global.openIncomingIDRequestPopup.connect(openIncomingIDRequestPopup)
|
||||||
Global.openInviteFriendsToCommunityPopup.connect(openInviteFriendsToCommunityPopup)
|
Global.openInviteFriendsToCommunityPopup.connect(openInviteFriendsToCommunityPopup)
|
||||||
Global.openContactRequestPopup.connect(openContactRequestPopup)
|
Global.openContactRequestPopup.connect(openContactRequestPopup)
|
||||||
|
Global.openContactRequestPopupWithContactData.connect(openContactRequestPopupWithContactData)
|
||||||
Global.openChooseBrowserPopup.connect(openChooseBrowserPopup)
|
Global.openChooseBrowserPopup.connect(openChooseBrowserPopup)
|
||||||
Global.openDownloadModalRequested.connect(openDownloadModal)
|
Global.openDownloadModalRequested.connect(openDownloadModal)
|
||||||
Global.openImagePopup.connect(openImagePopup)
|
Global.openImagePopup.connect(openImagePopup)
|
||||||
|
@ -195,6 +196,14 @@ QtObject {
|
||||||
openPopup(sendContactRequestPopupComponent, popupProperties, cb)
|
openPopup(sendContactRequestPopupComponent, popupProperties, cb)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function openContactRequestPopupWithContactData(contactData, cb) {
|
||||||
|
const popupProperties = {
|
||||||
|
userPublicKey: contactData.publicKey,
|
||||||
|
userDisplayName: contactData.displayName
|
||||||
|
}
|
||||||
|
openPopup(sendContactRequestPopupComponent, popupProperties, cb)
|
||||||
|
}
|
||||||
|
|
||||||
function openPinnedMessagesPopup(store, messageStore, pinnedMessagesModel, messageToPin, chatId) {
|
function openPinnedMessagesPopup(store, messageStore, pinnedMessagesModel, messageToPin, chatId) {
|
||||||
openPopup(pinnedMessagesPopup, {
|
openPopup(pinnedMessagesPopup, {
|
||||||
store: store,
|
store: store,
|
||||||
|
|
|
@ -35,6 +35,14 @@ StatusModal {
|
||||||
onAboutToShow: {
|
onAboutToShow: {
|
||||||
messageInput.input.edit.forceActiveFocus()
|
messageInput.input.edit.forceActiveFocus()
|
||||||
|
|
||||||
|
if (userDisplayName !== "" && userPublicKey !== "") {
|
||||||
|
d.updateContactDetails({
|
||||||
|
displayName: userDisplayName,
|
||||||
|
largeImage: "",
|
||||||
|
userIsEnsVerified: false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const contactDetails = Utils.getContactDetailsAsJson(userPublicKey, false)
|
const contactDetails = Utils.getContactDetailsAsJson(userPublicKey, false)
|
||||||
|
|
||||||
if (contactDetails.displayName !== "") {
|
if (contactDetails.displayName !== "") {
|
||||||
|
|
|
@ -21,17 +21,18 @@ Control {
|
||||||
property var store
|
property var store
|
||||||
property string communityId
|
property string communityId
|
||||||
property bool loading: false
|
property bool loading: false
|
||||||
|
property var communityData
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
||||||
property var invitedCommunity
|
property var invitedCommunity
|
||||||
|
|
||||||
readonly property string communityName: !!d.invitedCommunity ? d.invitedCommunity.name : ""
|
readonly property string communityName: !!d.invitedCommunity ? d.invitedCommunity.name : (communityData ? communityData.displayName : "")
|
||||||
readonly property string communityDescription: !!d.invitedCommunity ? d.invitedCommunity.description : ""
|
readonly property string communityDescription: !!d.invitedCommunity ? d.invitedCommunity.description : (communityData ? communityData.description : "")
|
||||||
readonly property string communityImage: !!d.invitedCommunity ? d.invitedCommunity.image : ""
|
readonly property string communityImage: !!d.invitedCommunity ? d.invitedCommunity.image : ""
|
||||||
readonly property string communityColor: !!d.invitedCommunity ? d.invitedCommunity.color : ""
|
readonly property string communityColor: !!d.invitedCommunity ? d.invitedCommunity.color : (communityData ? communityData.color : "")
|
||||||
readonly property int communityNbMembers: !!d.invitedCommunity ? d.invitedCommunity.nbMembers : 0
|
readonly property int communityNbMembers: !!d.invitedCommunity ? d.invitedCommunity.nbMembers : (communityData ? communityData.membersCount : 0)
|
||||||
readonly property bool communityVerified: false //!!d.invitedCommunity ? d.invitedCommunity.verified : false TODO: add this to the community object if we should support verified communities
|
readonly property bool communityVerified: false //!!d.invitedCommunity ? d.invitedCommunity.verified : false TODO: add this to the community object if we should support verified communities
|
||||||
readonly property bool communityJoined: !!d.invitedCommunity ? d.invitedCommunity.joined : false
|
readonly property bool communityJoined: !!d.invitedCommunity ? d.invitedCommunity.joined : false
|
||||||
readonly property bool communitySpectated: !!d.invitedCommunity ? d.invitedCommunity.spectated : false
|
readonly property bool communitySpectated: !!d.invitedCommunity ? d.invitedCommunity.spectated : false
|
||||||
|
@ -135,7 +136,7 @@ Control {
|
||||||
isImage: true
|
isImage: true
|
||||||
}
|
}
|
||||||
|
|
||||||
visible: !root.loading
|
visible: d.communityColor && d.communityName
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
@ -144,7 +145,7 @@ Control {
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: root.loading ? qsTr("Community data not loaded yet.") : d.communityName
|
text: d.communityName
|
||||||
font.weight: Font.Bold
|
font.weight: Font.Bold
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
font.pixelSize: 17
|
font.pixelSize: 17
|
||||||
|
@ -154,7 +155,7 @@ Control {
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: root.loading ? qsTr("Please wait for the unfurl to show") : d.communityDescription
|
text: d.communityDescription
|
||||||
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
}
|
}
|
||||||
|
@ -162,7 +163,7 @@ Control {
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
|
||||||
text: root.loading ? "" : qsTr("%n member(s)", "", d.communityNbMembers)
|
text: qsTr("%n member(s)", "", d.communityNbMembers)
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
color: Theme.palette.baseColor1
|
color: Theme.palette.baseColor1
|
||||||
|
@ -193,6 +194,7 @@ Control {
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
anchors.verticalCenterOffset: d.radius/2
|
anchors.verticalCenterOffset: d.radius/2
|
||||||
|
visible: !joinBtn.loading
|
||||||
font: joinBtn.font
|
font: joinBtn.font
|
||||||
color: joinBtn.enabled ? joinBtn.textColor : joinBtn.disabledTextColor
|
color: joinBtn.enabled ? joinBtn.textColor : joinBtn.disabledTextColor
|
||||||
text: qsTr("Go to Community")
|
text: qsTr("Go to Community")
|
||||||
|
|
|
@ -143,7 +143,8 @@ ColumnLayout {
|
||||||
property var invitationData: root.store.getLinkDataForStatusLinks(link)
|
property var invitationData: root.store.getLinkDataForStatusLinks(link)
|
||||||
|
|
||||||
store: root.store
|
store: root.store
|
||||||
communityId: invitationData ? invitationData.communityId : ""
|
communityId: invitationData && invitationData.communityData ? invitationData.communityData.communityId : ""
|
||||||
|
communityData: invitationData && invitationData.communityData ? invitationData.communityData : null
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
visible: !!invitationData
|
visible: !!invitationData
|
||||||
loading: invitationData.fetching
|
loading: invitationData.fetching
|
||||||
|
|
|
@ -39,6 +39,7 @@ QtObject {
|
||||||
signal openActivityCenterPopupRequested()
|
signal openActivityCenterPopupRequested()
|
||||||
signal openSendIDRequestPopup(string publicKey, var cb)
|
signal openSendIDRequestPopup(string publicKey, var cb)
|
||||||
signal openContactRequestPopup(string publicKey, var cb)
|
signal openContactRequestPopup(string publicKey, var cb)
|
||||||
|
signal openContactRequestPopupWithContactData(var contactData, var cb)
|
||||||
signal removeContactRequested(string displayName, string publicKey)
|
signal removeContactRequested(string displayName, string publicKey)
|
||||||
signal openInviteFriendsToCommunityPopup(var community, var communitySectionModule, var cb)
|
signal openInviteFriendsToCommunityPopup(var community, var communitySectionModule, var cb)
|
||||||
signal openIncomingIDRequestPopup(string publicKey, var cb)
|
signal openIncomingIDRequestPopup(string publicKey, var cb)
|
||||||
|
|
|
@ -10,6 +10,7 @@ import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
property var mainModuleInst: typeof mainModule !== "undefined" ? mainModule : null
|
property var mainModuleInst: typeof mainModule !== "undefined" ? mainModule : null
|
||||||
|
property var sharedUrlsModuleInst: typeof sharedUrlsModule !== "undefined" ? sharedUrlsModule : null
|
||||||
property var globalUtilsInst: typeof globalUtils !== "undefined" ? globalUtils : null
|
property var globalUtilsInst: typeof globalUtils !== "undefined" ? globalUtils : null
|
||||||
property var communitiesModuleInst: typeof communitiesModule !== "undefined" ? communitiesModule : null
|
property var communitiesModuleInst: typeof communitiesModule !== "undefined" ? communitiesModule : null
|
||||||
|
|
||||||
|
@ -515,6 +516,22 @@ QtObject {
|
||||||
return communityKey
|
return communityKey
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCommunityDataFromSharedLink(link) {
|
||||||
|
let index = link.lastIndexOf("/c/")
|
||||||
|
if (index === -1) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let communityDataString = sharedUrlsModuleInst.parseCommunitySharedUrl(link)
|
||||||
|
try {
|
||||||
|
let communityData = JSON.parse(communityDataString)
|
||||||
|
return communityData
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Error while parsing community data from url:", e.message)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
function changeCommunityKeyCompression(communityKey) {
|
function changeCommunityKeyCompression(communityKey) {
|
||||||
return globalUtilsInst.changeCommunityKeyCompression(communityKey)
|
return globalUtilsInst.changeCommunityKeyCompression(communityKey)
|
||||||
|
@ -669,6 +686,21 @@ QtObject {
|
||||||
return text
|
return text
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function parseContactUrl(link) {
|
||||||
|
let index = link.lastIndexOf("/u/")
|
||||||
|
if (index === -1) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
let contactDataString = sharedUrlsModuleInst.parseContactSharedUrl(link)
|
||||||
|
try {
|
||||||
|
let contactObj = JSON.parse(contactDataString)
|
||||||
|
return contactObj
|
||||||
|
} catch (e) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function dropCommunityLinkPrefix(text) {
|
function dropCommunityLinkPrefix(text) {
|
||||||
if (text.startsWith(Constants.communityLinkPrefix))
|
if (text.startsWith(Constants.communityLinkPrefix))
|
||||||
text = text.slice(Constants.communityLinkPrefix.length)
|
text = text.slice(Constants.communityLinkPrefix.length)
|
||||||
|
|
Loading…
Reference in New Issue