feat: Integrate the new manage assets/collectibles panels into Settings
- display a customized floating bubble to save/apply the settings - display a toast message on Apply with an action to jump to Wallet main page - add home/end/pgup/pgdown keyboard shortcuts to StatusScrollView to be able to navigate more easily in long list views - some smaller fixes and cleanups in wallet and settings related views Fixes https://github.com/status-im/status-desktop/issues/12762
This commit is contained in:
parent
77197040a4
commit
8791d028e6
|
@ -24,8 +24,9 @@ SplitView {
|
|||
|
||||
StatusScrollView { // wrapped in a ScrollView on purpose; to simulate SettingsContentBase.qml
|
||||
SplitView.fillWidth: true
|
||||
SplitView.preferredHeight: 500
|
||||
ManageTokensPanel {
|
||||
SplitView.fillHeight: true
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
ManageAssetsPanel {
|
||||
id: showcasePanel
|
||||
width: 500
|
||||
baseModel: ctrlEmptyModel.checked ? null : assetsModel
|
|
@ -26,6 +26,9 @@ SplitView {
|
|||
StatusScrollView { // wrapped in a ScrollView on purpose; to simulate SettingsContentBase.qml
|
||||
SplitView.fillWidth: true
|
||||
SplitView.fillHeight: true
|
||||
|
||||
Component.onCompleted: forceActiveFocus()
|
||||
|
||||
ManageCollectiblesPanel {
|
||||
id: showcasePanel
|
||||
width: 500
|
||||
|
|
|
@ -181,6 +181,43 @@ T.ScrollView {
|
|||
applyFlickableFix()
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
switch (event.key) {
|
||||
case Qt.Key_Home:
|
||||
scrollHome()
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_End:
|
||||
scrollEnd()
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_PageUp:
|
||||
scrollPageUp()
|
||||
event.accepted = true
|
||||
break
|
||||
case Qt.Key_PageDown:
|
||||
scrollPageDown()
|
||||
event.accepted = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
function scrollHome() {
|
||||
flickable.contentY = 0
|
||||
}
|
||||
|
||||
function scrollEnd() {
|
||||
flickable.contentY = flickable.contentHeight - flickable.height
|
||||
}
|
||||
|
||||
function scrollPageUp() {
|
||||
root.ScrollBar.vertical.decrease()
|
||||
}
|
||||
|
||||
function scrollPageDown() {
|
||||
root.ScrollBar.vertical.increase()
|
||||
}
|
||||
|
||||
ScrollBar.vertical: StatusScrollBar {
|
||||
parent: root
|
||||
x: root.mirrored ? 1 : root.width - width - 1
|
||||
|
|
|
@ -126,7 +126,7 @@ void ManageTokensController::saveSettings()
|
|||
result.insert(m_hiddenTokensModel->save(false));
|
||||
|
||||
// save to QSettings
|
||||
m_settings.beginGroup(QStringLiteral("ManageTokens-%1").arg(m_settingsKey));
|
||||
m_settings.beginGroup(settingsGroupName());
|
||||
m_settings.beginWriteArray(m_settingsKey);
|
||||
SerializedTokenData::const_key_value_iterator it = result.constKeyValueBegin();
|
||||
for (auto i = 0; it != result.constKeyValueEnd() && i < result.size(); it++, i++) {
|
||||
|
@ -151,7 +151,7 @@ void ManageTokensController::clearSettings()
|
|||
Q_ASSERT(!m_settingsKey.isEmpty());
|
||||
|
||||
// clear the relevant QSettings group
|
||||
m_settings.beginGroup(QStringLiteral("ManageTokens-%1").arg(m_settingsKey));
|
||||
m_settings.beginGroup(settingsGroupName());
|
||||
m_settings.remove(QString());
|
||||
m_settings.endGroup();
|
||||
m_settings.sync();
|
||||
|
@ -164,7 +164,7 @@ void ManageTokensController::loadSettings()
|
|||
m_settingsData.clear();
|
||||
|
||||
// load from QSettings
|
||||
m_settings.beginGroup(QStringLiteral("ManageTokens-%1").arg(m_settingsKey));
|
||||
m_settings.beginGroup(settingsGroupName());
|
||||
const auto size = m_settings.beginReadArray(m_settingsKey);
|
||||
for (auto i = 0; i < size; i++) {
|
||||
m_settings.setArrayIndex(i);
|
||||
|
@ -187,6 +187,36 @@ void ManageTokensController::revert()
|
|||
parseSourceModel();
|
||||
}
|
||||
|
||||
QString ManageTokensController::settingsGroupName() const
|
||||
{
|
||||
return QStringLiteral("ManageTokens-%1").arg(m_settingsKey);
|
||||
}
|
||||
|
||||
bool ManageTokensController::hasSettings() const
|
||||
{
|
||||
Q_ASSERT(!m_settingsKey.isEmpty());
|
||||
const auto groups = m_settings.childGroups();
|
||||
return !groups.isEmpty() && groups.contains(settingsGroupName());
|
||||
}
|
||||
|
||||
bool ManageTokensController::lessThan(const QString& lhsSymbol, const QString& rhsSymbol) const
|
||||
{
|
||||
auto [leftPos, leftVisible, leftGroup] = m_settingsData.value(lhsSymbol, {INT_MAX, false, QString()});
|
||||
auto [rightPos, rightVisible, rightGroup] = m_settingsData.value(rhsSymbol, {INT_MAX, false, QString()});
|
||||
|
||||
// check if visible
|
||||
leftPos = leftVisible ? leftPos : INT_MAX;
|
||||
rightPos = rightVisible ? rightPos : INT_MAX;
|
||||
|
||||
return leftPos <= rightPos;
|
||||
}
|
||||
|
||||
bool ManageTokensController::filterAcceptsSymbol(const QString& symbol) const
|
||||
{
|
||||
const auto& [pos, visible, groupId] = m_settingsData.value(symbol, {INT_MAX, false, QString()});
|
||||
return visible;
|
||||
}
|
||||
|
||||
void ManageTokensController::classBegin()
|
||||
{
|
||||
// empty on purpose
|
||||
|
|
|
@ -36,10 +36,10 @@ public:
|
|||
Q_INVOKABLE void saveSettings();
|
||||
Q_INVOKABLE void clearSettings();
|
||||
Q_INVOKABLE void revert();
|
||||
Q_INVOKABLE bool hasSettings() const;
|
||||
|
||||
// TODO: to be used by SFPM on the main wallet page as an "expressionRole"
|
||||
// bool lessThan(lhsSymbol, rhsSymbol) const;
|
||||
// bool filterAcceptsRow(index or symbol?) const;
|
||||
Q_INVOKABLE bool lessThan(const QString& lhsSymbol, const QString& rhsSymbol) const;
|
||||
Q_INVOKABLE bool filterAcceptsSymbol(const QString& symbol) const;
|
||||
|
||||
protected:
|
||||
void classBegin() override;
|
||||
|
@ -85,6 +85,7 @@ private:
|
|||
|
||||
QString m_settingsKey;
|
||||
QString settingsKey() const;
|
||||
QString settingsGroupName() const;
|
||||
void setSettingsKey(const QString& newSettingsKey);
|
||||
QSettings m_settings;
|
||||
void loadSettings();
|
||||
|
|
|
@ -23,6 +23,7 @@ const auto kEnabledNetworkCurrencyBalanceRoleName = QByteArrayLiteral("enabledNe
|
|||
const auto kCustomSortOrderNoRoleName = QByteArrayLiteral("customSortOrderNo");
|
||||
const auto kTokenImageRoleName = QByteArrayLiteral("imageUrl");
|
||||
const auto kBackgroundColorRoleName = QByteArrayLiteral("backgroundColor");
|
||||
// TODO add communityPrivilegesLevel for collectibles
|
||||
} // namespace
|
||||
|
||||
struct TokenData {
|
||||
|
|
|
@ -123,8 +123,8 @@ StatusStackModal {
|
|||
}
|
||||
IssuePill {
|
||||
id: issuePill
|
||||
type: root.communitiesStore.discordImportErrorsCount ? IssuePill.Type.Error : IssuePill.Type.Warning
|
||||
count: root.communitiesStore.discordImportErrorsCount || root.communitiesStore.discordImportWarningsCount || 0
|
||||
type: root.store.discordImportErrorsCount ? IssuePill.Type.Error : IssuePill.Type.Warning
|
||||
count: root.store.discordImportErrorsCount || root.store.discordImportWarningsCount || 0
|
||||
visible: !!count && !fileListView.fileListModelEmpty
|
||||
}
|
||||
StatusButton {
|
||||
|
|
|
@ -80,7 +80,7 @@ StatusSectionLayout {
|
|||
store: root.store
|
||||
anchors.fill: parent
|
||||
onMenuItemClicked: {
|
||||
if (profileContainer.currentItem.dirty) {
|
||||
if (profileContainer.currentItem.dirty && !profileContainer.currentItem.ignoreDirty) {
|
||||
event.accepted = true;
|
||||
profileContainer.currentItem.notifyDirty();
|
||||
}
|
||||
|
|
|
@ -21,11 +21,12 @@ StatusListView {
|
|||
|
||||
signal itemClicked(string key)
|
||||
|
||||
implicitHeight: contentHeight
|
||||
model: root.sourcesOfTokensModel
|
||||
spacing: 8
|
||||
delegate: StatusListItem {
|
||||
height: 76
|
||||
width: parent.width
|
||||
width: ListView.view.width
|
||||
title: model.name
|
||||
subTitle: qsTr("%n token(s) · Last updated %1 @%2",
|
||||
"",
|
||||
|
|
|
@ -9,7 +9,7 @@ import StatusQ.Core 0.1
|
|||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Core.Theme 0.1
|
||||
|
||||
Item {
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
property string sectionTitle
|
||||
|
@ -24,10 +24,13 @@ Item {
|
|||
property alias titleLayout: titleLayout
|
||||
|
||||
property bool dirty: false
|
||||
property bool ignoreDirty // ignore dirty state and do not notifyDirty()
|
||||
property bool saveChangesButtonEnabled: false
|
||||
readonly property alias toast: settingsDirtyToastMessage
|
||||
|
||||
signal baseAreaClicked()
|
||||
signal saveChangesClicked()
|
||||
signal saveForLaterClicked()
|
||||
signal resetChangesClicked()
|
||||
|
||||
function notifyDirty() {
|
||||
|
@ -112,15 +115,17 @@ Item {
|
|||
|
||||
Column {
|
||||
id: contentWrapper
|
||||
onVisibleChanged: if (visible) forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
// This is a settingsDirtyToastMessage placeholder
|
||||
width: settingsDirtyToastMessage.implicitWidth
|
||||
height: settingsDirtyToastMessage.active ? settingsDirtyToastMessage.implicitHeight : 0
|
||||
height: settingsDirtyToastMessage.active && !root.ignoreDirty ? settingsDirtyToastMessage.implicitHeight : 0
|
||||
|
||||
Behavior on implicitHeight {
|
||||
enabled: !root.ignoreDirty
|
||||
NumberAnimation {
|
||||
duration: 150
|
||||
easing.type: Easing.InOutQuad
|
||||
|
@ -133,11 +138,13 @@ Item {
|
|||
SettingsDirtyToastMessage {
|
||||
id: settingsDirtyToastMessage
|
||||
anchors.bottom: scrollView.bottom
|
||||
anchors.bottomMargin: root.ignoreDirty ? 40 : 0
|
||||
anchors.horizontalCenter: scrollView.horizontalCenter
|
||||
active: root.dirty
|
||||
flickable: scrollView.flickable
|
||||
flickable: root.ignoreDirty ? null : scrollView.flickable
|
||||
saveChangesButtonEnabled: root.saveChangesButtonEnabled
|
||||
onResetChangesClicked: root.resetChangesClicked()
|
||||
onSaveChangesClicked: root.saveChangesClicked()
|
||||
onSaveForLaterClicked: root.saveForLaterClicked()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,11 +29,11 @@ SettingsContentBase {
|
|||
property var walletStore
|
||||
required property TokensStore tokensStore
|
||||
|
||||
readonly property int mainViewIndex: 0;
|
||||
readonly property int networksViewIndex: 1;
|
||||
readonly property int editNetworksViewIndex: 2;
|
||||
readonly property int accountOrderViewIndex: 3;
|
||||
readonly property int accountViewIndex: 4;
|
||||
readonly property int mainViewIndex: 0
|
||||
readonly property int networksViewIndex: 1
|
||||
readonly property int editNetworksViewIndex: 2
|
||||
readonly property int accountOrderViewIndex: 3
|
||||
readonly property int accountViewIndex: 4
|
||||
readonly property int manageTokensViewIndex: 5
|
||||
|
||||
readonly property string walletSectionTitle: qsTr("Wallet")
|
||||
|
@ -48,6 +48,34 @@ SettingsContentBase {
|
|||
}
|
||||
}
|
||||
|
||||
dirty: manageTokensView.dirty
|
||||
ignoreDirty: stackContainer.currentIndex === manageTokensViewIndex
|
||||
saveChangesButtonEnabled: dirty
|
||||
toast.type: SettingsDirtyToastMessage.Type.Info
|
||||
toast.cancelButtonVisible: false
|
||||
toast.saveForLaterButtonVisible: dirty
|
||||
toast.saveChangesText: qsTr("Apply to my Wallet")
|
||||
toast.changesDetectedText: qsTr("New custom sort order created")
|
||||
|
||||
onSaveForLaterClicked: {
|
||||
manageTokensView.saveChanges()
|
||||
}
|
||||
onSaveChangesClicked: {
|
||||
manageTokensView.saveChanges()
|
||||
Global.displayToastMessage(
|
||||
qsTr("Your new custom asset order has been applied to your %1", "Go to Wallet")
|
||||
.arg(`<a style="text-decoration:none" href="#${Constants.appSection.wallet}">` + qsTr("Wallet", "Go to Wallet") + "</a>"),
|
||||
"",
|
||||
"checkmark-circle",
|
||||
false,
|
||||
Constants.ephemeralNotificationType.success,
|
||||
""
|
||||
)
|
||||
}
|
||||
onResetChangesClicked: {
|
||||
manageTokensView.resetChanges()
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: stackContainer
|
||||
|
||||
|
@ -55,7 +83,9 @@ SettingsContentBase {
|
|||
height: stackContainer.currentIndex === root.mainViewIndex ? main.height:
|
||||
stackContainer.currentIndex === root.networksViewIndex ? networksView.height:
|
||||
stackContainer.currentIndex === root.editNetworksViewIndex ? editNetwork.height:
|
||||
stackContainer.currentIndex === root.accountOrderViewIndex ? accountOrderView.height: accountView.height
|
||||
stackContainer.currentIndex === root.accountOrderViewIndex ? accountOrderView.height:
|
||||
stackContainer.currentIndex === root.manageTokensViewIndex ? manageTokensView.implicitHeight :
|
||||
accountView.height
|
||||
currentIndex: mainViewIndex
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
|
@ -218,12 +248,15 @@ SettingsContentBase {
|
|||
}
|
||||
|
||||
ManageTokensView {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: Style.current.padding
|
||||
Layout.rightMargin: Style.current.padding
|
||||
|
||||
id: manageTokensView
|
||||
sourcesOfTokensModel: tokensStore.sourcesOfTokensModel
|
||||
tokensListModel: tokensStore.extendedFlatTokensModel
|
||||
baseWalletAssetsModel: RootStore.assets // TODO include community assets (#12369)
|
||||
baseWalletCollectiblesModel: {
|
||||
RootStore.setFillterAllAddresses() // FIXME no other way to get _all_ collectibles?
|
||||
// TODO concat proxy model to include community collectibles (#12519)
|
||||
return RootStore.collectiblesStore.ownedCollectibles
|
||||
}
|
||||
}
|
||||
|
||||
DappPermissionsView {
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import QtQuick 2.15
|
||||
import SortFilterProxyModel 0.2
|
||||
import QtQuick.Controls 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
|
@ -38,7 +37,6 @@ ColumnLayout {
|
|||
text: accountsList.count > 1? qsTr("Move your most frequently used accounts to the top of your wallet list") :
|
||||
qsTr("This account looks a little lonely. Add another account to enable re-ordering.")
|
||||
color: Theme.palette.baseColor1
|
||||
font.pixelSize: Style.current.primaryTextFontSize
|
||||
}
|
||||
|
||||
StatusListView {
|
||||
|
@ -102,7 +100,6 @@ ColumnLayout {
|
|||
icon.height: 40
|
||||
icon.name: model.emoji
|
||||
icon.color: Utils.getColorForId(model.colorId)
|
||||
actions: []
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
import QtQuick 2.13
|
||||
import SortFilterProxyModel 0.2
|
||||
|
||||
import utils 1.0
|
||||
import shared.status 1.0
|
||||
import shared.panels 1.0
|
||||
import StatusQ.Core.Theme 0.1
|
||||
import StatusQ.Core 0.1
|
||||
import StatusQ.Controls 0.1
|
||||
import StatusQ.Components 0.1
|
||||
|
||||
import utils 1.0
|
||||
import shared.status 1.0
|
||||
import shared.panels 1.0
|
||||
import shared.popups 1.0
|
||||
import shared.popups.addaccount 1.0
|
||||
|
||||
|
|
|
@ -4,8 +4,10 @@ import QtQuick.Layouts 1.15
|
|||
import StatusQ.Controls 0.1
|
||||
|
||||
import shared.controls 1.0
|
||||
import utils 1.0
|
||||
|
||||
import AppLayouts.Profile.panels 1.0
|
||||
import AppLayouts.Wallet.panels 1.0
|
||||
|
||||
ColumnLayout {
|
||||
id: root
|
||||
|
@ -13,6 +15,58 @@ ColumnLayout {
|
|||
required property var sourcesOfTokensModel // Expected roles: key, name, updatedAt, source, version, tokensCount, image
|
||||
required property var tokensListModel // Expected roles: name, symbol, image, chainName, explorerUrl
|
||||
|
||||
required property var baseWalletAssetsModel
|
||||
required property var baseWalletCollectiblesModel
|
||||
|
||||
readonly property bool dirty: {
|
||||
if (!loader.item)
|
||||
return false
|
||||
if (tabBar.currentIndex > d.collectiblesTabIndex)
|
||||
return false
|
||||
if (tabBar.currentIndex === d.collectiblesTabIndex && baseCollectiblesModel.isFetching)
|
||||
return false
|
||||
return loader.item && loader.item.dirty
|
||||
}
|
||||
|
||||
function saveChanges() {
|
||||
if (tabBar.currentIndex > d.collectiblesTabIndex)
|
||||
return
|
||||
loader.item.saveSettings()
|
||||
}
|
||||
|
||||
function resetChanges() {
|
||||
if (tabBar.currentIndex > d.collectiblesTabIndex)
|
||||
return
|
||||
loader.item.revert()
|
||||
}
|
||||
|
||||
QtObject {
|
||||
id: d
|
||||
|
||||
readonly property int assetsTabIndex: 0
|
||||
readonly property int collectiblesTabIndex: 1
|
||||
readonly property int tokenSourcesTabIndex: 2
|
||||
|
||||
function checkLoadMoreCollectibles() {
|
||||
if (tabBar.currentIndex !== collectiblesTabIndex)
|
||||
return
|
||||
// If there is no more items to load or we're already fetching, return
|
||||
if (!root.baseCollectiblesModel.hasMore || root.baseCollectiblesModel.isFetching)
|
||||
return
|
||||
root.baseCollectiblesModel.loadMore()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: root.baseCollectiblesModel
|
||||
function onHasMoreChanged() {
|
||||
d.checkLoadMoreCollectibles()
|
||||
}
|
||||
function onIsFetchingChanged() {
|
||||
d.checkLoadMoreCollectibles()
|
||||
}
|
||||
}
|
||||
|
||||
StatusTabBar {
|
||||
id: tabBar
|
||||
|
||||
|
@ -20,49 +74,60 @@ ColumnLayout {
|
|||
Layout.topMargin: 5
|
||||
|
||||
StatusTabButton {
|
||||
id: assetsTab
|
||||
leftPadding: 0
|
||||
width: implicitWidth
|
||||
text: qsTr("Assets")
|
||||
}
|
||||
|
||||
StatusTabButton {
|
||||
id: collectiblesTab
|
||||
width: implicitWidth
|
||||
text: qsTr("Collectibles ")
|
||||
text: qsTr("Collectibles")
|
||||
}
|
||||
|
||||
StatusTabButton {
|
||||
id: tokensListTab
|
||||
width: implicitWidth
|
||||
text: qsTr("Token lists")
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: stackLayout
|
||||
|
||||
// NB: we want to discard any pending unsaved changes when switching tabs or navigating away
|
||||
Loader {
|
||||
id: loader
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
currentIndex: tabBar.currentIndex
|
||||
active: visible
|
||||
|
||||
ShapeRectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: parent.width - 4 // The rectangular path is rendered outside
|
||||
Layout.maximumHeight: 44
|
||||
text: qsTr("You’ll be able to manage the display of your assets here")
|
||||
sourceComponent: {
|
||||
switch (tabBar.currentIndex) {
|
||||
case d.assetsTabIndex:
|
||||
return tokensPanel
|
||||
case d.collectiblesTabIndex:
|
||||
return collectiblesPanel
|
||||
case d.tokenSourcesTabIndex:
|
||||
return supportedTokensListPanel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ShapeRectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: parent.width - 4 // The rectangular path is rendered outside
|
||||
Layout.maximumHeight: 44
|
||||
text: qsTr("You’ll be able to manage the display of your collectibles here")
|
||||
Component {
|
||||
id: tokensPanel
|
||||
ManageAssetsPanel {
|
||||
baseModel: root.baseWalletAssetsModel
|
||||
}
|
||||
// TODO #12611 add Advanced section
|
||||
}
|
||||
|
||||
Component {
|
||||
id: collectiblesPanel
|
||||
ManageCollectiblesPanel {
|
||||
baseModel: root.baseWalletCollectiblesModel
|
||||
Component.onCompleted: d.checkLoadMoreCollectibles()
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: supportedTokensListPanel
|
||||
SupportedTokenListsPanel {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
|
||||
sourcesOfTokensModel: root.sourcesOfTokensModel
|
||||
tokensListModel: root.tokensListModel
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ DropArea {
|
|||
objectName: "manageTokensDelegate-%1".arg(index)
|
||||
|
||||
// expected roles: symbol, name, communityId, communityName, communityImage, collectionName, imageUrl
|
||||
// + enabledNetworkBalance, enabledNetworkCurrencyBalance -> TODO might get dropped/renamed in the future!!!
|
||||
|
||||
property var controller
|
||||
property int visualIndex: index
|
||||
|
@ -71,7 +72,7 @@ DropArea {
|
|||
: LocaleUtils.currencyAmountToLocaleString(model.enabledNetworkBalance)
|
||||
bgRadius: priv.bgRadius
|
||||
hasImage: true
|
||||
icon.source: root.isCollectible ? model.imageUrl : Constants.tokenIcon(model.symbol) // TODO unify via backend model for both assets and collectibles
|
||||
icon.source: root.isCollectible ? model.imageUrl : Constants.tokenIcon(model.symbol) // TODO unify via backend model for both assets and collectibles; handle communityPrivilegesLevel
|
||||
icon.width: priv.iconSize
|
||||
icon.height: priv.iconSize
|
||||
spacing: 12
|
||||
|
|
|
@ -18,8 +18,8 @@ ColumnLayout {
|
|||
property int outNetworkLayer: 0
|
||||
property int inNetworkLayer: 0
|
||||
|
||||
property int outNetworkTimestamp: 0
|
||||
property int inNetworkTimestamp: 0
|
||||
property double outNetworkTimestamp: 0
|
||||
property double inNetworkTimestamp: 0
|
||||
|
||||
property string outChainName
|
||||
property string inChainName
|
||||
|
|
|
@ -2,5 +2,5 @@ WalletHeader 1.0 WalletHeader.qml
|
|||
WalletTxProgressBlock 1.0 WalletTxProgressBlock.qml
|
||||
WalletNftPreview 1.0 WalletNftPreview.qml
|
||||
ActivityFilterPanel 1.0 ActivityFilterPanel.qml
|
||||
ManageTokensPanel 1.0 ManageTokensPanel.qml
|
||||
ManageAssetsPanel 1.0 ManageAssetsPanel.qml
|
||||
ManageCollectiblesPanel 1.0 ManageCollectiblesPanel.qml
|
||||
|
|
|
@ -38,7 +38,8 @@ QtObject {
|
|||
|
||||
property CollectiblesStore collectiblesStore: CollectiblesStore {}
|
||||
|
||||
property var areTestNetworksEnabled: networksModule.areTestNetworksEnabled
|
||||
readonly property bool areTestNetworksEnabled: networksModule.areTestNetworksEnabled
|
||||
readonly property bool isSepoliaEnabled: networksModule.isSepoliaEnabled
|
||||
|
||||
property var savedAddresses: SortFilterProxyModel {
|
||||
sourceModel: walletSectionSavedAddresses.model
|
||||
|
|
|
@ -40,7 +40,6 @@ Item {
|
|||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
color: Style.current.secondaryText
|
||||
text: qsTr("Collectibles will appear here")
|
||||
font.pixelSize: 15
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -65,7 +64,7 @@ Item {
|
|||
isLoading: !!model.isLoading
|
||||
privilegesLevel: model.communityPrivilegesLevel ?? Constants.TokenPrivilegesLevel.Community
|
||||
ornamentColor: model.communityColor ?? "transparent"
|
||||
communityId: model.communityId
|
||||
communityId: model.communityId ?? ""
|
||||
|
||||
onClicked: root.collectibleClicked(model.chainId, model.contractAddress, model.tokenId, model.uid)
|
||||
}
|
||||
|
|
|
@ -49,13 +49,13 @@ Item {
|
|||
id: d
|
||||
function getBackButtonText(index) {
|
||||
switch(index) {
|
||||
case 1:
|
||||
case 1:
|
||||
return qsTr("Collectibles")
|
||||
case 2:
|
||||
case 2:
|
||||
return qsTr("Assets")
|
||||
case 3:
|
||||
case 3:
|
||||
return qsTr("Activity")
|
||||
default:
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
@ -156,8 +156,6 @@ Item {
|
|||
}
|
||||
}
|
||||
CollectibleDetailView {
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
collectible: RootStore.collectiblesStore.detailedCollectible
|
||||
isCollectibleLoading: RootStore.collectiblesStore.isDetailedCollectibleLoading
|
||||
|
||||
|
@ -169,8 +167,6 @@ Item {
|
|||
AssetsDetailView {
|
||||
id: assetDetailView
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
visible: (stack.currentIndex === 2)
|
||||
|
||||
assetsLoading: RootStore.assetsLoading
|
||||
|
@ -186,8 +182,6 @@ Item {
|
|||
|
||||
TransactionDetailView {
|
||||
id: transactionDetailView
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
onVisibleChanged: {
|
||||
if (!visible)
|
||||
transaction = null
|
||||
|
|
|
@ -1612,6 +1612,7 @@ Item {
|
|||
this.open = false
|
||||
}
|
||||
onLinkActivated: {
|
||||
this.open = false
|
||||
if(actionRequired) {
|
||||
toastsManager.doAction(model.actionType, model.actionData)
|
||||
return
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import QtQuick 2.14
|
||||
import QtQuick.Layouts 1.14
|
||||
import QtGraphicalEffects 1.13
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.15
|
||||
|
||||
import utils 1.0
|
||||
|
||||
|
@ -12,14 +12,24 @@ Rectangle {
|
|||
id: root
|
||||
|
||||
property bool active: false
|
||||
property bool cancelButtonVisible: true
|
||||
property bool saveChangesButtonEnabled: false
|
||||
property bool saveForLaterButtonVisible
|
||||
property alias saveChangesText: saveChangesButton.text
|
||||
property alias saveForLaterText: saveForLaterButton.text
|
||||
property alias cancelChangesText: cancelChangesButton.text
|
||||
property alias changesDetectedText: changesDetectedTextItem.text
|
||||
|
||||
property Flickable flickable: null
|
||||
|
||||
enum Type {
|
||||
Danger,
|
||||
Info
|
||||
}
|
||||
property int type: SettingsDirtyToastMessage.Type.Danger
|
||||
|
||||
signal saveChangesClicked
|
||||
signal saveForLaterClicked
|
||||
signal resetChangesClicked
|
||||
|
||||
function notifyDirty() {
|
||||
|
@ -33,8 +43,9 @@ Rectangle {
|
|||
opacity: active ? 1 : 0
|
||||
color: Theme.palette.statusToastMessage.backgroundColor
|
||||
radius: 8
|
||||
border.color: Theme.palette.dangerColor2
|
||||
border.color: type === SettingsDirtyToastMessage.Type.Danger ? Theme.palette.dangerColor2 : Theme.palette.primaryColor2
|
||||
border.width: 2
|
||||
|
||||
layer.enabled: true
|
||||
layer.effect: DropShadow {
|
||||
verticalOffset: 3
|
||||
|
@ -42,7 +53,7 @@ Rectangle {
|
|||
samples: 15
|
||||
fast: true
|
||||
cached: true
|
||||
color: Theme.palette.dangerColor2
|
||||
color: root.border.color
|
||||
spread: 0.1
|
||||
}
|
||||
|
||||
|
@ -104,7 +115,6 @@ Rectangle {
|
|||
|
||||
StatusBaseText {
|
||||
id: changesDetectedTextItem
|
||||
Layout.columnSpan: 2
|
||||
Layout.fillWidth: true
|
||||
padding: 8
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
|
@ -116,10 +126,19 @@ Rectangle {
|
|||
id: cancelChangesButton
|
||||
text: qsTr("Cancel")
|
||||
enabled: root.active
|
||||
visible: root.cancelButtonVisible
|
||||
type: StatusBaseButton.Type.Danger
|
||||
onClicked: root.resetChangesClicked()
|
||||
}
|
||||
|
||||
StatusFlatButton {
|
||||
id: saveForLaterButton
|
||||
text: qsTr("Save for later")
|
||||
enabled: root.active && root.saveChangesButtonEnabled
|
||||
visible: root.saveForLaterButtonVisible
|
||||
onClicked: root.saveForLaterClicked()
|
||||
}
|
||||
|
||||
StatusButton {
|
||||
id: saveChangesButton
|
||||
objectName: "settingsDirtyToastMessageSaveButton"
|
||||
|
|
Loading…
Reference in New Issue