Skip to content

Commit

Permalink
feat(new-links): Parse url data and display
Browse files Browse the repository at this point in the history
Fixes: #10852
  • Loading branch information
borismelnik committed Jul 26, 2023
1 parent cfa1965 commit bc3abdc
Show file tree
Hide file tree
Showing 20 changed files with 418 additions and 28 deletions.
7 changes: 5 additions & 2 deletions src/app/boot/app_controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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/community_tokens/service as tokens_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/startup/module as startup_module
Expand Down Expand Up @@ -99,6 +100,7 @@ type
ensService: ens_service.Service
tokensService: tokens_service.Service
networkConnectionService: network_connection_service.Service
sharedUrlsService: shared_urls_service.Service

# Modules
startupModule: startup_module.AccessInterface
Expand Down Expand Up @@ -228,7 +230,7 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.transactionService, result.tokenService, result.settingsService, result.walletAccountService)
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.sharedUrlsService = shared_urls_service.newService(statusFoundation.events, statusFoundation.threadpool)
# Modules
result.startupModule = startup_module.newModule[AppController](
result,
Expand Down Expand Up @@ -277,7 +279,8 @@ proc newAppController*(statusFoundation: StatusFoundation): AppController =
result.networkService,
result.generalService,
result.keycardService,
result.networkConnectionService
result.networkConnectionService,
result.sharedUrlsService
)

# Do connections
Expand Down
2 changes: 1 addition & 1 deletion src/app/modules/main/controller.nim
Original file line number Diff line number Diff line change
Expand Up @@ -509,4 +509,4 @@ proc slowdownArchivesImport*(self:Controller) =
communityService.slowdownArchivesImport()

proc speedupArchivesImport*(self:Controller) =
communityService.speedupArchivesImport()
communityService.speedupArchivesImport()
21 changes: 20 additions & 1 deletion src/app/modules/main/module.nim
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import communities/module as communities_module
import node_section/module as node_section_module
import communities/tokens/models/token_item
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/keychain/service as keychain_service
Expand Down Expand Up @@ -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/general/service as general_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/common/types
import ../../../app_service/common/social_links
Expand Down Expand Up @@ -102,6 +105,7 @@ type
keycardSharedModule: keycard_shared_module.AccessInterface
keycardSharedModuleKeycardSyncPurpose: keycard_shared_module.AccessInterface
networkConnectionModule: network_connection_module.AccessInterface
sharedUrlsModule: shared_urls_module.AccessInterface
moduleLoaded: bool
chatsLoaded: bool
communityDataLoaded: bool
Expand Down Expand Up @@ -147,7 +151,8 @@ proc newModule*[T](
networkService: network_service.Service,
generalService: general_service.Service,
keycardService: keycard_service.Service,
networkConnectionService: network_connection_service.Service
networkConnectionService: network_connection_service.Service,
sharedUrlsService: urls_service.Service
): Module[T] =
result = Module[T]()
result.delegate = delegate
Expand Down Expand Up @@ -214,6 +219,7 @@ proc newModule*[T](
messageService)
result.nodeSectionModule = node_section_module.newModule(result, events, settingsService, nodeService, nodeConfigurationService)
result.networkConnectionModule = network_connection_module.newModule(result, events, networkConnectionService)
result.sharedUrlsModule = shared_urls_module.newModule(result, events, sharedUrlsService)

method delete*[T](self: Module[T]) =
self.controller.delete
Expand All @@ -233,6 +239,7 @@ method delete*[T](self: Module[T]) =
if not self.keycardSharedModuleKeycardSyncPurpose.isNil:
self.keycardSharedModuleKeycardSyncPurpose.delete
self.networkConnectionModule.delete
self.sharedUrlsModule.delete
self.view.delete
self.viewVariant.delete

Expand Down Expand Up @@ -521,6 +528,7 @@ method load*[T](
# Load wallet last as it triggers events that are listened by other modules
self.walletSectionModule.load()
self.networkConnectionModule.load()
self.sharedUrlsModule.load()

# Set active section on app start
# If section is empty or profile then open the loading section until chats are loaded
Expand Down Expand Up @@ -1245,6 +1253,16 @@ method onDisplayKeycardSharedModuleFlow*[T](self: Module[T]) =
self.view.emitDisplayKeycardSharedModuleFlow()

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)
self.urlsManager.onUrlActivated(linkToActivate)

Expand All @@ -1257,3 +1275,4 @@ method windowActivated*[T](self: Module[T]) =

method windowDeactivated*[T](self: Module[T]) =
self.controller.speedupArchivesImport()

40 changes: 40 additions & 0 deletions src/app/modules/main/shared_urls/controller.nim
Original file line number Diff line number Diff line change
@@ -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)
32 changes: 32 additions & 0 deletions src/app/modules/main/shared_urls/io_interface.nim
Original file line number Diff line number Diff line change
@@ -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()
65 changes: 65 additions & 0 deletions src/app/modules/main/shared_urls/module.nim
Original file line number Diff line number Diff line change
@@ -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
28 changes: 28 additions & 0 deletions src/app/modules/main/shared_urls/view.nim
Original file line number Diff line number Diff line change
@@ -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)
2 changes: 1 addition & 1 deletion src/app/modules/main/view.nim
Original file line number Diff line number Diff line change
Expand Up @@ -273,4 +273,4 @@ QtObject:

## Signals for in app (ephemeral) notifications
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.}
97 changes: 97 additions & 0 deletions src/app_service/service/shared_urls/dto/url_data.nim
Original file line number Diff line number Diff line change
@@ -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
Loading

0 comments on commit bc3abdc

Please sign in to comment.