diff --git a/src/app/global/local_account_settings.nim b/src/app/global/local_account_settings.nim index faef2705df..53da7b1442 100644 --- a/src/app/global/local_account_settings.nim +++ b/src/app/global/local_account_settings.nim @@ -5,6 +5,8 @@ import ../../constants # Local Account Settings keys: const LS_KEY_STORE_TO_KEYCHAIN* = "storeToKeychain" const DEFAULT_STORE_TO_KEYCHAIN = "notNow" +const LS_KEY_IS_FIRST_SHOWCASE_INTERACTION* = "isFirstShowcaseInteraction" +const DEFAULT_IS_FIRST_SHOWCASE_INTERACTION = true # Local Account Settings values: const LS_VALUE_STORE* = "store" const LS_VALUE_NOT_NOW* = "notNow" @@ -71,3 +73,23 @@ QtObject: read = getStoreToKeychainValue write = setStoreToKeychainValue notify = storeToKeychainValueChanged + + proc isFirstShowcaseInteractionChanged*(self: LocalAccountSettings) {.signal.} + + proc getIsFirstShowcaseInteraction*(self: LocalAccountSettings): bool {.slot.} = + if self.settings.isNil: + return DEFAULT_IS_FIRST_SHOWCASE_INTERACTION + + self.settings.value(LS_KEY_IS_FIRST_SHOWCASE_INTERACTION, newQVariant(DEFAULT_IS_FIRST_SHOWCASE_INTERACTION)).boolVal + + proc setIsFirstShowcaseInteraction*(self: LocalAccountSettings, value: bool) = + if(self.settings.isNil): + return + + self.settings.setValue(LS_KEY_IS_FIRST_SHOWCASE_INTERACTION, newQVariant(value)) + self.isFirstShowcaseInteractionChanged() + + QtProperty[bool] isFirstShowcaseInteraction: + read = getIsFirstShowcaseInteraction + write = setIsFirstShowcaseInteraction + notify = isFirstShowcaseInteractionChanged \ No newline at end of file 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 2c6c428940..cd3c471b09 100644 --- a/src/app/modules/main/profile_section/profile/io_interface.nim +++ b/src/app/modules/main/profile_section/profile/io_interface.nim @@ -63,6 +63,9 @@ method storeProfileShowcasePreferences*(self: AccessInterface, method requestProfileShowcasePreferences*(self: AccessInterface) {.base.} = raise newException(ValueError, "No implementation available") +method setIsFirstShowcaseInteraction*(self: AccessInterface) {.base.} = + raise newException(ValueError, "No implementation available") + method requestProfileShowcase*(self: AccessInterface, publicKey: string) {.base.} = raise newException(ValueError, "No implementation available") diff --git a/src/app/modules/main/profile_section/profile/module.nim b/src/app/modules/main/profile_section/profile/module.nim index 926b8826d0..276ecda12e 100644 --- a/src/app/modules/main/profile_section/profile/module.nim +++ b/src/app/modules/main/profile_section/profile/module.nim @@ -157,6 +157,9 @@ method storeProfileShowcasePreferences(self: Module, revealedAddresses ) +method setIsFirstShowcaseInteraction(self: Module) = + singletonInstance.localAccountSettings.setIsFirstShowcaseInteraction(false) + method requestProfileShowcasePreferences(self: Module) = let myPublicKey = singletonInstance.userProfile.getPubKey() if self.presentedPublicKey != myPublicKey: diff --git a/src/app/modules/main/profile_section/profile/view.nim b/src/app/modules/main/profile_section/profile/view.nim index 29965f34c7..85f36968cc 100644 --- a/src/app/modules/main/profile_section/profile/view.nim +++ b/src/app/modules/main/profile_section/profile/view.nim @@ -224,6 +224,9 @@ QtObject: proc requestProfileShowcasePreferences(self: View) {.slot.} = self.delegate.requestProfileShowcasePreferences() + proc setIsFirstShowcaseInteraction(self: View) {.slot.} = + self.delegate.setIsFirstShowcaseInteraction() + proc getProfileShowcaseCommunities*(self: View): seq[ProfileShowcaseCommunityItem] = return self.profileShowcaseCommunitiesModel.items() diff --git a/storybook/pages/ProfileShowcaseInfoPopupPage.qml b/storybook/pages/ProfileShowcaseInfoPopupPage.qml new file mode 100644 index 0000000000..ee240b1f5a --- /dev/null +++ b/storybook/pages/ProfileShowcaseInfoPopupPage.qml @@ -0,0 +1,56 @@ +import QtQuick 2.14 +import QtQuick.Controls 2.14 +import QtQuick.Layouts 1.14 + +import Storybook 1.0 + +import AppLayouts.Profile.popups 1.0 + +import shared.popups 1.0 + + + +SplitView { + Logs { id: logs } + + SplitView { + orientation: Qt.Vertical + SplitView.fillWidth: true + + Item { + SplitView.fillWidth: true + SplitView.fillHeight: true + + PopupBackground { + anchors.fill: parent + } + + Button { + anchors.centerIn: parent + text: "Reopen" + + onClicked: dialog.open() + } + + ProfileShowcaseInfoPopup { + id: dialog + } + } + + LogsAndControlsPanel { + id: logsAndControlsPanel + + SplitView.minimumHeight: 100 + SplitView.preferredHeight: 150 + + logsView.logText: logs.logText + } + } + + Pane { + SplitView.minimumWidth: 300 + SplitView.preferredWidth: 300 + } +} + +// category: Popups diff --git a/ui/app/AppLayouts/Communities/panels/IntroPanel.qml b/ui/app/AppLayouts/Communities/panels/IntroPanel.qml index ee47b8bc68..759845e83c 100644 --- a/ui/app/AppLayouts/Communities/panels/IntroPanel.qml +++ b/ui/app/AppLayouts/Communities/panels/IntroPanel.qml @@ -15,10 +15,11 @@ Control { property alias subtitle: subtitleItem.text property alias checkersModel: checkersItems.model - readonly property int imageWidth: 256 - readonly property int imageHeigth: root.imageWidth + property int imageWidth: 256 + property int imageHeigth: root.imageWidth + property int imageBottomMargin: 0 - padding : Style.current.padding + padding: Style.current.padding bottomPadding: Style.current.xlPadding QtObject { @@ -46,6 +47,8 @@ Control { Layout.preferredWidth: root.imageWidth Layout.preferredHeight: root.imageHeigth Layout.alignment: Qt.AlignHCenter + Layout.bottomMargin: root.imageBottomMargin + fillMode: Image.PreserveAspectFit mipmap: true cache: false diff --git a/ui/app/AppLayouts/Profile/popups/ProfileShowcaseInfoPopup.qml b/ui/app/AppLayouts/Profile/popups/ProfileShowcaseInfoPopup.qml new file mode 100644 index 0000000000..0b5bce5bf5 --- /dev/null +++ b/ui/app/AppLayouts/Profile/popups/ProfileShowcaseInfoPopup.qml @@ -0,0 +1,61 @@ +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import StatusQ.Popups.Dialog 0.1 +import StatusQ.Controls 0.1 + +import AppLayouts.Communities.panels 1.0 + +import utils 1.0 + +StatusDialog { + id: root + + width: 480 // by design + padding: Style.current.padding + closePolicy: Popup.NoAutoClose + footer.visible: false + header: Item { + width: root.width + + StatusHeaderActions { + anchors { + top: parent.top + right: parent.right + margins: Style.current.smallPadding + } + closeButton.onClicked: root.close() + } + } + contentItem: ColumnLayout { + spacing: Style.current.padding + + IntroPanel { + Layout.fillWidth: true + + image: Style.png("onboarding/welcome") + imageWidth: 200 + imageBottomMargin: Style.current.padding + bottomPadding: 0 + padding: 0 + title: qsTr("Build your profile showcase") + subtitle: qsTr("Show visitors to your profile...") + background: Item {} + checkersModel: [ + qsTr("Communities you are a member of"), + qsTr("Assets and collectibles you hodl"), + qsTr("Accounts you own to make sending your funds easy"), + qsTr("Choose your level of privacy with visibility controls") + ] + } + + StatusButton { + Layout.alignment: Qt.AlignHCenter + Layout.bottomMargin: Style.current.bigPadding + + text: qsTr("Build your showcase") + onClicked: root.close() + } + } +} diff --git a/ui/app/AppLayouts/Profile/popups/qmldir b/ui/app/AppLayouts/Profile/popups/qmldir index 20e7b261a4..98340156cb 100644 --- a/ui/app/AppLayouts/Profile/popups/qmldir +++ b/ui/app/AppLayouts/Profile/popups/qmldir @@ -2,6 +2,7 @@ BackupSeedModal 1.0 BackupSeedModal.qml SetupSyncingPopup 1.0 SetupSyncingPopup.qml AddSocialLinkModal 1.0 AddSocialLinkModal.qml ModifySocialLinkModal 1.0 ModifySocialLinkModal.qml +ProfileShowcaseInfoPopup 1.0 ProfileShowcaseInfoPopup.qml RenameKeypairPopup 1.0 RenameKeypairPopup.qml RenameAccontModal 1.0 RenameAccontModal.qml RemoveKeypairPopup 1.0 RemoveKeypairPopup.qml diff --git a/ui/app/AppLayouts/Profile/stores/ProfileStore.qml b/ui/app/AppLayouts/Profile/stores/ProfileStore.qml index 9a8866f479..3222cba9be 100644 --- a/ui/app/AppLayouts/Profile/stores/ProfileStore.qml +++ b/ui/app/AppLayouts/Profile/stores/ProfileStore.qml @@ -35,6 +35,7 @@ QtObject { readonly property var profileShowcaseAccountsModel: profileModule.profileShowcaseAccountsModel readonly property var profileShowcaseCollectiblesModel: profileModule.profileShowcaseCollectiblesModel readonly property var profileShowcaseAssetsModel: profileModule.profileShowcaseAssetsModel + readonly property bool isFirstShowcaseInteraction: localAccountSettings.isFirstShowcaseInteraction onUserDeclinedBackupBannerChanged: { if (userDeclinedBackupBanner !== localAccountSensitiveSettings.userDeclinedBackupBanner) { @@ -107,4 +108,8 @@ QtObject { function requestProfileShowcase(publicKey) { root.profileModule.requestProfileShowcase(publicKey) } + + function setIsFirstShowcaseInteraction() { + root.profileModule.setIsFirstShowcaseInteraction() + } } diff --git a/ui/app/AppLayouts/Profile/views/MyProfileView.qml b/ui/app/AppLayouts/Profile/views/MyProfileView.qml index 21a4132400..319ff16621 100644 --- a/ui/app/AppLayouts/Profile/views/MyProfileView.qml +++ b/ui/app/AppLayouts/Profile/views/MyProfileView.qml @@ -43,6 +43,15 @@ SettingsContentBase { property url profileLargeImage: profileHeader.previewIcon } + enum TabIndex { + Identity = 0, + Communities = 1, + Accounts = 2, + Collectibles = 3, + Assets = 4, + Web = 5 + } + titleRowComponentLoader.sourceComponent: StatusButton { text: qsTr("Preview") onClicked: Global.openPopup(profilePreview) @@ -156,6 +165,13 @@ SettingsContentBase { height: contentHeight currentIndex: profileTabBar.currentIndex + onCurrentIndexChanged: { + if(root.profileStore.isFirstShowcaseInteraction && currentIndex !== MyProfileView.TabIndex.Identity) { + root.profileStore.setIsFirstShowcaseInteraction() + Global.openPopup(profileShowcaseInfoPopup) + } + } + // identity ColumnLayout { objectName: "myProfileSettingsView" @@ -216,10 +232,10 @@ SettingsContentBase { id: profileShowcaseCollectiblesPanel baseModel: root.profileStore.collectiblesModel showcaseModel: root.profileStore.profileShowcaseCollectiblesModel - addAccountsButtonVisible: root.profileStore.profileShowcaseAccountsModel.hiddenCount > 0 + addAccountsButtonVisible: root.profileStore.profileShowcaseAccountsModel.hiddenCount > 0 - onShowcaseEntryChanged: priv.hasAnyProfileShowcaseChanges = true - onNavigateToAccountsTab: profileTabBar.currentIndex = 2 + onShowcaseEntryChanged: priv.hasAnyProfileShowcaseChanges = true + onNavigateToAccountsTab: profileTabBar.currentIndex = MyProfileView.TabIndex.Accounts } // assets @@ -234,7 +250,7 @@ SettingsContentBase { } onShowcaseEntryChanged: priv.hasAnyProfileShowcaseChanges = true - onNavigateToAccountsTab: profileTabBar.currentIndex = 2 + onNavigateToAccountsTab: profileTabBar.currentIndex = MyProfileView.TabIndex.Accounts } // web @@ -253,5 +269,13 @@ SettingsContentBase { onClosed: destroy() } } + + Component { + id: profileShowcaseInfoPopup + + ProfileShowcaseInfoPopup { + destroyOnClose: true + } + } } }