mirror of
https://github.com/status-im/status-desktop.git
synced 2025-01-09 13:56:10 +00:00
fa4755ce9e
+ store the card state in user settings + amend the BannerCard close button state. It needs to change color on hover and to become visible only when the card is hovered.
660 lines
25 KiB
QML
660 lines
25 KiB
QML
import QtQuick 2.15
|
|
import QtQuick.Layouts 1.15
|
|
import QtQuick.Controls 2.15
|
|
import QtQml 2.15
|
|
|
|
import StatusQ 0.1
|
|
import StatusQ.Components 0.1
|
|
import StatusQ.Controls 0.1
|
|
import StatusQ.Core 0.1
|
|
import StatusQ.Core.Theme 0.1
|
|
import StatusQ.Core.Utils 0.1
|
|
import StatusQ.Models 0.1
|
|
import StatusQ.Popups 0.1
|
|
import StatusQ.Popups.Dialog 0.1
|
|
|
|
import shared.controls 1.0
|
|
import shared.panels 1.0
|
|
import shared.popups 1.0
|
|
|
|
import utils 1.0
|
|
|
|
import AppLayouts.Wallet.views.collectibles 1.0
|
|
import AppLayouts.Wallet.controls 1.0
|
|
|
|
import SortFilterProxyModel 0.2
|
|
|
|
ColumnLayout {
|
|
id: root
|
|
|
|
required property var ownedAccountsModel
|
|
required property var controller
|
|
required property string addressFilters
|
|
required property string networkFilters
|
|
property bool sendEnabled: true
|
|
property bool filterVisible
|
|
property bool isFetching: false // Indicates if a collectibles page is being loaded from the backend
|
|
property bool isUpdating: false // Indicates if the collectibles list is being updated
|
|
property bool isError: false // Indicates an error occurred while updating/fetching the collectibles list
|
|
property alias bannerComponent: banner.sourceComponent
|
|
|
|
// allows/disables choosing custom sort order from a sorter
|
|
property bool customOrderAvailable
|
|
|
|
property alias selectedFilterGroupIds: cmbFilter.selectedFilterGroupIds
|
|
|
|
signal collectibleClicked(int chainId, string contractAddress, string tokenId, string uid, int tokenType, string communityId)
|
|
signal sendRequested(string symbol, int tokenType, string fromAddress)
|
|
signal receiveRequested(string symbol)
|
|
signal switchToCommunityRequested(string communityId)
|
|
signal manageTokensRequested()
|
|
|
|
spacing: 0
|
|
|
|
function setSortOrder(order) {
|
|
d.sortOrder = order
|
|
}
|
|
|
|
function getSortOrder() {
|
|
return d.sortOrder
|
|
}
|
|
|
|
function getSortValue() {
|
|
return d.sortValue
|
|
}
|
|
|
|
function sortByValue(value) {
|
|
d.sortValue = value
|
|
}
|
|
|
|
QtObject {
|
|
id: d
|
|
|
|
property int sortValue: SortOrderComboBox.TokenOrderAlpha
|
|
property int sortOrder: Qt.DescendingOrder
|
|
|
|
readonly property int cellHeight: 225
|
|
readonly property int communityCellHeight: 242
|
|
readonly property int cellWidth: 176
|
|
readonly property int headerHeight: 56
|
|
|
|
readonly property bool isCustomView: cmbTokenOrder.currentValue === SortOrderComboBox.TokenOrderCustom
|
|
|
|
readonly property var sourceModel: root.controller.sourceModel
|
|
readonly property bool isLoading: root.isUpdating || root.isFetching
|
|
|
|
function setSortByDateIsDisabled(value) {
|
|
const orderByDateIndex = cmbTokenOrder.indexOfValue(SortOrderComboBox.TokenOrderDateAdded)
|
|
|
|
cmbTokenOrder.model[orderByDateIndex].isDisabled = value
|
|
cmbTokenOrder.modelChanged()
|
|
|
|
if (!value && cmbTokenOrder.currentIndex === orderByDateIndex) {
|
|
cmbTokenOrder.indexOfValue(SortOrderComboBox.TokenOrderAlpha)
|
|
}
|
|
}
|
|
|
|
onIsLoadingChanged: {
|
|
d.loadingItemsModel.refresh()
|
|
}
|
|
|
|
readonly property var loadingItemsModel: ListModel {
|
|
Component.onCompleted: {
|
|
refresh()
|
|
}
|
|
|
|
function refresh() {
|
|
clear()
|
|
if (d.isLoading) {
|
|
for (let i = 0; i < 10; i++) {
|
|
append({ isLoading: true, name: qsTr("Loading collectible...") })
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
readonly property var communityModel: CustomSFPM {
|
|
isCommunity: true
|
|
}
|
|
|
|
readonly property var communityModelWithLoadingItems: ConcatModel {
|
|
sources: [
|
|
SourceModel {
|
|
model: d.communityModel
|
|
markerRoleValue: "communityModel"
|
|
},
|
|
SourceModel {
|
|
model: d.loadingItemsModel
|
|
markerRoleValue: "loadingItemsModel"
|
|
}
|
|
]
|
|
|
|
markerRoleName: "sourceGroup"
|
|
}
|
|
|
|
readonly property var nonCommunityModel: CustomSFPM {
|
|
isCommunity: false
|
|
}
|
|
|
|
readonly property var nonCommunityModelWithLoadingItems: ConcatModel {
|
|
sources: [
|
|
SourceModel {
|
|
model: d.nonCommunityModel
|
|
markerRoleValue: "nonCommunityModel"
|
|
},
|
|
SourceModel {
|
|
model: d.loadingItemsModel
|
|
markerRoleValue: "loadingItemsModel"
|
|
}
|
|
]
|
|
|
|
markerRoleName: "sourceGroup"
|
|
}
|
|
|
|
readonly property var allCollectiblesModel: ConcatModel {
|
|
sources: [
|
|
SourceModel {
|
|
model: d.communityModel
|
|
markerRoleValue: "loadingItemsModel"
|
|
},
|
|
SourceModel {
|
|
model: d.nonCommunityModel
|
|
markerRoleValue: "nonCommunityModel"
|
|
}
|
|
]
|
|
markerRoleName: "sourceGroup"
|
|
}
|
|
|
|
|
|
readonly property bool hasRegularCollectibles: d.nonCommunityModel.count || d.loadingItemsModel.count
|
|
readonly property bool hasCommunityCollectibles: d.communityModel.count || d.loadingItemsModel.count
|
|
readonly property bool onlyRegularCollectiblesType: hasRegularCollectibles && !hasCommunityCollectibles
|
|
|
|
readonly property var nwFilters: root.networkFilters.split(":")
|
|
readonly property var addrFilters: root.addressFilters.split(":").map((addr) => addr.toLowerCase())
|
|
|
|
function getLatestTimestamp(ownership, filterList) {
|
|
let latest = 0
|
|
|
|
if (!!ownership) {
|
|
for (let i = 0; i < ownership.count; i++) {
|
|
let accountAddress = ModelUtils.get(ownership, i, "accountAddress").toLowerCase()
|
|
if (filterList.includes(accountAddress)) {
|
|
let txTimestamp = ModelUtils.get(ownership, i, "txTimestamp")
|
|
latest = Math.max(latest, txTimestamp)
|
|
}
|
|
}
|
|
}
|
|
return latest
|
|
}
|
|
|
|
function getBalance(ownership, filterList) {
|
|
// Balance is a Uint256, so we need to use AmountsArithmetic to handle it
|
|
let balance = AmountsArithmetic.fromNumber(0)
|
|
|
|
if (!!ownership) {
|
|
for (let i = 0; i < ownership.count; i++) {
|
|
let accountAddress = ModelUtils.get(ownership, i, "accountAddress").toLowerCase()
|
|
if (filterList.includes(accountAddress)) {
|
|
let tokenBalanceStr = ModelUtils.get(ownership, i, "balance")+""
|
|
if (tokenBalanceStr !== "") {
|
|
let tokenBalance = AmountsArithmetic.fromString(tokenBalanceStr)
|
|
balance = AmountsArithmetic.sum(balance, tokenBalance)
|
|
}
|
|
}
|
|
}
|
|
// For simplicity, we limit the result to the maximum int manageable by QML
|
|
const maxInt = 2147483647
|
|
if (AmountsArithmetic.cmp(balance, AmountsArithmetic.fromNumber(maxInt)) === 1) {
|
|
return maxInt
|
|
}
|
|
}
|
|
return AmountsArithmetic.toNumber(balance)
|
|
}
|
|
|
|
function getFirstUserOwnedAddress(ownershipModel) {
|
|
if (!ownershipModel) return ""
|
|
|
|
for (let i = 0; i < ownershipModel.rowCount(); i++) {
|
|
const accountAddress = ModelUtils.get(ownershipModel, i, "accountAddress")
|
|
if (ModelUtils.contains(root.ownedAccountsModel, "address", accountAddress, Qt.CaseInsensitive))
|
|
return accountAddress
|
|
}
|
|
return ""
|
|
}
|
|
|
|
property FunctionAggregator hasAllTimestampsAggregator: FunctionAggregator {
|
|
model: d.allCollectiblesModel
|
|
initialValue: true
|
|
roleName: "lastTxTimestamp"
|
|
|
|
aggregateFunction: (aggr, value) => aggr && value > 0
|
|
|
|
onValueChanged: {
|
|
Qt.callLater(() => {
|
|
d.hasAllTimestamps = value
|
|
d.setSortByDateIsDisabled(value)
|
|
})
|
|
}
|
|
|
|
Component.onCompleted: d.hasAllTimestamps = value
|
|
}
|
|
|
|
property bool hasAllTimestamps
|
|
}
|
|
|
|
component CustomSFPM: SortFilterProxyModel {
|
|
id: customFilter
|
|
property bool isCommunity
|
|
|
|
sourceModel: d.sourceModel
|
|
proxyRoles: [
|
|
FastExpressionRole {
|
|
name: "groupName"
|
|
expression: !!model.communityId ? model.communityName : model.collectionName
|
|
expectedRoles: ["communityId", "collectionName", "communityName"]
|
|
},
|
|
FastExpressionRole {
|
|
name: "balance"
|
|
expression: {
|
|
d.addrFilters
|
|
return d.getBalance(model.ownership, d.addrFilters)
|
|
}
|
|
expectedRoles: ["ownership"]
|
|
},
|
|
FastExpressionRole {
|
|
name: "lastTxTimestamp"
|
|
expression: {
|
|
d.addrFilters
|
|
return d.getLatestTimestamp(model.ownership, d.addrFilters)
|
|
}
|
|
expectedRoles: ["ownership"]
|
|
}
|
|
]
|
|
filters: [
|
|
FastExpressionFilter {
|
|
expression: {
|
|
return d.nwFilters.includes(model.chainId+"")
|
|
}
|
|
expectedRoles: ["chainId"]
|
|
},
|
|
ValueFilter {
|
|
roleName: "balance"
|
|
value: 0
|
|
inverted: true
|
|
},
|
|
FastExpressionFilter {
|
|
expression: {
|
|
root.controller.revision
|
|
return root.controller.filterAcceptsSymbol(model.symbol) && (customFilter.isCommunity ? !!model.communityId : !model.communityId)
|
|
}
|
|
expectedRoles: ["symbol", "communityId"]
|
|
},
|
|
FastExpressionFilter {
|
|
enabled: customFilter.isCommunity && cmbFilter.hasEnabledFilters
|
|
expression: cmbFilter.selectedFilterGroupIds.includes(model.communityId) ||
|
|
(!model.communityId && cmbFilter.selectedFilterGroupIds.includes(""))
|
|
expectedRoles: ["communityId"]
|
|
},
|
|
FastExpressionFilter {
|
|
enabled: !customFilter.isCommunity && cmbFilter.hasEnabledFilters
|
|
expression: cmbFilter.selectedFilterGroupIds.includes(model.collectionUid) ||
|
|
(!model.collectionUid && cmbFilter.selectedFilterGroupIds.includes(""))
|
|
expectedRoles: ["collectionUid"]
|
|
}
|
|
]
|
|
sorters: [
|
|
FastExpressionSorter {
|
|
expression: {
|
|
root.controller.revision
|
|
return root.controller.compareTokens(modelLeft.symbol, modelRight.symbol)
|
|
}
|
|
enabled: d.isCustomView
|
|
expectedRoles: ["symbol"]
|
|
},
|
|
RoleSorter {
|
|
roleName: cmbTokenOrder.currentSortRoleName
|
|
sortOrder: cmbTokenOrder.currentSortOrder
|
|
enabled: !d.isCustomView
|
|
}
|
|
]
|
|
}
|
|
|
|
ColumnLayout {
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: false
|
|
Layout.preferredHeight: root.filterVisible ? implicitHeight : 0
|
|
spacing: 20
|
|
opacity: root.filterVisible ? 1 : 0
|
|
|
|
Behavior on Layout.preferredHeight { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
|
|
Behavior on opacity { NumberAnimation { duration: 200; easing.type: Easing.InOutQuad } }
|
|
|
|
StatusDialogDivider {
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
RowLayout {
|
|
Layout.fillWidth: true
|
|
spacing: Theme.halfPadding
|
|
|
|
FilterComboBox {
|
|
id: cmbFilter
|
|
sourceModel: SortFilterProxyModel {
|
|
sourceModel: d.sourceModel
|
|
proxyRoles: [
|
|
FastExpressionRole {
|
|
name: "balance"
|
|
expression: {
|
|
d.addrFilters
|
|
return d.getBalance(model.ownership, d.addrFilters)
|
|
}
|
|
expectedRoles: ["ownership"]
|
|
}
|
|
]
|
|
filters: [
|
|
FastExpressionFilter {
|
|
expression: {
|
|
return d.nwFilters.includes(model.chainId+"")
|
|
}
|
|
expectedRoles: ["chainId"]
|
|
},
|
|
ValueFilter {
|
|
roleName: "balance"
|
|
value: 0
|
|
inverted: true
|
|
}
|
|
]
|
|
}
|
|
|
|
regularTokensModel: root.controller.regularTokensModel
|
|
collectionGroupsModel: root.controller.collectionGroupsModel
|
|
communityTokenGroupsModel: root.controller.communityTokenGroupsModel
|
|
hasCommunityGroups: d.hasCommunityCollectibles
|
|
}
|
|
|
|
Rectangle {
|
|
Layout.preferredHeight: 34
|
|
Layout.preferredWidth: 1
|
|
Layout.leftMargin: 12
|
|
Layout.rightMargin: 12
|
|
color: Theme.palette.baseColor2
|
|
}
|
|
|
|
StatusBaseText {
|
|
color: Theme.palette.baseColor1
|
|
font.pixelSize: Theme.additionalTextSize
|
|
text: qsTr("Sort by:")
|
|
}
|
|
|
|
SortOrderComboBox {
|
|
id: cmbTokenOrder
|
|
hasCustomOrderDefined: root.customOrderAvailable
|
|
Binding on currentIndex {
|
|
value: {
|
|
cmbTokenOrder.count
|
|
let sortValue = d.sortValue
|
|
if (root.sortValue === SortOrderComboBox.TokenOrderDateAdded && !d.hasAllTimestamps)
|
|
sortValue = SortOrderComboBox.TokenOrderAlpha
|
|
let id = cmbTokenOrder.indexOfValue(sortValue)
|
|
if (id === -1)
|
|
id = cmbTokenOrder.indexOfValue(SortOrderComboBox.TokenOrderAlpha)
|
|
return id
|
|
}
|
|
when: cmbTokenOrder.count > 0
|
|
}
|
|
onCurrentValueChanged: d.sortValue = cmbTokenOrder.currentValue
|
|
Binding on currentSortOrder {
|
|
value: d.sortOrder
|
|
}
|
|
onCurrentSortOrderChanged: d.sortOrder = cmbTokenOrder.currentSortOrder
|
|
model: [
|
|
{ value: SortOrderComboBox.TokenOrderDateAdded, text: qsTr("Date added"), icon: "", sortRoleName: "lastTxTimestamp", isDisabled: !d.hasAllTimestamps }, // Custom SFPM role
|
|
{ value: SortOrderComboBox.TokenOrderAlpha, text: qsTr("Collectible name"), icon: "", sortRoleName: "name" },
|
|
{ value: SortOrderComboBox.TokenOrderGroupName, text: qsTr("Collection/community name"), icon: "", sortRoleName: "groupName" }, // Custom SFPM role communityName || collectionName
|
|
{ value: SortOrderComboBox.TokenOrderCustom, text: qsTr("Custom order"), icon: "", sortRoleName: "" },
|
|
{ value: SortOrderComboBox.TokenOrderNone, text: "---", icon: "", sortRoleName: "" }, // separator
|
|
{ value: SortOrderComboBox.TokenOrderCreateCustom, text: hasCustomOrderDefined ? qsTr("Edit custom order →") : qsTr("Create custom order →"),
|
|
icon: "", sortRoleName: "" }
|
|
]
|
|
onCreateOrEditRequested: {
|
|
root.manageTokensRequested()
|
|
}
|
|
}
|
|
|
|
Item { Layout.fillWidth: true }
|
|
|
|
StatusLinkText {
|
|
visible: cmbFilter.hasEnabledFilters
|
|
normalColor: Theme.palette.primaryColor1
|
|
text: qsTr("Clear filter")
|
|
onClicked: cmbFilter.clearFilter()
|
|
}
|
|
}
|
|
|
|
StatusDialogDivider {
|
|
Layout.fillWidth: true
|
|
}
|
|
}
|
|
|
|
Loader {
|
|
id: banner
|
|
Layout.fillWidth: true
|
|
}
|
|
|
|
ShapeRectangle {
|
|
Layout.fillWidth: true
|
|
Layout.topMargin: Theme.padding
|
|
visible: !d.hasRegularCollectibles && !d.hasCommunityCollectibles
|
|
text: qsTr("Collectibles will appear here")
|
|
}
|
|
|
|
DoubleFlickableWithFolding {
|
|
id: doubleFlickable
|
|
|
|
Layout.fillWidth: true
|
|
Layout.fillHeight: true
|
|
|
|
clip: true
|
|
|
|
flickable1: CustomGridView {
|
|
id: communityCollectiblesView
|
|
|
|
header: d.hasCommunityCollectibles ? communityHeaderComponent : null
|
|
width: doubleFlickable.width
|
|
cellHeight: d.communityCellHeight
|
|
model: d.communityModelWithLoadingItems
|
|
|
|
Component {
|
|
id: communityHeaderComponent
|
|
|
|
FoldableHeader {
|
|
height: d.headerHeight
|
|
width: doubleFlickable.width
|
|
title: qsTr("Community minted")
|
|
titleColor: Theme.palette.baseColor1
|
|
folded: doubleFlickable.flickable1Folded
|
|
rightAdditionalComponent: StatusFlatButton {
|
|
icon.name: "info"
|
|
textColor: Theme.palette.baseColor1
|
|
|
|
onClicked: Global.openPopup(communityInfoPopupCmp)
|
|
}
|
|
onToggleFolding:doubleFlickable.flip1Folding()
|
|
}
|
|
}
|
|
}
|
|
|
|
flickable2: CustomGridView {
|
|
id: regularCollectiblesView
|
|
|
|
header: !d.hasRegularCollectibles || d.onlyRegularCollectiblesType ? null : regularHeaderComponent
|
|
width: doubleFlickable.width
|
|
cellHeight: d.cellHeight
|
|
model: d.nonCommunityModelWithLoadingItems
|
|
|
|
Component {
|
|
id: regularHeaderComponent
|
|
|
|
FoldableHeader {
|
|
height: d.headerHeight
|
|
width: doubleFlickable.width
|
|
title: qsTr("Others")
|
|
titleColor: Theme.palette.baseColor1
|
|
folded: doubleFlickable.flickable2Folded
|
|
|
|
onToggleFolding:doubleFlickable.flip2Folding()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
component CustomGridView: StatusGridView {
|
|
id: gridView
|
|
|
|
interactive: false
|
|
|
|
cellWidth: d.cellWidth
|
|
delegate: collectibleDelegate
|
|
}
|
|
|
|
Component {
|
|
id: collectibleDelegate
|
|
CollectibleView {
|
|
width: d.cellWidth
|
|
height: isCommunityCollectible ? d.communityCellHeight : d.cellHeight
|
|
title: model.name ?? ""
|
|
subTitle: model.collectionName ? model.collectionName : model.collectionUid ? model.collectionUid : ""
|
|
mediaUrl: model.mediaUrl ?? ""
|
|
mediaType: model.mediaType ?? ""
|
|
fallbackImageUrl: model.imageUrl ?? ""
|
|
backgroundColor: model.backgroundColor ? model.backgroundColor : "transparent"
|
|
isLoading: !!model.isLoading
|
|
isMetadataValid: !!model.isMetadataValid
|
|
privilegesLevel: model.communityPrivilegesLevel ?? Constants.TokenPrivilegesLevel.Community
|
|
ornamentColor: model.communityColor ?? "transparent"
|
|
communityId: model.communityId ?? ""
|
|
communityName: model.communityName ?? ""
|
|
communityImage: model.communityImage ?? ""
|
|
balance: model.balance ?? 1
|
|
|
|
onClicked: root.collectibleClicked(model.chainId, model.contractAddress, model.tokenId, model.symbol, model.tokenType, model.communityId ?? "")
|
|
onRightClicked: {
|
|
const userOwnedAddress = d.getFirstUserOwnedAddress(model.ownership)
|
|
Global.openMenu(tokenContextMenu, this,
|
|
{symbol: model.symbol, tokenName: model.name, tokenImage: model.imageUrl,
|
|
communityId: model.communityId, communityName: model.communityName,
|
|
communityImage: model.communityImage, tokenType: model.tokenType,
|
|
soulbound: model.soulbound, userOwnedAddress: userOwnedAddress})
|
|
}
|
|
onSwitchToCommunityRequested: (communityId) => root.switchToCommunityRequested(communityId)
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: tokenContextMenu
|
|
StatusMenu {
|
|
id: tokenMenu
|
|
onClosed: destroy()
|
|
|
|
property string symbol
|
|
property string tokenName
|
|
property string tokenImage
|
|
property string communityId
|
|
property string communityName
|
|
property string communityImage
|
|
property string userOwnedAddress
|
|
property int tokenType
|
|
property bool ownedByUser: !!userOwnedAddress
|
|
property bool soulbound
|
|
|
|
// Show send button for owned collectibles
|
|
// Disable send button for owned soulbound collectibles
|
|
Instantiator {
|
|
model: tokenMenu.ownedByUser ? 1 : 0
|
|
delegate: StatusAction {
|
|
enabled: root.sendEnabled && !tokenMenu.soulbound
|
|
visibleOnDisabled: true
|
|
icon.name: "send"
|
|
text: qsTr("Send")
|
|
onTriggered: root.sendRequested(tokenMenu.symbol, tokenMenu.tokenType, tokenMenu.userOwnedAddress)
|
|
}
|
|
onObjectAdded: tokenMenu.insertAction(0, object)
|
|
onObjectRemoved: tokenMenu.removeAction(0)
|
|
}
|
|
|
|
StatusAction {
|
|
icon.name: "receive"
|
|
text: qsTr("Receive")
|
|
onTriggered: root.receiveRequested(symbol)
|
|
}
|
|
StatusMenuSeparator {}
|
|
StatusAction {
|
|
icon.name: "settings"
|
|
text: qsTr("Manage tokens")
|
|
onTriggered: root.manageTokensRequested()
|
|
}
|
|
StatusAction {
|
|
enabled: symbol !== Constants.ethToken
|
|
type: StatusAction.Type.Danger
|
|
icon.name: "hide"
|
|
text: qsTr("Hide collectible")
|
|
onTriggered: Global.openConfirmHideCollectiblePopup(symbol, tokenName, tokenImage, !!communityId)
|
|
}
|
|
StatusAction {
|
|
enabled: !!communityId
|
|
type: StatusAction.Type.Danger
|
|
icon.name: "hide"
|
|
text: qsTr("Hide all collectibles from this community")
|
|
onTriggered: Global.openPopup(confirmHideCommunityCollectiblesPopup, {communityId, communityName, communityImage})
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: communityInfoPopupCmp
|
|
StatusDialog {
|
|
destroyOnClose: true
|
|
title: qsTr("What are community collectibles?")
|
|
standardButtons: Dialog.Ok
|
|
width: 520
|
|
contentItem: StatusBaseText {
|
|
wrapMode: Text.Wrap
|
|
text: qsTr("Community collectibles are collectibles that have been minted by a community. As these collectibles cannot be verified, always double check their origin and validity before interacting with them. If in doubt, ask a trusted member or admin of the relevant community.")
|
|
}
|
|
}
|
|
}
|
|
|
|
Component {
|
|
id: confirmHideCommunityCollectiblesPopup
|
|
ConfirmationDialog {
|
|
property string communityId
|
|
property string communityName
|
|
property string communityImage
|
|
|
|
width: 520
|
|
destroyOnClose: true
|
|
confirmButtonLabel: qsTr("Hide '%1' collectibles").arg(communityName)
|
|
cancelBtnType: ""
|
|
showCancelButton: true
|
|
headerSettings.title: qsTr("Hide %1 community collectibles").arg(communityName)
|
|
headerSettings.asset.name: communityImage
|
|
confirmationText: qsTr("Are you sure you want to hide all community collectibles minted by %1? You will no longer see or be able to interact with these collectibles anywhere inside Status.").arg(communityName)
|
|
onCancelButtonClicked: close()
|
|
onConfirmButtonClicked: {
|
|
root.controller.showHideGroup(communityId, false)
|
|
close()
|
|
Global.displayToastMessage(
|
|
qsTr("%1 community collectibles were successfully hidden. You can toggle collectible visibility via %2.").arg(communityName)
|
|
.arg(`<a style="text-decoration:none" href="#${Constants.appSection.profile}/${Constants.settingsSubsection.wallet}/${Constants.walletSettingsSubsection.manageCollectibles}">` + qsTr("Settings", "Go to Settings") + "</a>"),
|
|
"",
|
|
"checkmark-circle",
|
|
false,
|
|
Constants.ephemeralNotificationType.success,
|
|
""
|
|
)
|
|
}
|
|
}
|
|
}
|
|
}
|