feat(token mgmt): update main wallet view layout with community assets
- update the CollectiblesView.qml view and delegates according to the latest design - add CollectiblesView to Storybook - add new section for Community Collectibles - (re)use the community badge with tooltip and link action to take the user to the respective community - add Community Collectibles info icon + popup - create context menu for token delegates with actions (Send/Receive/Manage tokens/Hide) - add confirmation popups when hiding a single or all community tokens - emit a toast bubble after hiding the token(s) - fix eliding the community name inside ManageTokensCommunityTag - some smaller fixes/cleanups Fixes #12519
This commit is contained in:
parent
e2fa702ec4
commit
d7614beb99
|
@ -0,0 +1,69 @@
|
|||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import StatusQ.Core 0.1
|
||||
|
||||
import mainui 1.0
|
||||
import utils 1.0
|
||||
|
||||
import AppLayouts.Wallet.views 1.0
|
||||
|
||||
import shared.views 1.0
|
||||
|
||||
import Storybook 1.0
|
||||
import Models 1.0
|
||||
|
||||
SplitView {
|
||||
id: root
|
||||
|
||||
Logs { id: logs }
|
||||
|
||||
orientation: Qt.Horizontal
|
||||
|
||||
ManageCollectiblesModel {
|
||||
id: collectiblesModel
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: emptyModel
|
||||
}
|
||||
|
||||
Popups {
|
||||
popupParent: root
|
||||
rootStore: QtObject {}
|
||||
communityTokensStore: QtObject {}
|
||||
}
|
||||
|
||||
CollectiblesView {
|
||||
id: assetsView
|
||||
SplitView.preferredWidth: 600
|
||||
SplitView.fillHeight: true
|
||||
collectiblesModel: ctrlEmptyModel.checked ? emptyModel : collectiblesModel
|
||||
onCollectibleClicked: logs.logEvent("onCollectibleClicked", ["chainId", "contractAddress", "tokenId", "uid"], arguments)
|
||||
onSendRequested: logs.logEvent("onSendRequested", ["symbol"], arguments)
|
||||
onReceiveRequested: logs.logEvent("onReceiveRequested", ["symbol"], arguments)
|
||||
onSwitchToCommunityRequested: logs.logEvent("onSwitchToCommunityRequested", ["communityId"], arguments)
|
||||
onManageTokensRequested: logs.logEvent("onManageTokensRequested")
|
||||
}
|
||||
|
||||
LogsAndControlsPanel {
|
||||
id: logsAndControlsPanel
|
||||
|
||||
SplitView.minimumWidth: 150
|
||||
SplitView.preferredWidth: 250
|
||||
|
||||
logsView.logText: logs.logText
|
||||
|
||||
ColumnLayout {
|
||||
Switch {
|
||||
id: ctrlEmptyModel
|
||||
text: "Empty model"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// category: Views
|
||||
// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?type=design&node-id=19558-95270&mode=design&t=ShZOuMRfiIIl2aR8-0
|
||||
// https://www.figma.com/file/idUoxN7OIW2Jpp3PMJ1Rl8/%E2%9A%99%EF%B8%8F-Settings-%7C-Desktop?type=design&node-id=19558-96427&mode=design&t=ShZOuMRfiIIl2aR8-0
|
|
@ -36,7 +36,7 @@ ListModel {
|
|||
uid: "pp23",
|
||||
name: "pepepunk#23",
|
||||
collectionUid: "pepepunks",
|
||||
collectionName: "",
|
||||
collectionName: "Pepepunks",
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
imageUrl: "https://i.seadn.io/s/raw/files/ba2811bb5cd0bed67529d69fa92ef5aa.jpg?auto=format&dpr=1&w=1000",
|
||||
|
@ -51,7 +51,7 @@ ListModel {
|
|||
communityId: "",
|
||||
communityName: "",
|
||||
imageUrl: ModelsData.collectibles.kitty1Big,
|
||||
isLoading: false,
|
||||
isLoading: true,
|
||||
backgroundColor: ""
|
||||
},
|
||||
{
|
||||
|
@ -94,7 +94,7 @@ ListModel {
|
|||
collectionUid: "",
|
||||
collectionName: "",
|
||||
communityId: "bbrz",
|
||||
communityName: "Bearz",
|
||||
communityName: "Bearz with a very long name",
|
||||
communityImage: "https://i.seadn.io/gcs/files/4a875f997063f4f3772190852c1c44f0.png?w=128&auto=format",
|
||||
imageUrl: "https://assets.killabears.com/content/killabears/transparent-512/2385-86ba13cc6945ed0aea7c32a363a96be2f218898358745ae07b947452cb7e4e79.png",
|
||||
isLoading: false,
|
||||
|
@ -102,7 +102,7 @@ ListModel {
|
|||
},
|
||||
{
|
||||
uid: "fp#3195",
|
||||
name: "Frenly Panda #3195",
|
||||
name: "Frenly Panda #3195324354654756756756784234523",
|
||||
collectionUid: "",
|
||||
collectionName: "",
|
||||
communityId: "fpan",
|
||||
|
@ -140,7 +140,7 @@ ListModel {
|
|||
uid: "pp21",
|
||||
name: "pepepunk#21",
|
||||
collectionUid: "pepepunks",
|
||||
collectionName: "",
|
||||
collectionName: "Pepepunks",
|
||||
communityId: "",
|
||||
communityName: "",
|
||||
imageUrl: "https://i.seadn.io/s/raw/files/cfa559bb63e4378f17649c1e3b8f18fe.jpg?auto=format&dpr=1&w=1000",
|
||||
|
|
|
@ -35,13 +35,14 @@ Rectangle {
|
|||
|
||||
RowLayout {
|
||||
id: rootLayout
|
||||
spacing: 0
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.leftMargin: 16
|
||||
anchors.rightMargin: 18
|
||||
|
||||
Row {
|
||||
RowLayout {
|
||||
id: leftButtonsLayout
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignLeft
|
||||
visible: statusModalFooter.showFooter
|
||||
|
@ -51,10 +52,9 @@ Rectangle {
|
|||
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
implicitHeight: 1
|
||||
}
|
||||
|
||||
Row {
|
||||
RowLayout {
|
||||
id: rightButtonsLayout
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
visible: statusModalFooter.showFooter
|
||||
|
|
|
@ -335,12 +335,11 @@ StatusDropdown {
|
|||
|
||||
//When the collectible is unique, there is no need for the user to select amount
|
||||
//Just send the add/update events
|
||||
if(item.supply.toString() === "1"
|
||||
|| (item.remainingSupply
|
||||
&& item.remainingSupply.toString() === "1")) {
|
||||
if((item.supply && item.supply.toString() === "1")
|
||||
|| (item.remainingSupply && item.remainingSupply.toString() === "1")) {
|
||||
root.collectibleAmount = "1"
|
||||
d.updateSelected ? root.updateCollectible(root.collectibleKey, "1")
|
||||
: root.addCollectible(root.collectibleKey, "1")
|
||||
: root.addCollectible(root.collectibleKey, "1")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,9 +47,12 @@ Control {
|
|||
visible: !!image.source
|
||||
}
|
||||
StatusBaseText {
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: Style.current.tertiaryTextFontSize
|
||||
font.weight: Font.Medium
|
||||
text: root.text
|
||||
elide: Text.ElideRight
|
||||
color: enabled ? Theme.palette.directColor1 : Theme.palette.baseColor1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -77,7 +77,7 @@ Control {
|
|||
// LayoutMirroring.childrenInherit: true
|
||||
// id: switchArrangeByCollection
|
||||
// textColor: Theme.palette.baseColor1
|
||||
// text: qsTr("Arrange by collection (TODO)")
|
||||
// text: qsTr("Arrange by collection")
|
||||
// visible: d.controller.regularTokensModel.count
|
||||
// }
|
||||
|
||||
|
|
|
@ -1,5 +1,2 @@
|
|||
LeftTabView 1.0 LeftTabView.qml
|
||||
WalletHeader 1.0 WalletHeader.qml
|
||||
CollectiblesView 1.0 CollectiblesView.qml
|
||||
WalletLayout 1.0 WalletLayout.qml
|
||||
singleton WalletUtils 1.0 WalletUtils.qml
|
||||
|
|
|
@ -1,105 +1,374 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.13
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtQuick.Controls 2.15
|
||||
|
||||
import StatusQ 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Components 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Models 0.1
|
||||
import StatusQ.Internal 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 "collectibles"
|
||||
import AppLayouts.Wallet.views.collectibles 1.0
|
||||
|
||||
Item {
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
StatusScrollView {
|
||||
id: root
|
||||
property var collectiblesModel
|
||||
width: parent.width
|
||||
|
||||
required property var collectiblesModel
|
||||
property bool sendEnabled: true
|
||||
|
||||
signal collectibleClicked(int chainId, string contractAddress, string tokenId, string uid)
|
||||
signal sendRequested(string symbol)
|
||||
signal receiveRequested(string symbol)
|
||||
signal switchToCommunityRequested(string communityId)
|
||||
signal manageTokensRequested()
|
||||
|
||||
Loader {
|
||||
id: contentLoader
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
sourceComponent: {
|
||||
/* TODO: Issue #11635
|
||||
if (!root.collectiblesModel.hasMore && root.collectiblesModel.count === 0)
|
||||
return empty;
|
||||
*/
|
||||
return loaded;
|
||||
readonly property int cellHeight: 225
|
||||
readonly property int communityCellHeight: 242
|
||||
readonly property int cellWidth: 176
|
||||
|
||||
readonly property bool isCustomView: d.controller.hasSettings // TODO add respect other predefined orders (#12517)
|
||||
|
||||
function symbolIsVisible(symbol) {
|
||||
return d.controller.filterAcceptsSymbol(symbol)
|
||||
}
|
||||
|
||||
readonly property var renamedModel: RolesRenamingModel {
|
||||
sourceModel: root.collectiblesModel
|
||||
|
||||
mapping: [
|
||||
RoleRename {
|
||||
from: "uid"
|
||||
to: "symbol"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
readonly property var regularCollectiblesModel: SortFilterProxyModel {
|
||||
sourceModel: d.renamedModel
|
||||
|
||||
filters: [
|
||||
ExpressionFilter {
|
||||
expression: {
|
||||
d.controller.settingsDirty
|
||||
return d.symbolIsVisible(model.symbol) && !model.communityId
|
||||
}
|
||||
}
|
||||
// TODO add other sort/filter using ManageTokensController (#12517)
|
||||
]
|
||||
sorters: [
|
||||
RoleSorter {
|
||||
roleName: "name"
|
||||
enabled: !d.isCustomView
|
||||
},
|
||||
ExpressionSorter {
|
||||
expression: {
|
||||
d.controller.settingsDirty
|
||||
return d.controller.lessThan(modelLeft.symbol, modelRight.symbol)
|
||||
}
|
||||
enabled: d.isCustomView
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
readonly property var communityCollectiblesModel: SortFilterProxyModel {
|
||||
sourceModel: d.renamedModel
|
||||
filters: [
|
||||
ExpressionFilter {
|
||||
expression: {
|
||||
d.controller.settingsDirty
|
||||
return d.symbolIsVisible(model.symbol) && !!model.communityId
|
||||
}
|
||||
}
|
||||
// TODO add other sort/filter using ManageTokensController (#12517)
|
||||
]
|
||||
sorters: [
|
||||
RoleSorter {
|
||||
roleName: "name"
|
||||
enabled: !d.isCustomView
|
||||
},
|
||||
ExpressionSorter {
|
||||
expression: {
|
||||
d.controller.settingsDirty
|
||||
return d.controller.lessThan(modelLeft.symbol, modelRight.symbol)
|
||||
}
|
||||
enabled: d.isCustomView
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
readonly property bool hasCollectibles: d.regularCollectiblesModel.count
|
||||
readonly property bool hasCommunityCollectibles: d.communityCollectiblesModel.count
|
||||
|
||||
readonly property var controller: ManageTokensController {
|
||||
settingsKey: "WalletCollectibles"
|
||||
}
|
||||
|
||||
function hideAllCommunityTokens(communityId) {
|
||||
const tokenSymbols = ModelUtils.getAll(communityCollectiblesModel, "symbol", "communityId", communityId)
|
||||
d.controller.settingsHideCommunityTokens(communityId, tokenSymbols)
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
width: root.availableWidth
|
||||
spacing: 0
|
||||
|
||||
ShapeRectangle {
|
||||
visible: !d.hasCollectibles && !d.hasCommunityCollectibles
|
||||
Layout.fillWidth: true
|
||||
text: qsTr("Collectibles will appear here")
|
||||
}
|
||||
|
||||
CustomGridView {
|
||||
cellHeight: d.cellHeight
|
||||
model: d.regularCollectiblesModel
|
||||
visible: d.hasCollectibles
|
||||
}
|
||||
|
||||
StatusDialogDivider {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: Style.current.padding
|
||||
Layout.bottomMargin: Style.current.halfPadding
|
||||
visible: d.hasCommunityCollectibles
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.smallPadding
|
||||
Layout.bottomMargin: 4
|
||||
visible: d.hasCommunityCollectibles
|
||||
StatusBaseText {
|
||||
text: qsTr("Community collectibles")
|
||||
color: Theme.palette.baseColor1
|
||||
}
|
||||
Item { Layout.fillWidth: true }
|
||||
StatusFlatButton {
|
||||
Layout.preferredWidth: 32
|
||||
Layout.preferredHeight: 32
|
||||
icon.name: "info"
|
||||
textColor: Theme.palette.baseColor1
|
||||
horizontalPadding: 0
|
||||
verticalPadding: 0
|
||||
onClicked: Global.openPopup(communityInfoPopupCmp)
|
||||
}
|
||||
}
|
||||
|
||||
CustomGridView {
|
||||
cellHeight: d.communityCellHeight
|
||||
model: d.communityCollectiblesModel
|
||||
visible: d.hasCommunityCollectibles
|
||||
}
|
||||
}
|
||||
|
||||
component CustomGridView: StatusGridView {
|
||||
id: gridView
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.preferredHeight: contentHeight
|
||||
interactive: false
|
||||
|
||||
cellWidth: d.cellWidth
|
||||
delegate: collectibleDelegate
|
||||
|
||||
// For some reason fetchMore is not working properly.
|
||||
// Adding some logic here as a workaround.
|
||||
visibleArea.onYPositionChanged: checkLoadMore()
|
||||
visibleArea.onHeightRatioChanged: checkLoadMore()
|
||||
|
||||
Connections {
|
||||
target: gridView
|
||||
function onVisibleChanged() {
|
||||
gridView.checkLoadMore()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.collectiblesModel
|
||||
function onHasMoreChanged() {
|
||||
gridView.checkLoadMore()
|
||||
}
|
||||
function onIsFetchingChanged() {
|
||||
gridView.checkLoadMore()
|
||||
}
|
||||
}
|
||||
|
||||
function checkLoadMore() {
|
||||
// If there is no more items to load or we're already fetching, return
|
||||
if (!gridView.visible || !root.collectiblesModel.hasMore || root.collectiblesModel.isFetching)
|
||||
return
|
||||
// Only trigger if close to the bottom of the list
|
||||
if (visibleArea.yPosition + visibleArea.heightRatio > 0.9)
|
||||
root.collectiblesModel.loadMore()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: empty
|
||||
Item {
|
||||
StyledText {
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Style.current.secondaryText
|
||||
text: qsTr("Collectibles will appear here")
|
||||
id: collectibleDelegate
|
||||
CollectibleView {
|
||||
width: d.cellWidth
|
||||
height: isCommunityCollectible ? d.communityCellHeight : d.cellHeight
|
||||
title: model.name ? model.name : "..."
|
||||
subTitle: model.collectionName ?? ""
|
||||
mediaUrl: model.mediaUrl ?? ""
|
||||
mediaType: model.mediaType ?? ""
|
||||
fallbackImageUrl: model.imageUrl ?? ""
|
||||
backgroundColor: model.backgroundColor ? model.backgroundColor : "transparent"
|
||||
isLoading: !!model.isLoading
|
||||
privilegesLevel: model.communityPrivilegesLevel ?? Constants.TokenPrivilegesLevel.Community
|
||||
ornamentColor: model.communityColor ?? "transparent"
|
||||
communityId: model.communityId ?? ""
|
||||
communityName: model.communityName ?? ""
|
||||
communityImage: model.communityImage ?? ""
|
||||
|
||||
onClicked: root.collectibleClicked(model.chainId, model.contractAddress, model.tokenId, model.symbol)
|
||||
onRightClicked: {
|
||||
Global.openMenu(tokenContextMenu, this,
|
||||
{symbol: model.symbol, tokenName: model.name, tokenImage: model.imageUrl,
|
||||
communityId: model.communityId, communityName: model.communityName, communityImage: model.communityImage})
|
||||
}
|
||||
onSwitchToCommunityRequested: (communityId) => root.switchToCommunityRequested(communityId)
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: tokenContextMenu
|
||||
StatusMenu {
|
||||
onClosed: destroy()
|
||||
|
||||
property string symbol
|
||||
property string tokenName
|
||||
property string tokenImage
|
||||
property string communityId
|
||||
property string communityName
|
||||
property string communityImage
|
||||
|
||||
StatusAction {
|
||||
enabled: root.sendEnabled
|
||||
icon.name: "send"
|
||||
text: qsTr("Send")
|
||||
onTriggered: root.sendRequested(symbol)
|
||||
}
|
||||
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 !== "ETH"
|
||||
type: StatusAction.Type.Danger
|
||||
icon.name: "hide"
|
||||
text: qsTr("Hide collectible")
|
||||
onTriggered: Global.openPopup(confirmHideCollectiblePopup, {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: loaded
|
||||
StatusGridView {
|
||||
id: gridView
|
||||
anchors.fill: parent
|
||||
model: root.collectiblesModel
|
||||
cellHeight: 229
|
||||
cellWidth: 176
|
||||
delegate: CollectibleView {
|
||||
height: gridView.cellHeight
|
||||
width: gridView.cellWidth
|
||||
title: model.name ? model.name : "..."
|
||||
subTitle: model.collectionName ?? ""
|
||||
mediaUrl: model.mediaUrl ?? ""
|
||||
mediaType: model.mediaType ?? ""
|
||||
fallbackImageUrl: model.imageUrl ?? ""
|
||||
backgroundColor: model.backgroundColor ? model.backgroundColor : "transparent"
|
||||
isLoading: !!model.isLoading
|
||||
privilegesLevel: model.communityPrivilegesLevel ?? Constants.TokenPrivilegesLevel.Community
|
||||
ornamentColor: model.communityColor ?? "transparent"
|
||||
communityId: model.communityId ?? ""
|
||||
|
||||
onClicked: root.collectibleClicked(model.chainId, model.contractAddress, model.tokenId, model.uid)
|
||||
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.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ScrollBar.vertical: StatusScrollBar {}
|
||||
Component {
|
||||
id: confirmHideCollectiblePopup
|
||||
ConfirmationDialog {
|
||||
property string symbol
|
||||
property string tokenName
|
||||
property string tokenImage
|
||||
property string communityId
|
||||
|
||||
// For some reason fetchMore is not working properly.
|
||||
// Adding some logic here as a workaround.
|
||||
visibleArea.onYPositionChanged: checkLoadMore()
|
||||
visibleArea.onHeightRatioChanged: checkLoadMore()
|
||||
readonly property string formattedName: tokenName + (communityId ? " (" + qsTr("community collectible") + ")" : "")
|
||||
|
||||
Connections {
|
||||
target: gridView
|
||||
function onVisibleChanged() {
|
||||
checkLoadMore()
|
||||
}
|
||||
width: 520
|
||||
destroyOnClose: true
|
||||
confirmButtonLabel: qsTr("Hide %1").arg(tokenName)
|
||||
cancelBtnType: ""
|
||||
showCancelButton: true
|
||||
headerSettings.title: qsTr("Hide %1").arg(formattedName)
|
||||
headerSettings.asset.name: tokenImage
|
||||
confirmationText: qsTr("Are you sure you want to hide %1? You will no longer see or be able to interact with this collectible anywhere inside Status.").arg(formattedName)
|
||||
onCancelButtonClicked: close()
|
||||
onConfirmButtonClicked: {
|
||||
d.controller.settingsHideToken(symbol)
|
||||
close()
|
||||
Global.displayToastMessage(
|
||||
qsTr("%1 was successfully hidden. You can toggle collectible visibility via %2.").arg(formattedName)
|
||||
.arg(`<a style="text-decoration:none" href="#${Constants.appSection.profile}/${Constants.settingsSubsection.wallet}">` + qsTr("Settings", "Go to Settings") + "</a>"),
|
||||
"",
|
||||
"checkmark-circle",
|
||||
false,
|
||||
Constants.ephemeralNotificationType.success,
|
||||
""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.collectiblesModel
|
||||
function onHasMoreChanged() {
|
||||
checkLoadMore()
|
||||
}
|
||||
function onIsFetchingChanged() {
|
||||
checkLoadMore()
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: confirmHideCommunityCollectiblesPopup
|
||||
ConfirmationDialog {
|
||||
property string communityId
|
||||
property string communityName
|
||||
property string communityImage
|
||||
|
||||
function checkLoadMore() {
|
||||
// If there is no more items to load or we're already fetching, return
|
||||
if (!gridView.visible || !root.collectiblesModel.hasMore || root.collectiblesModel.isFetching)
|
||||
return
|
||||
// Only trigger if close to the bottom of the list
|
||||
if (visibleArea.yPosition + visibleArea.heightRatio > 0.9)
|
||||
root.collectiblesModel.loadMore()
|
||||
width: 520
|
||||
destroyOnClose: true
|
||||
confirmButtonLabel: qsTr("Hide all collectibles minted by this community")
|
||||
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: {
|
||||
d.hideAllCommunityTokens(communityId)
|
||||
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}">` + qsTr("Settings", "Go to Settings") + "</a>"),
|
||||
"",
|
||||
"checkmark-circle",
|
||||
false,
|
||||
Constants.ephemeralNotificationType.success,
|
||||
""
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -159,11 +159,22 @@ Item {
|
|||
id: collectiblesView
|
||||
CollectiblesView {
|
||||
collectiblesModel: RootStore.collectiblesStore.ownedCollectibles
|
||||
sendEnabled: root.networkConnectionStore.sendBuyBridgeEnabled && !RootStore.overview.isWatchOnlyAccount && RootStore.overview.canSend
|
||||
onCollectibleClicked: {
|
||||
RootStore.collectiblesStore.getDetailedCollectible(chainId, contractAddress, tokenId)
|
||||
RootStore.setCurrentViewedHolding(uid, Constants.TokenType.ERC721)
|
||||
stack.currentIndex = 1
|
||||
}
|
||||
onSendRequested: (symbol) => {
|
||||
root.sendModal.preSelectedSendType = Constants.SendType.Transfer
|
||||
root.sendModal.preSelectedHoldingID = symbol
|
||||
root.sendModal.preSelectedHoldingType = Constants.TokenType.ERC721
|
||||
root.sendModal.onlyAssets = false
|
||||
root.sendModal.open()
|
||||
}
|
||||
onReceiveRequested: (symbol) => root.launchShareAddressModal()
|
||||
onSwitchToCommunityRequested: (communityId) => Global.switchToCommunity(communityId)
|
||||
onManageTokensRequested: Global.changeAppSectionBySectionType(Constants.appSection.profile, Constants.settingsSubsection.wallet)
|
||||
}
|
||||
}
|
||||
Component {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import QtQuick 2.13
|
||||
import QtQuick.Controls 2.1
|
||||
import QtQuick.Layouts 1.13
|
||||
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
|
||||
|
@ -8,6 +8,7 @@ import StatusQ.Components 0.1
|
|||
import StatusQ.Controls 0.1
|
||||
|
||||
import AppLayouts.Communities.panels 1.0
|
||||
import AppLayouts.Wallet.controls 1.0
|
||||
|
||||
import utils 1.0
|
||||
|
||||
|
@ -24,6 +25,8 @@ Control {
|
|||
property bool isLoading: false
|
||||
property bool navigationIconVisible: false
|
||||
property string communityId: ""
|
||||
property string communityName
|
||||
property string communityImage
|
||||
|
||||
// Special Owner and TMaster token properties
|
||||
readonly property bool isCommunityCollectible: communityId !== ""
|
||||
|
@ -33,14 +36,28 @@ Control {
|
|||
property color ornamentColor // Relevant color for these special tokens (community color)
|
||||
|
||||
signal clicked
|
||||
|
||||
implicitHeight: 225
|
||||
implicitWidth: 176
|
||||
signal rightClicked
|
||||
signal switchToCommunityRequested(string communityId)
|
||||
|
||||
background: Rectangle {
|
||||
radius: 8
|
||||
radius: Style.current.radius
|
||||
color: Theme.palette.baseColor2
|
||||
visible: !root.isLoading && mouse.containsMouse
|
||||
visible: !root.isLoading && root.hovered
|
||||
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
enabled: !root.isLoading
|
||||
onTapped: root.clicked()
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.RightButton
|
||||
enabled: !root.isLoading
|
||||
onTapped: root.rightClicked()
|
||||
}
|
||||
}
|
||||
|
||||
HoverHandler {
|
||||
cursorShape: !root.isLoading ? Qt.PointingHandCursor : undefined
|
||||
}
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
|
@ -55,14 +72,12 @@ Control {
|
|||
Layout.preferredHeight: width
|
||||
|
||||
visible: !specialCollectible.visible
|
||||
radius: 8
|
||||
radius: Style.current.radius
|
||||
mediaUrl: root.mediaUrl
|
||||
mediaType: root.mediaType
|
||||
fallbackImageUrl: root.fallbackImageUrl
|
||||
border.color: Theme.palette.baseColor2
|
||||
border.width: 1
|
||||
showLoadingIndicator: true
|
||||
color: root.isLoading ? "transparent": root.backgroundColor
|
||||
color: root.isLoading ? "transparent" : root.backgroundColor
|
||||
|
||||
Loader {
|
||||
anchors.fill: parent
|
||||
|
@ -99,11 +114,9 @@ Control {
|
|||
Layout.preferredWidth: root.isLoading ? 134 : width
|
||||
|
||||
StatusTextWithLoadingState {
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.fillWidth: true
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
font.pixelSize: 15
|
||||
customColor: Theme.palette.directColor1
|
||||
font.weight: Font.DemiBold
|
||||
elide: Text.ElideRight
|
||||
|
@ -112,7 +125,6 @@ Control {
|
|||
}
|
||||
|
||||
StatusIcon {
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
visible: root.navigationIconVisible
|
||||
icon: "next"
|
||||
color: Theme.palette.baseColor1
|
||||
|
@ -122,8 +134,7 @@ Control {
|
|||
StatusTextWithLoadingState {
|
||||
id: subTitleItem
|
||||
|
||||
Layout.alignment: Qt.AlignLeft
|
||||
Layout.topMargin: 3
|
||||
Layout.topMargin: 4
|
||||
Layout.leftMargin: Style.current.halfPadding
|
||||
Layout.rightMargin: Layout.leftMargin
|
||||
Layout.fillWidth: !root.isLoading
|
||||
|
@ -133,8 +144,28 @@ Control {
|
|||
font.pixelSize: 13
|
||||
customColor: Theme.palette.baseColor1
|
||||
elide: Text.ElideRight
|
||||
text: root.isLoading? Constants.dummyText : root.subTitle
|
||||
text: root.isLoading ? Constants.dummyText : root.subTitle
|
||||
loading: root.isLoading
|
||||
visible: text && !root.communityName
|
||||
}
|
||||
|
||||
ManageTokensCommunityTag {
|
||||
Layout.topMargin: Style.current.halfPadding
|
||||
Layout.leftMargin: Style.current.halfPadding
|
||||
Layout.rightMargin: Style.current.halfPadding
|
||||
Layout.maximumWidth: parent.width - Layout.leftMargin - Layout.rightMargin
|
||||
text: root.communityName
|
||||
imageSrc: root.communityImage
|
||||
visible: root.isCommunityCollectible
|
||||
enabled: !root.isLoading
|
||||
StatusToolTip {
|
||||
text: qsTr("This token was minted by the %1 community").arg(root.communityName)
|
||||
visible: parent.hovered
|
||||
}
|
||||
TapHandler {
|
||||
acceptedButtons: Qt.LeftButton
|
||||
onSingleTapped: root.switchToCommunityRequested(root.communityId)
|
||||
}
|
||||
}
|
||||
|
||||
// Filler
|
||||
|
@ -142,16 +173,4 @@ Control {
|
|||
Layout.fillHeight: true
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: mouse
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
onClicked: {
|
||||
if (!root.isLoading) {
|
||||
root.clicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
CollectiblesView 1.0 CollectiblesView.qml
|
|
@ -119,11 +119,11 @@ StatusListItem {
|
|||
}
|
||||
ManageTokensCommunityTag {
|
||||
anchors.right: parent.right
|
||||
text: modelData.communityName
|
||||
imageSrc: modelData.communityImage
|
||||
text: modelData && !!modelData.communityName ? modelData.communityName : ""
|
||||
imageSrc: modelData && !!modelData.communityImage ? modelData.communityImage : ""
|
||||
visible: root.isCommunityToken
|
||||
StatusToolTip {
|
||||
text: qsTr("This token was minted by the %1 community").arg(modelData.communityName)
|
||||
text: modelData ? qsTr("This token was minted by the %1 community").arg(modelData.communityName) : ""
|
||||
visible: parent.hovered
|
||||
}
|
||||
TapHandler {
|
||||
|
|
|
@ -107,6 +107,7 @@ StatusModal {
|
|||
}
|
||||
},
|
||||
StatusButton {
|
||||
Layout.maximumWidth: confirmationDialog.availableWidth/2
|
||||
id: confirmButton
|
||||
objectName: confirmationDialog.confirmButtonObjectName
|
||||
type: {
|
||||
|
|
|
@ -64,10 +64,6 @@ ColumnLayout {
|
|||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
enabled: root.visible
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
readonly property bool isInitialLoading: RootStore.loadingHistoryTransactions && transactionListRoot.count === 0
|
||||
|
|
Loading…
Reference in New Issue