feat(ProfileShowcase): Created first info popup

- Created `ProfileShowcaseInfoPopup` component.
- Added storybook support for the new popup component.
- Added new popup into the application flow.
- New property stored in local account settings file.

Closes #13338
This commit is contained in:
Noelia 2024-02-23 10:22:50 +01:00 committed by Noelia
parent 90f4e1477c
commit 3386ce74e7
10 changed files with 188 additions and 7 deletions

View File

@ -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

View File

@ -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")

View File

@ -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:

View File

@ -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()

View File

@ -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

View File

@ -15,8 +15,9 @@ 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
bottomPadding: Style.current.xlPadding
@ -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

View File

@ -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()
}
}
}

View File

@ -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

View File

@ -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()
}
}

View File

@ -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"
@ -219,7 +235,7 @@ SettingsContentBase {
addAccountsButtonVisible: root.profileStore.profileShowcaseAccountsModel.hiddenCount > 0
onShowcaseEntryChanged: priv.hasAnyProfileShowcaseChanges = true
onNavigateToAccountsTab: profileTabBar.currentIndex = 2
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
}
}
}
}