diff --git a/src/app/modules/main/stickers/models/sticker_list.nim b/src/app/modules/main/stickers/models/sticker_list.nim index 745a3a8d0f..98b889a40d 100644 --- a/src/app/modules/main/stickers/models/sticker_list.nim +++ b/src/app/modules/main/stickers/models/sticker_list.nim @@ -52,9 +52,16 @@ QtObject: self.stickers.insert(sticker, 0) self.endInsertRows() + proc findIndexByPackId(self: StickerList, packId: string): int = + for i in 0 ..< self.stickers.len: + if(self.stickers[i].getPackId() == packId): + return i + return -1 + proc removeStickersFromList*(self: StickerList, packId: string) = - if not self.stickers.anyIt(it.getPackId == packId): + let idx = self.findIndexByPackId(packId) + if idx == -1: return - self.beginRemoveRows(newQModelIndex(), 0, 0) - self.stickers.keepItIf(it.getPackId != packId) + self.beginRemoveRows(newQModelIndex(), idx, idx) + self.stickers.delete(idx) self.endRemoveRows() diff --git a/src/app/modules/main/stickers/models/sticker_pack_list.nim b/src/app/modules/main/stickers/models/sticker_pack_list.nim index 73935f5f5c..b5651793e5 100644 --- a/src/app/modules/main/stickers/models/sticker_pack_list.nim +++ b/src/app/modules/main/stickers/models/sticker_pack_list.nim @@ -105,21 +105,19 @@ QtObject: proc removeStickerPackFromList*(self: StickerPackList, packId: string) = let idx = self.findIndexById(packId) self.beginRemoveRows(newQModelIndex(), idx, idx) - self.packs.keepItIf(it.pack.id != packId) + self.packs.delete(idx) self.endRemoveRows() proc updateStickerPackInList*(self: StickerPackList, packId: string, installed: bool, pending: bool) = - if not self.hasKey(packId): + let idx = self.findIndexById(packId) + if idx == -1: return - - let topLeft = self.createIndex(0, 0, nil) - let bottomRight = self.createIndex(self.packs.len, 0, nil) + let index = self.createIndex(idx, 0, nil) self.packs.apply(proc(it: var StickerPackView) = if it.pack.id == packId: it.installed = installed it.pending = pending) - - self.dataChanged(topLeft, bottomRight, @[StickerPackRoles.Installed.int, StickerPackRoles.Pending.int]) + self.dataChanged(index, index, @[StickerPackRoles.Installed.int, StickerPackRoles.Pending.int]) proc getStickers*(self: StickerPackList): QVariant {.slot.} = let packInfo = self.packs[self.packIdToRetrieve] diff --git a/ui/imports/shared/status/StatusStickerMarket.qml b/ui/imports/shared/status/StatusStickerMarket.qml index efd7435bf5..80d5c46773 100644 --- a/ui/imports/shared/status/StatusStickerMarket.qml +++ b/ui/imports/shared/status/StatusStickerMarket.qml @@ -2,6 +2,7 @@ import QtQuick 2.13 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 +import QtQml.Models 2.13 import utils 1.0 import shared 1.0 @@ -39,147 +40,189 @@ Item { anchors.topMargin: Style.current.padding cellWidth: parent.width - (Style.current.padding * 2) cellHeight: height - 72 - model: stickerPacks + focus: true clip: true - delegate: Item { - width: availableStickerPacks.cellWidth - height: availableStickerPacks.cellHeight - RoundedImage { - id: imgPreview - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - height: 220 - width: parent.width - radius: 12 - source: model.preview - onClicked: { - stickerPackDetailsPopup.open() + model: DelegateModel { + id: delegateModel + + function update() { + if (items.count > 0) { + items.setGroups(0, items.count, "items"); + } + + var visible = []; + for (var i = 0; i < items.count; ++i) { + var item = items.get(i); + if (delegateModel.walletEnabled || + !delegateModel.walletEnabled && item.model.price == 0) { + visible.push(item); + } + } + + for (i = 0; i < visible.length; ++i) { + item = visible[i]; + item.inVisible = true; + if (item.visibleIndex !== i) { + visibleItems.move(item.visibleIndex, i, 1); + } } } - // TODO: replace with StatusModal - ModalPopup { - id: stickerPackDetailsPopup - height: 540 - header: StatusStickerPackDetails { + readonly property bool walletEnabled: localAccountSensitiveSettings.isWalletEnabled + onWalletEnabledChanged: { + update() + } + + model: stickerPacks + items.onChanged: update() + filterOnGroup: "visible" + groups: DelegateModelGroup { + id: visibleItems + + name: "visible" + includeByDefault: false + } + + delegate: Item { + width: availableStickerPacks.cellWidth + height: availableStickerPacks.cellHeight + RoundedImage { + id: imgPreview + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + height: 220 + width: parent.width + radius: 12 + source: model.preview + onClicked: { + stickerPackDetailsPopup.open() + } + } + + // TODO: replace with StatusModal + ModalPopup { + id: stickerPackDetailsPopup + height: 540 + header: StatusStickerPackDetails { + packThumb: thumbnail + packName: name + packAuthor: author + packNameFontSize: 17 + spacing: Style.current.padding / 2 + } + + contentWrapper.anchors.topMargin: 0 + contentWrapper.anchors.bottomMargin: 0 + StatusStickerList { + id: stickerGridInPopup + anchors.fill: parent + anchors.topMargin: Style.current.padding + model: stickers + packId: root.packId + } + + footer: StatusStickerButton { + height: 44 + anchors.right: parent.right + style: StatusStickerButton.StyleType.LargeNoIcon + packPrice: price + isInstalled: installed + isBought: bought + isPending: pending + onInstallClicked: root.installClicked(stickers, packId, index) + onUninstallClicked: root.uninstallClicked(packId) + onCancelClicked: root.cancelClicked(packId) + onUpdateClicked: root.updateClicked(packId) + onBuyClicked: { + Global.openPopup(stickerPackPurchaseModal) + root.buyClicked(packId) + } + } + } + Component { + id: stickerPackPurchaseModal + StatusSNTTransactionModal { + store: root.store + stickersStore: root.store.stickersStore + contractAddress: root.store.stickersStore.getStickersMarketAddress() + contactsStore: root.store.contactsStore + assetPrice: price + chainId: root.store.stickersStore.getChainIdForStickers() + estimateGasFunction: function(selectedAccount, uuid) { + if (packId < 0 || !selectedAccount || !price) return 325000 + return root.store.stickersStore.estimate(packId, selectedAccount.address, price, uuid) + } + onSendTransaction: function(selectedAddress, gasLimit, gasPrice, tipLimit, overallLimit, password, eip1559Enabled) { + return root.store.stickersStore.buy(packId, + selectedAddress, + gasLimit, + gasPrice, + tipLimit, + overallLimit, + password, + eip1559Enabled) + } + onClosed: { + destroy() + } + asyncGasEstimateTarget: root.store.stickersStore.stickersModule + width: stickerPackDetailsPopup.width + height: stickerPackDetailsPopup.height + } + } + + StatusStickerPackDetails { + id: stickerPackDetails + height: 64 - (Style.current.smallPadding * 2) + width: parent.width - (Style.current.padding * 2) + anchors.top: imgPreview.bottom + anchors.topMargin: Style.current.smallPadding + anchors.bottomMargin: Style.current.smallPadding + anchors.left: parent.left + anchors.right: parent.right packThumb: thumbnail packName: name packAuthor: author - packNameFontSize: 17 - spacing: Style.current.padding / 2 - } - contentWrapper.anchors.topMargin: 0 - contentWrapper.anchors.bottomMargin: 0 - StatusStickerList { - id: stickerGridInPopup - anchors.fill: parent - anchors.topMargin: Style.current.padding - model: stickers - packId: root.packId - } - - footer: StatusStickerButton { - height: 44 - anchors.right: parent.right - style: StatusStickerButton.StyleType.LargeNoIcon - packPrice: price - isInstalled: installed - isBought: bought - isPending: pending - onInstallClicked: root.installClicked(stickers, packId, index) - onUninstallClicked: root.uninstallClicked(packId) - onCancelClicked: root.cancelClicked(packId) - onUpdateClicked: root.updateClicked(packId) - onBuyClicked: { - Global.openPopup(stickerPackPurchaseModal) - root.buyClicked(packId) - } - } - } - Component { - id: stickerPackPurchaseModal - StatusSNTTransactionModal { - store: root.store - stickersStore: root.store.stickersStore - contractAddress: root.store.stickersStore.getStickersMarketAddress() - contactsStore: root.store.contactsStore - assetPrice: price - chainId: root.store.stickersStore.getChainIdForStickers() - estimateGasFunction: function(selectedAccount, uuid) { - if (packId < 0 || !selectedAccount || !price) return 325000 - return root.store.stickersStore.estimate(packId, selectedAccount.address, price, uuid) - } - onSendTransaction: function(selectedAddress, gasLimit, gasPrice, tipLimit, overallLimit, password, eip1559Enabled) { - return root.store.stickersStore.buy(packId, - selectedAddress, - gasLimit, - gasPrice, - tipLimit, - overallLimit, - password, - eip1559Enabled) - } - onClosed: { - destroy() - } - asyncGasEstimateTarget: root.store.stickersStore.stickersModule - width: stickerPackDetailsPopup.width - height: stickerPackDetailsPopup.height - } - } - - StatusStickerPackDetails { - id: stickerPackDetails - height: 64 - (Style.current.smallPadding * 2) - width: parent.width - (Style.current.padding * 2) - anchors.top: imgPreview.bottom - anchors.topMargin: Style.current.smallPadding - anchors.bottomMargin: Style.current.smallPadding - anchors.left: parent.left - anchors.right: parent.right - packThumb: thumbnail - packName: name - packAuthor: author - - StatusStickerButton { - anchors.right: parent.right - packPrice: price - width: 75 // only needed for Qt Creator - isInstalled: installed - isBought: bought - isPending: pending - onInstallClicked: root.installClicked(stickers, packId, index) - onUninstallClicked: root.uninstallClicked(packId) - onCancelClicked: root.cancelClicked(packId) - onUpdateClicked: root.updateClicked(packId) - onBuyClicked: { - if (!SharedStores.RootStore.isWalletEnabled) { - confirmationPopup.open() - return + StatusStickerButton { + anchors.right: parent.right + packPrice: price + width: 75 // only needed for Qt Creator + isInstalled: installed + isBought: bought + isPending: pending + onInstallClicked: root.installClicked(stickers, packId, index) + onUninstallClicked: root.uninstallClicked(packId) + onCancelClicked: root.cancelClicked(packId) + onUpdateClicked: root.updateClicked(packId) + onBuyClicked: { + if (!SharedStores.RootStore.isWalletEnabled) { + confirmationPopup.open() + return + } + Global.openPopup(stickerPackPurchaseModal) + root.buyClicked(packId) } + } + } + + ConfirmationDialog { + id: confirmationPopup + showCancelButton: true + confirmationText: qsTr("This feature is experimental and is meant for testing purposes by core contributors and the community. It's not meant for real use and makes no claims of security or integrity of funds or data. Use at your own risk.") + confirmButtonLabel: qsTr("I understand") + onConfirmButtonClicked: { + SharedStores.RootStore.enableWallet(); + close() Global.openPopup(stickerPackPurchaseModal) root.buyClicked(packId) } - } - } - ConfirmationDialog { - id: confirmationPopup - showCancelButton: true - confirmationText: qsTr("This feature is experimental and is meant for testing purposes by core contributors and the community. It's not meant for real use and makes no claims of security or integrity of funds or data. Use at your own risk.") - confirmButtonLabel: qsTr("I understand") - onConfirmButtonClicked: { - SharedStores.RootStore.enableWallet(); - close() - Global.openPopup(stickerPackPurchaseModal) - root.buyClicked(packId) - } - - onCancelButtonClicked: { - close() + onCancelButtonClicked: { + close() + } } } }