feat(Profile): Move profile showcase out of contact

This commit is contained in:
MishkaRogachev 2023-11-09 17:14:37 +04:00 committed by Jonathan Rainville
parent e2c3cebdb5
commit 4a4f1b8bf9
11 changed files with 98 additions and 40 deletions

View File

@ -13,6 +13,7 @@ import ../../../../app_service/service/devices/dto/[installation]
import ../../../../app_service/service/settings/dto/[settings] import ../../../../app_service/service/settings/dto/[settings]
import ../../../../app_service/service/saved_address/dto as saved_address_dto import ../../../../app_service/service/saved_address/dto as saved_address_dto
import ../../../../app_service/service/wallet_account/dto/[keypair_dto] import ../../../../app_service/service/wallet_account/dto/[keypair_dto]
import ../../../../app_service/service/profile/dto/[profile_showcase]
type MessageSignal* = ref object of Signal type MessageSignal* = ref object of Signal
bookmarks*: seq[BookmarkDto] bookmarks*: seq[BookmarkDto]
@ -38,6 +39,7 @@ type MessageSignal* = ref object of Signal
keypairs*: seq[KeypairDto] keypairs*: seq[KeypairDto]
watchOnlyAccounts*: seq[WalletAccountDto] watchOnlyAccounts*: seq[WalletAccountDto]
accountsPositions*: seq[WalletAccountDto] accountsPositions*: seq[WalletAccountDto]
updatedProfileShowcases*: seq[ProfileShowcaseDto]
type MessageDeliveredSignal* = ref object of Signal type MessageDeliveredSignal* = ref object of Signal
chatId*: string chatId*: string
@ -156,5 +158,9 @@ proc fromEvent*(T: type MessageSignal, event: JsonNode): MessageSignal =
for jsonAcc in e["accountsPositions"]: for jsonAcc in e["accountsPositions"]:
signal.accountsPositions.add(jsonAcc.toWalletAccountDto()) signal.accountsPositions.add(jsonAcc.toWalletAccountDto())
if e.contains("updatedProfileShowcases"):
for jsonProfileShowcase in e["updatedProfileShowcases"]:
signal.updatedProfileShowcases.add(jsonProfileShowcase.toProfileShowcaseDto())
result = signal result = signal

View File

