status-desktop/ui/app/AppLayouts/Profile/views/MyProfileView.qml

337 lines
12 KiB
QML
Raw Normal View History

import QtQuick 2.13
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.13
import QtQml 2.15
import utils 1.0
import shared 1.0
import shared.panels 1.0
import shared.popups 1.0
import shared.stores 1.0
import shared.controls.chat 1.0
import "../popups"
import "../stores"
2022-06-22 12:16:21 +00:00
import "../controls"
import "./profile"
import StatusQ.Core 0.1
import StatusQ.Core.Theme 0.1
import StatusQ.Core.Utils 0.1
import StatusQ.Components 0.1
import StatusQ.Controls 0.1
import AppLayouts.Profile.helpers 1.0
import AppLayouts.Profile.panels 1.0
import AppLayouts.Wallet.stores 1.0
SettingsContentBase {
id: root
2022-06-22 12:16:21 +00:00
property WalletStore walletStore
property ProfileStore profileStore
2022-06-22 12:16:21 +00:00
property PrivacyStore privacyStore
2022-09-27 21:26:26 +00:00
property ContactsStore contactsStore
property NetworkConnectionStore networkConnectionStore
required property WalletAssetsStore walletAssetsStore
required property CurrenciesStore currencyStore
property var communitiesModel
2022-06-22 12:16:21 +00:00
property bool sideBySidePreview
property QtObject dirtyValues: QtObject {
property string displayName: descriptionPanel.displayName.text
property string bio: descriptionPanel.bio.text
property url profileLargeImage: profileHeader.previewIcon
}
enum TabIndex {
Identity = 0,
Communities = 1,
Accounts = 2,
Collectibles = 3,
//Assets = 4,
Web = 4
}
titleRowComponentLoader.sourceComponent: StatusButton {
text: qsTr("Preview")
onClicked: Global.openPopup(profilePreview)
visible: !root.sideBySidePreview
2022-06-22 12:16:21 +00:00
}
dirty: priv.isIdentityTabDirty ||
priv.hasAnyProfileShowcaseChanges
saveChangesButtonEnabled: !!descriptionPanel.displayName.text && descriptionPanel.displayName.valid
2022-06-22 12:16:21 +00:00
toast.saveChangesTooltipText: saveChangesButtonEnabled ? "" : qsTr("Invalid changes made to Identity")
autoscrollWhenDirty: profileTabBar.currentIndex === MyProfileView.Identity
onResetChangesClicked: priv.reset()
onSaveChangesClicked: priv.save()
bottomHeaderComponents: StatusTabBar {
id: profileTabBar
StatusTabButton {
objectName: "identityTabButton"
width: implicitWidth
leftPadding: 0
text: qsTr("Identity")
}
StatusTabButton {
objectName: "communitiesTabButton"
width: implicitWidth
text: qsTr("Communities")
}
StatusTabButton {
objectName: "accountsTabButton"
width: implicitWidth
text: qsTr("Accounts")
}
StatusTabButton {
objectName: "collectiblesTabButton"
width: implicitWidth
text: qsTr("Collectibles")
}
// TODO: Uncomment when assets tab is implemented
// StatusTabButton {
// objectName: "assetsTabButton"
// width: implicitWidth
// text: qsTr("Assets")
// }
StatusTabButton {
objectName: "webTabButton"
width: implicitWidth
text: qsTr("Web")
}
}
onVisibleChanged: if (visible) profileStore.requestProfileShowcasePreferences()
Component.onCompleted: profileStore.requestProfileShowcasePreferences()
readonly property var priv: QtObject {
id: priv
property bool hasAnyProfileShowcaseChanges: showcaseModels.dirty
property bool isIdentityTabDirty: (!descriptionPanel.isEnsName &&
descriptionPanel.displayName.text !== profileStore.displayName) ||
descriptionPanel.bio.text !== profileStore.bio ||
profileStore.socialLinksDirty ||
profileHeader.icon !== profileStore.profileLargeImage
property ProfileShowcaseModels showcaseModels: ProfileShowcaseModels {
communitiesSourceModel: root.communitiesModel
communitiesShowcaseModel: root.profileStore.showcasePreferencesCommunitiesModel
communitiesSearcherText: profileShowcaseCommunitiesPanel.searcherText
accountsSourceModel: root.walletStore.ownAccounts
accountsShowcaseModel: root.profileStore.showcasePreferencesAccountsModel
accountsSearcherText: profileShowcaseAccountsPanel.searcherText
collectiblesSourceModel: root.profileStore.collectiblesModel
collectiblesShowcaseModel: root.profileStore.showcasePreferencesCollectiblesModel
collectiblesSearcherText: profileShowcaseCollectiblesPanel.searcherText
socialLinksSourceModel: root.profileStore.showcasePreferencesSocialLinksModel
}
function reset() {
descriptionPanel.displayName.text = Qt.binding(() => { return profileStore.displayName })
descriptionPanel.bio.text = Qt.binding(() => { return profileStore.bio })
profileStore.resetSocialLinks()
profileHeader.icon = Qt.binding(() => { return profileStore.profileLargeImage })
priv.showcaseModels.revert()
root.profileStore.requestProfileShowcasePreferences()
}
function save() {
// Accounts, Communities, Assets, Collectibles and social links info
if (hasAnyProfileShowcaseChanges) {
root.profileStore.saveProfileShowcasePreferences(showcaseModels.buildJSONModelsCurrentState())
}
// Identity info
if (isIdentityTabDirty) {
root.profileStore.saveIdentityInfo(descriptionPanel.displayName.text,
descriptionPanel.bio.text.trim(),
profileHeader.icon,
profileHeader.cropRect.x,
profileHeader.cropRect.y,
(profileHeader.cropRect.x + profileHeader.cropRect.width),
(profileHeader.cropRect.y + profileHeader.cropRect.height))
profileHeader.icon = Qt.binding(() => { return profileStore.profileLargeImage })
}
}
}
StackLayout {
id: stackLayout
width: root.contentWidth
height: profileTabBar.currentIndex === MyProfileView.Web ? implicitHeight : root.contentHeight
currentIndex: profileTabBar.currentIndex
onCurrentIndexChanged: {
if(root.profileStore.isFirstShowcaseInteraction && currentIndex !== MyProfileView.TabIndex.Identity) {
root.profileStore.setIsFirstShowcaseInteraction()
Global.openPopup(profileShowcaseInfoPopup)
}
}
// identity
ColumnLayout {
objectName: "myProfileSettingsView"
ProfileHeader {
id: profileHeader
Layout.fillWidth: true
Layout.leftMargin: Style.current.padding
Layout.rightMargin: Style.current.padding
store: root.profileStore
displayName: profileStore.name
pubkey: profileStore.pubkey
icon: profileStore.profileLargeImage
imageSize: ProfileHeader.ImageSize.Big
displayNameVisible: false
pubkeyVisible: false
emojiHashVisible: false
editImageButtonVisible: true
}
ProfileDescriptionPanel {
id: descriptionPanel
readonly property bool isEnsName: profileStore.preferredName
Layout.fillWidth: true
displayName.focus: !isEnsName
displayName.input.edit.readOnly: isEnsName
displayName.text: profileStore.name
displayName.validationMode: StatusInput.ValidationMode.Always
displayName.validators: isEnsName ? [] : Constants.validators.displayName
bio.text: profileStore.bio
}
}
// communities
ProfileShowcaseCommunitiesPanel {
id: profileShowcaseCommunitiesPanel
inShowcaseModel: priv.showcaseModels.communitiesVisibleModel
hiddenModel: priv.showcaseModels.communitiesHiddenModel
showcaseLimit: root.profileStore.getProfileShowcaseEntriesLimit()
onChangePositionRequested: function (from, to) {
priv.showcaseModels.changeCommunityPosition(from, to)
}
onSetVisibilityRequested: function (key, toVisibility) {
priv.showcaseModels.setCommunityVisibility(key, toVisibility)
}
}
// accounts
ProfileShowcaseAccountsPanel {
id: profileShowcaseAccountsPanel
inShowcaseModel: priv.showcaseModels.accountsVisibleModel
hiddenModel: priv.showcaseModels.accountsHiddenModel
showcaseLimit: root.profileStore.getProfileShowcaseEntriesLimit()
currentWallet: root.walletStore.overview.mixedcaseAddress
onChangePositionRequested: function (from, to) {
priv.showcaseModels.changeAccountPosition(from, to)
}
onSetVisibilityRequested: function (key, toVisibility) {
priv.showcaseModels.setAccountVisibility(key, toVisibility)
}
}
// collectibles
ProfileShowcaseCollectiblesPanel {
id: profileShowcaseCollectiblesPanel
inShowcaseModel: priv.showcaseModels.collectiblesVisibleModel
hiddenModel: priv.showcaseModels.collectiblesHiddenModel
showcaseLimit: root.profileStore.getProfileShowcaseEntriesLimit()
addAccountsButtonVisible: priv.showcaseModels.accountsHiddenModel.count > 0
onNavigateToAccountsTab: profileTabBar.currentIndex = MyProfileView.TabIndex.Accounts
onChangePositionRequested: function (from, to) {
priv.showcaseModels.changeCollectiblePosition(from, to)
}
2022-11-11 16:46:35 +00:00
onSetVisibilityRequested: function (key, toVisibility) {
priv.showcaseModels.setCollectibleVisibility(key, toVisibility)
}
}
// assets
// TODO: Integrate the assets tab with the new backend
// ProfileShowcaseAssetsPanel {
// id: profileShowcaseAssetsPanel
// baseModel: root.walletAssetsStore.groupedAccountAssetsModel // TODO: instantiate an assets model in profile module
// showcaseModel: root.profileStore.profileShowcaseAssetsModel
// addAccountsButtonVisible: root.profileStore.profileShowcaseAccountsModel.hiddenCount > 0
// formatCurrencyAmount: function(amount, symbol) {
// return root.currencyStore.formatCurrencyAmount(amount, symbol)
// }
// onShowcaseEntryChanged: priv.hasAnyProfileShowcaseChanges = true
// onNavigateToAccountsTab: profileTabBar.currentIndex = MyProfileView.TabIndex.Accounts
// }
// web
ProfileSocialLinksPanel {
showcaseLimit: root.profileStore.getProfileShowcaseSocialLinksLimit()
socialLinksModel: priv.showcaseModels.socialLinksVisibleModel
onAddSocialLink: function(url, text) {
priv.showcaseModels.appendSocialLink({ showcaseKey: "", text: text, url: url })
}
onUpdateSocialLink: function(index, url, text) {
priv.showcaseModels.updateSocialLink(index, { text: text, url: url })
}
onRemoveSocialLink: function(index) {
priv.showcaseModels.removeSocialLink(index)
}
onChangePosition: function(from, to) {
priv.showcaseModels.changeSocialLinkPosition(from, to)
}
}
Component {
id: profilePreview
ProfileDialog {
publicKey: root.contactsStore.myPublicKey
profileStore: root.profileStore
contactsStore: root.contactsStore
networkConnectionStore: root.networkConnectionStore
onClosed: destroy()
}
2020-08-19 21:01:22 +00:00
}
Component {
id: profileShowcaseInfoPopup
ProfileShowcaseInfoPopup {
destroyOnClose: true
}
}
2020-08-19 21:01:22 +00:00
}
}