From cd428678f7f61037eba77fe6e99566ec54ea2eab Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Tue, 2 Nov 2021 15:00:47 -0400 Subject: [PATCH] fix(profile): fix profile pic change and move it to new architecture Fixes #3997 --- .../profile_section/profile/controller.nim | 7 +++++ .../profile/controller_interface.nim | 7 +++++ .../profile_section/profile/io_interface.nim | 8 +++++ .../main/profile_section/profile/model.nim | 1 - .../main/profile_section/profile/module.nim | 10 ++++++- .../main/profile_section/profile/view.nim | 29 +++++++++++++++++++ src/app_service/service/profile/service.nim | 8 ++++- .../service/profile/service_interface.nim | 10 +++++++ .../Profile/popups/ChangeProfilePicModal.qml | 2 +- .../AppLayouts/Profile/stores/RootStore.qml | 6 ++-- 10 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/app/modules/main/profile_section/profile/controller.nim b/src/app/modules/main/profile_section/profile/controller.nim index 50d438612a..08d0eb62b0 100644 --- a/src/app/modules/main/profile_section/profile/controller.nim +++ b/src/app/modules/main/profile_section/profile/controller.nim @@ -4,6 +4,7 @@ import ../../../../../app_service/service/accounts/service as accounts_service import ../../../../../app_service/service/settings/service as settings_service import ./item as item +import status/types/identity_image export controller_interface @@ -59,3 +60,9 @@ method getProfile*[T](self: Controller[T]): item.Item = ) return item + +method storeIdentityImage*[T](self: Controller[T], address: string, image: string, aX: int, aY: int, bX: int, bY: int): identity_image.IdentityImage = + self.profileService.storeIdentityImage(address, image, aX, aY, bX, bY) + +method deleteIdentityImage*[T](self: Controller[T], address: string): string = + self.profileService.deleteIdentityImage(address) \ No newline at end of file diff --git a/src/app/modules/main/profile_section/profile/controller_interface.nim b/src/app/modules/main/profile_section/profile/controller_interface.nim index 25f6bc748b..18d424e868 100644 --- a/src/app/modules/main/profile_section/profile/controller_interface.nim +++ b/src/app/modules/main/profile_section/profile/controller_interface.nim @@ -1,5 +1,6 @@ import ../../../../../app_service/service/profile/service as profile_service import ./item +import status/types/identity_image type AccessInterface* {.pure inheritable.} = ref object of RootObj @@ -14,6 +15,12 @@ method init*(self: AccessInterface) {.base.} = method getProfile*(self: AccessInterface): Item {.base.} = raise newException(ValueError, "No implementation available") +method storeIdentityImage*(self: AccessInterface, address: string, image: string, aX: int, aY: int, bX: int, bY: int): identity_image.IdentityImage {.base.} = + raise newException(ValueError, "No implementation available") + +method deleteIdentityImage*(self: AccessInterface, address: string): string {.base.} = + raise newException(ValueError, "No implementation available") + type ## Abstract class (concept) which must be implemented by object/s used in this ## module. diff --git a/src/app/modules/main/profile_section/profile/io_interface.nim b/src/app/modules/main/profile_section/profile/io_interface.nim index c7ee22a658..73a398f9bb 100644 --- a/src/app/modules/main/profile_section/profile/io_interface.nim +++ b/src/app/modules/main/profile_section/profile/io_interface.nim @@ -1,3 +1,5 @@ +import status/types/identity_image + type AccessInterface* {.pure inheritable.} = ref object of RootObj ## Abstract class for any input/interaction with this module. @@ -11,6 +13,12 @@ method load*(self: AccessInterface) {.base.} = method isLoaded*(self: AccessInterface): bool {.base.} = raise newException(ValueError, "No implementation available") +method storeIdentityImage*(self: AccessInterface, address: string, image: string, aX: int, aY: int, bX: int, bY: int): identity_image.IdentityImage {.base.} = + raise newException(ValueError, "No implementation available") + +method deleteIdentityImage*(self: AccessInterface, address: string): string {.base.} = + raise newException(ValueError, "No implementation available") + type ## Abstract class (concept) which must be implemented by object/s used in this ## module. diff --git a/src/app/modules/main/profile_section/profile/model.nim b/src/app/modules/main/profile_section/profile/model.nim index 28897224a4..27992d7801 100644 --- a/src/app/modules/main/profile_section/profile/model.nim +++ b/src/app/modules/main/profile_section/profile/model.nim @@ -136,7 +136,6 @@ QtObject: proc hasIdentityImage*(self: Model): bool {.slot.} = result = (?.self.identityImage.thumbnail != "") - result = false QtProperty[bool] hasIdentityImage: read = hasIdentityImage diff --git a/src/app/modules/main/profile_section/profile/module.nim b/src/app/modules/main/profile_section/profile/module.nim index 80be3a05e8..0e995888f9 100644 --- a/src/app/modules/main/profile_section/profile/module.nim +++ b/src/app/modules/main/profile_section/profile/module.nim @@ -7,6 +7,8 @@ import ../../../../../app_service/service/profile/service as profile_service import ../../../../../app_service/service/accounts/service as accounts_service import ../../../../../app_service/service/settings/service as settings_service +import status/types/identity_image + export io_interface type @@ -21,7 +23,7 @@ proc newModule*[T](delegate: T, accountsService: accounts_service.ServiceInterfa result = Module[T]() result.delegate = delegate result.view = newView(result) - result.viewVariant = result.view.getModel + result.viewVariant = newQVariant(result.view) result.controller = controller.newController[Module[T]](result, accountsService, settingsService, profileService) result.moduleLoaded = false @@ -37,3 +39,9 @@ method load*[T](self: Module[T]) = method isLoaded*[T](self: Module[T]): bool = return self.moduleLoaded + +method storeIdentityImage*[T](self: Module[T], address: string, image: string, aX: int, aY: int, bX: int, bY: int): identity_image.IdentityImage = + self.controller.storeIdentityImage(address, image, aX, aY, bX, bY) + +method deleteIdentityImage*[T](self: Module[T], address: string): string = + self.controller.deleteIdentityImage(address) diff --git a/src/app/modules/main/profile_section/profile/view.nim b/src/app/modules/main/profile_section/profile/view.nim index 0c023b95de..bd6a003441 100644 --- a/src/app/modules/main/profile_section/profile/view.nim +++ b/src/app/modules/main/profile_section/profile/view.nim @@ -3,6 +3,9 @@ import NimQml import ./item import ./model import ./io_interface +import status/profile as status_profile +import status/status +import ../../../../utils/image_utils import status/types/[identity_image, profile] @@ -37,3 +40,29 @@ QtObject: proc setProfile*(self: View, profile: Item) = self.model.setProfile(profile) self.modelChanged() + + proc upload*(self: View, imageUrl: string, aX: int, aY: int, bX: int, bY: int): string {.slot.} = + var image = image_utils.formatImagePath(imageUrl) + # FIXME the function to get the file size is messed up + # var size = image_getFileSize(image) + # TODO find a way to i18n this (maybe send just a code and then QML sets the right string) + # return "Max file size is 20MB" + + try: + # TODO add crop tool for the image + let identityImage = self.delegate.storeIdentityImage(self.model.address, image, aX, aY, bX, bY) + # TODO use only one type + let identityImageConverted = item.IdentityImage( + thumbnail: identityImage.thumbnail, + large: identityImage.thumbnail + ) + self.model.setIdentityImage(identityImageConverted) + result = "" + except Exception as e: + echo "Error storing identity image", e.msg + result = "Error storing identity image: " & e.msg + + proc remove*(self: View): string {.slot.} = + result = self.delegate.deleteIdentityImage(self.model.address) + if (result == ""): + self.model.removeIdentityImage() diff --git a/src/app_service/service/profile/service.nim b/src/app_service/service/profile/service.nim index 00807689ef..21a5ddba1c 100644 --- a/src/app_service/service/profile/service.nim +++ b/src/app_service/service/profile/service.nim @@ -1,4 +1,5 @@ import json, sequtils, chronicles +import status/statusgo_backend/accounts import ./service_interface, ./dto @@ -35,4 +36,9 @@ method getProfile*(self: Service): Dto = hasIdentityImage: false, messagesFromContactsOnly: false ) - \ No newline at end of file + +method storeIdentityImage*(self: Service, address: string, image: string, aX: int, aY: int, bX: int, bY: int): IdentityImage = + storeIdentityImage(address, image, aX, aY, bX, bY) + +method deleteIdentityImage*(self: Service, address: string): string = + deleteIdentityImage(address) \ No newline at end of file diff --git a/src/app_service/service/profile/service_interface.nim b/src/app_service/service/profile/service_interface.nim index 8cd2fe6b52..52be249bdc 100644 --- a/src/app_service/service/profile/service_interface.nim +++ b/src/app_service/service/profile/service_interface.nim @@ -2,6 +2,10 @@ import dto export dto +import status/types/identity_image + +export IdentityImage + type ServiceInterface* {.pure inheritable.} = ref object of RootObj ## Abstract class for this service access. @@ -15,5 +19,11 @@ method init*(self: ServiceInterface) {.base.} = method getProfile*(self: ServiceInterface): Dto {.base.} = raise newException(ValueError, "No implementation available") +method storeIdentityImage*(self: ServiceInterface, address: string, image: string, aX: int, aY: int, bX: int, bY: int): IdentityImage {.base.} = + raise newException(ValueError, "No implementation available") + +method deleteIdentityImage*(self: ServiceInterface, address: string): string {.base.} = + raise newException(ValueError, "No implementation available") + # method getTokens*(self: ServiceInterface, chainId: int): seq[Dto] {.base.} = # raise newException(ValueError, "No implementation available") \ No newline at end of file diff --git a/ui/app/AppLayouts/Profile/popups/ChangeProfilePicModal.qml b/ui/app/AppLayouts/Profile/popups/ChangeProfilePicModal.qml index 479706f122..c4c6d8b067 100644 --- a/ui/app/AppLayouts/Profile/popups/ChangeProfilePicModal.qml +++ b/ui/app/AppLayouts/Profile/popups/ChangeProfilePicModal.qml @@ -19,7 +19,7 @@ ModalPopup { property url largeImage: "" property bool hasIdentityImage: false - signal cropFinished(var aX, var aY, var bX, var bY) + signal cropFinished(string selectedImage, var aX, var aY, var bX, var bY) signal removeImageButtonClicked() //% "Profile picture" diff --git a/ui/app/AppLayouts/Profile/stores/RootStore.qml b/ui/app/AppLayouts/Profile/stores/RootStore.qml index 327785aab2..922b241fd9 100644 --- a/ui/app/AppLayouts/Profile/stores/RootStore.qml +++ b/ui/app/AppLayouts/Profile/stores/RootStore.qml @@ -6,7 +6,7 @@ QtObject { property var profileModelInst: profileModel property var profileModuleInst: profileSectionModule - property var profile: profileModule + property var profile: profileModule.model property var contactsModuleInst: contactsModule property var aboutModuleInst: aboutModule property var languageModuleInst: languageModule @@ -178,11 +178,11 @@ QtObject { } function uploadImage(source, aX, aY, bX, bY) { - return profileModelInst.picture.upload(source, aX, aY, bX, bY) + return profileModule.upload(source, aX, aY, bX, bY) } function removeImage() { - return profileModelInst.picture.remove() + return profileModule.remove() } function lookupContact(value) {