feat: Profile Showcase: Proof of concept for own Profile Dialog
- the goal of this PR is to get some bsais UI building blocks done for the followup PRs - the order of showcase tabs now is: Communities/Accounts/Collectibles/Assets - there will be further changes to accomodate for different types of backend models as those get developed (for other users' profiles) Fixes #9664
This commit is contained in:
parent
2204273a22
commit
5c0f1981ad
|
@ -67,7 +67,11 @@
|
||||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A17655",
|
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A17655",
|
||||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A17087",
|
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=682%3A17087",
|
||||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23525",
|
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23525",
|
||||||
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23932"
|
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23932",
|
||||||
|
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A23932&t=h8DUW6Eysawqe5u0-0",
|
||||||
|
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=724%3A15511&t=h8DUW6Eysawqe5u0-0",
|
||||||
|
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=6%3A16845&t=h8DUW6Eysawqe5u0-0",
|
||||||
|
"https://www.figma.com/file/ibJOTPlNtIxESwS96vJb06/%F0%9F%91%A4-Profile-%7C-Desktop?node-id=4%3A25437&t=h8DUW6Eysawqe5u0-0"
|
||||||
],
|
],
|
||||||
"StatusCommunityCard": [
|
"StatusCommunityCard": [
|
||||||
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A416159",
|
"https://www.figma.com/file/17fc13UBFvInrLgNUKJJg5/Kuba%E2%8E%9CDesktop?node-id=8159%3A416159",
|
||||||
|
|
|
@ -2,13 +2,15 @@ import QtQuick 2.14
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.14
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.14
|
||||||
|
|
||||||
import Storybook 1.0
|
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import shared.views 1.0
|
import shared.views 1.0
|
||||||
import mainui 1.0
|
import mainui 1.0
|
||||||
|
|
||||||
import StatusQ 0.1
|
import StatusQ 0.1
|
||||||
|
import StatusQ.Core.Utils 0.1 as CoreUtils
|
||||||
|
|
||||||
|
import Storybook 1.0
|
||||||
|
import Models 1.0
|
||||||
|
|
||||||
SplitView {
|
SplitView {
|
||||||
id: root
|
id: root
|
||||||
|
@ -55,7 +57,7 @@ SplitView {
|
||||||
alias: "Mock Alias Triplet",
|
alias: "Mock Alias Triplet",
|
||||||
lastUpdated: Date.now(),
|
lastUpdated: Date.now(),
|
||||||
lastUpdatedLocally: Date.now(),
|
lastUpdatedLocally: Date.now(),
|
||||||
localNickname: "MockNickname",
|
localNickname: localNickname.text,
|
||||||
thumbnailImage: "",
|
thumbnailImage: "",
|
||||||
largeImage: userImage.checked ? Style.png("status-logo") : "",
|
largeImage: userImage.checked ? Style.png("status-logo") : "",
|
||||||
isContact: isContact.checked,
|
isContact: isContact.checked,
|
||||||
|
@ -74,8 +76,8 @@ SplitView {
|
||||||
text: "__twitter",
|
text: "__twitter",
|
||||||
url: "https://twitter.com/ethstatus",
|
url: "https://twitter.com/ethstatus",
|
||||||
icon: "twitter"
|
icon: "twitter"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: "__github",
|
text: "__github",
|
||||||
url: "https://github.com/status-im",
|
url: "https://github.com/status-im",
|
||||||
icon: "github"
|
icon: "github"
|
||||||
|
@ -122,6 +124,8 @@ SplitView {
|
||||||
|
|
||||||
publicKey: switchOwnProfile.checked ? "0xdeadbeef" : "0xrandomguy"
|
publicKey: switchOwnProfile.checked ? "0xdeadbeef" : "0xrandomguy"
|
||||||
|
|
||||||
|
onCloseRequested: logs.logEvent("closeRequested()")
|
||||||
|
|
||||||
profileStore: QtObject {
|
profileStore: QtObject {
|
||||||
readonly property string pubkey: "0xdeadbeef"
|
readonly property string pubkey: "0xdeadbeef"
|
||||||
readonly property string ensName: name.text
|
readonly property string ensName: name.text
|
||||||
|
@ -169,6 +173,209 @@ SplitView {
|
||||||
logs.logEvent("contactsStore::verifiedUntrustworthy", ["publicKey"], arguments)
|
logs.logEvent("contactsStore::verifiedUntrustworthy", ["publicKey"], arguments)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
communitiesModel: ListModel {
|
||||||
|
ListElement {
|
||||||
|
name: "Not the cool gang"
|
||||||
|
amISectionAdmin: false
|
||||||
|
description: "Nothing to write home about"
|
||||||
|
color: "indigo"
|
||||||
|
image: ""
|
||||||
|
joined: true
|
||||||
|
members: [
|
||||||
|
ListElement { displayName: "Joe" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Awesome bunch"
|
||||||
|
amISectionAdmin: true
|
||||||
|
description: "Where the cool guys hang out & Nothing to write home about"
|
||||||
|
color: "green"
|
||||||
|
image: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAlklEQVR4nOzW0QmDQBAG4SSkl7SUQlJGCrElq9F3QdjjVhh/5nv3cFhY9vUIYQiNITSG0BhCExPynn1gWf9bx498P7/
|
||||||
|
nzPcxEzGExhBdJGYihtAYQlO+tUZvqrPbqeudo5iJGEJjCE15a3VtodH3q2ImYgiNITTlTdG1nUZ5a92VITQxITFiJmIIjSE0htAYQrMHAAD//+wwFVpz+yqXAAAAAElFTkSuQmCC"
|
||||||
|
joined: true
|
||||||
|
members: [
|
||||||
|
ListElement { displayName: "Alex" },
|
||||||
|
ListElement { displayName: "AlexJb" },
|
||||||
|
ListElement { displayName: "Michal" },
|
||||||
|
ListElement { displayName: "Noelia" },
|
||||||
|
ListElement { displayName: "Lukáš" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Invisible community (should not display!)"
|
||||||
|
amISectionAdmin: false
|
||||||
|
description: "Get outta here"
|
||||||
|
color: "red"
|
||||||
|
image: ""
|
||||||
|
joined: false
|
||||||
|
members: []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
walletStore: QtObject {
|
||||||
|
function switchAccountByAddress(address) {
|
||||||
|
logs.logEvent("walletStore::switchAccountByAddress", ["address"], arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectCollectible(slug, id) {
|
||||||
|
logs.logEvent("walletStore::selectCollectible", ["slug", "id"], arguments)
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var accounts: ListModel {
|
||||||
|
ListElement {
|
||||||
|
name: "My Status Account"
|
||||||
|
address: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7420"
|
||||||
|
color: "aliceblue"
|
||||||
|
emoji: "🇨🇿"
|
||||||
|
walletType: ""
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "testing (no emoji, colored, saved, seed)"
|
||||||
|
address: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7000"
|
||||||
|
color: "olive"
|
||||||
|
walletType: "seed"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "My Bro's Account"
|
||||||
|
address: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7421"
|
||||||
|
color: "ghostwhite"
|
||||||
|
emoji: "🇸🇰"
|
||||||
|
walletType: "watch"
|
||||||
|
}
|
||||||
|
ListElement {
|
||||||
|
name: "Keycard"
|
||||||
|
address: "0xdeadbeef"
|
||||||
|
color: "red"
|
||||||
|
emoji: ""
|
||||||
|
walletType: "key"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getNameForSavedWalletAddress(address) {
|
||||||
|
return CoreUtils.ModelUtils.getByKey(savedAddresses, "address", address, "name") ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function createOrUpdateSavedAddress(name, address, favourite) {
|
||||||
|
logs.logEvent("walletStore::createOrUpdateSavedAddress", ["name", "address", "favourite"], arguments)
|
||||||
|
savedAddresses.append({name, address, favourite, ens: false})
|
||||||
|
return "" // no error
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var savedAddresses: ListModel {
|
||||||
|
ListElement {
|
||||||
|
name: "My Status Saved Account"
|
||||||
|
address: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7000"
|
||||||
|
favourite: true
|
||||||
|
ens: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var currentAccount: QtObject {
|
||||||
|
readonly property var assets: ListModel {
|
||||||
|
readonly property var data: [
|
||||||
|
{
|
||||||
|
symbol: "MANA",
|
||||||
|
enabledNetworkBalance: {
|
||||||
|
amount: 301,
|
||||||
|
symbol: "MANA"
|
||||||
|
},
|
||||||
|
changePct24hour: -2.1,
|
||||||
|
visibleForNetworkWithPositiveBalance: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: "AAVE",
|
||||||
|
enabledNetworkBalance: {
|
||||||
|
amount: 23.3,
|
||||||
|
symbol: "AAVE"
|
||||||
|
},
|
||||||
|
changePct24hour: 4.56,
|
||||||
|
visibleForNetworkWithPositiveBalance: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: "POLY",
|
||||||
|
enabledNetworkBalance: {
|
||||||
|
amount: 3590,
|
||||||
|
symbol: "POLY"
|
||||||
|
},
|
||||||
|
changePct24hour: -11.6789,
|
||||||
|
visibleForNetworkWithPositiveBalance: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: "CDT",
|
||||||
|
enabledNetworkBalance: {
|
||||||
|
amount: 1000,
|
||||||
|
symbol: "CDT"
|
||||||
|
},
|
||||||
|
changePct24hour: 0,
|
||||||
|
visibleForNetworkWithPositiveBalance: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: "MKR",
|
||||||
|
enabledNetworkBalance: {
|
||||||
|
amount: 1.3,
|
||||||
|
symbol: "MKR"
|
||||||
|
},
|
||||||
|
//changePct24hour: undefined // NB 'undefined' on purpose
|
||||||
|
visibleForNetworkWithPositiveBalance: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
symbol: "InvisibleHere",
|
||||||
|
enabledNetworkBalance: {},
|
||||||
|
changePct24hour: 0,
|
||||||
|
visibleForNetworkWithPositiveBalance: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
Component.onCompleted: append(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property var flatCollectibles: ListModel {
|
||||||
|
readonly property var data: [
|
||||||
|
{
|
||||||
|
//id: 123,
|
||||||
|
name: "Crypto Kitties",
|
||||||
|
description: "Super Crypto Kitty",
|
||||||
|
backgroundColor: "",
|
||||||
|
imageUrl: ModelsData.collectibles.cryptoKitties,
|
||||||
|
permalink: ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 34545656768,
|
||||||
|
name: "Kitty 1",
|
||||||
|
description: "",
|
||||||
|
backgroundColor: "green",
|
||||||
|
imageUrl: ModelsData.collectibles.kitty1Big,
|
||||||
|
permalink: ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 123456,
|
||||||
|
name: "Kitty 2",
|
||||||
|
description: "",
|
||||||
|
backgroundColor: "",
|
||||||
|
imageUrl: ModelsData.collectibles.kitty2Big,
|
||||||
|
permalink: ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 12345645459537432,
|
||||||
|
name: "",
|
||||||
|
description: "Kitty 3 description",
|
||||||
|
backgroundColor: "oink",
|
||||||
|
imageUrl: ModelsData.collectibles.kitty3Big,
|
||||||
|
permalink: ""
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 691,
|
||||||
|
name: "KILLABEAR #691",
|
||||||
|
description: "Please note that weapons are not yet reflected in the rarity stats.",
|
||||||
|
backgroundColor: "#807c56",
|
||||||
|
imageUrl: "https://assets.killabears.com/content/killabears/img/691-e81f892696a8ae700e0dbc62eb072060679a2046d1ef5eb2671bdb1fad1f68e3.png",
|
||||||
|
permalink: "https://opensea.io/assets/ethereum/0xc99c679c50033bbc5321eb88752e89a93e9e83c5/691"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
Component.onCompleted: append(data)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,6 +399,12 @@ SplitView {
|
||||||
}
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
|
Label { text: "localNickname:" }
|
||||||
|
TextField {
|
||||||
|
id: localNickname
|
||||||
|
text: "MockNickname"
|
||||||
|
placeholderText: "Local Nickname"
|
||||||
|
}
|
||||||
Label { text: "displayName:" }
|
Label { text: "displayName:" }
|
||||||
TextField {
|
TextField {
|
||||||
id: displayName
|
id: displayName
|
||||||
|
@ -237,7 +450,7 @@ SplitView {
|
||||||
TextField {
|
TextField {
|
||||||
id: name
|
id: name
|
||||||
enabled: ensVerified.checked
|
enabled: ensVerified.checked
|
||||||
text: ensVerified.checked ? "mock-ens-name" : ""
|
text: ensVerified.checked ? "mock-ens-name.eth" : ""
|
||||||
placeholderText: "ENS name"
|
placeholderText: "ENS name"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,6 +503,7 @@ SplitView {
|
||||||
TextField {
|
TextField {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
id: bio
|
id: bio
|
||||||
|
selectByMouse: true
|
||||||
text: "Hi, I am Alex. I'm an indie developer who mainly works on web products.
|
text: "Hi, I am Alex. I'm an indie developer who mainly works on web products.
|
||||||
|
|
||||||
I worked for several different companies and created a couple of my own products from scratch. Currently building Telescope and Prepacked.
|
I worked for several different companies and created a couple of my own products from scratch. Currently building Telescope and Prepacked.
|
||||||
|
|
|
@ -140,7 +140,7 @@ Control {
|
||||||
This signal is emitted when the ToastMessage contains a url and this url
|
This signal is emitted when the ToastMessage contains a url and this url
|
||||||
is clicked by the user.
|
is clicked by the user.
|
||||||
*/
|
*/
|
||||||
signal linkActivated(var link)
|
signal linkActivated(string link)
|
||||||
|
|
||||||
QtObject {
|
QtObject {
|
||||||
id: d
|
id: d
|
||||||
|
|
|
@ -70,7 +70,7 @@ Item {
|
||||||
textSelectedAddress.text = selectedAccount.address
|
textSelectedAddress.text = selectedAccount.address
|
||||||
}
|
}
|
||||||
if (selectedAccount.currencyBalance) {
|
if (selectedAccount.currencyBalance) {
|
||||||
textSelectedAddressFiatBalance.text = selectedAccount.currencyBalance + " " + currency.toUpperCase()
|
textSelectedAddressFiatBalance.text = LocaleUtils.currencyAmountToLocaleString(selectedAccount.currencyBalance)
|
||||||
}
|
}
|
||||||
if (selectedAccount.assets && showBalanceForAssetSymbol) {
|
if (selectedAccount.assets && showBalanceForAssetSymbol) {
|
||||||
assetFound = Utils.findAssetByChainAndSymbol(root.chainId, selectedAccount.assets, showBalanceForAssetSymbol)
|
assetFound = Utils.findAssetByChainAndSymbol(root.chainId, selectedAccount.assets, showBalanceForAssetSymbol)
|
||||||
|
@ -239,7 +239,7 @@ Item {
|
||||||
id: txtFiatBalance
|
id: txtFiatBalance
|
||||||
Layout.rightMargin: 4
|
Layout.rightMargin: 4
|
||||||
font.pixelSize: 15
|
font.pixelSize: 15
|
||||||
text: currencyBalance
|
text: LocaleUtils.currencyAmountToLocaleString(currencyBalance, {onlyAmount: true})
|
||||||
color: Theme.palette.directColor1
|
color: Theme.palette.directColor1
|
||||||
}
|
}
|
||||||
StatusBaseText {
|
StatusBaseText {
|
||||||
|
|
|
@ -18,11 +18,8 @@ ToolTip {
|
||||||
property int offset: 0
|
property int offset: 0
|
||||||
property alias arrow: arrow
|
property alias arrow: arrow
|
||||||
|
|
||||||
implicitWidth: Math.min(maxWidth, contentItem.implicitWidth + 16)
|
implicitWidth: Math.min(maxWidth, implicitContentWidth + 16)
|
||||||
leftPadding: 8
|
padding: 8
|
||||||
rightPadding: 8
|
|
||||||
topPadding: 8
|
|
||||||
bottomPadding: 8
|
|
||||||
delay: 200
|
delay: 200
|
||||||
background: Item {
|
background: Item {
|
||||||
id: statusToolTipBackground
|
id: statusToolTipBackground
|
||||||
|
@ -73,6 +70,6 @@ ToolTip {
|
||||||
font.weight: Font.Medium
|
font.weight: Font.Medium
|
||||||
horizontalAlignment: Text.AlignHCenter
|
horizontalAlignment: Text.AlignHCenter
|
||||||
bottomPadding: 8
|
bottomPadding: 8
|
||||||
|
textFormat: Text.RichText
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,8 +71,7 @@ SettingsPageLayout {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
readonly property string initialState: root.permissionsModel.count > 0
|
readonly property string initialState: d.permissionsExist ? d.permissionsViewState : d.welcomeViewState
|
||||||
? d.permissionsViewState : d.welcomeViewState
|
|
||||||
|
|
||||||
function initializeData() {
|
function initializeData() {
|
||||||
holdingsToEditModel = emptyModel
|
holdingsToEditModel = emptyModel
|
||||||
|
|
|
@ -101,7 +101,7 @@ QtObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
function setActiveCommunity(communityId) {
|
function setActiveCommunity(communityId) {
|
||||||
mainModule.setActiveSectionById(communityId);
|
root.mainModuleInst.setActiveSectionById(communityId);
|
||||||
}
|
}
|
||||||
|
|
||||||
function navigateToCommunity(communityId) {
|
function navigateToCommunity(communityId) {
|
||||||
|
|
|
@ -107,6 +107,7 @@ StatusSectionLayout {
|
||||||
profileStore: root.store.profileStore
|
profileStore: root.store.profileStore
|
||||||
privacyStore: root.store.privacyStore
|
privacyStore: root.store.privacyStore
|
||||||
contactsStore: root.store.contactsStore
|
contactsStore: root.store.contactsStore
|
||||||
|
communitiesModel: root.store.communitiesList
|
||||||
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.profile)
|
sectionTitle: root.store.getNameForSubsection(Constants.settingsSubsection.profile)
|
||||||
contentWidth: d.contentWidth
|
contentWidth: d.contentWidth
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
CommunityDelegate 1.0 CommunityDelegate.qml
|
||||||
|
WalletAccountDelegate 1.0 WalletAccountDelegate.qml
|
|
@ -25,6 +25,7 @@ SettingsContentBase {
|
||||||
property ProfileStore profileStore
|
property ProfileStore profileStore
|
||||||
property PrivacyStore privacyStore
|
property PrivacyStore privacyStore
|
||||||
property ContactsStore contactsStore
|
property ContactsStore contactsStore
|
||||||
|
property var communitiesModel
|
||||||
|
|
||||||
titleRowComponentLoader.sourceComponent: StatusButton {
|
titleRowComponentLoader.sourceComponent: StatusButton {
|
||||||
objectName: "profileSettingsChangePasswordButton"
|
objectName: "profileSettingsChangePasswordButton"
|
||||||
|
@ -72,6 +73,7 @@ SettingsContentBase {
|
||||||
profileStore: root.profileStore
|
profileStore: root.profileStore
|
||||||
privacyStore: root.privacyStore
|
privacyStore: root.privacyStore
|
||||||
walletStore: root.walletStore
|
walletStore: root.walletStore
|
||||||
|
communitiesModel: root.communitiesModel
|
||||||
|
|
||||||
onVisibleChanged: if (visible) stackLayout.Layout.preferredHeight = settingsView.implicitHeight
|
onVisibleChanged: if (visible) stackLayout.Layout.preferredHeight = settingsView.implicitHeight
|
||||||
Component.onCompleted: stackLayout.Layout.preferredHeight = Qt.binding(() => settingsView.implicitHeight)
|
Component.onCompleted: stackLayout.Layout.preferredHeight = Qt.binding(() => settingsView.implicitHeight)
|
||||||
|
@ -82,6 +84,7 @@ SettingsContentBase {
|
||||||
|
|
||||||
profileStore: root.profileStore
|
profileStore: root.profileStore
|
||||||
contactsStore: root.contactsStore
|
contactsStore: root.contactsStore
|
||||||
|
communitiesModel: root.communitiesModel
|
||||||
dirtyValues: settingsView.dirtyValues
|
dirtyValues: settingsView.dirtyValues
|
||||||
dirty: settingsView.dirty
|
dirty: settingsView.dirty
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import StatusQ.Core.Theme 0.1
|
||||||
Item {
|
Item {
|
||||||
property alias profileStore: profilePreview.profileStore
|
property alias profileStore: profilePreview.profileStore
|
||||||
property alias contactsStore: profilePreview.contactsStore
|
property alias contactsStore: profilePreview.contactsStore
|
||||||
|
property alias communitiesModel: profilePreview.communitiesModel
|
||||||
property alias dirtyValues: profilePreview.dirtyValues
|
property alias dirtyValues: profilePreview.dirtyValues
|
||||||
property alias dirty: profilePreview.dirty
|
property alias dirty: profilePreview.dirty
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,7 @@ ColumnLayout {
|
||||||
property PrivacyStore privacyStore
|
property PrivacyStore privacyStore
|
||||||
property ProfileStore profileStore
|
property ProfileStore profileStore
|
||||||
property WalletStore walletStore
|
property WalletStore walletStore
|
||||||
|
property var communitiesModel
|
||||||
|
|
||||||
property QtObject dirtyValues: QtObject {
|
property QtObject dirtyValues: QtObject {
|
||||||
property string displayName: descriptionPanel.displayName.text
|
property string displayName: descriptionPanel.displayName.text
|
||||||
|
@ -158,7 +159,7 @@ ColumnLayout {
|
||||||
|
|
||||||
StatusListItem {
|
StatusListItem {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
visible: Qt.platform.os == "osx"
|
visible: Qt.platform.os === Constants.mac
|
||||||
title: qsTr("Biometric login and transaction authentication")
|
title: qsTr("Biometric login and transaction authentication")
|
||||||
asset.name: "touch-id"
|
asset.name: "touch-id"
|
||||||
components: [ StatusSwitch {
|
components: [ StatusSwitch {
|
||||||
|
@ -218,13 +219,13 @@ ColumnLayout {
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
id: communitiesRepeater
|
id: communitiesRepeater
|
||||||
model: communitiesModule.model
|
model: root.communitiesModel
|
||||||
|
|
||||||
CommunityDelegate {
|
CommunityDelegate {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: joined
|
visible: joined
|
||||||
community: model
|
community: model
|
||||||
enabled: false
|
sensor.enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -246,7 +247,7 @@ ColumnLayout {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
account: model
|
account: model
|
||||||
showShevronIcon: false
|
showShevronIcon: false
|
||||||
enabled: false
|
sensor.enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -141,6 +141,10 @@ QtObject {
|
||||||
walletSection.switchAccount(newIndex)
|
walletSection.switchAccount(newIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function switchAccountByAddress(address) {
|
||||||
|
walletSection.switchAccountByAddress(address)
|
||||||
|
}
|
||||||
|
|
||||||
function generateNewAccount(password, accountName, color, emoji, path, derivedFrom) {
|
function generateNewAccount(password, accountName, color, emoji, path, derivedFrom) {
|
||||||
return walletSectionAccounts.generateNewAccount(password, accountName, color, emoji, path, derivedFrom)
|
return walletSectionAccounts.generateNewAccount(password, accountName, color, emoji, path, derivedFrom)
|
||||||
}
|
}
|
||||||
|
@ -198,6 +202,10 @@ QtObject {
|
||||||
walletSectionCurrentCollectible.update(slug, id)
|
walletSectionCurrentCollectible.update(slug, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getNameForSavedWalletAddress(address) {
|
||||||
|
return walletSectionSavedAddresses.getNameByAddress(address)
|
||||||
|
}
|
||||||
|
|
||||||
function createOrUpdateSavedAddress(name, address, favourite, chainShortNames, ens) {
|
function createOrUpdateSavedAddress(name, address, favourite, chainShortNames, ens) {
|
||||||
return walletSectionSavedAddresses.createOrUpdateSavedAddress(name, address, favourite, chainShortNames, ens)
|
return walletSectionSavedAddresses.createOrUpdateSavedAddress(name, address, favourite, chainShortNames, ens)
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,9 +169,9 @@ Rectangle {
|
||||||
components: [
|
components: [
|
||||||
StatusIcon {
|
StatusIcon {
|
||||||
icon: {
|
icon: {
|
||||||
if (model.walletType == "watch")
|
if (model.walletType === Constants.watchWalletType)
|
||||||
return "show"
|
return "show"
|
||||||
else if (model.walletType == "key")
|
if (model.walletType === Constants.keyWalletType)
|
||||||
return "keycard"
|
return "keycard"
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -163,6 +163,14 @@ Item {
|
||||||
Global.settingsSubsection = subsection;
|
Global.settingsSubsection = subsection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onOpenSendModal(address: string) {
|
||||||
|
sendModal.open(address)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onSwitchToCommunity(communityId: string) {
|
||||||
|
communitiesPortalLayoutContainer.communitiesStore.setActiveCommunity(communityId)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeAppSectionBySectionId(sectionId) {
|
function changeAppSectionBySectionId(sectionId) {
|
||||||
|
@ -1119,7 +1127,10 @@ Item {
|
||||||
this.open = false
|
this.open = false
|
||||||
}
|
}
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
Qt.openUrlExternally(link);
|
if (link.startsWith("#")) // internal link to section
|
||||||
|
globalConns.onAppSectionBySectionTypeChanged(link.substring(1))
|
||||||
|
else
|
||||||
|
Global.openLink(link)
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose: {
|
onClose: {
|
||||||
|
|
|
@ -287,6 +287,7 @@ QtObject {
|
||||||
id: profilePopup
|
id: profilePopup
|
||||||
profileStore: rootStore.profileSectionStore.profileStore
|
profileStore: rootStore.profileSectionStore.profileStore
|
||||||
contactsStore: rootStore.profileSectionStore.contactsStore
|
contactsStore: rootStore.profileSectionStore.contactsStore
|
||||||
|
communitiesModel: rootStore.profileSectionStore.communitiesList
|
||||||
|
|
||||||
onClosed: {
|
onClosed: {
|
||||||
if (profilePopup.parentPopup) {
|
if (profilePopup.parentPopup) {
|
||||||
|
|
|
@ -14,8 +14,6 @@ import StatusQ.Core.Backpressure 1.0
|
||||||
import shared.controls 1.0
|
import shared.controls 1.0
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
|
|
||||||
import utils 1.0
|
|
||||||
|
|
||||||
import "../controls"
|
import "../controls"
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
|
@ -13,6 +13,7 @@ StatusDialog {
|
||||||
|
|
||||||
property var profileStore
|
property var profileStore
|
||||||
property var contactsStore
|
property var contactsStore
|
||||||
|
property var communitiesModel
|
||||||
|
|
||||||
width: 640
|
width: 640
|
||||||
padding: 0
|
padding: 0
|
||||||
|
@ -24,6 +25,7 @@ StatusDialog {
|
||||||
publicKey: root.publicKey
|
publicKey: root.publicKey
|
||||||
profileStore: root.profileStore
|
profileStore: root.profileStore
|
||||||
contactsStore: root.contactsStore
|
contactsStore: root.contactsStore
|
||||||
|
communitiesModel: root.communitiesModel
|
||||||
onCloseRequested: root.close()
|
onCloseRequested: root.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,9 +32,8 @@ Item {
|
||||||
id: assetListView
|
id: assetListView
|
||||||
objectName: "assetViewStatusListView"
|
objectName: "assetViewStatusListView"
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
model: RootStore.tokensLoading ? 25 : filteredModel
|
model: RootStore.tokensLoading ? Constants.dummyModelItems : filteredModel
|
||||||
delegate: RootStore.tokensLoading ? loadingTokenDelegate : tokenDelegate
|
delegate: RootStore.tokensLoading ? loadingTokenDelegate : tokenDelegate
|
||||||
ScrollBar.vertical: StatusScrollBar {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SortFilterProxyModel {
|
SortFilterProxyModel {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import QtQuick 2.14
|
import QtQuick 2.15
|
||||||
import QtQuick.Controls 2.14
|
import QtQuick.Controls 2.15
|
||||||
import QtQuick.Layouts 1.14
|
import QtQuick.Layouts 1.15
|
||||||
import QtGraphicalEffects 1.14
|
import QtGraphicalEffects 1.15
|
||||||
|
|
||||||
import StatusQ.Core 0.1
|
import StatusQ.Core 0.1
|
||||||
import StatusQ.Core.Theme 0.1
|
import StatusQ.Core.Theme 0.1
|
||||||
|
@ -9,6 +9,7 @@ import StatusQ.Controls 0.1
|
||||||
import StatusQ.Components 0.1
|
import StatusQ.Components 0.1
|
||||||
import StatusQ.Popups 0.1
|
import StatusQ.Popups 0.1
|
||||||
import StatusQ.Popups.Dialog 0.1
|
import StatusQ.Popups.Dialog 0.1
|
||||||
|
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||||
|
|
||||||
import utils 1.0
|
import utils 1.0
|
||||||
import shared.controls 1.0
|
import shared.controls 1.0
|
||||||
|
@ -16,16 +17,23 @@ import shared.panels 1.0
|
||||||
import shared.popups 1.0
|
import shared.popups 1.0
|
||||||
import shared.controls.chat 1.0
|
import shared.controls.chat 1.0
|
||||||
import shared.controls.chat.menuItems 1.0
|
import shared.controls.chat.menuItems 1.0
|
||||||
|
import shared.views.profile 1.0
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
import AppLayouts.Wallet.stores 1.0 as WalletNS
|
||||||
|
|
||||||
Pane {
|
Pane {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool readOnly
|
property bool readOnly // inside settings/profile/preview
|
||||||
|
|
||||||
property string publicKey: contactsStore.myPublicKey
|
property string publicKey: contactsStore.myPublicKey
|
||||||
|
|
||||||
property var profileStore
|
property var profileStore
|
||||||
property var contactsStore
|
property var contactsStore
|
||||||
|
property var walletStore: WalletNS.RootStore
|
||||||
|
property var communitiesModel
|
||||||
|
|
||||||
property QtObject dirtyValues: null
|
property QtObject dirtyValues: null
|
||||||
property bool dirty: false
|
property bool dirty: false
|
||||||
|
@ -547,8 +555,10 @@ Pane {
|
||||||
|
|
||||||
StatusScrollView {
|
StatusScrollView {
|
||||||
id: scrollView
|
id: scrollView
|
||||||
|
implicitWidth: contentWidth + leftPadding + rightPadding
|
||||||
|
implicitHeight: contentHeight + topPadding + bottomPadding
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.preferredHeight: contentHeight + topPadding + bottomPadding
|
Layout.fillHeight: true
|
||||||
Layout.leftMargin: -column.anchors.leftMargin
|
Layout.leftMargin: -column.anchors.leftMargin
|
||||||
Layout.rightMargin: -column.anchors.rightMargin
|
Layout.rightMargin: -column.anchors.rightMargin
|
||||||
Layout.topMargin: -column.spacing
|
Layout.topMargin: -column.spacing
|
||||||
|
@ -562,8 +572,7 @@ Pane {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: column.anchors.leftMargin + Style.current.halfPadding
|
Layout.leftMargin: column.anchors.leftMargin + Style.current.halfPadding
|
||||||
Layout.rightMargin: column.anchors.rightMargin + Style.current.halfPadding
|
Layout.rightMargin: column.anchors.rightMargin + Style.current.halfPadding
|
||||||
bio: root.dirty ? root.dirtyValues.bio
|
bio: root.dirty ? root.dirtyValues.bio : d.contactDetails.bio
|
||||||
: d.contactDetails.bio
|
|
||||||
userSocialLinksJson: root.dirty ? root.profileStore.temporarySocialLinksJson
|
userSocialLinksJson: root.dirty ? root.profileStore.temporarySocialLinksJson
|
||||||
: d.contactDetails.socialLinks
|
: d.contactDetails.socialLinks
|
||||||
}
|
}
|
||||||
|
@ -666,26 +675,17 @@ Pane {
|
||||||
height: width
|
height: width
|
||||||
mipmap: true
|
mipmap: true
|
||||||
smooth: false
|
smooth: false
|
||||||
source: root.profileStore.getQrCodeSource(root.profileStore.pubkey)
|
source: root.profileStore.getQrCodeSource(Utils.getCompressedPk(root.profileStore.pubkey))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusTabBar {
|
StatusTabBar {
|
||||||
|
id: showcaseTabBar
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.leftMargin: column.anchors.leftMargin
|
Layout.leftMargin: column.anchors.leftMargin
|
||||||
Layout.rightMargin: column.anchors.rightMargin
|
Layout.rightMargin: column.anchors.rightMargin
|
||||||
bottomPadding: -4
|
bottomPadding: -4
|
||||||
|
|
||||||
StatusTabButton {
|
|
||||||
leftPadding: 0
|
|
||||||
width: implicitWidth
|
|
||||||
text: qsTr("Assets")
|
|
||||||
}
|
|
||||||
StatusTabButton {
|
|
||||||
width: implicitWidth
|
|
||||||
text: qsTr("Collectibles")
|
|
||||||
}
|
|
||||||
StatusTabButton {
|
StatusTabButton {
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
text: qsTr("Communities")
|
text: qsTr("Communities")
|
||||||
|
@ -694,27 +694,32 @@ Pane {
|
||||||
width: implicitWidth
|
width: implicitWidth
|
||||||
text: qsTr("Accounts")
|
text: qsTr("Accounts")
|
||||||
}
|
}
|
||||||
|
StatusTabButton {
|
||||||
|
width: implicitWidth
|
||||||
|
text: qsTr("Collectibles")
|
||||||
|
}
|
||||||
|
StatusTabButton {
|
||||||
|
leftPadding: 0
|
||||||
|
width: implicitWidth
|
||||||
|
text: qsTr("Assets")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusDialogBackground {
|
// Profile Showcase
|
||||||
|
ProfileShowcaseView {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: -column.spacing
|
Layout.topMargin: -column.spacing
|
||||||
Layout.preferredHeight: 300
|
Layout.preferredHeight: 300
|
||||||
color: Theme.palette.baseColor4
|
|
||||||
|
|
||||||
Rectangle {
|
currentTabIndex: showcaseTabBar.currentIndex
|
||||||
anchors.left: parent.left
|
isCurrentUser: d.isCurrentUser
|
||||||
anchors.right: parent.right
|
mainDisplayName: d.mainDisplayName
|
||||||
anchors.top: parent.top
|
readOnly: root.readOnly
|
||||||
height: parent.radius
|
profileStore: root.profileStore
|
||||||
color: parent.color
|
walletStore: root.walletStore
|
||||||
}
|
communitiesModel: root.communitiesModel
|
||||||
|
|
||||||
StatusBaseText {
|
onCloseRequested: root.closeRequested()
|
||||||
anchors.centerIn: parent
|
|
||||||
color: Theme.palette.baseColor1
|
|
||||||
text: qsTr("More content to appear here soon...")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,6 +159,7 @@ Column {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
text: "GIF"
|
text: "GIF"
|
||||||
font.pixelSize: 13
|
font.pixelSize: 13
|
||||||
|
color: "white"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,395 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import QtQuick.Layouts 1.15
|
||||||
|
|
||||||
|
import StatusQ.Core 0.1
|
||||||
|
import StatusQ.Core.Theme 0.1
|
||||||
|
import StatusQ.Controls 0.1
|
||||||
|
import StatusQ.Components 0.1
|
||||||
|
import StatusQ.Popups.Dialog 0.1
|
||||||
|
import StatusQ.Core.Utils 0.1 as StatusQUtils
|
||||||
|
|
||||||
|
import utils 1.0
|
||||||
|
import shared.controls 1.0 // Timer
|
||||||
|
|
||||||
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
|
Control {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property alias currentTabIndex: stackLayout.currentIndex
|
||||||
|
property bool isCurrentUser
|
||||||
|
property string mainDisplayName
|
||||||
|
property bool readOnly
|
||||||
|
property var profileStore
|
||||||
|
property var walletStore
|
||||||
|
property var communitiesModel
|
||||||
|
|
||||||
|
signal closeRequested()
|
||||||
|
|
||||||
|
horizontalPadding: readOnly ? 20 : 40 // smaller in settings/preview
|
||||||
|
topPadding: Style.current.bigPadding
|
||||||
|
|
||||||
|
QtObject {
|
||||||
|
id: d
|
||||||
|
|
||||||
|
readonly property string copyLiteral: qsTr("Copy")
|
||||||
|
|
||||||
|
readonly property var timer: Timer {
|
||||||
|
id: timer
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: StatusDialogBackground {
|
||||||
|
color: Theme.palette.baseColor4
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
height: parent.radius
|
||||||
|
color: parent.color
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: StackLayout {
|
||||||
|
id: stackLayout
|
||||||
|
|
||||||
|
// communities
|
||||||
|
ColumnLayout {
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
visible: communitiesView.count == 0
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
text: qsTr("%1 hasn't joined any communities yet").arg(root.mainDisplayName)
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusGridView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
id: communitiesView
|
||||||
|
rightMargin: Style.current.halfPadding
|
||||||
|
cellWidth: (width-rightMargin)/2
|
||||||
|
cellHeight: cellWidth/2
|
||||||
|
visible: count
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
sourceModel: root.isCurrentUser ? root.communitiesModel : null // TODO show other users too
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "joined"
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
sorters: [
|
||||||
|
RoleSorter {
|
||||||
|
roleName: "amISectionAdmin"
|
||||||
|
sortOrder: Qt.DescendingOrder // admin first
|
||||||
|
},
|
||||||
|
StringSorter {
|
||||||
|
roleName: "name"
|
||||||
|
caseSensitivity: Qt.CaseInsensitive
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
ScrollBar.vertical: StatusScrollBar { }
|
||||||
|
delegate: StatusListItem { // TODO custom delegate
|
||||||
|
width: GridView.view.cellWidth - Style.current.smallPadding
|
||||||
|
height: GridView.view.cellHeight - Style.current.smallPadding
|
||||||
|
title: model.name
|
||||||
|
statusListItemTitle.font.pixelSize: 17
|
||||||
|
statusListItemTitle.font.bold: true
|
||||||
|
subTitle: model.description
|
||||||
|
tertiaryTitle: qsTr("%n member(s)", "", model.members.count)
|
||||||
|
asset.name: model.image ?? model.name
|
||||||
|
asset.isImage: asset.name.startsWith("data:image/")
|
||||||
|
asset.isLetterIdenticon: !model.image
|
||||||
|
asset.color: model.color
|
||||||
|
asset.width: 40
|
||||||
|
asset.height: 40
|
||||||
|
border.width: 1
|
||||||
|
border.color: Theme.palette.baseColor2
|
||||||
|
components: [
|
||||||
|
StatusIcon {
|
||||||
|
visible: model.amISectionAdmin
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
icon: "crown"
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
onClicked: {
|
||||||
|
if (root.readOnly)
|
||||||
|
return
|
||||||
|
root.closeRequested()
|
||||||
|
Global.switchToCommunity(model.id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// wallets/accounts
|
||||||
|
ColumnLayout {
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
visible: accountsView.count == 0
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
text: qsTr("%1 doesn't have any wallet accounts yet").arg(root.mainDisplayName)
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusListView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
id: accountsView
|
||||||
|
spacing: Style.current.halfPadding
|
||||||
|
visible: count
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
sourceModel: root.isCurrentUser ? root.walletStore.accounts : null // TODO show other users too
|
||||||
|
filters: ValueFilter { // everything except keycards
|
||||||
|
roleName: "walletType"
|
||||||
|
value: Constants.keyWalletType
|
||||||
|
inverted: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delegate: StatusListItem {
|
||||||
|
id: accountDelegate
|
||||||
|
property bool saved: root.walletStore.getNameForSavedWalletAddress(model.address) !== ""
|
||||||
|
border.width: 1
|
||||||
|
border.color: Theme.palette.baseColor2
|
||||||
|
width: ListView.view.width
|
||||||
|
title: model.name
|
||||||
|
subTitle: StatusQUtils.Utils.elideText(model.address, 6, 4).replace("0x", "0×")
|
||||||
|
asset.color: model.color
|
||||||
|
asset.emoji: model.emoji ?? ""
|
||||||
|
asset.name: asset.emoji || "filled-account"
|
||||||
|
asset.isLetterIdenticon: asset.emoji
|
||||||
|
asset.letterSize: 14
|
||||||
|
asset.bgColor: Theme.palette.primaryColor3
|
||||||
|
asset.isImage: asset.emoji
|
||||||
|
components: [
|
||||||
|
StatusIcon {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
visible: model.walletType === Constants.watchWalletType
|
||||||
|
icon: "show"
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
},
|
||||||
|
StatusFlatButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
size: StatusBaseButton.Size.Small
|
||||||
|
enabled: !accountDelegate.saved
|
||||||
|
text: accountDelegate.saved ? qsTr("Address saved") : qsTr("Save Address")
|
||||||
|
onClicked: {
|
||||||
|
accountDelegate.saved = root.walletStore.createOrUpdateSavedAddress(model.name, model.address, false) === ""
|
||||||
|
Global.displayToastMessage(qsTr("%1 saved to your wallet").arg(accountDelegate.subTitle),
|
||||||
|
qsTr("Go to your wallet"),
|
||||||
|
"wallet",
|
||||||
|
false,
|
||||||
|
Constants.ephemeralNotificationType.normal,
|
||||||
|
`#${Constants.appSection.wallet}` // internal link to wallet section
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
StatusFlatRoundButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
type: StatusFlatRoundButton.Type.Secondary
|
||||||
|
icon.name: "send"
|
||||||
|
tooltip.text: qsTr("Send")
|
||||||
|
onClicked: {
|
||||||
|
root.walletStore.switchAccountByAddress(model.address)
|
||||||
|
Global.openSendModal(model.address)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
StatusFlatRoundButton {
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
type: StatusFlatRoundButton.Type.Secondary
|
||||||
|
icon.name: "copy"
|
||||||
|
tooltip.text: d.copyLiteral
|
||||||
|
onClicked: {
|
||||||
|
tooltip.text = qsTr("Copied")
|
||||||
|
root.profileStore.copyToClipboard(model.address)
|
||||||
|
d.timer.setTimeout(function() {
|
||||||
|
tooltip.text = d.copyLiteral
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
onClicked: {
|
||||||
|
if (root.readOnly)
|
||||||
|
return
|
||||||
|
root.walletStore.switchAccountByAddress(model.address)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// collectibles/NFTs
|
||||||
|
ColumnLayout {
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
visible: collectiblesView.count == 0
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
text: qsTr("%1 doesn't have any collectibles/NFTs yet").arg(root.mainDisplayName)
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusGridView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
id: collectiblesView
|
||||||
|
rightMargin: Style.current.halfPadding
|
||||||
|
cellWidth: (width-rightMargin)/4
|
||||||
|
cellHeight: cellWidth
|
||||||
|
visible: count
|
||||||
|
model: root.isCurrentUser ? root.walletStore.flatCollectibles : null // TODO show other users too
|
||||||
|
ScrollBar.vertical: StatusScrollBar { }
|
||||||
|
delegate: StatusRoundedImage {
|
||||||
|
width: GridView.view.cellWidth - Style.current.smallPadding
|
||||||
|
height: GridView.view.cellHeight - Style.current.smallPadding
|
||||||
|
border.width: 1
|
||||||
|
border.color: Theme.palette.directColor7
|
||||||
|
color: !!model.backgroundColor ? model.backgroundColor : "transparent"
|
||||||
|
radius: Style.current.radius
|
||||||
|
showLoadingIndicator: model.isLoading
|
||||||
|
image.fillMode: Image.PreserveAspectCrop
|
||||||
|
image.source: model.imageUrl ?? ""
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.current.halfPadding
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: Style.current.halfPadding
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.rightMargin: Style.current.halfPadding
|
||||||
|
|
||||||
|
Control {
|
||||||
|
Layout.maximumWidth: parent.width
|
||||||
|
horizontalPadding: Style.current.halfPadding
|
||||||
|
verticalPadding: Style.current.halfPadding/2
|
||||||
|
visible: !!model.id
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
radius: Style.current.halfPadding/2
|
||||||
|
color: Theme.palette.indirectColor2
|
||||||
|
}
|
||||||
|
contentItem: StatusBaseText {
|
||||||
|
font.pixelSize: 13
|
||||||
|
font.weight: Font.Medium
|
||||||
|
maximumLineCount: 1
|
||||||
|
elide: Text.ElideRight
|
||||||
|
text: `#${model.id}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusToolTip {
|
||||||
|
visible: hhandler.hovered && (!!model.name || !!model.description)
|
||||||
|
text: {
|
||||||
|
const name = model.name
|
||||||
|
const descr = model.description
|
||||||
|
const sep = !!name && !!descr ? "<br>" : ""
|
||||||
|
return `<b>${name}</b>${sep}${descr}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
id: hhandler
|
||||||
|
cursorShape: hovered ? Qt.PointingHandCursor : undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
TapHandler {
|
||||||
|
onSingleTapped: {
|
||||||
|
Global.openLink(model.permalink)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// assets/tokens
|
||||||
|
ColumnLayout {
|
||||||
|
StatusBaseText {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
Layout.alignment: Qt.AlignCenter
|
||||||
|
visible: assetsView.count == 0
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
color: Theme.palette.directColor1
|
||||||
|
text: qsTr("%1 doesn't have any assets/tokens yet").arg(root.mainDisplayName)
|
||||||
|
}
|
||||||
|
|
||||||
|
StatusGridView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
id: assetsView
|
||||||
|
rightMargin: Style.current.halfPadding
|
||||||
|
cellWidth: (width-rightMargin)/3
|
||||||
|
cellHeight: cellWidth/2.5
|
||||||
|
visible: count
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
// TODO show assets for all accounts, not just the current one?
|
||||||
|
sourceModel: root.isCurrentUser ? root.walletStore.currentAccount.assets : null // TODO show other users too
|
||||||
|
filters: ValueFilter {
|
||||||
|
roleName: "visibleForNetworkWithPositiveBalance"
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
sorters: [
|
||||||
|
StringSorter {
|
||||||
|
roleName: "name"
|
||||||
|
},
|
||||||
|
StringSorter {
|
||||||
|
roleName: "symbol"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
ScrollBar.vertical: StatusScrollBar { }
|
||||||
|
delegate: StatusListItem {
|
||||||
|
readonly property double changePct24hour: model.changePct24hour ?? 0
|
||||||
|
readonly property string textColor: changePct24hour === 0
|
||||||
|
? Theme.palette.baseColor1 : changePct24hour < 0
|
||||||
|
? Theme.palette.dangerColor1 : Theme.palette.successColor1
|
||||||
|
readonly property string arrow: changePct24hour === 0 ? "" : changePct24hour < 0 ? "↓" : "↑"
|
||||||
|
|
||||||
|
width: GridView.view.cellWidth - Style.current.halfPadding
|
||||||
|
height: GridView.view.cellHeight - Style.current.halfPadding
|
||||||
|
title: LocaleUtils.currencyAmountToLocaleString(model.enabledNetworkBalance)
|
||||||
|
statusListItemTitle.font.weight: Font.Medium
|
||||||
|
tertiaryTitle: qsTr("%1% today %2")
|
||||||
|
.arg(LocaleUtils.numberToLocaleString(changePct24hour, changePct24hour === 0 ? 0 : 2)).arg(arrow)
|
||||||
|
statusListItemTertiaryTitle.color: textColor
|
||||||
|
statusListItemTertiaryTitle.font.pixelSize: Theme.asideTextFontSize
|
||||||
|
statusListItemTertiaryTitle.anchors.topMargin: 6
|
||||||
|
leftPadding: Style.current.halfPadding
|
||||||
|
rightPadding: Style.current.halfPadding
|
||||||
|
border.width: 1
|
||||||
|
border.color: Theme.palette.baseColor2
|
||||||
|
components: [
|
||||||
|
Image {
|
||||||
|
width: 40
|
||||||
|
height: 40
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
source: Style.png("tokens/" + model.symbol)
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status === Image.Error) {
|
||||||
|
source = Style.png("tokens/DEFAULT-TOKEN")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
onClicked: {
|
||||||
|
if (root.readOnly)
|
||||||
|
return
|
||||||
|
// TODO what to do here?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
ProfileShowcaseView 1.0 ProfileShowcaseView.qml
|
|
@ -47,6 +47,9 @@ QtObject {
|
||||||
signal setNthEnabledSectionActive(int nthSection)
|
signal setNthEnabledSectionActive(int nthSection)
|
||||||
signal appSectionBySectionTypeChanged(int sectionType, int subsection)
|
signal appSectionBySectionTypeChanged(int sectionType, int subsection)
|
||||||
|
|
||||||
|
signal openSendModal(string address)
|
||||||
|
signal switchToCommunity(string communityId)
|
||||||
|
|
||||||
signal playSendMessageSound()
|
signal playSendMessageSound()
|
||||||
signal playNotificationSound()
|
signal playNotificationSound()
|
||||||
signal playErrorSound()
|
signal playErrorSound()
|
||||||
|
|
Loading…
Reference in New Issue