emizzle ac7deb3af0 feat: Un/install free sticker packs in sticker market
Sticker pack details retreived from contract:
 - pack data decoded from contract response
 - data contains contentHash which, once decoded, contains an IPFS identifier
 - futher pack data in EDN format is downloaded from IPFS
 - the EDN info is decoded in to a StickerPack

List of available packs from contract are obtained separately from list of installed contracts (stored as a setting in Status-go).

Sticker market contains dynamic list of sticker packs. The sticker button shown for each pack has all states defined (in the design) for all UI states (ie bought, free, installed, pending, etc)

Add modal popup showing sticker pack details and list of stickers to be un/installed. Contains a "larger" version of the sticker pack button with many differnt UI states defined.

Uninstallation of a sticker pack removes those sticker pack's stickers from the recent sticker list and persists the list

Simplify the view model by including stickers, instead of setting an "activeStickerPackId" property. This allowed for display of sticker pack stickers to be displayed in the modal popup separately from the sticker packs shown in the market.
2020-07-15 15:53:48 -04:00

255 lines
8.6 KiB
QML

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.3
import QtGraphicalEffects 1.0
import "../../../../imports"
import "../../../../shared"
Item {
id: root
enum StyleType {
Default,
LargeNoIcon
}
property int style: StickerButton.StyleType.Default
property int packPrice: 0
property bool isBought: false
property bool isPending: false
property bool isInstalled: false
property bool hasUpdate: false
property bool isTimedOut: false
property bool hasInsufficientFunds: false
property bool enabled: true
property var icon: new Object({
path: "../../../img/status-logo-no-bg",
rotation: 0,
runAnimation: false
})
property string text: root.style === StickerButton.StyleType.Default ? packPrice : qsTr("Buy for %1 SNT").arg(packPrice )
property color textColor: style === StickerButton.StyleType.Default ? Style.current.white : Style.current.blue
property color bgColor: style === StickerButton.StyleType.Default ? Style.current.blue : Style.current.lightBlue
signal uninstallClicked()
signal installClicked()
signal cancelClicked()
signal updateClicked()
signal buyClicked()
width: pill.width
states: [
State {
name: "installed"
when: root.isInstalled
PropertyChanges {
target: root;
text: root.style === StickerButton.StyleType.Default ? "" : qsTr("Uninstall");
textColor: root.style === StickerButton.StyleType.Default ? Style.current.white : Style.current.red;
bgColor: root.style === StickerButton.StyleType.Default ? Style.current.green : Style.current.lightRed;
icon: new Object({
path: "../../../img/check.svg",
rotation: 0,
runAnimation: false
})
}
},
State {
name: "bought"
when: root.isBought;
PropertyChanges {
target: root;
text: qsTr("Install");
icon: new Object({
path: "../../../img/arrowUp.svg",
rotation: 180,
runAnimation: false
})
}
},
State {
name: "free"
when: root.packPrice === 0;
extend: "bought"
PropertyChanges {
target: root;
text: qsTr("Free");
}
},
State {
name: "insufficientFunds"
when: root.hasInsufficientFunds
PropertyChanges {
target: root;
text: root.style === StickerButton.StyleType.Default ? packPrice : packPrice + " SNT";
textColor: root.style === StickerButton.StyleType.Default ? Style.current.white : Style.current.darkGrey
bgColor: root.style === StickerButton.StyleType.Default ? Style.current.darkGrey : Style.current.grey;
enabled: false;
}
},
State {
name: "pending"
when: root.isPending
PropertyChanges {
target: root;
text: qsTr("Pending...");
textColor: root.style === StickerButton.StyleType.Default ? Style.current.white : Style.current.darkGrey
bgColor: root.style === StickerButton.StyleType.Default ? Style.current.darkGrey : Style.current.grey;
enabled: false;
icon: new Object({
path: "../../../img/loading.png",
rotation: 0,
runAnimation: true
})
}
},
State {
name: "timedOut"
when: root.isTimedOut
extend: "pending"
PropertyChanges {
target: root;
text: qsTr("Cancel");
textColor: root.style === StickerButton.StyleType.Default ? Style.current.white : Style.current.red;
bgColor: root.style === StickerButton.StyleType.Default ? Style.current.darkGrey : Style.current.lightRed;
}
},
State {
name: "hasUpdate"
when: root.hasUpdate
extend: "bought"
PropertyChanges {
target: root;
text: qsTr("Update");
}
}
]
TextMetrics {
id: textMetrics
font.weight: Font.Medium
font.family: Style.current.fontBold.name
font.pixelSize: 15
text: root.text
}
Rectangle {
id: pill
anchors.right: parent.right
width: textMetrics.width + roundedIconImage.width + (Style.current.smallPadding * 2) + 6.7
height: 26
color: root.bgColor
radius: root.style === StickerButton.StyleType.Default ? (width / 2) : 8
states: [
State {
name: "installed"
when: root.isInstalled && root.style === StickerButton.StyleType.Default
PropertyChanges {
target: pill;
width: 28;
height: 28
}
},
State {
name: "large"
when: root.style === StickerButton.StyleType.LargeNoIcon
PropertyChanges {
target: pill;
width: textMetrics.width + (Style.current.padding * 4);
height: 44
}
}
]
SVGImage {
id: roundedIconImage
width: 12
height: 12
anchors.left: parent.left
anchors.leftMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
fillMode: Image.PreserveAspectFit
source: icon.path
rotation: icon.rotation
RotationAnimator {
target: roundedIconImage;
from: 0;
to: 360;
duration: 1200
running: root.icon.runAnimation
loops: Animation.Infinite
}
states: [
State {
name: "installed"
when: root.isInstalled && root.style === StickerButton.StyleType.Default
PropertyChanges {
target: roundedIconImage;
anchors.leftMargin: 9
width: 11;
height: 8
}
},
State {
name: "large"
when: root.style === StickerButton.StyleType.LargeNoIcon
PropertyChanges {
target: roundedIconImage;
visible: false;
}
}
]
}
Text {
id: content
color: root.textColor
anchors.right: parent.right
anchors.rightMargin: Style.current.smallPadding
anchors.verticalCenter: parent.verticalCenter
text: root.text
font.weight: Font.Medium
font.family: Style.current.fontBold.name
font.pixelSize: 15
states: [
State {
name: "installed"
when: root.isInstalled && root.style === StickerButton.StyleType.Default
PropertyChanges {
target: content;
anchors.rightMargin: 9;
}
},
State {
name: "large"
when: root.style === StickerButton.StyleType.LargeNoIcon
PropertyChanges {
target: content;
anchors.horizontalCenter: parent.horizontalCenter;
anchors.leftMargin: Style.current.padding * 2
anchors.rightMargin: Style.current.padding * 2
}
}
]
}
MouseArea {
id: mouseArea
anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: {
if (root.isInstalled) return root.uninstallClicked();
if (root.packPrice === 0 || root.isBought) return root.installClicked()
if (root.isTimedOut) return root.cancelClicked()
if (root.hasUpdate) return root.updateClicked()
return root.buyClicked()
}
}
}
}
/*##^##
Designer {
D{i:0;autoSize:true;height:480;width:640}
}
##^##*/