feat(profile dialog): General UI updates

- create new `ShareProfileDialog` with QR code + links
- align the context menu items with latest Figma designs
- add `isBlocked` to contact icons
- adjust SB to show more options and showcase models

Fixes #13416
Fixes #13417
This commit is contained in:
Lukáš Tinkl 2024-02-07 15:56:45 +01:00 committed by Lukáš Tinkl
parent 0378b12b7d
commit 319b5dd23e
29 changed files with 558 additions and 631 deletions

View File

@ -35,114 +35,8 @@ SplitView {
id: emptyModel
}
ListModel {
CommunitiesModel {
id: communitiesModel
Component.onCompleted:
append([{
id: "0x0001",
name: "I am 0wner!1!!",
description: "Lorem ipsum dolor sit amet",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.owner,
isControlNode: true,
image: ModelsData.icons.dribble,
color: "yellow",
muted: false,
members: [ { pubKey: "0xdeadbeef" } ]
},
{
id: "0x0002",
name: "Test community 2",
description: "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: ModelsData.icons.status,
color: "peach",
muted: false,
members: [ { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" } ]
},
{
id: "0x0003",
name: "Free to join",
introMessage: "Welcome to ze club",
description: "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.",
outroMessage: "Sad to see you go",
joined: false,
spectated: true,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: ModelsData.icons.coinbase,
color: "red",
muted: false,
members: [ { pubKey: "0xdeadbeef" } ]
},
{
id: "0x0004",
name: "Muted community",
introMessage: "Welcome to ze club",
description: "Lorem ipsum dolor sit amet",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: "",
color: "whitesmoke",
muted: true,
members: []
},
{
id: "0x0005",
name: "Admin test community",
description: "Lorem ipsum dolor sit amet",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.admin,
isControlNode: false,
image: ModelsData.icons.socks,
color: "green",
muted: false,
members: [{ pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }]
},
{
id: "0x0006",
name: "Pending request here",
description: "Lorem ipsum dolor sit amet",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: false,
spectated: true,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: ModelsData.icons.spotify,
color: "pink",
muted: false,
members: [{ pubKey: "0xdeadbeef" }]
},
{
id: "0x0007",
name: "Token Master Club",
description: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.tokenMaster,
image: ModelsData.icons.cryptPunks,
color: "lightslategrey",
muted: false,
members: [{ pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }]
}
])
}
CommunitiesView {

View File

@ -8,7 +8,8 @@ import shared.stores 1.0
import mainui 1.0
import StatusQ 0.1
import StatusQ.Core.Utils 0.1 as CoreUtils
import AppLayouts.Wallet.stores 1.0
import Storybook 1.0
import Models 1.0
@ -35,6 +36,10 @@ SplitView {
function isCompressedPubKey(publicKey) { return true }
function addTimestampToURL(url) {
return url
}
Component.onCompleted: {
Utils.globalUtilsInst = this
root.globalUtilsReady = true
@ -48,9 +53,9 @@ SplitView {
// mainModuleInst mock
QtObject {
function getContactDetailsAsJson(publicKey, getVerificationRequest) {
return JSON.stringify({ displayName: displayName.text || "Mock User Name",
optionalName: optionalName.text,
function getContactDetailsAsJson(publicKey, getVerificationRequest=false) {
return JSON.stringify({ displayName: displayName.text,
optionalName: "",
displayIcon: "",
publicKey: publicKey,
name: name.text,
@ -62,16 +67,12 @@ SplitView {
thumbnailImage: "",
largeImage: userImage.checked ? Style.png("status-logo") : "",
isContact: isContact.checked,
isAdded: isAdded.checked,
isBlocked: isBlocked.checked,
removed: removed.checked,
requestReceived: hasAddedUs.checked,
hasAddedUs: hasAddedUs.checked, // same as above
isSyncing: false,
trustStatus: trustStatus.currentValue,
verificationStatus: Constants.verificationStatus.unverified,
incomingVerificationStatus: Constants.verificationStatus.unverified,
contactRequestState: Constants.ContactRequestState.None,
contactRequestState: ctrlContactRequestState.currentValue,
bio: bio.text,
socialLinks: JSON.stringify
([{
@ -105,11 +106,24 @@ SplitView {
function changeContactNickname(publicKey, newNickname) {
logs.logEvent("rootStore::contactStore::changeContactNickname", ["publicKey", "newNickname"], arguments)
}
function blockContact(publicKey) {
logs.logEvent("rootStore::contactsStore::blockContact", ["publicKey"], arguments)
}
function unblockContact(publicKey) {
logs.logEvent("rootStore::contactsStore::unblockContact", ["publicKey"], arguments)
}
}
}
communityTokensStore: CommunityTokensStore {}
}
WalletAssetsStore {
id: assetsStore
assetsWithFilteredBalances: groupedAccountsAssetsModel
}
SplitView {
orientation: Qt.Vertical
SplitView.fillWidth: true
@ -131,6 +145,8 @@ SplitView {
sourceComponent: ProfileDialogView {
implicitWidth: 640
readOnly: ctrlReadOnly.checked
publicKey: switchOwnProfile.checked ? "0xdeadbeef" : "0xrandomguy"
onCloseRequested: logs.logEvent("closeRequested()")
@ -140,11 +156,19 @@ SplitView {
readonly property string ensName: name.text
function getQrCodeSource() {
return ""
return "https://upload.wikimedia.org/wikipedia/commons/4/41/QR_Code_Example.svg"
}
function copyToClipboard(text) {
logs.logEvent("profileStore::copyToClipboard", ["text"], arguments)
}
function requestProfileShowcase(publicKey) {
console.warn("STUB: requestProfileShowcase(publicKey)")
}
readonly property var profileShowcaseCommunitiesModel: CommunitiesModel {}
readonly property var profileShowcaseAccountsModel: WalletAccountsModel {}
readonly property var profileShowcaseCollectiblesModel: ManageCollectiblesModel {}
readonly property var profileShowcaseAssetsModel: assetsStore.groupedAccountAssetsModel
}
contactsStore: QtObject {
@ -178,50 +202,12 @@ SplitView {
logs.logEvent("contactsStore::verifiedUntrustworthy", ["publicKey"], arguments)
}
function getLinkToProfile(publicKey) {
return "https://status.app/u/" + publicKey
function verifiedTrusted(publicKey) {
logs.logEvent("contactsStore::verifiedTrusted", ["publicKey"], arguments)
}
}
communitiesModel: ListModel {
ListElement {
name: "Not the cool gang"
memberRole: 0 // Constants.memberRole.none
isControlNode: false
description: "Nothing to write home about"
color: "indigo"
image: ""
joined: true
members: [
ListElement { displayName: "Joe" }
]
}
ListElement {
name: "Awesome bunch"
memberRole: 4 // Constants.memberRole.admin
isControlNode: false
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!)"
memberRole: 1 // Constants.memberRole.owner
isControlNode: true
description: "Get outta here"
color: "red"
image: ""
joined: false
members: []
function getLinkToProfile(publicKey) {
return Constants.userLinkPrefix + publicKey
}
}
@ -230,156 +216,25 @@ SplitView {
logs.logEvent("walletStore::setFilterAddress", ["address"], arguments)
}
readonly property var accounts: ListModel {
ListElement {
name: "My Status Account"
address: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7420"
colorId: "primary"
emoji: "🇨🇿"
walletType: ""
}
ListElement {
name: "testing (no emoji, colored, saved, seed)"
address: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7000"
colorId: "turquoise"
walletType: "seed"
}
ListElement {
name: "My Bro's Account"
address: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7421"
colorId: "sky"
emoji: "🇸🇰"
walletType: "watch"
}
ListElement {
name: "Keycard"
address: "0xdeadbeef"
colorId: "purple"
emoji: ""
walletType: "key"
function getSavedAddress(address) {
return {
name: "My Status Saved Account",
address: "0xcdc2ea3b6ba8fed3a3402f8db8b2fab53e7b7000",
ens: false,
colorId: Constants.walletAccountColors.primary,
chainShortNames: "",
isTest: false
}
}
function getNameForSavedWalletAddress(address) {
return CoreUtils.ModelUtils.getByKey(savedAddresses, "address", address, "name") ?? ""
function createOrUpdateSavedAddress(name, address, ens, colorId, chainShortNames) {
logs.logEvent("walletStore::createOrUpdateSavedAddress", ["name", "address", "ens", "colorId", "chainShortNames"],
arguments)
}
}
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 assets: ListModel {
readonly property var data: [
{
symbol: "MANA",
enabledNetworkBalance: {
amount: 301,
symbol: "MANA"
},
changePct24hour: -2.1,
},
{
symbol: "AAVE",
enabledNetworkBalance: {
amount: 23.3,
symbol: "AAVE"
},
changePct24hour: 4.56,
},
{
symbol: "POLY",
enabledNetworkBalance: {
amount: 3590,
symbol: "POLY"
},
changePct24hour: -11.6789,
},
{
symbol: "CDT",
enabledNetworkBalance: {
amount: 1000,
symbol: "CDT"
},
changePct24hour: 0,
},
{
symbol: "MKR",
enabledNetworkBalance: {
amount: 1.3,
symbol: "MKR"
},
//changePct24hour: undefined // NB 'undefined' on purpose
},
{
symbol: "InvisibleHere",
enabledNetworkBalance: {},
changePct24hour: 0,
}
]
Component.onCompleted: append(data)
}
readonly property var collectibles: ListModel {
readonly property var data: [
{
//id: 123,
name: "Crypto Kitties",
description: "Super Crypto Kitty",
backgroundColor: "",
imageUrl: ModelsData.collectibles.cryptoKitties,
permalink: "",
isLoading: false
},
{
id: 34545656768,
name: "Kitty 1",
description: "",
backgroundColor: "green",
imageUrl: ModelsData.collectibles.kitty1Big,
permalink: "",
isLoading: false
},
{
id: 123456,
name: "Kitty 2",
description: "",
backgroundColor: "",
imageUrl: ModelsData.collectibles.kitty2Big,
permalink: "",
isLoading: false
},
{
id: 12345645459537432,
name: "",
description: "Kitty 3 description",
backgroundColor: "oink",
imageUrl: ModelsData.collectibles.kitty3Big,
permalink: "",
isLoading: false
},
{
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",
isLoading: true
}
]
Component.onCompleted: append(data)
}
networkConnectionStore: QtObject {
readonly property bool sendBuyBridgeEnabled: true
}
}
}
@ -401,6 +256,12 @@ SplitView {
text: "Own profile"
checked: false
}
Switch {
id: ctrlReadOnly
text: "Readonly (preview)"
visible: switchOwnProfile.checked
checked: false
}
}
RowLayout {
Layout.fillWidth: true
@ -415,12 +276,6 @@ SplitView {
id: displayName
placeholderText: "Display Name"
}
Label { text: "optionalName:" }
TextField {
id: optionalName
placeholderText: "Optional/Original Name"
text: ""
}
}
RowLayout {
CheckBox {
@ -464,23 +319,21 @@ SplitView {
enabled: !switchOwnProfile.checked
CheckBox {
id: isContact
enabled: false
checked: isAdded.checked && hasAddedUs.checked
enabled: true
checked: ctrlContactRequestState.currentValue === Constants.ContactRequestState.Mutual
text: "isContact"
}
CheckBox {
id: isAdded
checked: true
text: "isAdded"
}
CheckBox {
id: hasAddedUs
checked: true
text: "hasAddedUs"
}
CheckBox {
id: removed
text: "removed"
ComboBox {
id: ctrlContactRequestState
textRole: "text"
valueRole: "value"
model: [
{ value: Constants.ContactRequestState.None, text: "None" },
{ value: Constants.ContactRequestState.Mutual, text: "Mutual" },
{ value: Constants.ContactRequestState.Sent, text: "Sent" },
{ value: Constants.ContactRequestState.Received, text: "Received" },
{ value: Constants.ContactRequestState.Dismissed, text: "Dismissed" }
]
}
CheckBox {
id: isBlocked

View File

@ -41,7 +41,7 @@ SplitView {
if (visibility === Constants.ShowcaseVisibility.NoOne) {
remove(index)
} else {
get(index).showcaseVisibility = visibility
get(index).showcaseVisibility = visibility
}
}
@ -77,9 +77,9 @@ SplitView {
showcaseModel: inShowcaseAssetsModel
formatCurrencyAmount: function (amount, symbol) {
return ({amount: amount,
symbol: symbol.toUpperCase(),
displayDecimals: 4,
stripTrailingZeroes: false})
symbol: symbol.toUpperCase(),
displayDecimals: 4,
stripTrailingZeroes: false})
}
}
}

View File

@ -3,23 +3,124 @@ import QtQuick 2.15
import utils 1.0
ListModel {
readonly property var data: [
{
communityId: "ddls",
communityName: "Doodles",
communityImage: ModelsData.collectibles.doodles
},
{
communityId: "sox",
communityName: "Socks",
communityImage: ModelsData.icons.socks
},
{
communityId: "ast",
communityName: "Astafarians",
communityImage: ModelsData.icons.dribble
}
]
Component.onCompleted: append(data)
Component.onCompleted:
append([{
id: "0x0001",
name: "I am 0wner!1!!",
description: "Lorem ipsum dolor sit amet",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.owner,
isControlNode: true,
image: ModelsData.icons.dribble,
color: "yellow",
muted: false,
members: [ { pubKey: "0xdeadbeef" } ],
membersCount: 1,
loading: false
},
{
id: "0x0002",
name: "Test community 2",
description: "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: ModelsData.icons.status,
color: "peach",
muted: false,
members: [ { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" } ],
membersCount: 3,
loading: false
},
{
id: "0x0003",
name: "Free to join",
introMessage: "Welcome to ze club",
description: "Lorem ipsum dolor sit amet, consectetur adipisici elit, sed eiusmod tempor incidunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquid ex ea commodi consequat.",
outroMessage: "Sad to see you go",
joined: false,
spectated: true,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: ModelsData.icons.coinbase,
color: "red",
muted: false,
members: [ { pubKey: "0xdeadbeef" } ],
membersCount: 1,
loading: false
},
{
id: "0x0004",
name: "Muted community",
introMessage: "Welcome to ze club",
description: "Lorem ipsum dolor sit amet",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: "",
color: "whitesmoke",
muted: true,
members: [],
membersCount: 0,
loading: false
},
{
id: "0x0005",
name: "Admin test community",
description: "Lorem ipsum dolor sit amet",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.admin,
isControlNode: false,
image: ModelsData.icons.socks,
color: "green",
muted: false,
members: [{ pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }],
membersCount: 4,
loading: false
},
{
id: "0x0006",
name: "Pending request here",
description: "Lorem ipsum dolor sit amet",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: false,
spectated: true,
memberRole: Constants.memberRole.none,
isControlNode: false,
image: ModelsData.icons.spotify,
color: "pink",
muted: false,
members: [{ pubKey: "0xdeadbeef" }],
membersCount: 1,
loading: false
},
{
id: "0x0007",
name: "Token Master Club",
description: "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi",
introMessage: "Welcome to ze club",
outroMessage: "Sad to see you go",
joined: true,
spectated: false,
memberRole: Constants.memberRole.tokenMaster,
image: ModelsData.icons.cryptPunks,
color: "lightslategrey",
muted: false,
members: [{ pubKey: "0xdeadbeef" }, { pubKey: "0xdeadbeef" }],
membersCount: 2,
loading: false
}
])
}

View File

@ -104,7 +104,7 @@ ListModel {
},
{
name: "Fab (key)",
emoji: "",
emoji: "🔑",
colorId: Constants.walletAccountColors.camel,
color: "#C78F67",
address: "0x7F47C2e98a4BBf5487E6fb082eC2D9Ab0E6d8884",

View File

@ -1,8 +1,6 @@
import QtQuick 2.15
import SortFilterProxyModel 0.2
import StatusQ 0.1
import StatusQ.Core.Utils 0.1 as SQUtils
import Storybook 1.0
import Models 1.0
@ -15,7 +13,23 @@ QtObject {
readonly property var groupedAccountsAssetsModel: GroupedAccountsAssetsModel {}
property var assetsWithFilteredBalances
readonly property var tokensBySymbolModel: TokensBySymbolModel {}
readonly property CommunitiesModel communityModel: CommunitiesModel{}
readonly property var communityModel: ListModel {
Component.onCompleted: append([{
communityId: "ddls",
communityName: "Doodles",
communityImage: ModelsData.collectibles.doodles
},
{
communityId: "sox",
communityName: "Socks",
communityImage: ModelsData.icons.socks
},
{
communityId: "ast",
communityName: "Astafarians",
communityImage: ModelsData.icons.dribble
}])
}
// renaming tokens by symbol key so that can be used to join models
readonly property var renamedTokensBySymbolModel: RolesRenamingModel {

View File

@ -9,6 +9,7 @@ Row {
property bool isContact: false
property int trustIndicator: StatusContactVerificationIcons.TrustedType.None
property bool isBlocked
property bool tiny: true
property StatusAssetSettings mutualConnectionIcon: StatusAssetSettings {
@ -38,7 +39,7 @@ Row {
bgWidth: root.tiny ? 10 : 16
bgHeight: root.tiny ? 10 : 16
bgRadius: bgWidth / 2
bgColor: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? Theme.palette.primaryColor1 : Theme.palette.dangerColor1
bgColor: root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified ? Theme.palette.successColor1 : Theme.palette.dangerColor1
// Only used to get implicit width and height from the actual image
property Image dummyImage: Image {
source: trustContactIcon.name ? "../../assets/img/icons/" + trustContactIcon.name + ".svg": ""
@ -47,6 +48,22 @@ Row {
}
}
property StatusAssetSettings blockedContactIcon: StatusAssetSettings {
name: root.isBlocked ? "cancel" : ""
color: Theme.palette.dangerColor1
width: Math.min(bgWidth, dummyImage.width)
height: Math.min(bgHeight, dummyImage.height)
bgWidth: root.tiny ? 10 : 16
bgHeight: root.tiny ? 10 : 16
bgRadius: bgWidth / 2
// Only used to get implicit width and height from the actual image
property Image dummyImage: Image {
source: blockedContactIcon.name ? "../../assets/img/icons/" + blockedContactIcon.name + ".svg": ""
visible: false
cache: false
}
}
enum TrustedType {
None, //0
Verified, //1
@ -62,28 +79,38 @@ Row {
StatusToolTip {
text: {
if (root.isBlocked)
return qsTr("Blocked")
if (root.isContact) {
if (root.trustIndicator === StatusContactVerificationIcons.TrustedType.Verified)
return qsTr("Verified contact")
return qsTr("ID verified contact")
if (root.trustIndicator === StatusContactVerificationIcons.TrustedType.Untrustworthy)
return qsTr("Untrustworthy contact")
return qsTr("Untrusted contact")
return qsTr("Contact")
}
if (root.trustIndicator === StatusContactVerificationIcons.TrustedType.Untrustworthy)
return qsTr("Untrustworthy")
return qsTr("Untrusted")
return ""
}
visible: hoverHandler.hovered && text
}
// blocked
StatusRoundIcon {
visible: root.isContact && root.trustIndicator !== StatusContactVerificationIcons.TrustedType.Verified
asset: root.mutualConnectionIcon
visible: root.isBlocked
asset: root.blockedContactIcon
}
// (un)trusted
StatusRoundIcon {
visible: root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None
visible: !root.isBlocked && root.trustIndicator !== StatusContactVerificationIcons.TrustedType.None
asset: root.trustContactIcon
}
}
// contact?
StatusRoundIcon {
visible: !root.isBlocked && root.isContact && root.trustIndicator !== StatusContactVerificationIcons.TrustedType.Verified
asset: root.mutualConnectionIcon
}
}

View File

@ -46,5 +46,5 @@ Image {
readonly property bool isError: status === Image.Error
fillMode: Image.PreserveAspectFit
sourceSize: source.toString().endsWith(".svg") ? Qt.size(width, 0) : Qt.size(width * Screen.devicePixelRatio, height * Screen.devicePixelRatio)
sourceSize: source.toString().endsWith(".svg") ? Qt.size(width, 0) : undefined
}

View File

@ -12,8 +12,6 @@ Item {
Layout.fillHeight: true
Layout.fillWidth: true
property var rootStore
signal shareChatKeyClicked()
Image {
@ -98,7 +96,6 @@ Item {
Component {
id: inviteFriendsPopup
InviteFriendsPopup {
rootStore: element.rootStore
destroyOnClose: true
}
}

View File

@ -184,7 +184,6 @@ Item {
EmptyChatPanel {
anchors.fill: parent
visible: root.activeChatId === "" || root.chatsCount == 0
rootStore: root.rootStore
onShareChatKeyClicked: Global.openProfilePopup(userProfile.pubKey);
}

View File

@ -253,7 +253,6 @@ SettingsContentBase {
profileStore: root.profileStore
contactsStore: root.contactsStore
networkConnectionStore: root.networkConnectionStore
communitiesModel: root.communitiesModel
onClosed: destroy()
}
}

View File

@ -9,7 +9,6 @@ Item {
property alias profileStore: profilePreview.profileStore
property alias contactsStore: profilePreview.contactsStore
property alias networkConnectionStore: profilePreview.networkConnectionStore
property alias communitiesModel: profilePreview.communitiesModel
property alias dirtyValues: profilePreview.dirtyValues
property alias dirty: profilePreview.dirty

View File

@ -431,6 +431,7 @@ QtObject {
}
},
// FIXME remove, unused
Component {
id: displayNamePopupComponent
DisplayNamePopup {
@ -461,7 +462,6 @@ QtObject {
profileStore: rootStore.profileSectionStore.profileStore
contactsStore: rootStore.profileSectionStore.contactsStore
networkConnectionStore: root.networkConnectionStore
communitiesModel: rootStore.profileSectionStore.communitiesList
onClosed: {
if (profilePopup.parentPopup) {

View File

@ -242,6 +242,5 @@ Item {
id: noContactsRect
visible: showContactList && existingContacts.count === 0
anchors.centerIn: parent
rootStore: root.rootStore
}
}

View File

@ -12,6 +12,8 @@ StatusIcon {
required property string textToCopy
readonly property bool hovered: mouseArea.containsMouse
icon: "copy"
color: mouseArea.containsMouse? Theme.palette.primaryColor1 : Theme.palette.baseColor1

View File

@ -26,6 +26,7 @@ Item {
property url previewIcon: icon
property int trustStatus
property bool isContact: false
property bool isBlocked
property bool isCurrentUser
property bool userIsEnsVerified
property rect cropRect
@ -211,6 +212,7 @@ Item {
visible: !root.isCurrentUser && !root.isBridgedAccount
isContact: root.isContact
trustIndicator: root.trustStatus
isBlocked: root.isBlocked
}
Loader {
@ -279,16 +281,16 @@ Item {
StatusMenu {
StatusAction {
text: qsTr("Select different image")
text: !!root.icon ? qsTr("Select different image") : qsTr("Select image")
assetSettings.name: "image"
onTriggered: Global.openChangeProfilePicPopup(editButton.tempIcon)
}
StatusAction {
text: qsTr("Use an NFT")
text: qsTr("Use a collectible")
assetSettings.name: "nft-profile"
onTriggered: Global.openChangeProfilePicPopup(editButton.tempIcon)
enabled: false // TODO enable this with the profile showcase
enabled: false // TODO enable this with the profile showcase (#13418)
}
StatusMenuSeparator {}

View File

@ -3,6 +3,6 @@ import QtQuick 2.14
import StatusQ.Popups 0.1
StatusAction {
text: qsTr("Send Contact Request")
text: qsTr("Send contact request")
icon.name: "add-contact"
}

View File

@ -3,6 +3,6 @@ import QtQuick 2.14
import StatusQ.Popups 0.1
StatusAction {
text: qsTr("Send Message")
text: qsTr("Send message")
icon.name: "chat"
}

View File

@ -5,8 +5,6 @@ import utils 1.0
StatusModal {
id: root
property var rootStore
headerSettings.title: qsTr("Download Status link")
height: 156
@ -15,7 +13,7 @@ StatusModal {
tooltip.text: qsTr("Copied!")
asset.name: "copy"
iconButton.onClicked: {
root.rootStore.copyToClipboard(Constants.downloadLink)
Utils.copyToClipboard(Constants.downloadLink)
tooltip.visible = !tooltip.visible
}
width: parent.width

View File

@ -66,7 +66,7 @@ StatusModal {
}
]
Keys.onReleased: {
if (event.key === Qt.Key_Return) {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
editDone(nicknameInput.text)
}
}

View File

@ -14,7 +14,6 @@ StatusDialog {
property var profileStore
property var contactsStore
property var networkConnectionStore
property var communitiesModel
width: 640
padding: 0
@ -27,7 +26,6 @@ StatusDialog {
profileStore: root.profileStore
contactsStore: root.contactsStore
networkConnectionStore: root.networkConnectionStore
communitiesModel: root.communitiesModel
onCloseRequested: root.close()
}
}

View File

@ -85,6 +85,7 @@ StatusDialog {
userIsEnsVerified: d.userIsEnsVerified
isContact: d.contactDetails.isContact
trustStatus: d.contactDetails.trustStatus
isBlocked: d.contactDetails.isBlocked
imageSize: ProfileHeader.ImageSize.Middle
loading: d.loadingContactDetails
}

View File

@ -15,7 +15,6 @@ Item {
property string text: qsTr("You dont have any contacts yet. Invite your friends to start chatting.")
property alias textColor: noContacts.color
property var rootStore
StatusBaseText {
id: noContacts
@ -40,7 +39,6 @@ Item {
Component {
id: inviteFriendsPopup
InviteFriendsPopup {
rootStore: noContactsRect.rootStore
destroyOnClose: true
}
}

View File

@ -34,7 +34,6 @@ Pane {
property var contactsStore
property var walletStore: WalletNS.RootStore
property var networkConnectionStore
property var communitiesModel
property var dirtyValues: ({})
property bool dirty: false
@ -121,10 +120,6 @@ Pane {
d.reload()
}
}
readonly property var timer: Timer {
id: timer
}
}
function reload() {
@ -157,6 +152,7 @@ Pane {
}
}
// TODO a popup here instead of buttons
Component {
id: btnAcceptContactRequestComponent
ColumnLayout {
@ -165,7 +161,7 @@ Pane {
StatusBaseText {
color: Theme.palette.baseColor1
font.pixelSize: 13
text: qsTr("Respond to contact request")
text: qsTr("Review contact request")
}
AcceptRejectOptionsButtonsPanel {
@ -208,19 +204,27 @@ Pane {
id: btnUnblockUserComponent
StatusButton {
size: StatusButton.Size.Small
text: qsTr("Unblock User")
text: qsTr("Unblock")
onClicked: Global.unblockContactRequested(root.publicKey, d.mainDisplayName)
}
}
Component {
id: txtPendingContactRequestComponent
StatusBaseText {
font.pixelSize: 13
font.weight: Font.Medium
color: Theme.palette.baseColor1
verticalAlignment: Text.AlignVCenter
text: qsTr("Contact Request Pending...")
RowLayout {
StatusIcon {
icon: "history"
width: 16
height: width
color: Theme.palette.baseColor1
}
StatusBaseText {
font.pixelSize: 13
font.weight: Font.Medium
color: Theme.palette.baseColor1
verticalAlignment: Text.AlignVCenter
text: qsTr("Contact Request Pending…")
}
}
}
@ -239,7 +243,7 @@ Pane {
id: btnRespondToIdRequestComponent
StatusButton {
size: StatusButton.Size.Small
text: qsTr("Respond to ID Request")
text: qsTr("Respond to ID verification request")
objectName: "respondToIDRequest_StatusItem"
onClicked: {
Global.openIncomingIDRequestPopup(root.publicKey,
@ -259,6 +263,17 @@ Pane {
}
}
Component {
id: shareProfileCmp
ShareProfileDialog {
destroyOnClose: true
title: d.isCurrentUser ? qsTr("Share your profile") : qsTr("%1's profile").arg(d.mainDisplayName)
publicKey: root.publicKey
qrCode: root.profileStore.getQrCodeSource(Utils.getCompressedPk(root.publicKey))
linkToProfile: d.linkToProfile
}
}
ColumnLayout {
id: column
spacing: 20
@ -281,85 +296,36 @@ Pane {
image: root.dirty ? root.dirtyValues.profileLargeImage
: Utils.addTimestampToURL(d.contactDetails.largeImage)
interactive: false
imageWidth: 80
imageWidth: 90
imageHeight: imageWidth
ensVerified: d.contactDetails.ensVerified
}
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: 4
Item { Layout.fillWidth: true }
// TODO a Loader with additional secondary buttons
StatusFlatButton {
Layout.alignment: Qt.AlignTop
spacing: 4
Item {
id: contactRow
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
StatusBaseText {
id: contactName
anchors.left: parent.left
width: Math.min(implicitWidth, contactRow.width - verificationIcons.width - verificationIcons.anchors.leftMargin)
objectName: "ProfileDialog_displayName"
font.bold: true
font.pixelSize: 22
elide: Text.ElideRight
text: root.dirty ? root.dirtyValues.displayName
: d.mainDisplayName
}
StatusContactVerificationIcons {
id: verificationIcons
anchors.left: contactName.right
anchors.leftMargin: Style.current.halfPadding
anchors.verticalCenter: contactName.verticalCenter
objectName: "ProfileDialog_userVerificationIcons"
visible: !d.isCurrentUser
isContact: d.isContact
trustIndicator: d.contactDetails.trustStatus
tiny: false
}
}
StatusBaseText {
id: contactSecondaryName
font.pixelSize: 12
color: Theme.palette.baseColor1
text: "(%1)".arg(d.optionalDisplayName)
visible: !!d.userNickName
}
EmojiHash {
objectName: "ProfileDialog_userEmojiHash"
publicKey: root.publicKey
}
RowLayout {
StatusBaseText {
font.pixelSize: 12
color: Theme.palette.baseColor1
text: Utils.getElidedCompressedPk(root.publicKey)
}
StatusFlatButton {
size: StatusFlatButton.Size.Tiny
icon.name: "copy"
enabled: !d.timer.running
onClicked: {
copyKeyTooltip.text = qsTr("Copied")
root.profileStore.copyToClipboard(Utils.getCompressedPk(root.publicKey))
d.timer.setTimeout(function() {
copyKeyTooltip.text = qsTr("Copy Chat Key")
}, 1500);
}
StatusToolTip {
id: copyKeyTooltip
text: qsTr("Copy Chat Key")
visible: parent.hovered || d.timer.running
}
}
}
Layout.preferredHeight: menuButton.visible ? menuButton.height : -1
visible: d.isCurrentUser && !root.readOnly
size: StatusButton.Size.Small
text: qsTr("Share Profile")
onClicked: Global.openPopup(shareProfileCmp)
}
Loader {
Layout.alignment: Qt.AlignTop
Layout.preferredHeight: menuButton.visible ? menuButton.height : -1
HoverHandler {
id: actionButtonHoverHandler
enabled: root.readOnly
}
StatusToolTip {
text: qsTr("Not available in preview mode")
visible: actionButtonHoverHandler.hovered
}
sourceComponent: {
// current user
if (d.isCurrentUser)
@ -373,6 +339,10 @@ Pane {
if (d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy)
return btnBlockUserComponent
// mutual contact
if (d.isContact || d.contactRequestState === Constants.ContactRequestState.Mutual)
return btnSendMessageComponent
// depend on contactRequestState
switch (d.contactRequestState) {
case Constants.ContactRequestState.Sent:
@ -385,7 +355,7 @@ Pane {
} else if (!d.isTrusted && d.isVerificationRequestReceived) {
return btnRespondToIdRequestComponent
}
return btnSendMessageComponent
break
}
case Constants.ContactRequestState.None:
case Constants.ContactRequestState.Dismissed:
@ -422,7 +392,7 @@ Pane {
}
}
StatusAction {
text: qsTr("Verify Identity")
text: qsTr("Request ID verification")
icon.name: "checkmark-circle"
enabled: d.isContact && !d.isBlocked &&
d.outgoingVerificationStatus === Constants.verificationStatus.unverified &&
@ -433,8 +403,9 @@ Pane {
popup => popup.accepted.connect(d.reload))
}
}
// TODO Mark as ID verified
StatusAction {
text: qsTr("ID Request Pending...")
text: qsTr("Review ID verification reply")
icon.name: "checkmark-circle"
enabled: d.isContact && !d.isBlocked && !d.isTrusted && d.isVerificationRequestSent
onTriggered: {
@ -444,7 +415,7 @@ Pane {
}
}
StatusAction {
text: qsTr("Rename")
text: d.userNickName ? qsTr("Edit nickname") : qsTr("Add nickname")
icon.name: "edit_pencil"
onTriggered: {
moreMenu.close()
@ -453,28 +424,39 @@ Pane {
}
}
StatusAction {
text: qsTr("Copy Link to Profile")
text: qsTr("Show QR code")
icon.name: "qr"
enabled: !d.isCurrentUser
onTriggered: {
moreMenu.close()
Global.openPopup(shareProfileCmp)
}
}
StatusAction {
text: qsTr("Copy link to profile")
icon.name: "copy"
onTriggered: {
moreMenu.close()
root.profileStore.copyToClipboard(d.linkToProfile)
}
}
StatusMenuSeparator {}
// TODO Remove nickname
StatusAction {
text: qsTr("Unblock User")
icon.name: "remove-circle"
text: qsTr("Unblock user")
icon.name: "cancel"
type: StatusAction.Type.Danger
enabled: d.isBlocked
onTriggered: {
moreMenu.close()
Global.unblockContactRequested(root.publicKey, d.mainDisplayName)
}
}
StatusMenuSeparator {}
StatusAction {
text: qsTr("Mark as Untrustworthy")
text: qsTr("Mark as untrusted")
icon.name: "warning"
type: StatusAction.Type.Danger
enabled: d.contactDetails.trustStatus === Constants.trustStatus.unknown
enabled: d.contactDetails.trustStatus === Constants.trustStatus.unknown && !d.isBlocked
onTriggered: {
moreMenu.close()
if (d.isContact && !d.isTrusted && d.isVerificationRequestReceived)
@ -485,9 +467,10 @@ Pane {
}
}
StatusAction {
text: qsTr("Remove Untrustworthy Mark")
text: qsTr("Remove untrusted mark")
icon.name: "warning"
enabled: d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy
type: StatusAction.Type.Danger
enabled: d.contactDetails.trustStatus === Constants.trustStatus.untrustworthy && !d.isBlocked
onTriggered: {
moreMenu.close()
root.contactsStore.removeTrustStatus(root.publicKey)
@ -495,7 +478,7 @@ Pane {
}
}
StatusAction {
text: qsTr("Remove Identity Verification")
text: qsTr("Remove ID verification")
icon.name: "warning"
type: StatusAction.Type.Danger
enabled: d.isContact && d.isTrusted
@ -505,7 +488,7 @@ Pane {
}
}
StatusAction {
text: qsTr("Remove Contact")
text: qsTr("Remove contact")
icon.name: "remove-contact"
type: StatusAction.Type.Danger
enabled: d.isContact && !d.isBlocked && d.contactRequestState !== Constants.ContactRequestState.Sent
@ -515,7 +498,7 @@ Pane {
}
}
StatusAction {
text: qsTr("Block User")
text: qsTr("Block user")
icon.name: "cancel"
type: StatusAction.Type.Danger
enabled: !d.isBlocked
@ -528,14 +511,79 @@ Pane {
}
}
StatusDialogDivider {
ColumnLayout {
Layout.fillWidth: true
Layout.leftMargin: -column.anchors.leftMargin
Layout.rightMargin: -column.anchors.rightMargin
Layout.topMargin: -column.spacing
Layout.bottomMargin: -column.spacing
opacity: scrollView.atYBeginning ? 0 : 1
Behavior on opacity { OpacityAnimator {} }
spacing: 4
Item {
id: contactRow
Layout.fillWidth: true
Layout.preferredHeight: childrenRect.height
StatusBaseText {
id: contactName
anchors.left: parent.left
width: Math.min(implicitWidth, contactRow.width - verificationIcons.width - verificationIcons.anchors.leftMargin)
objectName: "ProfileDialog_displayName"
font.bold: true
font.pixelSize: 22
elide: Text.ElideRight
text: root.dirty ? root.dirtyValues.displayName
: d.mainDisplayName
}
StatusContactVerificationIcons {
id: verificationIcons
anchors.left: contactName.right
anchors.leftMargin: Style.current.halfPadding
anchors.verticalCenter: contactName.verticalCenter
objectName: "ProfileDialog_userVerificationIcons"
visible: !d.isCurrentUser
isContact: d.isContact
trustIndicator: d.contactDetails.trustStatus
isBlocked: d.isBlocked
tiny: false
}
}
RowLayout {
spacing: Style.current.halfPadding
StatusBaseText {
id: contactSecondaryName
color: Theme.palette.baseColor1
text: d.optionalDisplayName
visible: !!d.userNickName
}
Rectangle {
Layout.preferredWidth: 4
Layout.preferredHeight: 4
radius: width/2
color: Theme.palette.baseColor1
visible: contactSecondaryName.visible
}
StatusBaseText {
color: Theme.palette.baseColor1
text: Utils.getElidedCompressedPk(root.publicKey)
}
CopyButton {
Layout.leftMargin: -4
Layout.preferredWidth: 16
Layout.preferredHeight: 16
textToCopy: Utils.getCompressedPk(root.publicKey)
StatusToolTip {
text: qsTr("Copy Chat Key")
visible: parent.hovered
}
}
}
StatusBaseText {
Layout.fillWidth: true
Layout.topMargin: Style.current.halfPadding
wrapMode: Text.WrapAtWordBoundaryOrAnywhere
text: root.dirty ? root.dirtyValues.bio : d.contactDetails.bio
}
EmojiHash {
Layout.topMargin: Style.current.halfPadding
objectName: "ProfileDialog_userEmojiHash"
publicKey: root.publicKey
oneRow: true
}
}
StatusScrollView {
@ -551,117 +599,15 @@ Pane {
width: scrollView.availableWidth
spacing: 20
ProfileBioSocialsPanel {
Layout.fillWidth: true
Layout.leftMargin: column.anchors.leftMargin + Style.current.halfPadding
Layout.rightMargin: column.anchors.rightMargin + Style.current.halfPadding
bio: root.dirty ? root.dirtyValues.bio : d.contactDetails.bio
userSocialLinksJson: root.readOnly ? root.profileStore.temporarySocialLinksJson
: d.contactDetails.socialLinks
}
GridLayout {
Layout.fillWidth: true
Layout.leftMargin: column.anchors.leftMargin
Layout.rightMargin: column.anchors.rightMargin
flow: GridLayout.TopToBottom
rowSpacing: Style.current.halfPadding
columnSpacing: Style.current.bigPadding
visible: d.isCurrentUser
enabled: visible
columns: 2
rows: 4
StatusBaseText {
Layout.fillWidth: true
text: qsTr("Link to Profile")
font.pixelSize: 13
}
StatusBaseInput {
Layout.fillWidth: true
Layout.preferredHeight: 56
leftPadding: Style.current.padding
rightPadding: Style.current.halfPadding
topPadding: 0
bottomPadding: 0
placeholder.rightPadding: Style.current.halfPadding
placeholderText: d.linkToProfile
placeholderTextColor: Theme.palette.directColor1
edit.readOnly: true
rightComponent: StatusButton {
id: copyLinkBtn
anchors.verticalCenter: parent.verticalCenter
borderColor: Theme.palette.primaryColor1
size: StatusBaseButton.Size.Tiny
text: qsTr("Copy")
onClicked: {
text = qsTr("Copied")
root.profileStore.copyToClipboard(d.linkToProfile)
d.timer.setTimeout(function() {
copyLinkBtn.text = qsTr("Copy")
}, 2000);
}
}
}
StatusBaseText {
Layout.fillWidth: true
Layout.topMargin: Style.current.smallPadding
text: qsTr("Emoji Hash")
font.pixelSize: 13
}
StatusBaseInput {
Layout.fillWidth: true
Layout.preferredHeight: 56
leftPadding: Style.current.padding
rightPadding: Style.current.halfPadding
topPadding: 0
bottomPadding: 0
edit.readOnly: true
leftComponent: EmojiHash {
publicKey: root.publicKey
oneRow: !root.readOnly
}
rightComponent: StatusButton {
id: copyHashBtn
anchors.verticalCenter: parent.verticalCenter
borderColor: Theme.palette.primaryColor1
size: StatusBaseButton.Size.Tiny
text: qsTr("Copy")
onClicked: {
root.profileStore.copyToClipboard(Utils.getEmojiHashAsJson(root.publicKey).join("").toString())
text = qsTr("Copied")
d.timer.setTimeout(function() {
copyHashBtn.text = qsTr("Copy")
}, 2000);
}
}
}
Rectangle {
Layout.rowSpan: 4
Layout.fillHeight: true
Layout.preferredWidth: height
Layout.alignment: Qt.AlignCenter
color: "transparent"
border.width: 1
border.color: Theme.palette.baseColor2
radius: Style.current.halfPadding
Image {
anchors.centerIn: parent
asynchronous: true
fillMode: Image.PreserveAspectFit
width: 170
height: width
mipmap: true
smooth: false
source: root.profileStore.getQrCodeSource(Utils.getCompressedPk(root.profileStore.pubkey))
}
}
}
// TODO own tab in Showcase
// ProfileBioSocialsPanel {
// Layout.fillWidth: true
// Layout.leftMargin: column.anchors.leftMargin + Style.current.halfPadding
// Layout.rightMargin: column.anchors.rightMargin + Style.current.halfPadding
// bio: root.dirty ? root.dirtyValues.bio : d.contactDetails.bio
// userSocialLinksJson: root.readOnly ? root.profileStore.temporarySocialLinksJson
// : d.contactDetails.socialLinks
// }
StatusTabBar {
id: showcaseTabBar
@ -701,7 +647,6 @@ Pane {
profileStore: root.profileStore
walletStore: root.walletStore
networkConnectionStore: root.networkConnectionStore
communitiesModel: root.communitiesModel
onCloseRequested: root.closeRequested()
}

View File

@ -1,7 +1,4 @@
import QtQuick 2.12
import QtQuick.Controls 2.3
import QtQuick.Layouts 1.3
import QtQml.Models 2.3
import QtQuick 2.15
import StatusQ.Popups 0.1
import StatusQ.Components 0.1
@ -104,6 +101,7 @@ StatusMenu {
trustStatus: contactDetails && contactDetails.trustStatus ? contactDetails.trustStatus
: Constants.trustStatus.unknown
isContact: root.isContact
isBlocked: root.isBlockedContact
isCurrentUser: root.isMe
userIsEnsVerified: (!!contactDetails && contactDetails.ensVerified) || false
isBridgedAccount: root.isBridgedAccount
@ -124,6 +122,8 @@ StatusMenu {
}
}
// TODO Review contact request popup
SendMessageMenuItem {
id: sendMessageMenuItem
objectName: "sendMessage_StatusItem"
@ -147,7 +147,7 @@ StatusMenu {
StatusAction {
id: verifyIdentityAction
text: qsTr("Verify Identity")
text: qsTr("Request ID verification")
objectName: "verifyIdentity_StatusItem"
icon.name: "checkmark-circle"
enabled: !root.isMe && root.isContact
@ -160,14 +160,12 @@ StatusMenu {
root.close()
}
}
// TODO Mark as ID verified
StatusAction {
id: pendingIdentityAction
objectName: "pendingIdentity_StatusItem"
text: isVerificationRequestSent ||
root.incomingVerificationStatus === Constants.verificationStatus.verified ?
qsTr("ID Request Pending....") :
qsTr("Respond to ID Request...")
text: isVerificationRequestSent || root.incomingVerificationStatus === Constants.verificationStatus.verified ? qsTr("ID Request Pending...")
: qsTr("Respond to ID Request...")
icon.name: "checkmark-circle"
enabled: !root.isMe && root.isContact
&& !root.isBlockedContact && !root.isTrusted
@ -188,7 +186,7 @@ StatusMenu {
StatusAction {
id: renameAction
objectName: "rename_StatusItem"
text: qsTr("Rename")
text: contactDetails.localNickname ? qsTr("Edit nickname") : qsTr("Add nickname")
icon.name: "edit_pencil"
enabled: !root.isMe && !root.isBridgedAccount
onTriggered: {
@ -198,42 +196,46 @@ StatusMenu {
}
}
StatusAction {
id: unblockAction
objectName: "unblock_StatusItem"
text: qsTr("Unblock User")
icon.name: "remove-circle"
enabled: !root.isMe && root.isBlockedContact && !root.isBridgedAccount
onTriggered: Global.unblockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
}
StatusMenuSeparator {
visible: blockMenuItem.enabled
|| markUntrustworthyMenuItem.enabled
|| removeUntrustworthyMarkMenuItem.enabled
}
StatusAction {
id: unblockAction
objectName: "unblock_StatusItem"
text: qsTr("Unblock user")
icon.name: "cancel"
type: StatusAction.Type.Danger
enabled: !root.isMe && root.isBlockedContact && !root.isBridgedAccount
onTriggered: Global.unblockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
}
// TODO Remove ID verification + confirmation dialog
StatusAction {
id: markUntrustworthyMenuItem
objectName: "markUntrustworthy_StatusItem"
text: qsTr("Mark as Untrustworthy")
text: qsTr("Mark as untrusted")
icon.name: "warning"
type: StatusAction.Type.Danger
enabled: !root.isMe && root.userTrustIsUnknown && !root.isBridgedAccount
enabled: !root.isMe && root.userTrustIsUnknown && !root.isBridgedAccount && !root.isBlockedContact
onTriggered: root.store.contactsStore.markUntrustworthy(root.selectedUserPublicKey)
}
StatusAction {
id: removeUntrustworthyMarkMenuItem
objectName: "removeUntrustworthy_StatusItem"
text: qsTr("Remove Untrustworthy Mark")
text: qsTr("Remove untrusted mark")
icon.name: "warning"
type: StatusAction.Type.Danger
enabled: !root.isMe && root.userIsUntrustworthy && !root.isBridgedAccount
onTriggered: root.store.contactsStore.removeTrustStatus(root.selectedUserPublicKey)
}
StatusAction {
text: qsTr("Remove Contact")
text: qsTr("Remove contact")
objectName: "removeContact_StatusItem"
icon.name: "remove-contact"
type: StatusAction.Type.Danger
@ -247,11 +249,10 @@ StatusMenu {
StatusAction {
id: blockMenuItem
objectName: "blockUser_StatusItem"
text: qsTr("Block User")
text: qsTr("Block user")
icon.name: "cancel"
type: StatusAction.Type.Danger
enabled: !root.isMe && !root.isBlockedContact && !root.isBridgedAccount
onTriggered: Global.blockContactRequested(root.selectedUserPublicKey, root.selectedUserDisplayName)
}
}

View File

@ -25,7 +25,6 @@ Control {
property var profileStore
property var walletStore
property var networkConnectionStore
property var communitiesModel
signal closeRequested()
@ -303,10 +302,10 @@ Control {
}
StatusToolTip {
visible: hhandler.hovered && (!!model.name || !!model.description)
visible: hhandler.hovered && (!!model.name || !!model.collectionName)
text: {
const name = model.name
const descr = model.description
const descr = model.collectionName
const sep = !!name && !!descr ? "<br>" : ""
return `<b>${name}</b>${sep}${descr}`
}
@ -365,7 +364,8 @@ Control {
width: GridView.view.cellWidth - Style.current.halfPadding
height: GridView.view.cellHeight - Style.current.halfPadding
title: LocaleUtils.currencyAmountToLocaleString(model.enabledNetworkBalance)
title: model.name
//subTitle: LocaleUtils.currencyAmountToLocaleString(model.enabledNetworkBalance)
statusListItemTitle.font.weight: Font.Medium
tertiaryTitle: qsTr("%1% today %2")
.arg(LocaleUtils.numberToLocaleString(changePct24hour, changePct24hour === 0 ? 0 : 2)).arg(arrow)

View File

@ -0,0 +1,99 @@
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.Popups.Dialog 0.1
import utils 1.0
import shared.controls 1.0
StatusDialog {
id: root
required property string publicKey
required property string qrCode
required property string linkToProfile
footer: null
width: 500
topPadding: Style.current.padding
bottomPadding: Style.current.xlPadding
horizontalPadding: 80
contentItem: ColumnLayout {
spacing: Style.current.halfPadding
Image {
Layout.preferredWidth: 290
Layout.preferredHeight: 290
Layout.alignment: Qt.AlignHCenter
asynchronous: true
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: false
source: root.qrCode
}
StatusBaseText {
Layout.topMargin: Style.current.smallPadding
Layout.fillWidth: true
text: qsTr("Profile link")
}
StatusBaseInput {
Layout.fillWidth: true
Layout.preferredHeight: 44
leftPadding: Style.current.padding
rightPadding: Style.current.halfPadding
topPadding: 0
bottomPadding: 0
placeholder.rightPadding: Style.current.halfPadding
placeholderText: root.linkToProfile
placeholderTextColor: Theme.palette.directColor1
edit.readOnly: true
background.color: "transparent"
background.border.color: Theme.palette.baseColor2
rightComponent: CopyButton {
textToCopy: root.linkToProfile
StatusToolTip {
text: qsTr("Copy link")
visible: parent.hovered
}
}
}
StatusBaseText {
Layout.topMargin: Style.current.halfPadding
Layout.fillWidth: true
text: qsTr("Emoji hash")
}
StatusBaseInput {
Layout.fillWidth: true
Layout.preferredHeight: 44
leftPadding: Style.current.padding
rightPadding: Style.current.halfPadding
topPadding: 0
bottomPadding: 0
edit.readOnly: true
background.color: "transparent"
background.border.color: Theme.palette.baseColor2
leftComponent: EmojiHash {
publicKey: root.publicKey
oneRow: true
}
rightComponent: CopyButton {
textToCopy: Utils.getEmojiHashAsJson(root.publicKey).join("").toString()
StatusToolTip {
text: qsTr("Copy emoji hash")
visible: parent.hovered
}
}
}
}
}

View File

@ -1 +1,2 @@
ProfileShowcaseView 1.0 ProfileShowcaseView.qml
ShareProfileDialog 1.0 ShareProfileDialog.qml

View File

@ -573,7 +573,7 @@ QtObject {
if (publicKey === "") {
return ""
}
return StatusQUtils.Utils.elideText(publicKey, 5, 3)
return StatusQUtils.Utils.elideText(publicKey, 3, 6)
}
function getElidedCommunityPK(publicKey) {
@ -588,7 +588,7 @@ QtObject {
return ""
}
let compressedPk = getCompressedPk(publicKey)
return getElidedPk(compressedPk, 6, 3)
return getElidedPk(compressedPk)
}
function elideIfTooLong(str, maxLength) {