@ -94,7 +94,7 @@ proc newModule*(delegate: delegate_interface.AccessInterface,
result.controller = controller.newController(result) result.controller = controller.newController(result)
result.moduleLoaded = false result.moduleLoaded = false
result.profileModule = profile_module.newModule(result, events, profileService, settingsService, communityService, walletAccountService, contactsService) result.profileModule = profile_module.newModule(result, events, profileService, settingsService, communityService, walletAccountService)
result.contactsModule = contacts_module.newModule(result, events, contactsService, chatService) result.contactsModule = contacts_module.newModule(result, events, contactsService, chatService)
result.languageModule = language_module.newModule(result, events, languageService) result.languageModule = language_module.newModule(result, events, languageService)
result.privacyModule = privacy_module.newModule(result, events, settingsService, keychainService, privacyService, generalService) result.privacyModule = privacy_module.newModule(result, events, settingsService, keychainService, privacyService, generalService)

View File

@ -7,7 +7,6 @@ import app_service/service/profile/service as profile_service
import app_service/service/settings/service as settings_service import app_service/service/settings/service as settings_service
import app_service/service/community/service as community_service import app_service/service/community/service as community_service
import app_service/service/wallet_account/service as wallet_account_service import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/contacts/service as contacts_service
import app_service/common/social_links import app_service/common/social_links
import app_service/service/profile/dto/profile_showcase_preferences import app_service/service/profile/dto/profile_showcase_preferences
@ -20,7 +19,6 @@ type
settingsService: settings_service.Service settingsService: settings_service.Service
communityService: community_service.Service communityService: community_service.Service
walletAccountService: wallet_account_service.Service walletAccountService: wallet_account_service.Service
contactsService: contacts_service.Service
proc newController*( proc newController*(
delegate: io_interface.AccessInterface, delegate: io_interface.AccessInterface,
@ -28,8 +26,7 @@ proc newController*(
profileService: profile_service.Service, profileService: profile_service.Service,
settingsService: settings_service.Service, settingsService: settings_service.Service,
communityService: community_service.Service, communityService: community_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service): Controller =
contactsService: contacts_service.Service): Controller =
result = Controller() result = Controller()
result.delegate = delegate result.delegate = delegate
result.events = events result.events = events
@ -37,7 +34,6 @@ proc newController*(
result.settingsService = settingsService result.settingsService = settingsService
result.communityService = communityService result.communityService = communityService
result.walletAccountService = walletAccountService result.walletAccountService = walletAccountService
result.contactsService = contactsService
proc delete*(self: Controller) = proc delete*(self: Controller) =
discard discard
@ -57,9 +53,9 @@ proc init*(self: Controller) =
let args = ProfileShowcasePreferencesArgs(e) let args = ProfileShowcasePreferencesArgs(e)
self.delegate.updateProfileShowcasePreferences(args.preferences) self.delegate.updateProfileShowcasePreferences(args.preferences)
self.events.on(SIGNAL_CONTACT_UPDATED) do(e: Args): self.events.on(SIGNAL_PROFILE_SHOWCASE_FOR_CONTACT_UPDATED) do(e: Args):
var args = ContactArgs(e) let args = ProfileShowcaseForContactArgs(e)
self.delegate.onContactDetailsUpdated(args.contactId) self.delegate.updateProfileShowcase(args.profileShowcase)
self.events.on(SIGNAL_COMMUNITIES_UPDATE) do(e: Args): self.events.on(SIGNAL_COMMUNITIES_UPDATE) do(e: Args):
let args = CommunitiesArgs(e) let args = CommunitiesArgs(e)
@ -86,9 +82,6 @@ proc getAccountByAddress*(self: Controller, address: string): WalletAccountDto =
proc getTokensByAddresses*(self: Controller, addresses: seq[string]): seq[WalletTokenDto] = proc getTokensByAddresses*(self: Controller, addresses: seq[string]): seq[WalletTokenDto] =
return self.walletAccountService.getTokensByAddresses(addresses) return self.walletAccountService.getTokensByAddresses(addresses)
proc getContactById*(self: Controller, id: string): ContactsDto =
return self.contactsService.getContactById(id)
proc setSocialLinks*(self: Controller, links: SocialLinks) = proc setSocialLinks*(self: Controller, links: SocialLinks) =
self.settingsService.setSocialLinks(links) self.settingsService.setSocialLinks(links)
@ -104,5 +97,8 @@ proc storeProfileShowcasePreferences*(self: Controller, preferences: ProfileShow
proc requestProfileShowcasePreferences*(self: Controller) = proc requestProfileShowcasePreferences*(self: Controller) =
self.profileService.requestProfileShowcasePreferences() self.profileService.requestProfileShowcasePreferences()
proc requestProfileShowcaseForContact*(self: Controller, contactId: string) =
self.profileService.requestProfileShowcaseForContact(contactId)
proc requestCommunityInfo*(self: Controller, communityId: string) = proc requestCommunityInfo*(self: Controller, communityId: string) =
self.communityService.requestCommunityInfo(communityId) self.communityService.requestCommunityInfo(communityId)

View File

@ -1,6 +1,7 @@
import NimQml import NimQml
import app_service/common/social_links import app_service/common/social_links
import app_service/service/profile/dto/profile_showcase
import app_service/service/profile/dto/profile_showcase_preferences import app_service/service/profile/dto/profile_showcase_preferences
import app_service/service/community/dto/community import app_service/service/community/dto/community
@ -62,6 +63,9 @@ method requestProfileShowcasePreferences*(self: AccessInterface) {.base.} =
method requestProfileShowcase*(self: AccessInterface, publicKey: string) {.base.} = method requestProfileShowcase*(self: AccessInterface, publicKey: string) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")
method updateProfileShowcase*(self: AccessInterface, profileShowcase: ProfileShowcaseDto) {.base.} =
raise newException(ValueError, "No implementation available")
method updateProfileShowcasePreferences*(self: AccessInterface, preferences: ProfileShowcasePreferencesDto) {.base.} = method updateProfileShowcasePreferences*(self: AccessInterface, preferences: ProfileShowcasePreferencesDto) {.base.} =
raise newException(ValueError, "No implementation available") raise newException(ValueError, "No implementation available")

View File

@ -9,7 +9,7 @@ import app_service/service/profile/service as profile_service
import app_service/service/settings/service as settings_service import app_service/service/settings/service as settings_service
import app_service/service/community/service as community_service import app_service/service/community/service as community_service
import app_service/service/wallet_account/service as wallet_account_service import app_service/service/wallet_account/service as wallet_account_service
import app_service/service/contacts/service as contacts_service import app_service/service/profile/dto/profile_showcase
import app_service/service/profile/dto/profile_showcase_preferences import app_service/service/profile/dto/profile_showcase_preferences
import app_service/common/social_links import app_service/common/social_links
@ -41,13 +41,12 @@ proc newModule*(
profileService: profile_service.Service, profileService: profile_service.Service,
settingsService: settings_service.Service, settingsService: settings_service.Service,
communityService: community_service.Service, communityService: community_service.Service,
walletAccountService: wallet_account_service.Service, walletAccountService: wallet_account_service.Service): Module =
contactsService: contacts_service.Service): Module =
result = Module() result = Module()
result.delegate = delegate result.delegate = delegate
result.view = view.newView(result) result.view = view.newView(result)
result.viewVariant = newQVariant(result.view) result.viewVariant = newQVariant(result.view)
result.controller = controller.newController(result, events, profileService, settingsService, communityService, walletAccountService, contactsService) result.controller = controller.newController(result, events, profileService, settingsService, communityService, walletAccountService)
result.moduleLoaded = false result.moduleLoaded = false
method delete*(self: Module) = method delete*(self: Module) =
@ -138,14 +137,18 @@ method requestProfileShowcase*(self: Module, publicKey: string) =
self.view.clearModels() self.view.clearModels()
self.presentedPublicKey = publicKey self.presentedPublicKey = publicKey
let contact = self.controller.getContactById(publicKey) self.controller.requestProfileShowcaseForContact(publicKey)
method updateProfileShowcase(self: Module, profileShowcase: ProfileShowcaseDto) =
if self.presentedPublicKey != profileShowcase.contactId:
return
var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[] var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[]
var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[] var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[]
var profileCollectibleItems: seq[ProfileShowcaseCollectibleItem] = @[] var profileCollectibleItems: seq[ProfileShowcaseCollectibleItem] = @[]
var profileAssetItems: seq[ProfileShowcaseAssetItem] = @[] var profileAssetItems: seq[ProfileShowcaseAssetItem] = @[]
for communityEntry in contact.profileShowcase.communities: for communityEntry in profileShowcase.communities:
let community = self.controller.getCommunityById(communityEntry.communityId) let community = self.controller.getCommunityById(communityEntry.communityId)
if community.id == "": if community.id == "":
self.controller.requestCommunityInfo(communityEntry.communityId) self.controller.requestCommunityInfo(communityEntry.communityId)
@ -157,7 +160,7 @@ method requestProfileShowcase*(self: Module, publicKey: string) =
self.view.updateProfileShowcaseCommunities(profileCommunityItems) self.view.updateProfileShowcaseCommunities(profileCommunityItems)
var addresses: seq[string] = @[] var addresses: seq[string] = @[]
for account in contact.profileShowcase.accounts: for account in profileShowcase.accounts:
profileAccountItems.add(initProfileShowcaseAccountItem( profileAccountItems.add(initProfileShowcaseAccountItem(
account.address, account.address,
account.name, account.name,
@ -168,7 +171,7 @@ method requestProfileShowcase*(self: Module, publicKey: string) =
)) ))
addresses.add(account.address) addresses.add(account.address)
for assetEntry in contact.profileShowcase.assets: for assetEntry in profileShowcase.assets:
for token in self.controller.getTokensByAddresses(addresses): for token in self.controller.getTokensByAddresses(addresses):
if assetEntry.symbol == token.symbol: if assetEntry.symbol == token.symbol:
profileAssetItems.add(initProfileShowcaseAssetItem(token, ProfileShowcaseVisibility.ToEveryone, assetEntry.order)) profileAssetItems.add(initProfileShowcaseAssetItem(token, ProfileShowcaseVisibility.ToEveryone, assetEntry.order))
@ -178,6 +181,9 @@ method requestProfileShowcase*(self: Module, publicKey: string) =
# TODO: collectibles, need wallet api to fetch collectible by uid # TODO: collectibles, need wallet api to fetch collectible by uid
method updateProfileShowcasePreferences(self: Module, preferences: ProfileShowcasePreferencesDto) = method updateProfileShowcasePreferences(self: Module, preferences: ProfileShowcasePreferencesDto) =
if self.presentedPublicKey != singletonInstance.userProfile.getPubKey():
return
var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[] var profileCommunityItems: seq[ProfileShowcaseCommunityItem] = @[]
var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[] var profileAccountItems: seq[ProfileShowcaseAccountItem] = @[]
var profileCollectibleItems: seq[ProfileShowcaseCollectibleItem] = @[] var profileCollectibleItems: seq[ProfileShowcaseCollectibleItem] = @[]
@ -215,10 +221,6 @@ method updateProfileShowcasePreferences(self: Module, preferences: ProfileShowca
self.view.updateProfileShowcaseAssets(profileAssetItems) self.view.updateProfileShowcaseAssets(profileAssetItems)
# TODO: collectibles, need wallet api to fetch collectible by uid # TODO: collectibles, need wallet api to fetch collectible by uid
method onContactDetailsUpdated*(self: Module, contactId: string) =
if self.presentedPublicKey == contactId:
self.requestProfileShowcase(contactId)
method onCommunitiesUpdated*(self: Module, communities: seq[CommunityDto]) = method onCommunitiesUpdated*(self: Module, communities: seq[CommunityDto]) =
var profileCommunityItems = self.view.getProfileShowcaseCommunities() var profileCommunityItems = self.view.getProfileShowcaseCommunities()

View File

@ -2,7 +2,6 @@
import json, strformat, strutils import json, strformat, strutils
import ../../../common/social_links import ../../../common/social_links
import ./contact_profile
include ../../../common/json_utils include ../../../common/json_utils
include ../../../common/utils include ../../../common/utils
@ -54,7 +53,6 @@ type ContactsDto* = object
localNickname*: string localNickname*: string
bio*: string bio*: string
socialLinks*: SocialLinks socialLinks*: SocialLinks
profileShowcase*: ProfileShowcase
image*: Images image*: Images
added*: bool added*: bool
blocked*: bool blocked*: bool
@ -169,10 +167,6 @@ proc toContactsDto*(jsonObj: JsonNode): ContactsDto =
if(jsonObj.getProp("socialLinks", socialLinksObj)): if(jsonObj.getProp("socialLinks", socialLinksObj)):
result.socialLinks = toSocialLinks(socialLinksObj) result.socialLinks = toSocialLinks(socialLinksObj)
var profileShowcaseObj: JsonNode
if(jsonObj.getProp("profileShowcase", profileShowcaseObj)):
result.profileShowcase = toProfileShowcase(profileShowcaseObj)
discard jsonObj.getProp("added", result.added) discard jsonObj.getProp("added", result.added)
discard jsonObj.getProp("blocked", result.blocked) discard jsonObj.getProp("blocked", result.blocked)
discard jsonObj.getProp("hasAddedUs", result.hasAddedUs) discard jsonObj.getProp("hasAddedUs", result.hasAddedUs)

View File

@ -17,3 +17,22 @@ const asyncGetProfileShowcasePreferencesTask: Task = proc(argEncoded: string) {.
arg.finish(%* { arg.finish(%* {
"error": e.msg, "error": e.msg,
}) })
type
AsyncGetProfileShowcaseForContactTaskArg = ref object of QObjectTaskArg
pubkey: string
const asyncGetProfileShowcaseForContactTask: Task = proc(argEncoded: string) {.gcsafe, nimcall.} =
let arg = decode[AsyncGetProfileShowcaseForContactTaskArg](argEncoded)
try:
let response = status_accounts.getProfileShowcaseForContact(arg.pubkey)
arg.finish(%* {
"publicKey": arg.pubkey,
"response": response,
"error": nil,
})
except Exception as e:
arg.finish(%* {
"publicKey": arg.pubkey,
"error": e.msg,
})

View File

@ -21,7 +21,8 @@ type ProfileShowcaseAsset* = ref object of RootObj
symbol*: string symbol*: string
order*: int order*: int
type ProfileShowcase* = ref object of RootObj type ProfileShowcaseDto* = ref object of RootObj
contactId*: string
communities*: seq[ProfileShowcaseCommunity] communities*: seq[ProfileShowcaseCommunity]
accounts*: seq[ProfileShowcaseAccount] accounts*: seq[ProfileShowcaseAccount]
collectibles*: seq[ProfileShowcaseCollectible] collectibles*: seq[ProfileShowcaseCollectible]
@ -50,8 +51,10 @@ proc toProfileShowcaseAsset*(jsonObj: JsonNode): ProfileShowcaseAsset =
discard jsonObj.getProp("symbol", result.symbol) discard jsonObj.getProp("symbol", result.symbol)
discard jsonObj.getProp("order", result.order) discard jsonObj.getProp("order", result.order)
proc toProfileShowcase*(jsonObj: JsonNode): ProfileShowcase = proc toProfileShowcaseDto*(jsonObj: JsonNode): ProfileShowcaseDto =
result = ProfileShowcase() result = ProfileShowcaseDto()
discard jsonObj.getProp("contactId", result.contactId)
for jsonMsg in jsonObj["communities"]: for jsonMsg in jsonObj["communities"]:
result.communities.add(jsonMsg.toProfileShowcaseCommunity()) result.communities.add(jsonMsg.toProfileShowcaseCommunity())

View File

@ -10,6 +10,7 @@ import ../../../app/core/tasks/[qt, threadpool]
import ../../../backend/accounts as status_accounts import ../../../backend/accounts as status_accounts
import ../accounts/dto/accounts import ../accounts/dto/accounts
import dto/profile_showcase
import dto/profile_showcase_preferences import dto/profile_showcase_preferences
include async_tasks include async_tasks
@ -21,8 +22,12 @@ type
ProfileShowcasePreferencesArgs* = ref object of Args ProfileShowcasePreferencesArgs* = ref object of Args
preferences*: ProfileShowcasePreferencesDto preferences*: ProfileShowcasePreferencesDto
ProfileShowcaseForContactArgs* = ref object of Args
profileShowcase*: ProfileShowcaseDto
# Signals which may be emitted by this service: # Signals which may be emitted by this service:
const SIGNAL_PROFILE_SHOWCASE_PREFERENCES_UPDATED* = "profileShowcasePreferencesUpdated" const SIGNAL_PROFILE_SHOWCASE_PREFERENCES_UPDATED* = "profileShowcasePreferencesUpdated"
const SIGNAL_PROFILE_SHOWCASE_FOR_CONTACT_UPDATED* = "profileShowcaseForContactUpdated"
QtObject: QtObject:
type Service* = ref object of QObject type Service* = ref object of QObject
@ -45,6 +50,13 @@ QtObject:
let args = SettingsTextValueArgs(e) let args = SettingsTextValueArgs(e)
singletonInstance.userProfile.setDisplayName(args.value) singletonInstance.userProfile.setDisplayName(args.value)
self.events.on(SignalType.Message.event) do(e: Args):
let receivedData = MessageSignal(e)
if receivedData.updatedProfileShowcases.len > 0:
for profileShowcase in receivedData.updatedProfileShowcases:
self.events.emit(SIGNAL_PROFILE_SHOWCASE_FOR_CONTACT_UPDATED,
ProfileShowcaseForContactArgs(profileShowcase: profileShowcase))
proc storeIdentityImage*(self: Service, address: string, image: string, aX: int, aY: int, bX: int, bY: int): seq[Image] = proc storeIdentityImage*(self: Service, address: string, image: string, aX: int, aY: int, bX: int, bY: int): seq[Image] =
try: try:
let response = status_accounts.storeIdentityImage(address, image, aX, aY, bX, bY) let response = status_accounts.storeIdentityImage(address, image, aX, aY, bX, bY)
@ -93,15 +105,38 @@ QtObject:
except Exception as e: except Exception as e:
error "error: ", procName="setDisplayName", errName = e.name, errDesription = e.msg error "error: ", procName="setDisplayName", errName = e.name, errDesription = e.msg
proc requestProfileShowcaseForContact*(self: Service, contactId: string) =
let arg = AsyncGetProfileShowcaseForContactTaskArg(
pubkey: contactId,
tptr: cast[ByteAddress](asyncGetProfileShowcaseForContactTask),
vptr: cast[ByteAddress](self.vptr),
slot: "asyncProfileShowcaseForContactLoaded",
)
self.threadpool.start(arg)
proc asyncProfileShowcaseForContactLoaded*(self: Service, rpcResponse: string) {.slot.} =
try:
let rpcResponseObj = rpcResponse.parseJson
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":
error "Error requesting profile showcase preferences", msg = rpcResponseObj{"error"}
return
let profileShowcase = rpcResponseObj["response"]["result"].toProfileShowcaseDto()
self.events.emit(SIGNAL_PROFILE_SHOWCASE_FOR_CONTACT_UPDATED,
ProfileShowcaseForContactArgs(profileShowcase: profileShowcase))
except Exception as e:
error "Error requesting profile showcase for a contact", msg = e.msg
proc requestProfileShowcasePreferences*(self: Service) = proc requestProfileShowcasePreferences*(self: Service) =
let arg = QObjectTaskArg( let arg = QObjectTaskArg(
tptr: cast[ByteAddress](asyncGetProfileShowcasePreferencesTask), tptr: cast[ByteAddress](asyncGetProfileShowcasePreferencesTask),
vptr: cast[ByteAddress](self.vptr), vptr: cast[ByteAddress](self.vptr),
slot: "asyncProfileShowcaseLoaded", slot: "asyncProfileShowcasePreferencesLoaded",
) )
self.threadpool.start(arg) self.threadpool.start(arg)
proc asyncProfileShowcaseLoaded*(self: Service, rpcResponse: string) {.slot.} = proc asyncProfileShowcasePreferencesLoaded*(self: Service, rpcResponse: string) {.slot.} =
try: try:
let rpcResponseObj = rpcResponse.parseJson let rpcResponseObj = rpcResponse.parseJson
if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "": if rpcResponseObj{"error"}.kind != JNull and rpcResponseObj{"error"}.getStr != "":

View File

@ -474,6 +474,10 @@ proc verifyKeystoreFileForAccount*(address, password: string): RpcResponse[JsonN
let payload = %* [address, password] let payload = %* [address, password]
return core.callPrivateRPC("accounts_verifyKeystoreFileForAccount", payload) return core.callPrivateRPC("accounts_verifyKeystoreFileForAccount", payload)
proc getProfileShowcaseForContact*(contactId: string): RpcResponse[JsonNode] {.raises: [Exception].} =
let payload = %* [contactId]
result = callPrivateRPC("getProfileShowcaseForContact".prefix, payload)
proc getProfileShowcasePreferences*(): RpcResponse[JsonNode] {.raises: [Exception].} = proc getProfileShowcasePreferences*(): RpcResponse[JsonNode] {.raises: [Exception].} =
result = callPrivateRPC("getProfileShowcasePreferences".prefix, %*[]) result = callPrivateRPC("getProfileShowcasePreferences".prefix, %*[])

View File

@ -217,11 +217,6 @@ Control {
} }
} }
] ]
onClicked: {
if (root.readOnly)
return
root.walletStore.setFilterAddress(model.address)
}
} }
} }
} }