diff --git a/ui/app/AppLayouts/Chat/stores/RootStore.qml b/ui/app/AppLayouts/Chat/stores/RootStore.qml index e3ddbc2b73..06169c619a 100644 --- a/ui/app/AppLayouts/Chat/stores/RootStore.qml +++ b/ui/app/AppLayouts/Chat/stores/RootStore.qml @@ -10,6 +10,8 @@ QtObject { property var contactsStore + property var networkConnectionStore + readonly property PermissionsStore permissionsStore: PermissionsStore { activeSectionId: mainModuleInst.activeSection.id chatCommunitySectionModuleInst: chatCommunitySectionModule diff --git a/ui/app/AppLayouts/Profile/ProfileLayout.qml b/ui/app/AppLayouts/Profile/ProfileLayout.qml index 8ab6fa290d..8fc1f06d8c 100644 --- a/ui/app/AppLayouts/Profile/ProfileLayout.qml +++ b/ui/app/AppLayouts/Profile/ProfileLayout.qml @@ -21,6 +21,7 @@ StatusSectionLayout { property var globalStore property var systemPalette property var emojiPopup + property var networkConnectionStore backButtonName: root.store.backButtonName notificationCount: activityCenterStore.unreadNotificationsCount @@ -139,7 +140,7 @@ StatusSectionLayout { ensUsernamesStore: root.store.ensUsernamesStore contactsStore: root.store.contactsStore stickersStore: root.store.stickersStore - + networkConnectionStore: root.networkConnectionStore profileContentWidth: d.contentWidth } } diff --git a/ui/app/AppLayouts/Profile/views/EnsView.qml b/ui/app/AppLayouts/Profile/views/EnsView.qml index 629a80407f..8323ab2123 100644 --- a/ui/app/AppLayouts/Profile/views/EnsView.qml +++ b/ui/app/AppLayouts/Profile/views/EnsView.qml @@ -15,6 +15,7 @@ Item { property var contactsStore property var stickersStore + property var networkConnectionStore property int profileContentWidth property bool showSearchScreen: false @@ -218,6 +219,8 @@ Item { username: ensView.ensUsernamesStore.username onStartBtnClicked: next(null) profileContentWidth: ensView.profileContentWidth + startButtonEnabled: ensView.networkConnectionStore.ensNetworkAvailable + tooltipText: ensView.networkConnectionStore.ensNetworkUnavailableText } } diff --git a/ui/app/AppLayouts/Profile/views/EnsWelcomeView.qml b/ui/app/AppLayouts/Profile/views/EnsWelcomeView.qml index facbe17f71..f18a9a85b1 100644 --- a/ui/app/AppLayouts/Profile/views/EnsWelcomeView.qml +++ b/ui/app/AppLayouts/Profile/views/EnsWelcomeView.qml @@ -7,6 +7,7 @@ import StatusQ.Core.Theme 0.1 import StatusQ.Controls 0.1 import utils 1.0 +import shared.controls 1.0 Item { id: root @@ -15,6 +16,8 @@ Item { property string username: "" property int profileContentWidth + property bool startButtonEnabled: true + property string tooltipText StatusScrollView { id: sview @@ -278,15 +281,16 @@ Item { } } - StatusButton { + DisabledTooltipButton { id: startBtn - objectName: "ensStartButton" + interactive: startButtonEnabled + buttonType: DisabledTooltipButton.Normal + aliasedObjectName: "ensStartButton" anchors.bottom: parent.bottom anchors.bottomMargin: Style.current.padding anchors.horizontalCenter: parent.horizontalCenter - text: enabled ? - qsTr("Start") : - qsTr("Only available on Mainnet") + text: qsTr("Start") + tooltipText: root.tooltipText onClicked: startBtnClicked() } } diff --git a/ui/app/AppLayouts/Wallet/WalletLayout.qml b/ui/app/AppLayouts/Wallet/WalletLayout.qml index a6010ab726..c71496ca3b 100644 --- a/ui/app/AppLayouts/Wallet/WalletLayout.qml +++ b/ui/app/AppLayouts/Wallet/WalletLayout.qml @@ -20,6 +20,7 @@ Item { property var contactsStore property var emojiPopup: null property var sendModalPopup + property var networkConnectionStore function showSigningPhrasePopup(){ if(!hideSignPhraseModal && !RootStore.hideSignPhraseModal){ @@ -56,6 +57,7 @@ Item { store: root.store contactsStore: root.contactsStore sendModal: root.sendModalPopup + networkConnectionStore: root.networkConnectionStore } } @@ -96,6 +98,7 @@ Item { rightPanelStackView.replace(walletContainer) } emojiPopup: root.emojiPopup + networkConnectionStore: root.networkConnectionStore } centerPanel: StackView { diff --git a/ui/app/AppLayouts/Wallet/controls/FooterTooltipButton.qml b/ui/app/AppLayouts/Wallet/controls/FooterTooltipButton.qml deleted file mode 100644 index f52b8a53ed..0000000000 --- a/ui/app/AppLayouts/Wallet/controls/FooterTooltipButton.qml +++ /dev/null @@ -1,29 +0,0 @@ -import QtQuick 2.14 - -import StatusQ.Controls 0.1 - -Item { - property alias button: button - property alias text: button.text - property alias icon: button.icon.name - property alias tooltipText: tooltip.text - - implicitWidth: button.width - implicitHeight: button.height - - StatusFlatButton { - id: button - anchors.centerIn: parent - } - MouseArea { - id: mouseArea - anchors.fill: button - hoverEnabled: !button.enabled - enabled: !button.enabled - cursorShape: Qt.PointingHandCursor - } - StatusToolTip { - id: tooltip - visible: mouseArea.containsMouse - } -} diff --git a/ui/app/AppLayouts/Wallet/panels/WalletFooter.qml b/ui/app/AppLayouts/Wallet/panels/WalletFooter.qml index a3e019d45c..1de59bbfd6 100644 --- a/ui/app/AppLayouts/Wallet/panels/WalletFooter.qml +++ b/ui/app/AppLayouts/Wallet/panels/WalletFooter.qml @@ -7,6 +7,7 @@ import StatusQ.Controls 0.1 import StatusQ.Core.Theme 0.1 import utils 1.0 +import shared.controls 1.0 import "../popups" import "../controls" @@ -31,12 +32,13 @@ Rectangle { height: parent.height spacing: Style.current.padding - FooterTooltipButton { - button.objectName: "walletFooterSendButton" - button.icon.name: "send" - button.text: qsTr("Send") - button.enabled: networkConnectionStore.sendBuyBridgeEnabled - button.onClicked: function() { + DisabledTooltipButton { + buttonType: DisabledTooltipButton.Flat + aliasedObjectName: "walletFooterSendButton" + icon: "send" + text: qsTr("Send") + interactive: networkConnectionStore.sendBuyBridgeEnabled + onClicked: function() { sendModal.open() } tooltipText: networkConnectionStore.sendBuyBridgeToolTipText @@ -50,11 +52,12 @@ Rectangle { } } - FooterTooltipButton { - button.icon.name: "bridge" - button.text: qsTr("Bridge") - button.enabled: networkConnectionStore.sendBuyBridgeEnabled - button.onClicked: function() { + DisabledTooltipButton { + icon: "bridge" + buttonType: DisabledTooltipButton.Flat + text: qsTr("Bridge") + interactive: networkConnectionStore.sendBuyBridgeEnabled + onClicked: function() { sendModal.isBridgeTx = true sendModal.open() } diff --git a/ui/app/AppLayouts/Wallet/views/LeftTabView.qml b/ui/app/AppLayouts/Wallet/views/LeftTabView.qml index 1584602009..eea64cd618 100644 --- a/ui/app/AppLayouts/Wallet/views/LeftTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/LeftTabView.qml @@ -25,7 +25,7 @@ import "../addaccount" Rectangle { id: root - readonly property NetworkConnectionStore networkConnectionStore: NetworkConnectionStore {} + property var networkConnectionStore property var changeSelectedAccount: function(){} property bool showSavedAddresses: false onShowSavedAddressesChanged: { diff --git a/ui/app/AppLayouts/Wallet/views/RightTabView.qml b/ui/app/AppLayouts/Wallet/views/RightTabView.qml index 52d7f883f9..ab602bea84 100644 --- a/ui/app/AppLayouts/Wallet/views/RightTabView.qml +++ b/ui/app/AppLayouts/Wallet/views/RightTabView.qml @@ -20,7 +20,7 @@ Item { property var store property var contactsStore property var sendModal - readonly property NetworkConnectionStore networkConnectionStore: NetworkConnectionStore {} + property var networkConnectionStore function resetStack() { stack.currentIndex = 0; diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index dddf90193a..18fa7a26e6 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -51,6 +51,7 @@ Item { contactsStore: appMain.rootStore.contactStore emojiReactionsModel: appMain.rootStore.emojiReactionsModel openCreateChat: createChatView.opened + networkConnectionStore: appMain.networkConnectionStore } property ActivityCenterStore activityCenterStore: ActivityCenterStore {} property NetworkConnectionStore networkConnectionStore: NetworkConnectionStore {} @@ -878,6 +879,7 @@ Item { emojiReactionsModel: appMain.rootStore.emojiReactionsModel openCreateChat: createChatView.opened chatCommunitySectionModule: appMain.rootStore.mainModuleInst.getChatSectionModule() + networkConnectionStore: appMain.networkConnectionStore } emojiPopup: statusEmojiPopup stickersPopup: statusStickersPopupLoader.item @@ -920,6 +922,7 @@ Item { contactsStore: appMain.rootStore.profileSectionStore.contactsStore emojiPopup: statusEmojiPopup sendModalPopup: sendModal + networkConnectionStore: appMain.networkConnectionStore } onLoaded: item.showSigningPhrasePopup() } @@ -951,6 +954,7 @@ Item { globalStore: appMain.rootStore systemPalette: appMain.sysPalette emojiPopup: statusEmojiPopup + networkConnectionStore: appMain.networkConnectionStore } } diff --git a/ui/imports/shared/controls/DisabledTooltipButton.qml b/ui/imports/shared/controls/DisabledTooltipButton.qml new file mode 100644 index 0000000000..c9407e7386 --- /dev/null +++ b/ui/imports/shared/controls/DisabledTooltipButton.qml @@ -0,0 +1,59 @@ +import QtQuick 2.15 + +import StatusQ.Controls 0.1 + +Item { + id: root + property string aliasedObjectName + property string text + property string icon + property alias tooltipText: tooltip.text + property int buttonType: DisabledTooltipButton.Normal + property bool interactive: true + signal clicked() + + enum Type { + Normal, // 0 + Flat // 1 + } + + implicitWidth: buttonLoader.item.width + implicitHeight: buttonLoader.item.height + + Loader { + id: buttonLoader + anchors.centerIn: parent + sourceComponent: buttonType === DisabledTooltipButton.Normal ? normalButton : flatButton + active: root.visible + } + HoverHandler { + id: hoverHandler + enabled: !root.interactive + cursorShape: Qt.PointingHandCursor + } + StatusToolTip { + id: tooltip + visible: hoverHandler.hovered + } + + Component{ + id: flatButton + StatusFlatButton { + objectName: root.aliasedObjectName + icon.name: root.icon + text: root.text + enabled: root.interactive + onClicked: root.clicked() + } + } + Component{ + id: normalButton + StatusButton { + objectName: root.aliasedObjectName + icon.name: root.icon + text: root.text + enabled: root.interactive + onClicked: root.clicked() + } + } +} diff --git a/ui/imports/shared/controls/qmldir b/ui/imports/shared/controls/qmldir index 9c19074834..9f1ec3ece8 100644 --- a/ui/imports/shared/controls/qmldir +++ b/ui/imports/shared/controls/qmldir @@ -38,3 +38,4 @@ GetSyncCodeMobileInstructions 1.0 GetSyncCodeMobileInstructions.qml GetSyncCodeDesktopInstructions 1.0 GetSyncCodeDesktopInstructions.qml ErrorDetails 1.0 ErrorDetails.qml CopyButton 1.0 CopyButton.qml +DisabledTooltipButton 1.0 DisabledTooltipButton.qml diff --git a/ui/imports/shared/status/StatusStickerButton.qml b/ui/imports/shared/status/StatusStickerButton.qml index 1233dfd7b7..96a612e4ea 100644 --- a/ui/imports/shared/status/StatusStickerButton.qml +++ b/ui/imports/shared/status/StatusStickerButton.qml @@ -1,8 +1,11 @@ -import QtQuick 2.13 +import QtQuick 2.15 import QtQuick.Controls 2.13 import QtQuick.Layouts 1.3 import QtGraphicalEffects 1.0 +import StatusQ.Core.Theme 0.1 +import StatusQ.Controls 0.1 + import utils 1.0 import shared 1.0 import shared.panels 1.0 @@ -13,6 +16,7 @@ Item { Default, LargeNoIcon } + property alias tooltip: tooltip property int style: StatusStickerButton.StyleType.Default property int packPrice: 0 property bool isBought: false @@ -22,14 +26,15 @@ Item { property bool isTimedOut: false property bool hasInsufficientFunds: false property bool enabled: true + property bool greyedOut: false property var icon: new Object({ path: Style.svg("status-logo-no-bg"), rotation: 0, runAnimation: false }) property string text: root.style === StatusStickerButton.StyleType.Default ? packPrice : qsTr("Buy for %1 SNT").arg(packPrice ) - property color textColor: style === StatusStickerButton.StyleType.Default ? Style.current.roundedButtonSecondaryForegroundColor : Style.current.buttonForegroundColor - property color bgColor: style === StatusStickerButton.StyleType.Default ? Style.current.blue : Style.current.secondaryBackground + property color textColor: root.greyedOut ? Theme.palette.baseColor1 : style === StatusStickerButton.StyleType.Default ? Style.current.roundedButtonSecondaryForegroundColor : Style.current.buttonForegroundColor + property color bgColor: root.greyedOut ? Theme.palette.baseColor2 : style === StatusStickerButton.StyleType.Default ? Style.current.blue : Style.current.secondaryBackground signal uninstallClicked() signal installClicked() signal cancelClicked() @@ -44,8 +49,8 @@ Item { PropertyChanges { target: root; text: root.style === StatusStickerButton.StyleType.Default ? "" : qsTr("Uninstall"); - textColor: root.style === StatusStickerButton.StyleType.Default ? Style.current.roundedButtonSecondaryForegroundColor : Style.current.red; - bgColor: root.style === StatusStickerButton.StyleType.Default ? Style.current.green : Style.current.lightRed; + textColor: root.style === StatusStickerButton.StyleType.Default ? Style.current.roundedButtonSecondaryForegroundColor : root.greyedOut ? Theme.palette.baseColor1 : Style.current.red; + bgColor: root.style === StatusStickerButton.StyleType.Default ? Style.current.green : root.greyedOut ? Theme.palette.baseColor2 : Style.current.lightRed; icon: new Object({ path: Style.svg("check"), rotation: 0, @@ -182,7 +187,7 @@ Item { ColorOverlay { anchors.fill: roundedIconImage source: roundedIconImage - color: Style.current.roundedButtonSecondaryForegroundColor + color: root.greyedOut && !root.isInstalled ? Theme.palette.baseColor1 : Style.current.roundedButtonSecondaryForegroundColor antialiasing: true } states: [ @@ -239,11 +244,23 @@ Item { ] } + // Tooltip only in case we are browsing an item to be installed/downloaded/bought + HoverHandler { + id: hoverHandler + enabled: root.greyedOut && !root.isInstalled + cursorShape: Qt.PointingHandCursor + } + StatusToolTip { + id: tooltip + visible: hoverHandler.hovered + maxWidth: 300 + } + MouseArea { id: mouseArea anchors.fill: parent acceptedButtons: Qt.LeftButton | Qt.RightButton - enabled: !root.isPending + enabled: !root.isPending && !root.greyedOut cursorShape: Qt.PointingHandCursor onClicked: { if (root.isPending) return; diff --git a/ui/imports/shared/status/StatusStickerMarket.qml b/ui/imports/shared/status/StatusStickerMarket.qml index fbc33e12c5..4ab9ab819c 100644 --- a/ui/imports/shared/status/StatusStickerMarket.qml +++ b/ui/imports/shared/status/StatusStickerMarket.qml @@ -137,6 +137,8 @@ Item { isInstalled: installed isBought: bought isPending: pending + greyedOut: !root.store.networkConnectionStore.stickersNetworkAvailable + tooltip.text: root.store.networkConnectionStore.stickersNetworkUnavailableText onInstallClicked: root.installClicked(stickers, packId, index) onUninstallClicked: root.uninstallClicked(packId) onCancelClicked: root.cancelClicked(packId) @@ -235,6 +237,8 @@ Item { isInstalled: installed isBought: bought isPending: pending + greyedOut: !root.store.networkConnectionStore.stickersNetworkAvailable + tooltip.text: root.store.networkConnectionStore.stickersNetworkUnavailableText onInstallClicked: root.installClicked(stickers, packId, index) onUninstallClicked: root.uninstallClicked(packId) onCancelClicked: root.cancelClicked(packId) diff --git a/ui/imports/shared/status/StatusStickerPackClickPopup.qml b/ui/imports/shared/status/StatusStickerPackClickPopup.qml index a4885924ca..0b5a85b633 100644 --- a/ui/imports/shared/status/StatusStickerPackClickPopup.qml +++ b/ui/imports/shared/status/StatusStickerPackClickPopup.qml @@ -140,6 +140,8 @@ ModalPopup { isInstalled: installed isBought: bought isPending: pending + greyedOut: store.networkConnectionStore.stickersNetworkAvailable + tooltip.text: root.store.networkConnectionStore.stickersNetworkUnavailableText onInstallClicked: { stickersModule.install(packId); stickerPackDetailsPopup.close(); diff --git a/ui/imports/shared/stores/NetworkConnectionStore.qml b/ui/imports/shared/stores/NetworkConnectionStore.qml index 516baeb3b0..38ffecba79 100644 --- a/ui/imports/shared/stores/NetworkConnectionStore.qml +++ b/ui/imports/shared/stores/NetworkConnectionStore.qml @@ -21,16 +21,15 @@ QtObject { readonly property bool sendBuyBridgeEnabled: localAppSettings.testEnvironment || (isOnline && (!networkConnectionModule.blockchainNetworkConnection.completelyDown && atleastOneBlockchainNetworkAvailable) && !networkConnectionModule.marketValuesNetworkConnection.completelyDown) - readonly property string sendBuyBridgeToolTipText: !isOnline ? - qsTr("Requires internet connection") : - networkConnectionModule.blockchainNetworkConnection.completelyDown || - (!networkConnectionModule.blockchainNetworkConnection.completelyDown && - !atleastOneBlockchainNetworkAvailable) ? - qsTr("Requires Pocket Network(POKT) or Infura, both of which are currently unavailable") : - networkConnectionModule.marketValuesNetworkConnection.completelyDown ? - qsTr("Requires CryptoCompare or CoinGecko, both of which are currently unavailable"): - qsTr("Requires POKT/ Infura and CryptoCompare/CoinGecko, which are all currently unavailable") - + readonly property string sendBuyBridgeToolTipText: !isOnline ? qsTr("Requires internet connection") : + noBlockchainAndMarketConnectionAndNoCache ? + qsTr("Requires POKT/Infura and CryptoCompare/CoinGecko, which are all currently unavailable") : + networkConnectionModule.blockchainNetworkConnection.completelyDown || + (!networkConnectionModule.blockchainNetworkConnection.completelyDown && + !atleastOneBlockchainNetworkAvailable) ? + qsTr("Requires Pocket Network(POKT) or Infura, both of which are currently unavailable") : + networkConnectionModule.marketValuesNetworkConnection.completelyDown ? + qsTr("Requires CryptoCompare or CoinGecko, both of which are currently unavailable"): "" readonly property bool notOnlineWithNoCache: !isOnline && !walletSectionCurrent.hasBalanceCache && !walletSectionCurrent.hasMarketValuesCache readonly property string notOnlineWithNoCacheText: qsTr("Internet connection lost. Data could not be retrieved.") @@ -50,7 +49,12 @@ QtObject { networkConnectionModule.blockchainNetworkConnection.completelyDown ? noBlockchainConnectionAndNoCacheText : networkConnectionModule.marketValuesNetworkConnection.completelyDown ? noBlockchainAndMarketConnectionAndNoCacheText : "" - property bool noTokenBalanceAvailable: networkConnectionStore.notOnlineWithNoCache || networkConnectionStore.noBlockchainConnectionAndNoCache + readonly property bool noTokenBalanceAvailable: networkConnectionStore.notOnlineWithNoCache || networkConnectionStore.noBlockchainConnectionAndNoCache + + readonly property bool ensNetworkAvailable: !blockchainNetworksDown.includes(profileSectionModule.ensUsernamesModule.chainId.toString()) + readonly property string ensNetworkUnavailableText: qsTr("Requires POKT/Infura for %1, which is currently unavailable").arg( networksModule.all.getNetworkFullName(profileSectionModule.ensUsernamesModule.chainId)) + readonly property bool stickersNetworkAvailable: false//!blockchainNetworksDown.includes(stickersModule.getChainIdForStickers().toString()) + readonly property string stickersNetworkUnavailableText: qsTr("Requires POKT/Infura for %1, which is currently unavailable").arg( networksModule.all.getNetworkFullName(stickersModule.getChainIdForStickers())) function getBlockchainNetworkDownTextForToken(balances) { if(!!balances && !networkConnectionModule.blockchainNetworkConnection.completelyDown && !networkConnectionStore.notOnlineWithNoCache) {