diff --git a/src/app/global/local_account_sensitive_settings.nim b/src/app/global/local_account_sensitive_settings.nim index 016e14b8ea3..35005390338 100644 --- a/src/app/global/local_account_sensitive_settings.nim +++ b/src/app/global/local_account_sensitive_settings.nim @@ -34,10 +34,9 @@ const LSS_KEY_ACTIVE_SECTION* = "activeSection" const DEFAULT_ACTIVE_SECTION = "" const LAST_SECTION_CHAT = "LastSectionChat" const DEFAULT_ACTIVE_CHAT = "" -const LSS_KEY_SHOW_BROWSER_SELECTOR* = "showBrowserSelector" const DEFAULT_SHOW_BROWSER_SELECTOR = true const LSS_KEY_OPEN_LINKS_IN_STATUS* = "openLinksInStatus" -const DEFAULT_OPEN_LINKS_IN_STATUS = true +const DEFAULT_OPEN_LINKS_IN_STATUS = false const LSS_KEY_SHOULD_SHOW_FAVORITES_BAR* = "shouldShowFavoritesBar" const DEFAULT_SHOULD_SHOW_FAVORITES_BAR = true const LSS_KEY_BROWSER_HOMEPAGE* = "browserHomepage" @@ -325,19 +324,6 @@ QtObject: write = setActiveSection notify = activeSectionChanged - proc showBrowserSelectorChanged*(self: LocalAccountSensitiveSettings) {.signal.} - proc getShowBrowserSelector*(self: LocalAccountSensitiveSettings): bool {.slot.} = - getSettingsProp[bool](self, LSS_KEY_SHOW_BROWSER_SELECTOR, newQVariant(DEFAULT_SHOW_BROWSER_SELECTOR)) - proc setShowBrowserSelector*(self: LocalAccountSensitiveSettings, value: bool) {.slot.} = - setSettingsProp(self, LSS_KEY_SHOW_BROWSER_SELECTOR, newQVariant(value)): - self.showBrowserSelectorChanged() - - QtProperty[bool] showBrowserSelector: - read = getShowBrowserSelector - write = setShowBrowserSelector - notify = showBrowserSelectorChanged - - proc openLinksInStatusChanged*(self: LocalAccountSensitiveSettings) {.signal.} proc getOpenLinksInStatus*(self: LocalAccountSensitiveSettings): bool {.slot.} = getSettingsProp[bool](self, LSS_KEY_OPEN_LINKS_IN_STATUS, newQVariant(DEFAULT_OPEN_LINKS_IN_STATUS)) @@ -603,7 +589,6 @@ QtObject: of LSS_KEY_SHOW_DELETE_MESSAGE_WARNING: self.showDeleteMessageWarningChanged() of LSS_KEY_DOWNLOAD_CHANNEL_MESSAGES_ENABLED: self.downloadChannelMessagesEnabledChanged() of LSS_KEY_ACTIVE_SECTION: self.activeSectionChanged() - of LSS_KEY_SHOW_BROWSER_SELECTOR: self.showBrowserSelectorChanged() of LSS_KEY_OPEN_LINKS_IN_STATUS: self.openLinksInStatusChanged() of LSS_KEY_SHOULD_SHOW_FAVORITES_BAR: self.shouldShowFavoritesBarChanged() of LSS_KEY_BROWSER_HOMEPAGE: self.browserHomepageChanged() @@ -629,4 +614,4 @@ QtObject: self.settingsFileDir = os.joinPath(DATADIR, "qt") proc delete*(self: LocalAccountSensitiveSettings) = - self.QObject.delete \ No newline at end of file + self.QObject.delete diff --git a/storybook/pages/ConfirmExternalLinkPopupPage.qml b/storybook/pages/ConfirmExternalLinkPopupPage.qml new file mode 100644 index 00000000000..71363b7ae08 --- /dev/null +++ b/storybook/pages/ConfirmExternalLinkPopupPage.qml @@ -0,0 +1,54 @@ +import QtQuick +import QtQuick.Layouts +import QtQuick.Controls + +import shared.popups + +import Storybook + +SplitView { + + Logs { id: logs } + + Item { + SplitView.fillWidth: true + SplitView.fillHeight: true + + PopupBackground { + anchors.fill: parent + } + + Button { + anchors.centerIn: parent + text: "Reopen" + + onClicked: popup.open() + } + + ConfirmExternalLinkPopup { + id: popup + + closePolicy: Popup.CloseOnEscape + modal: false + visible: true + + link: "https://etherscan.io/token/0xdac17f958d2ee523a220622064597c13d831ec7" + domain: "etherscan.io" + + onOpenExternalLink: logs.logEvent("onOpenExternalLink called with link: " + link) + onSaveDomainToUnfurledWhitelist: logs.logEvent("onSaveDomainToUnfurledWhitelist called with domain: " + domain) + } + } + + LogsAndControlsPanel { + id: logsAndControlsPanel + + SplitView.minimumHeight: 100 + SplitView.preferredHeight: 200 + + logsView.logText: logs.logText + } +} + +// category: Popups +// https://www.figma.com/design/idUoxN7OIW2Jpp3PMJ1Rl8/Settings----Desktop-Legacy?node-id=27093-584044&m=dev diff --git a/storybook/pages/KeycardIntroPagePage.qml b/storybook/pages/KeycardIntroPagePage.qml index 65bd1c428d0..0eea91b5e9d 100644 --- a/storybook/pages/KeycardIntroPagePage.qml +++ b/storybook/pages/KeycardIntroPagePage.qml @@ -30,8 +30,7 @@ Item { displayPromoBanner: ctrlDisplayPromo.checked onEmptyKeycardDetected: console.warn("!!! EMPTY DETECTED") onNotEmptyKeycardDetected: console.warn("!!! NOT EMPTY DETECTED") - onOpenLink: Qt.openUrlExternally(link) - onOpenLinkWithConfirmation: Qt.openUrlExternally(link) + onRequestOpenLink: Qt.openUrlExternally(link) onKeycardFactoryResetRequested: console.warn("!!! FACTORY RESET") onUnblockWithSeedphraseRequested: console.warn("!!! UNBLOCK WITH SEEDPHRASE") onUnblockWithPukRequested: console.warn("!!! UNBLOCK WITH PUK") diff --git a/storybook/pages/PrivacyAndSecurityViewPage.qml b/storybook/pages/PrivacyAndSecurityViewPage.qml index b0288a43418..3603543d768 100644 --- a/storybook/pages/PrivacyAndSecurityViewPage.qml +++ b/storybook/pages/PrivacyAndSecurityViewPage.qml @@ -21,6 +21,8 @@ SplitView { SplitView.fillHeight: true contentWidth: parent.width + privacySectionTitle: "Privacy" + whitelistedDomainsModel: ["example1.com", "example2.com", "example3.com"] isStatusNewsViaRSSEnabled: true isCentralizedMetricsEnabled: true thirdpartyServicesEnabled: ctrlThirdpartyServicesEnabled.checked diff --git a/storybook/pages/ProfileSocialLinksPanelPage.qml b/storybook/pages/ProfileSocialLinksPanelPage.qml index 536690ba041..72ab817c72e 100644 --- a/storybook/pages/ProfileSocialLinksPanelPage.qml +++ b/storybook/pages/ProfileSocialLinksPanelPage.qml @@ -73,8 +73,8 @@ SplitView { Connections { target: Global - function onOpenLink(link) { - logs.logEvent("Global::openLink", ["link"], [link]) + function onRequestOpenLink(link) { + logs.logEvent("Global::onRequestOpenLink", ["link"], [link]) } } diff --git a/storybook/qmlTests/tests/tst_BuyCryptoModal.qml b/storybook/qmlTests/tests/tst_BuyCryptoModal.qml index eba797fd2dc..9f2c897d7f3 100644 --- a/storybook/qmlTests/tests/tst_BuyCryptoModal.qml +++ b/storybook/qmlTests/tests/tst_BuyCryptoModal.qml @@ -111,7 +111,7 @@ Item { SignalSpy { id: notificationSpy target: Global - signalName: "openLinkWithConfirmation" + signalName: "requestOpenLink" } TestCase { @@ -249,7 +249,6 @@ Item { verify(controlUnderTest.rightButtons[0].loading) tryCompare(notificationSpy, "count", 1) compare(notificationSpy.signalArguments[0][0], "xxxx") - compare(notificationSpy.signalArguments[0][1], modelData.hostname) notificationSpy.clear() // popup should be closed @@ -273,7 +272,6 @@ Item { verify(loadingIndicator.visible) tryCompare(notificationSpy, "count", 1) compare(notificationSpy.signalArguments[0][0], "xxxx") - compare(notificationSpy.signalArguments[0][1], modelData.hostname) notificationSpy.clear() // popup should be closed diff --git a/storybook/qmlTests/tests/tst_SendSignModal.qml b/storybook/qmlTests/tests/tst_SendSignModal.qml index ddb7e65e9f8..368eac1b651 100644 --- a/storybook/qmlTests/tests/tst_SendSignModal.qml +++ b/storybook/qmlTests/tests/tst_SendSignModal.qml @@ -129,7 +129,7 @@ Item { SignalSpy { id: signalSpyOpenLink target: Global - signalName: "openLinkWithConfirmation" + signalName: "requestOpenLink" } property SendSignModal controlUnderTest: null diff --git a/ui/StatusQ/src/StatusQ/Components/StatusDraggableListItem.qml b/ui/StatusQ/src/StatusQ/Components/StatusDraggableListItem.qml index 195f6b895a5..629b4780f2e 100644 --- a/ui/StatusQ/src/StatusQ/Components/StatusDraggableListItem.qml +++ b/ui/StatusQ/src/StatusQ/Components/StatusDraggableListItem.qml @@ -81,7 +81,7 @@ import StatusQ.Core.Theme font.pixelSize: Theme.primaryTextFontSize font.weight: Font.Normal text: draggableDelegate.asideText - onClicked: Global.openLink(model.url) + onClicked: Global.requestOpenLink(model.url) }, StatusFlatRoundButton { icon.name: "edit_pencil" diff --git a/ui/app/AppLayouts/ActivityCenter/ActivityCenterLayout.qml b/ui/app/AppLayouts/ActivityCenter/ActivityCenterLayout.qml index c0e54f93ac6..6a17475a43c 100644 --- a/ui/app/AppLayouts/ActivityCenter/ActivityCenterLayout.qml +++ b/ui/app/AppLayouts/ActivityCenter/ActivityCenterLayout.qml @@ -679,7 +679,7 @@ StatusSectionLayout { id: newsMessagePopup NewsMessagePopup { - onLinkClicked: Global.openLinkWithConfirmation(link, StatusQUtils.StringUtils.extractDomainFromLink(link)); + onLinkClicked: (link) => Global.requestOpenLink(link) } } diff --git a/ui/app/AppLayouts/Chat/popups/ChooseBrowserPopup.qml b/ui/app/AppLayouts/Chat/popups/ChooseBrowserPopup.qml deleted file mode 100644 index 17292030122..00000000000 --- a/ui/app/AppLayouts/Chat/popups/ChooseBrowserPopup.qml +++ /dev/null @@ -1,66 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts - -import utils - -import StatusQ.Controls -import StatusQ.Core.Theme -import StatusQ.Popups.Dialog - -StatusDialog { - id: root - - property string link - - title: qsTr("Choose browser") - width: 400 - footer: null - - contentItem: ColumnLayout { - spacing: 20 - - Image { - source: Theme.png("browser/chooseBrowserImage@2x") - Layout.preferredWidth: 240 - Layout.preferredHeight: 148 - Layout.alignment: Qt.AlignHCenter - cache: false - } - - StatusButton { - Layout.alignment: Qt.AlignHCenter - text: qsTr("Open in Status") - onClicked: { - localAccountSensitiveSettings.showBrowserSelector = !rememberChoiceCheckBox.checked - if (rememberChoiceCheckBox.checked) { - localAccountSensitiveSettings.openLinksInStatus = true - } - Global.changeAppSectionBySectionType(Constants.appSection.browser) - Global.openLinkInBrowser(root.link) - root.close() - } - } - - StatusFlatButton { - text: qsTr("Open in my default browser") - Layout.alignment: Qt.AlignHCenter - onClicked: { - localAccountSensitiveSettings.showBrowserSelector = !rememberChoiceCheckBox.checked - if (rememberChoiceCheckBox.checked) { - localAccountSensitiveSettings.openLinksInStatus = false - } - Qt.openUrlExternally(root.link) - root.close() - } - } - - StatusCheckBox { - Layout.alignment: Qt.AlignHCenter - Layout.bottomMargin: Theme.smallPadding - id: rememberChoiceCheckBox - font.pixelSize: Theme.additionalTextSize - text: qsTr("Remember my choice. To override it, go to Settings.") - } - } -} diff --git a/ui/app/AppLayouts/Chat/popups/qmldir b/ui/app/AppLayouts/Chat/popups/qmldir index 7f99673852f..7a73d227cb7 100644 --- a/ui/app/AppLayouts/Chat/popups/qmldir +++ b/ui/app/AppLayouts/Chat/popups/qmldir @@ -1,3 +1,2 @@ PinnedMessagesPopup 1.0 PinnedMessagesPopup.qml PaymentRequestModal 1.0 PaymentRequestModal.qml -ChooseBrowserPopup 1.0 ChooseBrowserPopup.qml diff --git a/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml b/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml index 53d46c031dd..11953c78cc1 100644 --- a/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml +++ b/ui/app/AppLayouts/Chat/views/ChatHeaderContentView.qml @@ -329,7 +329,7 @@ RowLayout { break; } } - onLinkActivated: Global.openLink(link) + onLinkActivated: (link) => Global.requestOpenLink(link) } } diff --git a/ui/app/AppLayouts/Communities/controls/Options.qml b/ui/app/AppLayouts/Communities/controls/Options.qml index ff31a1df2de..276d535730b 100644 --- a/ui/app/AppLayouts/Communities/controls/Options.qml +++ b/ui/app/AppLayouts/Communities/controls/Options.qml @@ -113,8 +113,7 @@ ColumnLayout { text: qsTr("Learn more about token-gating") font.pixelSize: Theme.primaryTextFontSize normalColor: linkColor - onClicked: Global.openLinkWithConfirmation(d.aboutPermissionsLink, - StatusQUtils.StringUtils.extractDomainFromLink(d.aboutPermissionsLink)) + onClicked: Global.requestOpenLink(d.aboutPermissionsLink) } StatusIcon { @@ -127,8 +126,7 @@ ColumnLayout { anchors.fill: parent cursorShape: Qt.PointingHandCursor - onClicked: Global.openLinkWithConfirmation(d.aboutPermissionsLink, - StatusQUtils.StringUtils.extractDomainFromLink(d.aboutPermissionsLink)) + onClicked: Global.requestOpenLink(d.aboutPermissionsLink) } } } @@ -139,7 +137,7 @@ ColumnLayout { id: messageHistoryInfoPopupComponent EnableFullMessageHistoryPopup { - onAccepted: Global.openLinkWithConfirmation(d.aboutHistoryServiceLink, StatusQUtils.StringUtils.extractDomainFromLink(d.aboutHistoryServiceLink)) + onAccepted: Global.requestOpenLink(d.aboutHistoryServiceLink) onClosed: destroy() } } diff --git a/ui/app/AppLayouts/Communities/panels/OverviewSettingsPanel.qml b/ui/app/AppLayouts/Communities/panels/OverviewSettingsPanel.qml index 5e4b733259e..d603a56bb97 100644 --- a/ui/app/AppLayouts/Communities/panels/OverviewSettingsPanel.qml +++ b/ui/app/AppLayouts/Communities/panels/OverviewSettingsPanel.qml @@ -217,7 +217,7 @@ StackLayout { } onImportControlNodeClicked: root.importControlNodeClicked() onFinaliseOwnershipTransferClicked: root.finaliseOwnershipClicked() - onLearnMoreClicked: Global.openLink(Constants.statusHelpLinkPrefix + "communities/about-the-control-node-in-status-communities") + onLearnMoreClicked: Global.requestOpenLink(Constants.statusHelpLinkPrefix + "communities/about-the-control-node-in-status-communities") } } diff --git a/ui/app/AppLayouts/Communities/popups/CreateChannelPopup.qml b/ui/app/AppLayouts/Communities/popups/CreateChannelPopup.qml index 33e86b604cb..655fbf87bee 100644 --- a/ui/app/AppLayouts/Communities/popups/CreateChannelPopup.qml +++ b/ui/app/AppLayouts/Communities/popups/CreateChannelPopup.qml @@ -429,7 +429,7 @@ StatusStackModal { Layout.alignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter text: qsTr("Export the Discord channel’s chat history data using %1").arg("DiscordChatExporter") - onLinkActivated: Global.openLink(link) + onLinkActivated: (link) => Global.requestOpenLink(link) StatusMouseArea { anchors.fill: parent acceptedButtons: Qt.NoButton @@ -441,7 +441,7 @@ StatusStackModal { Layout.alignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter text: qsTr("Refer to this documentation if you have any queries") - onLinkActivated: Global.openLink(link) + onLinkActivated: (link) => Global.requestOpenLink(link) StatusMouseArea { anchors.fill: parent acceptedButtons: Qt.NoButton diff --git a/ui/app/AppLayouts/Communities/popups/CreateCommunityPopup.qml b/ui/app/AppLayouts/Communities/popups/CreateCommunityPopup.qml index 15d6f38f1f3..a68a083ed78 100644 --- a/ui/app/AppLayouts/Communities/popups/CreateCommunityPopup.qml +++ b/ui/app/AppLayouts/Communities/popups/CreateCommunityPopup.qml @@ -158,7 +158,7 @@ StatusStackModal { Layout.alignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter text: qsTr("Export your Discord JSON data using %1").arg("DiscordChatExporter") - onLinkActivated: link => Global.openLink(link) + onLinkActivated: link => Global.requestOpenLink(link) HoverHandler { id: handler1 } @@ -172,7 +172,7 @@ StatusStackModal { Layout.alignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter text: qsTr("Refer to this documentation if you have any queries") - onLinkActivated: link => Global.openLink(link) + onLinkActivated: link => Global.requestOpenLink(link) HoverHandler { id: handler2 } diff --git a/ui/app/AppLayouts/Communities/views/CommunitiesGridView.qml b/ui/app/AppLayouts/Communities/views/CommunitiesGridView.qml index c7f9d3ec1a8..979e90a76aa 100644 --- a/ui/app/AppLayouts/Communities/views/CommunitiesGridView.qml +++ b/ui/app/AppLayouts/Communities/views/CommunitiesGridView.qml @@ -227,10 +227,8 @@ StatusScrollView { PromotionalCommunityCard { width: d.delegateWidth - onLearnMore: Global.openLinkWithConfirmation(d.learnAboutCommunitiesVoteLink, - StringUtils.extractDomainFromLink(d.learnAboutCommunitiesVoteLink)) - onInitiateVote: Global.openLinkWithConfirmation(d.voteCommunityLink, - StringUtils.extractDomainFromLink(d.voteCommunityLink)) + onLearnMore: Global.requestOpenLink(d.learnAboutCommunitiesVoteLink) + onInitiateVote: Global.requestOpenLink(d.voteCommunityLink) } Repeater { diff --git a/ui/app/AppLayouts/Onboarding/OnboardingLayout.qml b/ui/app/AppLayouts/Onboarding/OnboardingLayout.qml index e39f633badc..3455bfe4296 100644 --- a/ui/app/AppLayouts/Onboarding/OnboardingLayout.qml +++ b/ui/app/AppLayouts/Onboarding/OnboardingLayout.qml @@ -268,10 +268,7 @@ Page { target: onboardingFlow.topLevelItem ignoreUnknownSignals: true - function onOpenLink(link: string) { - Qt.openUrlExternally(link) - } - function onOpenLinkWithConfirmation(link: string, domain: string) { + function onRequestOpenLink(link: string) { Qt.openUrlExternally(link) } } diff --git a/ui/app/AppLayouts/Onboarding/pages/KeycardBasePage.qml b/ui/app/AppLayouts/Onboarding/pages/KeycardBasePage.qml index 6dbfb321833..921dbe59f9c 100644 --- a/ui/app/AppLayouts/Onboarding/pages/KeycardBasePage.qml +++ b/ui/app/AppLayouts/Onboarding/pages/KeycardBasePage.qml @@ -55,7 +55,7 @@ OnboardingPage { color: Theme.palette.baseColor1 horizontalAlignment: Text.AlignHCenter visible: !!text - onLinkActivated: openLinkWithConfirmation(link, SQUtils.StringUtils.extractDomainFromLink(link)) + onLinkActivated: (link) => requestOpenLink(link) HoverHandler { // Qt CSS doesn't support custom cursor shape diff --git a/ui/app/AppLayouts/Onboarding/pages/KeycardIntroPage.qml b/ui/app/AppLayouts/Onboarding/pages/KeycardIntroPage.qml index be2318f94ff..c4ca3811179 100644 --- a/ui/app/AppLayouts/Onboarding/pages/KeycardIntroPage.qml +++ b/ui/app/AppLayouts/Onboarding/pages/KeycardIntroPage.qml @@ -77,7 +77,7 @@ KeycardBasePage { icon.name: "external-link" icon.width: 24 icon.height: 24 - onClicked: openLink("https://keycard.tech/") + onClicked: requestOpenLink("https://keycard.tech/") } } } diff --git a/ui/app/AppLayouts/Onboarding/pages/KeycardLostPage.qml b/ui/app/AppLayouts/Onboarding/pages/KeycardLostPage.qml index b063ca00574..353d46b2490 100644 --- a/ui/app/AppLayouts/Onboarding/pages/KeycardLostPage.qml +++ b/ui/app/AppLayouts/Onboarding/pages/KeycardLostPage.qml @@ -42,6 +42,6 @@ KeycardBasePage { icon.name: "external-link" icon.width: 24 icon.height: 24 - onClicked: openLink("https://keycard.tech/") + onClicked: requestOpenLink("https://keycard.tech/") } } diff --git a/ui/app/AppLayouts/Onboarding/pages/OnboardingPage.qml b/ui/app/AppLayouts/Onboarding/pages/OnboardingPage.qml index b6759bf8d66..9d3aa1cd276 100644 --- a/ui/app/AppLayouts/Onboarding/pages/OnboardingPage.qml +++ b/ui/app/AppLayouts/Onboarding/pages/OnboardingPage.qml @@ -4,8 +4,7 @@ import QtQuick.Controls import StatusQ.Core.Theme Page { - signal openLink(string link) - signal openLinkWithConfirmation(string link, string domain) + signal requestOpenLink(string link) implicitWidth: 1200 implicitHeight: 700 diff --git a/ui/app/AppLayouts/Profile/ProfileLayout.qml b/ui/app/AppLayouts/Profile/ProfileLayout.qml index cce271b725c..b57f286c5b1 100644 --- a/ui/app/AppLayouts/Profile/ProfileLayout.qml +++ b/ui/app/AppLayouts/Profile/ProfileLayout.qml @@ -87,6 +87,8 @@ StatusSectionLayout { required property int theme // Theme.Style.xxx required property int fontSize // Theme.FontSize.xxx + + required property var whitelistedDomainsModel signal addressWasShownRequested(string address) signal connectUsernameRequested(string ensName, string ownerAddress) @@ -101,6 +103,7 @@ StatusSectionLayout { signal openThirdpartyServicesInfoPopupRequested() signal openDiscussPageRequested() + signal removeWhitelistedDomain(int index) backButtonName: d.backButtonName onBackButtonClicked: { @@ -115,6 +118,9 @@ StatusSectionLayout { case Constants.settingsSubsection.wallet: walletView.item.resetStack() break; + case Constants.settingsSubsection.privacyAndSecurity: + privacyAndSecurityView.item.resetStack() + break; case Constants.settingsSubsection.keycard: keycardView.item.handleBackAction() break; @@ -204,6 +210,8 @@ StatusSectionLayout { d.backButtonName = settingsEntriesModel.getNameForSubsection(Constants.settingsSubsection.about) } else if (currentIndex === Constants.settingsSubsection.wallet) { walletView.item.resetStack() + } else if (currentIndex === Constants.settingsSubsection.privacyAndSecurity) { + privacyAndSecurityView.item.resetStack() } else if (currentIndex === Constants.settingsSubsection.keycard) { keycardView.item.handleBackAction() } @@ -476,7 +484,7 @@ StatusSectionLayout { qtRuntimeVersion: SystemUtils.qtRuntimeVersion() onCheckForUpdates: root.aboutStore.checkForUpdates() - onOpenLink: (url) => Global.openLink(url) + onOpenLink: (url) => Global.requestOpenLink(url) } } @@ -556,7 +564,7 @@ StatusSectionLayout { wrapMode: Text.Wrap textFormat: Text.MarkdownText text: SQUtils.StringUtils.readTextFile(":/imports/assets/docs/terms-of-use.mdwn") - onLinkActivated: Global.openLinkWithConfirmation(link, SQUtils.StringUtils.extractDomainFromLink(link)) + onLinkActivated: (link) => Global.requestOpenLink(link) } } } @@ -577,15 +585,18 @@ StatusSectionLayout { wrapMode: Text.Wrap textFormat: Text.MarkdownText text: SQUtils.StringUtils.readTextFile(":/imports/assets/docs/privacy.mdwn") - onLinkActivated: Global.openLinkWithConfirmation(link, SQUtils.StringUtils.extractDomainFromLink(link)) + onLinkActivated: (link) => Global.requestOpenLink(link) } } } Loader { + id: privacyAndSecurityView + active: false asynchronous: true sourceComponent: PrivacyAndSecurityView { + whitelistedDomainsModel: root.whitelistedDomainsModel isStatusNewsViaRSSEnabled: root.privacyStore.isStatusNewsViaRSSEnabled isCentralizedMetricsEnabled: root.isCentralizedMetricsEnabled thirdpartyServicesEnabled: root.privacyStore.thirdpartyServicesEnabled @@ -593,7 +604,7 @@ StatusSectionLayout { implicitWidth: parent.width implicitHeight: parent.height - sectionTitle: settingsEntriesModel.getNameForSubsection(Constants.settingsSubsection.privacyAndSecurity) + privacySectionTitle: settingsEntriesModel.getNameForSubsection(Constants.settingsSubsection.privacyAndSecurity) contentWidth: d.contentWidth onSetNewsRSSEnabledRequested: function (isStatusNewsViaRSSEnabled) { @@ -601,6 +612,9 @@ StatusSectionLayout { } onOpenThirdpartyServicesInfoPopupRequested: root.openThirdpartyServicesInfoPopupRequested() onOpenDiscussPageRequested: root.openDiscussPageRequested() + + onBackButtonTextChanged: d.backButtonName = backButtonText + onRemoveWhitelistedDomain: index => root.removeWhitelistedDomain(index) } } diff --git a/ui/app/AppLayouts/Profile/panels/ProfileSocialLinksPanel.qml b/ui/app/AppLayouts/Profile/panels/ProfileSocialLinksPanel.qml index 2db6fa6616b..08f6f08ec13 100644 --- a/ui/app/AppLayouts/Profile/panels/ProfileSocialLinksPanel.qml +++ b/ui/app/AppLayouts/Profile/panels/ProfileSocialLinksPanel.qml @@ -167,7 +167,7 @@ Control { font.pixelSize: Theme.primaryTextFontSize font.weight: Font.Normal text: draggableDelegate.asideText - onClicked: Global.openLink(model.url) + onClicked: Global.requestOpenLink(model.url) }, StatusFlatRoundButton { icon.name: "edit_pencil" diff --git a/ui/app/AppLayouts/Profile/panels/SupportedTokenListsPanel.qml b/ui/app/AppLayouts/Profile/panels/SupportedTokenListsPanel.qml index d422bac371b..4e054c21828 100644 --- a/ui/app/AppLayouts/Profile/panels/SupportedTokenListsPanel.qml +++ b/ui/app/AppLayouts/Profile/panels/SupportedTokenListsPanel.qml @@ -94,7 +94,7 @@ StatusListView { } } - onLinkClicked: (link) => Global.openLink(link) + onLinkClicked: (link) => Global.requestOpenLink(link) onClosed: keyFilter.value = "" } } diff --git a/ui/app/AppLayouts/Profile/popups/WalletAddressMenu.qml b/ui/app/AppLayouts/Profile/popups/WalletAddressMenu.qml index 39e5c5ec0a9..1fa329ad9fd 100644 --- a/ui/app/AppLayouts/Profile/popups/WalletAddressMenu.qml +++ b/ui/app/AppLayouts/Profile/popups/WalletAddressMenu.qml @@ -44,7 +44,7 @@ StatusMenu { flatNetworks: root.flatNetworks onNetworkClicked: { let link = Utils.getUrlForAddressOnNetwork(shortname, isTestnet, root.selectedAccount.address ?? ""); - Global.openLinkWithConfirmation(link, StatusQUtils.StringUtils.extractDomainFromLink(link)); + Global.requestOpenLink(link); } } diff --git a/ui/app/AppLayouts/Profile/views/EnsTermsAndConditionsView.qml b/ui/app/AppLayouts/Profile/views/EnsTermsAndConditionsView.qml index 53f8b3b3683..6399895486d 100644 --- a/ui/app/AppLayouts/Profile/views/EnsTermsAndConditionsView.qml +++ b/ui/app/AppLayouts/Profile/views/EnsTermsAndConditionsView.qml @@ -149,7 +149,7 @@ Item { .arg(root.ensUsernamesStore.getEnsRegisteredAddress()) anchors.left: parent.left anchors.right: parent.right - onLinkActivated: Global.openLink(link) + onLinkActivated: (link) => Global.requestOpenLink(link) color: Theme.palette.directColor1 StatusMouseArea { anchors.fill: parent @@ -173,7 +173,7 @@ Item { .arg(root.ensUsernamesStore.getEnsRegistry()) anchors.left: parent.left anchors.right: parent.right - onLinkActivated: Global.openLink(link) + onLinkActivated: (link) => Global.requestOpenLink(link) color: Theme.palette.directColor1 StatusMouseArea { anchors.fill: parent diff --git a/ui/app/AppLayouts/Profile/views/KeycardView.qml b/ui/app/AppLayouts/Profile/views/KeycardView.qml index 1e401fb723c..591648156e6 100644 --- a/ui/app/AppLayouts/Profile/views/KeycardView.qml +++ b/ui/app/AppLayouts/Profile/views/KeycardView.qml @@ -23,7 +23,7 @@ SettingsContentBase { titleRowComponentLoader.sourceComponent: StatusButton { text: qsTr("Get Keycard") onClicked: { - Global.openLink(Constants.keycard.general.purchasePage) + Global.requestOpenLink(Constants.keycard.general.purchasePage) } } diff --git a/ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml b/ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml index 537d20a90f3..97091a97942 100644 --- a/ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml +++ b/ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml @@ -6,6 +6,7 @@ import utils import StatusQ.Components import StatusQ.Controls +import StatusQ.Core import StatusQ.Core.Theme import shared.controls @@ -17,117 +18,198 @@ SettingsContentBase { required property bool isCentralizedMetricsEnabled required property bool thirdpartyServicesEnabled required property bool privacyModeFeatureEnabled + required property var whitelistedDomainsModel + required property string privacySectionTitle + + property string backButtonText signal setNewsRSSEnabledRequested(bool isStatusNewsViaRSSEnabled) signal openThirdpartyServicesInfoPopupRequested() signal openDiscussPageRequested() + signal removeWhitelistedDomain(int index) function refreshSwitch() { enableMetricsSwitch.checked = Qt.binding(function() { return root.isCentralizedMetricsEnabled }) } - titleRowComponentLoader.sourceComponent: StatusButton { - text: qsTr("Privacy policy") - onClicked: Global.privacyPolicyRequested() + function resetStack() { + stackContainer.currentIndex = 0 } - ColumnLayout { - StatusListItem { - Layout.preferredWidth: root.contentWidth - title: qsTr("Receive Status News via RSS") - subTitle: qsTr("Your IP address will be exposed to https://status.app") - components: [ - StatusSwitch { - id: statusNewsSwitch - checked: root.isStatusNewsViaRSSEnabled - onToggled: root.setNewsRSSEnabledRequested(statusNewsSwitch.checked) - } - ] - onClicked: root.setNewsRSSEnabledRequested(!statusNewsSwitch.checked) - enabled: root.thirdpartyServicesEnabled - } - - // Divider - Rectangle { - Layout.preferredWidth: root.contentWidth - Layout.preferredHeight: 1 - color: Theme.palette.baseColor2 - } + StackLayout { + id: stackContainer + + // Main Security & Privacy Page + ColumnLayout { + StatusListItem { + Layout.preferredWidth: root.contentWidth + title: qsTr("Receive Status News via RSS") + subTitle: qsTr("Your IP address will be exposed to https://status.app") + components: [ + StatusSwitch { + id: statusNewsSwitch + checked: root.isStatusNewsViaRSSEnabled + onToggled: root.setNewsRSSEnabledRequested(statusNewsSwitch.checked) + } + ] + onClicked: root.setNewsRSSEnabledRequested(!statusNewsSwitch.checked) + enabled: root.thirdpartyServicesEnabled + } - StatusListItem { - Layout.preferredWidth: root.contentWidth - title: qsTr("Third-party services") - subTitle: qsTr("Enable/disable all third-party services") - components: [ - StatusSwitch { - checkable: false - checked: root.thirdpartyServicesEnabled - onClicked: root.openThirdpartyServicesInfoPopupRequested() - } - ] - onClicked: root.openThirdpartyServicesInfoPopupRequested() - visible: root.privacyModeFeatureEnabled - } + // Divider + Rectangle { + Layout.preferredWidth: root.contentWidth + Layout.preferredHeight: 1 + color: Theme.palette.baseColor2 + } - InformationTag { - id: infoTag + StatusListItem { + Layout.preferredWidth: root.contentWidth + title: qsTr("Third-party services") + subTitle: qsTr("Enable/disable all third-party services") + components: [ + StatusSwitch { + checkable: false + checked: root.thirdpartyServicesEnabled + onClicked: root.openThirdpartyServicesInfoPopupRequested() + } + ] + onClicked: root.openThirdpartyServicesInfoPopupRequested() + visible: root.privacyModeFeatureEnabled + } - Layout.preferredWidth: root.contentWidth - Layout.preferredHeight: 40 - Layout.alignment: Qt.AlignHCenter - - leftInset: Theme.padding - rightInset: Theme.padding - leftPadding: horizontalPadding + Theme.padding - rightPadding: horizontalPadding + Theme.padding - - backgroundColor: Theme.palette.primaryColor3 - bgBorderColor: Theme.palette.primaryColor2 - bgRadius: 12 - asset.name: "info" - tagPrimaryLabel.wrapMode: Text.WordWrap - tagPrimaryLabel.textFormat: Text.RichText - tagPrimaryLabel.font.pixelSize: Theme.additionalTextSize - tagPrimaryLabel.text: qsTr("Share feedback or suggest improvements on our %1.") - .arg(Utils.getStyledLink("Discuss page", "#", tagPrimaryLabel.hoveredLink, Theme.palette.primaryColor1, Theme.palette.primaryColor1, false)) - tagPrimaryLabel.onLinkActivated: root.openDiscussPageRequested() - visible: root.privacyModeFeatureEnabled - } + InformationTag { + id: infoTag + + Layout.preferredWidth: root.contentWidth + Layout.preferredHeight: 40 + Layout.alignment: Qt.AlignHCenter + + leftInset: Theme.padding + rightInset: Theme.padding + leftPadding: horizontalPadding + Theme.padding + rightPadding: horizontalPadding + Theme.padding + + backgroundColor: Theme.palette.primaryColor3 + bgBorderColor: Theme.palette.primaryColor2 + bgRadius: 12 + asset.name: "info" + tagPrimaryLabel.wrapMode: Text.WordWrap + tagPrimaryLabel.textFormat: Text.RichText + tagPrimaryLabel.font.pixelSize: Theme.additionalTextSize + tagPrimaryLabel.text: qsTr("Share feedback or suggest improvements on our %1.") + .arg(Utils.getStyledLink("Discuss page", "#", tagPrimaryLabel.hoveredLink, Theme.palette.primaryColor1, Theme.palette.primaryColor1, false)) + tagPrimaryLabel.onLinkActivated: root.openDiscussPageRequested() + visible: root.privacyModeFeatureEnabled + } - // Divider - Rectangle { - Layout.preferredWidth: root.contentWidth - Layout.preferredHeight: 1 - color: Theme.palette.baseColor2 - visible: root.privacyModeFeatureEnabled - } + // Divider + Rectangle { + Layout.preferredWidth: root.contentWidth + Layout.preferredHeight: 1 + color: Theme.palette.baseColor2 + visible: root.privacyModeFeatureEnabled + } - StatusListItem { - Layout.preferredWidth: root.contentWidth - title: qsTr("Share usage data with Status") - subTitle: qsTr("From all profiles on device") - components: [ - StatusSwitch { - id: enableMetricsSwitch - checked: root.isCentralizedMetricsEnabled - onToggled: { - Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null) - refreshSwitch() + StatusListItem { + Layout.preferredWidth: root.contentWidth + title: qsTr("Share usage data with Status") + subTitle: qsTr("From all profiles on device") + components: [ + StatusSwitch { + id: enableMetricsSwitch + checked: root.isCentralizedMetricsEnabled + onToggled: { + Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null) + refreshSwitch() + } } + ] + onClicked: { + Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null) + refreshSwitch() } - ] - onClicked: { - Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null) - refreshSwitch() + enabled: root.thirdpartyServicesEnabled + } + + // Divider + Rectangle { + Layout.preferredWidth: root.contentWidth + Layout.preferredHeight: 1 + color: Theme.palette.baseColor2 + } + + // Trusted Sites + StatusListItem { + Layout.preferredWidth: root.contentWidth + title: qsTr("Trusted sites") + subTitle: qsTr("Manage trusted sites. Their links open without confirmation.") + components: [ + StatusIcon { + icon: "next" + color: Theme.palette.baseColor1 + } + ] + onClicked: stackContainer.currentIndex = 1 + } + + // Divider + Rectangle { + Layout.preferredWidth: root.contentWidth + Layout.preferredHeight: 1 + color: Theme.palette.baseColor2 } - enabled: root.thirdpartyServicesEnabled } - // Divider - Rectangle { + // Whitelisted Domains Page + WhitelistedDomainsView { Layout.preferredWidth: root.contentWidth - Layout.preferredHeight: 1 - color: Theme.palette.baseColor2 + whitelistedDomainsModel: root.whitelistedDomainsModel + onRemoveWhitelistedDomain: index => root.removeWhitelistedDomain(index) + } + + } + + Component { + id: privacyPolicyButton + StatusButton { + text: qsTr("Privacy policy") + onClicked: Global.privacyPolicyRequested() } } + + states: [ + State { + name: "mainView" + when: stackContainer.currentIndex === 0 + PropertyChanges { + target: root + backButtonText: "" + } + PropertyChanges { + target: titleRowComponentLoader + sourceComponent: privacyPolicyButton + } + PropertyChanges { + target: root + sectionTitle: root.privacySectionTitle + } + }, + State { + name: "whitelistedDomainsView" + when: stackContainer.currentIndex === 1 + PropertyChanges { + target: root + backButtonText: root.privacySectionTitle + } + PropertyChanges { + target: titleRowComponentLoader + sourceComponent: undefined + } + PropertyChanges { + target: root + sectionTitle: "" + } + } + ] } diff --git a/ui/app/AppLayouts/Profile/views/WhitelistedDomainsView.qml b/ui/app/AppLayouts/Profile/views/WhitelistedDomainsView.qml new file mode 100644 index 00000000000..dd90497a9b9 --- /dev/null +++ b/ui/app/AppLayouts/Profile/views/WhitelistedDomainsView.qml @@ -0,0 +1,52 @@ +import QtQuick +import QtQuick.Layouts + +import StatusQ.Controls +import StatusQ.Components +import StatusQ.Core +import StatusQ.Core.Theme + +ColumnLayout { + id: root + + required property var whitelistedDomainsModel + + signal removeWhitelistedDomain(int index) + + spacing: Theme.bigPadding + + StatusBaseText { + text: qsTr("Trusted sites") + font.pixelSize: 28 + font.bold: true + } + + StatusBaseText { + text: qsTr("Manage trusted sites. Their links open without confirmation.") + } + + StatusBaseText { + Layout.topMargin: Theme.xlPadding + Layout.alignment: Qt.AlignHCenter + text: qsTr("No trusted sites added yet") + visible: root.whitelistedDomainsModel.length === 0 + color: Theme.palette.baseColor1 + } + + StatusListView { + Layout.fillWidth: true + Layout.fillHeight: true + + model: root.whitelistedDomainsModel + delegate: StatusListItem { + Layout.preferredWidth: parent.width + title: modelData + components: [ + StatusFlatButton { + icon.name: "close" + onClicked: root.removeWhitelistedDomain(index) + } + ] + } + } +} diff --git a/ui/app/AppLayouts/Profile/views/qmldir b/ui/app/AppLayouts/Profile/views/qmldir index 5eb23084d43..8e38df06b09 100644 --- a/ui/app/AppLayouts/Profile/views/qmldir +++ b/ui/app/AppLayouts/Profile/views/qmldir @@ -11,3 +11,4 @@ PrivacyAndSecurityView 1.0 PrivacyAndSecurityView.qml SyncingView 1.0 SyncingView.qml SettingsLeftTabView 1.0 SettingsLeftTabView.qml SettingsContentBase 1.0 SettingsContentBase.qml +WhitelistedDomainsView 1.0 WhitelistedDomainsView.qml diff --git a/ui/app/AppLayouts/Wallet/controls/SavedAddressesDelegate.qml b/ui/app/AppLayouts/Wallet/controls/SavedAddressesDelegate.qml index 2a19d70a2e3..a2f6a980302 100644 --- a/ui/app/AppLayouts/Wallet/controls/SavedAddressesDelegate.qml +++ b/ui/app/AppLayouts/Wallet/controls/SavedAddressesDelegate.qml @@ -217,7 +217,7 @@ StatusListItem { flatNetworks: root.activeNetworks onNetworkClicked: { let link = Utils.getUrlForAddressOnNetwork(shortname, isTestnet, d.visibleAddress ? d.visibleAddress : root.ens); - Global.openLinkWithConfirmation(link, StatusQUtils.StringUtils.extractDomainFromLink(link)); + Global.requestOpenLink(link) } } diff --git a/ui/app/AppLayouts/Wallet/popups/SignTransactionModalBase.qml b/ui/app/AppLayouts/Wallet/popups/SignTransactionModalBase.qml index ee2cc83013c..8bc34714f36 100644 --- a/ui/app/AppLayouts/Wallet/popups/SignTransactionModalBase.qml +++ b/ui/app/AppLayouts/Wallet/popups/SignTransactionModalBase.qml @@ -111,8 +111,8 @@ StatusDialog { closePolicy: Popup.NoAutoClose - function openLinkWithConfirmation(linkUrl) { - Global.openLinkWithConfirmation(linkUrl, SQUtils.StringUtils.extractDomainFromLink(linkUrl)) + function requestOpenLink(linkUrl) { + Global.requestOpenLink(linkUrl) } header: StatusDialogHeader { diff --git a/ui/app/AppLayouts/Wallet/popups/buy/BuyCryptoModal.qml b/ui/app/AppLayouts/Wallet/popups/buy/BuyCryptoModal.qml index 8ed0ad63ce0..3ef0fe1cbed 100644 --- a/ui/app/AppLayouts/Wallet/popups/buy/BuyCryptoModal.qml +++ b/ui/app/AppLayouts/Wallet/popups/buy/BuyCryptoModal.qml @@ -48,7 +48,7 @@ StatusStackModal { if(uuid === d.uuid) { d.urlIsBeingFetched = false if (!!d.selectedProviderEntry.item && !!url) - Global.openLinkWithConfirmation(url, d.selectedProviderEntry.item.hostname) + Global.requestOpenLink(url) root.close() } } diff --git a/ui/app/AppLayouts/Wallet/popups/simpleSend/SendSignModal.qml b/ui/app/AppLayouts/Wallet/popups/simpleSend/SendSignModal.qml index 177fea69569..c29b84d1c12 100644 --- a/ui/app/AppLayouts/Wallet/popups/simpleSend/SendSignModal.qml +++ b/ui/app/AppLayouts/Wallet/popups/simpleSend/SendSignModal.qml @@ -436,7 +436,7 @@ SignTransactionModalBase { networkName: root.networkName networkShortName: root.networkShortName networkBlockExplorerUrl: root.networkBlockExplorerUrl - onOpenLink: (link) => root.openLinkWithConfirmation(link) + onOpenLink: (link) => root.requestOpenLink(link) } ] visible: !root.isCollectible @@ -464,7 +464,7 @@ SignTransactionModalBase { networkBlockExplorerUrl: root.networkBlockExplorerUrl loading: root.isCollectibleLoading openSeaExplorerUrl: root.fnGetOpenSeaExplorerUrl(root.networkShortName) - onOpenLink: (link) => root.openLinkWithConfirmation(link) + onOpenLink: (link) => root.requestOpenLink(link) } visible: root.isCollectible enabled: !root.internalPopupActive @@ -504,7 +504,7 @@ SignTransactionModalBase { networkName: root.networkName networkShortName: root.networkShortName networkBlockExplorerUrl: root.networkBlockExplorerUrl - onOpenLink: (link) => root.openLinkWithConfirmation(link) + onOpenLink: (link) => root.requestOpenLink(link) } ] enabled: !root.internalPopupActive diff --git a/ui/app/AppLayouts/Wallet/popups/swap/SwapApproveCapModal.qml b/ui/app/AppLayouts/Wallet/popups/swap/SwapApproveCapModal.qml index 0495c23b5d0..69543159c8e 100644 --- a/ui/app/AppLayouts/Wallet/popups/swap/SwapApproveCapModal.qml +++ b/ui/app/AppLayouts/Wallet/popups/swap/SwapApproveCapModal.qml @@ -74,8 +74,8 @@ SignTransactionModalBase { } SwapProvidersTermsAndConditionsText { serviceProviderName: root.serviceProviderName - onLinkClicked: root.openLinkWithConfirmation(root.serviceProviderURL) - onTermsAndConditionClicked: root.openLinkWithConfirmation(root.serviceProviderTandCUrl) + onLinkClicked: root.requestOpenLink(root.serviceProviderURL) + onTermsAndConditionClicked: root.requestOpenLink(root.serviceProviderTandCUrl) } } ] @@ -185,7 +185,7 @@ SignTransactionModalBase { networkName: root.networkName networkShortName: root.networkShortName networkBlockExplorerUrl: root.networkBlockExplorerUrl - onOpenLink: (link) => root.openLinkWithConfirmation(link) + onOpenLink: (link) => root.requestOpenLink(link) } ] } @@ -206,7 +206,7 @@ SignTransactionModalBase { networkName: root.serviceProviderName networkShortName: root.networkShortName networkBlockExplorerUrl: root.networkBlockExplorerUrl - onOpenLink: (link) => root.openLinkWithConfirmation(link) + onOpenLink: (link) => root.requestOpenLink(link) } ] } diff --git a/ui/app/AppLayouts/Wallet/popups/swap/SwapSignModal.qml b/ui/app/AppLayouts/Wallet/popups/swap/SwapSignModal.qml index da7a84367f2..54b5f9514ec 100644 --- a/ui/app/AppLayouts/Wallet/popups/swap/SwapSignModal.qml +++ b/ui/app/AppLayouts/Wallet/popups/swap/SwapSignModal.qml @@ -59,8 +59,8 @@ SignTransactionModalBase { headerSubTextLayout: [ SwapProvidersTermsAndConditionsText { serviceProviderName: root.serviceProviderName - onLinkClicked: root.openLinkWithConfirmation(root.serviceProviderURL) - onTermsAndConditionClicked: root.openLinkWithConfirmation(root.serviceProviderTandCUrl) + onLinkClicked: root.requestOpenLink(root.serviceProviderURL) + onTermsAndConditionClicked: root.requestOpenLink(root.serviceProviderTandCUrl) } ] infoTagText: qsTr("Review all details before signing") @@ -129,7 +129,7 @@ SignTransactionModalBase { networkName: root.networkName networkShortName: root.networkShortName networkBlockExplorerUrl: root.networkBlockExplorerUrl - onOpenLink: (link) => root.openLinkWithConfirmation(link) + onOpenLink: (link) => root.requestOpenLink(link) } ] } @@ -152,7 +152,7 @@ SignTransactionModalBase { networkName: root.networkName networkShortName: root.networkShortName networkBlockExplorerUrl: root.networkBlockExplorerUrl - onOpenLink: (link) => root.openLinkWithConfirmation(link) + onOpenLink: (link) => root.requestOpenLink(link) } ] } diff --git a/ui/app/AppLayouts/Wallet/views/AssetsDetailView.qml b/ui/app/AppLayouts/Wallet/views/AssetsDetailView.qml index 3be01b4ccd4..b65e066e3c6 100644 --- a/ui/app/AppLayouts/Wallet/views/AssetsDetailView.qml +++ b/ui/app/AppLayouts/Wallet/views/AssetsDetailView.qml @@ -449,7 +449,7 @@ Item { StatusMouseArea { anchors.fill: parent cursorShape: Qt.PointingHandCursor - onClicked: Global.openLink(token.websiteUrl) + onClicked: Global.requestOpenLink(token.websiteUrl) } } } diff --git a/ui/app/AppLayouts/Wallet/views/TransactionSettings.qml b/ui/app/AppLayouts/Wallet/views/TransactionSettings.qml index f9a5e0b261c..2f807992aa6 100644 --- a/ui/app/AppLayouts/Wallet/views/TransactionSettings.qml +++ b/ui/app/AppLayouts/Wallet/views/TransactionSettings.qml @@ -182,9 +182,7 @@ Rectangle { alertNote.text: infoBox.note alertNote.color: Theme.palette.baseColor1 - onCancelClicked: { - Qt.openUrlExternally(infoBox.url) - } + onCancelClicked: Global.requestOpenLink(infoBox.url) onClosed: { infoBox.active = false diff --git a/ui/app/AppLayouts/Wallet/views/collectibles/CollectibleDetailView.qml b/ui/app/AppLayouts/Wallet/views/collectibles/CollectibleDetailView.qml index f00b8a90ef6..7a682e9858d 100644 --- a/ui/app/AppLayouts/Wallet/views/collectibles/CollectibleDetailView.qml +++ b/ui/app/AppLayouts/Wallet/views/collectibles/CollectibleDetailView.qml @@ -109,11 +109,11 @@ Item { Global.switchToCommunity(collectible.communityId) } else { - Global.openLinkWithConfirmation(d.collectionLink, root.walletRootStore.getOpenseaDomainName()) + Global.requestOpenLink(d.collectionLink) } } - onOpenCollectibleExternally: Global.openLinkWithConfirmation(d.collectibleLink, root.walletRootStore.getOpenseaDomainName()) - onOpenCollectibleOnExplorer: Global.openLinkWithConfirmation(d.blockExplorerLink, Utils.getExplorerDomain(networkShortName)) + onOpenCollectibleExternally: Global.requestOpenLink(d.collectibleLink) + onOpenCollectibleOnExplorer: Global.requestOpenLink(d.blockExplorerLink) } ColumnLayout { @@ -321,21 +321,21 @@ Item { secondaryText: !!collectible ? collectible.website : "" visible: !!collectible && !!collectible.website && !!collectible.collectionName enabled: !!collectible ? Utils.getUrlStatus(collectible.website): false - onClicked: Global.openLinkWithConfirmation(collectible.website, collectible.website) + onClicked: Global.requestOpenLink(collectible.website) } CollectibleLinksTags { asset.name: "tiny/opensea" primaryText: qsTr("Opensea") secondaryText: d.collectionLink visible: Utils.getUrlStatus(d.collectionLink) - onClicked: Global.openLinkWithConfirmation(d.collectionLink, root.walletRootStore.getOpenseaDomainName()) + onClicked: Global.requestOpenLink(d.collectionLink) } CollectibleLinksTags { asset.name: "xtwitter" primaryText: qsTr("Twitter") secondaryText: !!collectible ? collectible.twitterHandle : "" visible: !!collectible && collectible.twitterHandle - onClicked: Global.openLinkWithConfirmation(root.walletRootStore.getTwitterLink(collectible.twitterHandle), Constants.socialLinkPrefixesByType[Constants.socialLinkType.twitter]) + onClicked: Global.requestOpenLink(root.walletRootStore.getTwitterLink(collectible.twitterHandle)) } } } diff --git a/ui/app/AppLayouts/stores/RootStore.qml b/ui/app/AppLayouts/stores/RootStore.qml index 53ed0e6d406..7be47b92896 100644 --- a/ui/app/AppLayouts/stores/RootStore.qml +++ b/ui/app/AppLayouts/stores/RootStore.qml @@ -149,7 +149,6 @@ QtObject { property real volume: !!appSettings ? appSettings.volume * 0.01 : 0.5 property bool notificationSoundsEnabled: !!appSettings ? appSettings.notificationSoundsEnabled : true - readonly property bool showBrowserSelector: localAccountSensitiveSettings.showBrowserSelector readonly property bool openLinksInStatus: localAccountSensitiveSettings.openLinksInStatus readonly property QtObject _d: QtObject { diff --git a/ui/app/mainui/AppMain.qml b/ui/app/mainui/AppMain.qml index a981390a895..ed7f33457f7 100644 --- a/ui/app/mainui/AppMain.qml +++ b/ui/app/mainui/AppMain.qml @@ -68,7 +68,7 @@ Item { localBackupEnabled: appMain.featureFlagsStore.localBackupEnabled thirdpartyServicesEnabled: appMain.featureFlagsStore.privacyModeFeatureEnabled ? appMain.privacyStore.thirdpartyServicesEnabled: true - onOpenUrl: (link) => Global.openLinkWithConfirmation(link, SQUtils.StringUtils.extractDomainFromLink(link)) + onOpenUrl: (link) => Global.requestOpenLink(link) keychain: appMain.keychain } @@ -849,6 +849,16 @@ Item { } return username } + + function openLinkInBrowser(link: string) { + if (!appMain.rootStore.openLinksInStatus || !d.isBrowserEnabled) { + Qt.openUrlExternally(link) + return + } + globalConns.onAppSectionBySectionTypeChanged(Constants.appSection.browser) + changeAppSectionBySectionId(Constants.appSection.browser) + Qt.callLater(() => browserLayoutContainer.item.openUrlInNewTab(link)) + } } Settings { @@ -905,12 +915,13 @@ Item { isDevBuild: !appMain.rootStore.isProduction - onOpenExternalLink: (link) => globalConns.onOpenLink(link) + onOpenExternalLink: (link) => d.openLinkInBrowser(link) onSaveDomainToUnfurledWhitelist: function(domain) { const whitelistedHostnames = appMainLocalSettings.whitelistedUnfurledDomains || [] if (!whitelistedHostnames.includes(domain)) { whitelistedHostnames.push(domain) appMainLocalSettings.whitelistedUnfurledDomains = whitelistedHostnames + Global.displaySuccessToastMessage(qsTr("%1 added to your trusted sites.").arg(domain)) } } onTransferOwnershipRequested: (tokenId, senderAddress) => popupRequestsHandler.sendModalHandler.transferOwnership(tokenId, senderAddress) @@ -945,11 +956,6 @@ Item { id: globalConns target: Global - function onOpenLinkInBrowser(link: string) { - changeAppSectionBySectionId(Constants.appSection.browser) - Qt.callLater(() => browserLayoutContainer.item.openUrlInNewTab(link)); - } - function onOpenCreateChatView() { createChatView.opened = true } @@ -958,30 +964,17 @@ Item { createChatView.opened = false } - function onOpenLink(link: string) { + function onRequestOpenLink(link: string) { // Qt sometimes inserts random HTML tags; and this will break on invalid URL inside QDesktopServices::openUrl(link) link = SQUtils.StringUtils.plainText(link) + const domain = SQUtils.StringUtils.extractDomainFromLink(link) - if (!d.isBrowserEnabled) - return Qt.openUrlExternally(link) - - if (appMain.rootStore.showBrowserSelector) { - popups.openChooseBrowserPopup(link) + if (appMainLocalSettings.whitelistedUnfurledDomains.includes(domain) || + link.startsWith("mailto:")) { + d.openLinkInBrowser(link) } else { - if (appMain.rootStore.openLinksInStatus) { - globalConns.onAppSectionBySectionTypeChanged(Constants.appSection.browser) - globalConns.onOpenLinkInBrowser(link) - } else { - Qt.openUrlExternally(link) - } - } - } - - function onOpenLinkWithConfirmation(link: string, domain: string) { - if (appMainLocalSettings.whitelistedUnfurledDomains.includes(domain) || link.startsWith("mailto:")) - globalConns.onOpenLink(link) - else popups.openConfirmExternalLinkPopup(link, domain) + } } function onActivateDeepLink(link: string) { @@ -2001,9 +1994,7 @@ Item { navBar: appMain.navBar onOpenThirdpartyServicesInfoPopupRequested: popupRequestsHandler.thirdpartyServicesPopupHandler.openPopup() - onOpenDiscussPageRequested: Global.openLinkWithConfirmation( - Constants.statusDiscussPageUrl, - SQUtils.StringUtils.extractDomainFromLink(Constants.statusDiscussPageUrl)) + onOpenDiscussPageRequested: Global.requestOpenLink(Constants.statusDiscussPageUrl) } } @@ -2136,6 +2127,8 @@ Item { theme: appMainLocalSettings.theme fontSize: appMainLocalSettings.fontSize + whitelistedDomainsModel: appMainLocalSettings.whitelistedUnfurledDomains + onAddressWasShownRequested: (address) => WalletStores.RootStore.addressWasShown(address) onSettingsSubsectionChanged: profileLoader.settingsSubsection = settingsSubsection onConnectUsernameRequested: (ensName, ownerAddress) => popupRequestsHandler.sendModalHandler.connectUsername(ensName, ownerAddress) @@ -2157,7 +2150,16 @@ Item { appMain.communitiesStore.communitiesProfileModule, null) onOpenThirdpartyServicesInfoPopupRequested: popupRequestsHandler.thirdpartyServicesPopupHandler.openPopup() - onOpenDiscussPageRequested: Global.openLinkWithConfirmation(Constants.statusDiscussPageUrl, SQUtils.StringUtils.extractDomainFromLink(Constants.statusDiscussPageUrl)) + onOpenDiscussPageRequested: Global.requestOpenLink(Constants.statusDiscussPageUrl) + + onRemoveWhitelistedDomain: function(index) { + // in order to notify changes in this model, we need to re assign to this model + const domainRemoved = appMainLocalSettings.whitelistedUnfurledDomains[index] + const whitelistedUnfurledDomainsCpy = appMainLocalSettings.whitelistedUnfurledDomains.slice() + whitelistedUnfurledDomainsCpy.splice(index, 1) + appMainLocalSettings.whitelistedUnfurledDomains = whitelistedUnfurledDomainsCpy + Global.displaySuccessToastMessage(qsTr("%1 was removed from your trusted sites.").arg(domainRemoved)) + } } onLoaded: { item.settingsSubsection = profileLoader.settingsSubsection @@ -2185,9 +2187,7 @@ Item { navBar: appMain.navBar onOpenThirdpartyServicesInfoPopupRequested: popupRequestsHandler.thirdpartyServicesPopupHandler.openPopup() - onOpenDiscussPageRequested: Global.openLinkWithConfirmation( - Constants.statusDiscussPageUrl, - SQUtils.StringUtils.extractDomainFromLink(Constants.statusDiscussPageUrl)) + onOpenDiscussPageRequested: Global.requestOpenLink(Constants.statusDiscussPageUrl) } } @@ -2532,7 +2532,7 @@ Item { Global.changeAppSectionBySectionType(section, subsection, subsubsection) } else - Global.openLink(link) + Global.requestOpenLink(link) } onClose: { appMain.rootStore.removeEphemeralNotification(model.timestamp) @@ -2873,7 +2873,7 @@ Item { if (connectorId == Constants.DAppConnectors.WalletConnect) { dappsWorkflow.openPairing() } else if (connectorId == Constants.DAppConnectors.StatusConnect) { - Global.openLink("https://chromewebstore.google.com/detail/a-wallet-connector-by-sta/kahehnbpamjplefhpkhafinaodkkenpg") + Global.requestOpenLink("https://chromewebstore.google.com/detail/a-wallet-connector-by-sta/kahehnbpamjplefhpkhafinaodkkenpg") } } diff --git a/ui/app/mainui/Handlers/HandlersManager.qml b/ui/app/mainui/Handlers/HandlersManager.qml index 85a843ffc7a..f949031f856 100644 --- a/ui/app/mainui/Handlers/HandlersManager.qml +++ b/ui/app/mainui/Handlers/HandlersManager.qml @@ -172,8 +172,8 @@ QtObject { root.privacyStore.toggleThirdpartyServicesEnabledRequested() Backpressure.debounce(root, 200, () => { SystemUtils.restartApplication() })() } - onOpenDiscussPageRequested: Global.openLinkWithConfirmation(Constants.statusDiscussPageUrl, SQUtils.StringUtils.extractDomainFromLink(Constants.statusDiscussPageUrl)) - onOpenThirdpartyServicesArticleRequested: Global.openLinkWithConfirmation(Constants.statusThirdpartyServicesArticle, SQUtils.StringUtils.extractDomainFromLink(Constants.statusThirdpartyServicesArticle)) + onOpenDiscussPageRequested: Global.requestOpenLink(Constants.statusDiscussPageUrl) + onOpenThirdpartyServicesArticleRequested: Global.requestOpenLink(Constants.statusThirdpartyServicesArticle) } readonly property Component enableMessageBackupPopupComponent: Component { diff --git a/ui/app/mainui/Popups.qml b/ui/app/mainui/Popups.qml index e206cd82cc8..0643c7bfa6a 100644 --- a/ui/app/mainui/Popups.qml +++ b/ui/app/mainui/Popups.qml @@ -84,7 +84,6 @@ QtObject { Global.openInviteFriendsToCommunityByIdPopup.connect(openInviteFriendsToCommunityByIdPopup) Global.openContactRequestPopup.connect(openContactRequestPopup) Global.openReviewContactRequestPopup.connect(openReviewContactRequestPopup) - Global.openChooseBrowserPopup.connect(openChooseBrowserPopup) Global.openDownloadModalRequested.connect(openDownloadModal) Global.openImagePopup.connect(openImagePopup) Global.openVideoPopup.connect(openVideoPopup) @@ -152,10 +151,6 @@ QtObject { root.currentPopup.close(); } - function openChooseBrowserPopup(link: string) { - openPopup(chooseBrowserPopupComponent, {link: link}) - } - function openDownloadModal(available: bool, version: string, url: string) { const popupProperties = { newVersionAvailable: available, @@ -654,13 +649,6 @@ QtObject { } }, - Component { - id: chooseBrowserPopupComponent - ChooseBrowserPopup { - onClosed: destroy() - } - }, - Component { id: communityProfilePopup @@ -1160,8 +1148,8 @@ QtObject { id: confirmExternalLinkPopup ConfirmExternalLinkPopup { destroyOnClose: true - onOpenExternalLink: root.openExternalLink(link) - onSaveDomainToUnfurledWhitelist: root.saveDomainToUnfurledWhitelist(domain) + onOpenExternalLink: (link) => root.openExternalLink(link) + onSaveDomainToUnfurledWhitelist: (domain) => root.saveDomainToUnfurledWhitelist(domain) } }, @@ -1201,7 +1189,7 @@ QtObject { onFinaliseOwnershipClicked: signPopup.open() onVisitCommunityClicked: communitiesStore.navigateToCommunity(finalisePopup.communityId) - onOpenControlNodeDocClicked: Global.openLink(link) + onOpenControlNodeDocClicked:(link) => Global.requestOpenLink(link) onCalculateFees: { feesBroker.registerSetSignerFeesSubscriber(feeSubscriber) @@ -1366,7 +1354,7 @@ QtObject { content { textFormat: Text.MarkdownText text: SQUtils.StringUtils.readTextFile(":/imports/assets/docs/privacy.mdwn") - onLinkActivated: Global.openLinkWithConfirmation(link, SQUtils.StringUtils.extractDomainFromLink(link)) + onLinkActivated: (link) => Global.requestOpenLink(link) } destroyOnClose: true } @@ -1378,7 +1366,7 @@ QtObject { content { textFormat: Text.MarkdownText text: SQUtils.StringUtils.readTextFile(":/imports/assets/docs/terms-of-use.mdwn") - onLinkActivated: Global.openLinkWithConfirmation(link, SQUtils.StringUtils.extractDomainFromLink(link)) + onLinkActivated: (link) => Global.requestOpenLink(link) } destroyOnClose: true } @@ -1414,7 +1402,7 @@ QtObject { NewsMessagePopup { activityCenterNotifications: root.activityCenterStore.activityCenterNotifications - onLinkClicked: (link) => Global.openLinkWithConfirmation(link, SQUtils.StringUtils.extractDomainFromLink(link)); + onLinkClicked: (link) => Global.requestOpenLink(link) } }, Component { diff --git a/ui/i18n/qml_base_en.ts b/ui/i18n/qml_base_en.ts index a06a5cdcd3d..e9c65ad8704 100644 --- a/ui/i18n/qml_base_en.ts +++ b/ui/i18n/qml_base_en.ts @@ -1847,6 +1847,10 @@ from "%1" to "%2" Sync in process. Keep device powered and app open. + + %1 added to your trusted sites. + + This device is now the control node for the %1 Community @@ -2050,6 +2054,10 @@ from "%1" to "%2" Error loading chats, try closing the app and restarting + + %1 was removed from your trusted sites. + + Where do you want to go? @@ -3163,25 +3171,6 @@ Do you wish to override the security check and continue? - - ChooseBrowserPopup - - Choose browser - - - - Open in Status - - - - Open in my default browser - - - - Remember my choice. To override it, go to Settings. - - - CollectibleDetailView @@ -3941,23 +3930,23 @@ file format ConfirmExternalLinkPopup - Before you go + Cancel - This link is taking you to the following site. Be careful to double check the URL before you go. + Opening external link - Trust <b>%1</b> links from now on + Status asks before opening links to protect your privacy, as websites may collect your IP address or device information. Copy the link to open it elsewhere, or tap Open to continue in your default browser. - Cancel + Always trust links to <b>%1</b> - Visit site + Open @@ -13487,6 +13476,14 @@ to load From all profiles on device + + Trusted sites + + + + Manage trusted sites. Their links open without confirmation. + + PrivacyStore @@ -19173,13 +19170,24 @@ If a transaction with a lower nonce is pending, higher nonce transactions will r - main + WhitelistedDomainsView - Status Desktop + Trusted sites - Hello World + Manage trusted sites. Their links open without confirmation. + + + + No trusted sites added yet + + + + + main + + Status Desktop diff --git a/ui/i18n/qml_base_lokalise_en.ts b/ui/i18n/qml_base_lokalise_en.ts index e9f8dd45674..21f6eaa25c3 100644 --- a/ui/i18n/qml_base_lokalise_en.ts +++ b/ui/i18n/qml_base_lokalise_en.ts @@ -1894,8 +1894,8 @@ %n key pair(s) successfully imported AppMain - %n key pair successfully imported - %n key pairs successfully imported + + @@ -2263,6 +2263,11 @@ AppMain Sync in process. Keep device powered and app open. + + %1 added to your trusted sites. + AppMain + %1 added to your trusted sites. + This device is now the control node for the %1 Community AppMain @@ -2352,8 +2357,8 @@ %n issue(s) AppMain - %n issue - %n issues + + @@ -2516,6 +2521,11 @@ AppMain Error loading chats, try closing the app and restarting + + %1 was removed from your trusted sites. + AppMain + %1 was removed from your trusted sites. + Where do you want to go? AppMain @@ -3867,29 +3877,6 @@ Loading chats... - - ChooseBrowserPopup - - Choose browser - ChooseBrowserPopup - Choose browser - - - Open in Status - ChooseBrowserPopup - Open in Status - - - Open in my default browser - ChooseBrowserPopup - Open in my default browser - - - Remember my choice. To override it, go to Settings. - ChooseBrowserPopup - Remember my choice. To override it, go to Settings. - - CollectibleDetailView @@ -4809,29 +4796,29 @@ ConfirmExternalLinkPopup - Before you go + Cancel ConfirmExternalLinkPopup - Before you go + Cancel - This link is taking you to the following site. Be careful to double check the URL before you go. + Opening external link ConfirmExternalLinkPopup - This link is taking you to the following site. Be careful to double check the URL before you go. + Opening external link - Trust <b>%1</b> links from now on + Status asks before opening links to protect your privacy, as websites may collect your IP address or device information. Copy the link to open it elsewhere, or tap Open to continue in your default browser. ConfirmExternalLinkPopup - Trust <b>%1</b> links from now on + Status asks before opening links to protect your privacy, as websites may collect your IP address or device information. Copy the link to open it elsewhere, or tap Open to continue in your default browser. - Cancel + Always trust links to <b>%1</b> ConfirmExternalLinkPopup - Cancel + Always trust links to <b>%1</b> - Visit site + Open ConfirmExternalLinkPopup - Visit site + Open @@ -16426,6 +16413,16 @@ PrivacyAndSecurityView From all profiles on device + + Trusted sites + PrivacyAndSecurityView + Trusted sites + + + Manage trusted sites. Their links open without confirmation. + PrivacyAndSecurityView + Manage trusted sites. Their links open without confirmation. + PrivacyStore @@ -23327,6 +23324,24 @@ Privacy Policy + + WhitelistedDomainsView + + Trusted sites + WhitelistedDomainsView + Trusted sites + + + Manage trusted sites. Their links open without confirmation. + WhitelistedDomainsView + Manage trusted sites. Their links open without confirmation. + + + No trusted sites added yet + WhitelistedDomainsView + No trusted sites added yet + + main @@ -23334,11 +23349,6 @@ main Status Desktop - - Hello World - main - Hello World - tst_StatusInput diff --git a/ui/i18n/qml_cs.ts b/ui/i18n/qml_cs.ts index f63adf3f4bd..92d9fd8903f 100644 --- a/ui/i18n/qml_cs.ts +++ b/ui/i18n/qml_cs.ts @@ -1847,12 +1847,16 @@ from "%1" to "%2" Device paired - Zařízení spárováno + Sync in process. Keep device powered and app open. + + %1 added to your trusted sites. + + This device is now the control node for the %1 Community @@ -1875,39 +1879,39 @@ from "%1" to "%2" Invite People - Pozvat lidi + Pozvat lidi Community Info - Info o komunitě + Community Rules - Komunitní pravidla + Mute Community - Ztlumit komunitu + Ztlumit komunitu Unmute Community - Zrušit ztlumení + Zrušit ztlumení Mark as read - Označit jako přečtěné + Edit Shared Addresses - Upravit sdílené adresy + Upravit sdílené adresy Close Community - Zavřít komunitu + Zavřít komunitu Leave Community - Opustit komunitu + Opustit komunitu The import of ‘%1’ from Discord to Status was stopped: <a href='#'>Critical issues found</a> @@ -1919,7 +1923,7 @@ from "%1" to "%2" Details (%1) - Podrobnosti (%1) + %n issue(s) @@ -1931,7 +1935,7 @@ from "%1" to "%2" Details - Podrobnosti + Podrobnosti Importing ‘%1’ from Discord to Status @@ -2057,6 +2061,10 @@ from "%1" to "%2" Error loading chats, try closing the app and restarting + + %1 was removed from your trusted sites. + + Where do you want to go? @@ -3172,25 +3180,6 @@ Do you wish to override the security check and continue? Načítání chatů... - - ChooseBrowserPopup - - Choose browser - - - - Open in Status - - - - Open in my default browser - - - - Remember my choice. To override it, go to Settings. - - - CollectibleDetailView @@ -3955,24 +3944,24 @@ file format ConfirmExternalLinkPopup - Before you go - + Cancel + Zrušit - This link is taking you to the following site. Be careful to double check the URL before you go. + Opening external link - Trust <b>%1</b> links from now on + Status asks before opening links to protect your privacy, as websites may collect your IP address or device information. Copy the link to open it elsewhere, or tap Open to continue in your default browser. - Cancel - Zrušit + Always trust links to <b>%1</b> + - Visit site - + Open + Otevřít @@ -13548,6 +13537,14 @@ to load From all profiles on device + + Trusted sites + + + + Manage trusted sites. Their links open without confirmation. + + PrivacyStore @@ -19254,16 +19251,27 @@ If a transaction with a lower nonce is pending, higher nonce transactions will r - main + WhitelistedDomainsView - Status Desktop - Status Desktop + Trusted sites + + + + Manage trusted sites. Their links open without confirmation. + - Hello World + No trusted sites added yet + + main + + Status Desktop + Status Desktop + + tst_StatusInput diff --git a/ui/i18n/qml_en.ts b/ui/i18n/qml_en.ts index 7651a8b1bbf..f8d8a944d7a 100644 --- a/ui/i18n/qml_en.ts +++ b/ui/i18n/qml_en.ts @@ -50,16 +50,16 @@ AppMain %n key pair(s) successfully imported - - %n key pair successfully imported - %n key pairs successfully imported + + + %n issue(s) - - %n issue - %n issues + + + diff --git a/ui/i18n/qml_ko.ts b/ui/i18n/qml_ko.ts index 18cebb72bc3..9d9a5e9549b 100644 --- a/ui/i18n/qml_ko.ts +++ b/ui/i18n/qml_ko.ts @@ -1508,572 +1508,580 @@ AppMain "%1" successfully added - "%1"가 성공적으로 추가됨 + "%1" successfully removed - "%1"이(가) 성공적으로 제거되었습니다 + You successfully renamed your key pair from "%1" to "%2" - 키 쌍 이름을 "%1"에서 "%2"(으)로 성공적으로 변경했습니다 + Test network settings for %1 updated - %1의 테스트 네트워크 설정이 업데이트됨 + Live network settings for %1 updated - %1의 라이브 네트워크 설정이 업데이트되었습니다 + “%1” key pair and its derived accounts were successfully removed from all devices - “%1” 키 쌍과 그로부터 파생된 계정이 모든 기기에서 성공적으로 제거되었습니다 + Please re-generate QR code and try importing again - QR 코드를 다시 생성한 뒤, 가져오기를 다시 시도해 주세요 + Make sure you're importing the exported key pair on paired device - 페어링된 기기에서 내보낸 키 페어를 가져오는지 확인하세요 + %1 key pair successfully imported - %1 키 쌍이 성공적으로 가져와졌습니다 + %n key pair(s) successfully imported - - %n개의 키 쌍을 성공적으로 가져왔습니다 + + unknown - 알 수 없음 + View on %1 - %1에서 보기 + %1에서 보기 Sending %1 from %2 to %3 - %2에서 %3로 %1 전송 중 + Registering %1 ENS name using %2 - %2로 %1 ENS 이름 등록 중 + Releasing %1 ENS username using %2 - %2을(를) 사용하여 %1 ENS 사용자 이름 해제 + Setting public key %1 using %2 - %2을(를) 사용해 공개 키 %1 설정 중 + Purchasing %1 sticker pack using %2 - %2로 %1 스티커 팩 구매 중 + Bridging %1 from %2 to %3 in %4 - %4 안에 %2에서 %3(으)로 %1 브릿지 중 + Setting spending cap: %1 in %2 for %3 - 지출 한도 설정: %3에 대해 %2에서 %1 + Sending %1 %2 from %3 to %4 - %3에서 %4로 %1 %2 전송 중 + Swapping %1 to %2 in %3 - %3에서 %1을(를) %2로 스왑하는 중 + Minting infinite %1 tokens for %2 using %3 - %3을(를) 사용해 %2에 무한 %1 토큰 발행 + Minting %1 %2 tokens for %3 using %4 - %4를 사용해 %3에 %1 %2 토큰 민팅 + Minting %1 and %2 tokens for %3 using %4 - %4를 사용해 %3에 %1 및 %2 토큰 민팅 중 + Airdropping %1x %2 to %3 using %4 - %4을 사용해 %3에게 %1x %2 Airdropping + Airdropping %1x %2 to %3 addresses using %4 - %4를 사용해 %3개 주소에 %1x %2 에어드롭 중 + Airdropping %1x %2 and %3x %4 to %5 using %6 - %6을 사용해 %5에게 %1x %2 및 %3x %4 Airdrop 진행 + Airdropping %1x %2 and %3x %4 to %5 addresses using %6 - %6을 사용해 %5개의 주소로 %1x %2와 %3x %4 를 Airdrop 중 + Airdropping %1 tokens to %2 using %3 - %3를 사용해 %2에게 %1 토큰 Airdrop 중 + Destroying %1x %2 at %3 using %4 - %4를 사용하여 %3에서 %1x %2 파기 + Destroying %1x %2 at %3 addresses using %4 - %4을 사용하여 %3 주소에서 %1x %2 파기 + Burning %1x %2 for %3 using %4 - %1x %2을(를) %3로, %4을 사용해 소각 + Finalizing ownership for %1 using %2 - %2을(를) 사용해 %1의 소유권을 최종 확정하는 중 + Sent %1 from %2 to %3 - %2에서 %3로 %1 전송함 + Registered %1 ENS name using %2 - %2을(를) 사용해 %1 ENS 이름을 등록함 + Released %1 ENS username using %2 - %2을(를) 사용해 %1 ENS 사용자 이름을 릴리스했습니다 + Set public key %1 using %2 - 공개 키 %1을(를) %2로 설정 + Purchased %1 sticker pack using %2 - %2로 %1 스티커 팩을 구매함 + Bridged %1 from %2 to %3 in %4 - %2에서 %3로 %1 브릿지 완료, 소요 시간 %4 + Spending spending cap: %1 in %2 for %3 - 지출 한도: %3에 대해 %2에서 %1 + Sent %1 %2 from %3 to %4 - %3에서 %4로 %1 %2 전송함 + Swapped %1 to %2 in %3 - %3에서 %1을(를) %2(으)로 스왑했어요 + Spending cap set: %1 in %2 for %3 - 지출 한도 설정됨: %3의 %2에서 %1 + Minted infinite %1 tokens for %2 using %3 - %3를 사용해 %2에 무한 %1 토큰을 민팅했습니다 + Minted %1 %2 tokens for %3 using %4 - %4을 사용해 %3에 %1 %2 토큰을 민트했습니다 + Minted %1 and %2 tokens for %3 using %4 - %4을 사용하여 %3에 %1 및 %2 토큰을 민팅했습니다 + Airdropped %1x %2 to %3 using %4 - %4를 사용해 %3에 %2를 %1x 에어드랍함 + Airdropped %1x %2 to %3 addresses using %4 - %4을 사용해 %1x %2를 %3 개 주소로 Airdrop했습니다 + Airdropped %1x %2 and %3x %4 to %5 using %6 - %1x %2와 %3x %4을(를) %6을(를) 사용해 %5에게 Airdrop함 + Airdropped %1x %2 and %3x %4 to %5 addresses using %6 - %6를 사용해 %5개 주소로 %1x %2 및 %3x %4를 Airdrop했습니다 + Airdropped %1 tokens to %2 using %3 - %3를 사용해 %2에게 %1개의 토큰을 Airdrop했습니다 + Destroyed %1x %2 at %3 using %4 - %1x %2을(를) %3에서 %4로 파괴함 + Destroyed %1x %2 at %3 addresses using %4 - %4를 사용해 %3개의 주소에서 %1x %2 파괴함 + Burned %1x %2 for %3 using %4 - %1x %2을(를) %3에 소각, 사용 도구: %4 + Finalized ownership for %1 using %2 - %2 를 사용해 %1의 소유권을 최종 확정했습니다 + Send failed: %1 from %2 to %3 - 전송 실패: %2의 %1 → %3 + ENS username registeration failed: %1 using %2 - ENS 사용자 이름 등록 실패: %1, %2 사용 중 + ENS username release failed: %1 using %2 - ENS 사용자 이름 해제 실패: %1, %2 사용 중 + Set public key failed: %1 using %2 - 공개 키 설정 실패: %1, 사용 중인 %2 + Sticker pack purchase failed: %1 using %2 - 스티커 팩 구매 실패: %1 을(를) %2로 사용 + Bridge failed: %1 from %2 to %3 in %4 - 브릿지 실패: %2에서 %3로 %1 전송 중, %4에서 오류 발생 + Spending spending failed: %1 in %2 for %3 - 지출 실패: %1, %2에서 %3 + Send failed: %1 %2 from %3 to %4 - 전송 실패: %1 %2, %3에서 %4로 + Swap failed: %1 to %2 in %3 - 스왑 실패: %1 → %2, 소요 시간 %3 + Spending cap failed: %1 in %2 for %3 - 지출 한도 실패: %2에서 %1, 대상 %3 + Mint failed: infinite %1 tokens for %2 using %3 - 민팅 실패: %3를 사용해 %2에 무한 %1 토큰 + Mint failed: %1 %2 tokens for %3 using %4 - 민팅 실패: %3에 대해 %4을(를) 사용해 %1 %2 토큰 + Mint failed: %1 and %2 tokens for %3 using %4 - 민팅 실패: %3에 대해 %1 및 %2 토큰을 %4 사용하여 + Airdrop failed: %1x %2 to %3 using %4 - Airdrop 실패: %1x %2를 %3에 %4로 전송 실패 + Airdrop failed: %1x %2 to %3 addresses using %4 - Airdrop 실패: %1x %2을(를) %3개 주소에 %4으로 전송하지 못했습니다 + Airdrop failed: %1x %2 and %3x %4 to %5 using %6 - Airdrop 실패: %1x %2 및 %3x %4을(를) %6을(를) 사용하여 %5에 전송하지 못했습니다 + Airdrop failed: %1x %2 and %3x %4 to %5 addresses using %6 - Airdrop 실패: %1x %2 및 %3x %4을(를) %5개의 주소로 %6을(를) 사용해 전송하지 못했습니다 + Airdrop failed: %1 tokens to %2 using %3 - Airdrop 실패: %3을(를) 사용해 %2에 %1 토큰 전송 실패 + Destruction failed: %1x %2 at %3 using %4 - 파기 실패: %1x %2, %3에서 %4 사용 + Destruction failed: %1x %2 at %3 addresses using %4 - 파기 실패: %1x %2, %3개의 주소에서 %4 사용 + Burn failed: %1x %2 for %3 using %4 - 소각 실패: %1x %2, 대상 %3, 방법 %4 + Finalize ownership failed: %1 using %2 - 소유권 최종화 실패: %2를 사용한 %1 + Unknown error resolving community - 커뮤니티를 확인하는 중 알 수 없는 오류가 발생했어요 + %1 was banned from %2 - %1이(가) %2에서 차단되었습니다 + %1 unbanned from %2 - %1 님이 %2에서 차단 해제됨 + %1 was kicked from %2 - %2에서 %1이(가) 강퇴되었습니다 + Device paired - 기기 페어링 완료 + Sync in process. Keep device powered and app open. - 동기화 중입니다. 기기를 켜 두고 앱을 열어 두세요. + + + + %1 added to your trusted sites. + This device is now the control node for the %1 Community - 이 기기는 이제 %1 커뮤니티의 제어 Node입니다 + '%1' community imported - '%1' 커뮤니티를 가져왔습니다 + Importing community is in progress - 커뮤니티 가져오기가 진행 중입니다 + Failed to import community '%1' - 커뮤니티 '%1' 가져오기 실패 + Import community '%1' was canceled - 커뮤니티 '%1' 가져오기가 취소되었습니다 + Invite People - 사람들 초대하기 + 사람 초대 Community Info - 커뮤니티 정보 + Community Rules - 커뮤니티 규칙 + Mute Community - 커뮤니티 음소거 + 커뮤니티 음소거 Unmute Community - 커뮤니티 소리 켜기 + 커뮤니티 음소거 해제 Mark as read - 읽음으로 표시 + Edit Shared Addresses - 공유 주소 편집 + 공유 주소 편집 Close Community - 닫기 커뮤니티 + Leave Community - 커뮤니티 나가기 + The import of ‘%1’ from Discord to Status was stopped: <a href='#'>Critical issues found</a> - Discord에서 Status로 ‘%1’ 가져오기가 중단되었습니다: <a href='#'>치명적인 문제가 발견됨</a> + ‘%1’ was successfully imported from Discord to Status - ‘%1’이(가) Discord에서 Status로 성공적으로 가져와졌습니다 + Details (%1) - 자세히 (%1) + %n issue(s) - - %n개 이슈 + + Details - 상세 + 세부 정보 Importing ‘%1’ from Discord to Status - Discord에서 Status로 ‘%1’ 가져오기 + Check progress (%1) - 진행 상황 확인 (%1) + Check progress - 진행 상황 확인 + Visit your new channel - 새 채널로 이동 + 새 채널로 이동 Visit your Community - 커뮤니티 방문 + Can not connect to store node. Retrying automatically - 스토어 Node에 연결할 수 없습니다. 자동으로 다시 시도합니다 + Pocket Network (POKT) & Infura are currently both unavailable for %1. Balances for those chains are as of %2. - Pocket Network (POKT) 및 Infura가 현재 %1에 대해 모두 사용할 수 없습니다. 해당 체인의 잔액은 %2 기준입니다. + Pocket Network (POKT) connection successful - Pocket Network (POKT) 연결 성공 + POKT & Infura down. Token balances are as of %1. - POKT와 Infura 장애. 토큰 잔액은 %1 기준입니다. + POKT & Infura down. Token balances cannot be retrieved. - POKT 및 Infura 장애. 토큰 잔액을 불러올 수 없습니다. + POKT & Infura down for <a href='#'>multiple chains </a>. Token balances for those chains cannot be retrieved. - POKT 및 Infura가 <a href='#'>여러 체인에서 </a> 중단되었습니다. 해당 체인의 토큰 잔액을 가져올 수 없습니다. + POKT & Infura down for %1. %1 token balances are as of %2. - POKT 및 Infura가 %1에 오류가 발생했습니다. %1 토큰 잔액은 %2 기준입니다. + POKT & Infura down for %1. %1 token balances cannot be retrieved. - %1에 대해 POKT 및 Infura가 중단됨. %1 토큰 잔액을 가져올 수 없습니다. + Retrying connection to POKT Network (grove.city). - POKT Network(grove.city)에 다시 연결하는 중입니다. + Collectibles providers are currently unavailable for %1. Collectibles for those chains are as of %2. - 수집품 제공자는 현재 %1에 사용할 수 없습니다. 해당 체인의 수집품은 %2 기준입니다. + Collectibles providers are currently unavailable for %1. - 수집품 제공자는 현재 %1에서 사용할 수 없습니다. + Collectibles providers connection successful - 콜렉터블 제공자 연결 성공 + Collectibles providers down. Collectibles are as of %1. - 수집품 제공자가 중단됨. 수집품은 %1 기준입니다. + Collectibles providers down. Collectibles cannot be retrieved. - 수집품 제공자가 다운되었습니다. 수집품을 가져올 수 없습니다. + Collectibles providers down for <a href='#'>multiple chains</a>. Collectibles for these chains cannot be retrieved. - <a href='#'>여러 체인</a>의 컬렉티블 제공자가 다운되었습니다. 해당 체인의 컬렉티블을 가져올 수 없습니다. + Collectibles providers down for %1. Collectibles for this chain are as of %2. - %1에 대한 수집품 제공자가 중단되었습니다. 이 체인의 수집품은 %2 기준입니다. + Collectibles providers down for %1. Collectibles for this chain cannot be retrieved. - %1용 콜렉터블 제공자가 다운되었습니다. 이 체인의 콜렉터블을 불러올 수 없습니다. + Collectibles providers down for %1. Collectibles for these chains are as of %2. - %1에 대한 수집품 제공자가 다운되었습니다. 이 체인의 수집품은 %2 기준입니다. + Collectibles providers down for %1. Collectibles for these chains cannot be retrieved. - %1의 수집품 제공자가 현재 중단되었습니다. 이 체인의 수집품을 불러올 수 없습니다. + Retrying connection to collectibles providers... - 수집품 제공자에 다시 연결하는 중... + CryptoCompare and CoinGecko connection successful - Cryptocompare 및 Coingecko 연결 성공 + CryptoCompare and CoinGecko down. Market values are as of %1. - Cryptocompare와 Coingecko가 다운되었습니다. 시장 가치는 %1 기준입니다. + CryptoCompare and CoinGecko down. Market values cannot be retrieved. - Cryptocompare와 Coingecko에 장애가 발생했습니다. 시장 가치를 가져올 수 없습니다. + Retrying connection to CryptoCompare and CoinGecko... - Cryptocompare 및 Coingecko에 다시 연결 시도 중... + Loading sections... - 섹션 불러오는 중... + Error loading chats, try closing the app and restarting - 채팅을 불러오지 못했습니다. 앱을 닫았다가 다시 시작해 주세요 + + + + %1 was removed from your trusted sites. + Where do you want to go? - 어디로 가고 싶어요? + adding - 추가하는 중 + editing - 편집 중 + An error occurred while %1 %2 address - %1 %2 주소를 처리하는 중 오류가 발생했습니다 + %1 successfully added to your saved addresses - 저장된 주소에 %1을(를) 성공적으로 추가했어요 + %1 saved address successfully edited - %1 저장된 주소가 성공적으로 수정되었습니다 + An error occurred while removing %1 address - %1 주소를 제거하는 동안 오류가 발생했습니다 + %1 was successfully removed from your saved addresses - %1이(가) 저장된 주소에서 성공적으로 제거되었어요 + @@ -3154,25 +3162,6 @@ Do you wish to override the security check and continue? 채팅 불러오는 중... - - ChooseBrowserPopup - - Choose browser - 브라우저 선택 - - - Open in Status - 스테이터스로 열기 - - - Open in my default browser - 기본 브라우저에서 열기 - - - Remember my choice. To override it, go to Settings. - 내 선택을 기억합니다. 변경하려면 설정으로 이동하세요. - - CollectibleDetailView @@ -3927,24 +3916,24 @@ file format ConfirmExternalLinkPopup - Before you go - 가기 전에 + Cancel + 취소 - This link is taking you to the following site. Be careful to double check the URL before you go. - 이 링크는 다음 사이트로 이동합니다. 이동하기 전에 URL을 다시 한 번 확인하세요. + Opening external link + - Trust <b>%1</b> links from now on - 지금부터 <b>%1</b> 링크를 신뢰하세요 + Status asks before opening links to protect your privacy, as websites may collect your IP address or device information. Copy the link to open it elsewhere, or tap Open to continue in your default browser. + - Cancel - 취소 + Always trust links to <b>%1</b> + - Visit site - 사이트 방문 + Open + 열기 @@ -13430,6 +13419,14 @@ to load From all profiles on device 이 기기의 모든 프로필에서 + + Trusted sites + + + + Manage trusted sites. Their links open without confirmation. + + PrivacyStore @@ -19099,16 +19096,27 @@ If a transaction with a lower nonce is pending, higher nonce transactions will r - main + WhitelistedDomainsView - Status Desktop - 스테이터스 데스크톱 + Trusted sites + + + + Manage trusted sites. Their links open without confirmation. + - Hello World + No trusted sites added yet + + main + + Status Desktop + 스테이터스 데스크톱 + + tst_StatusInput diff --git a/ui/imports/shared/controls/SocialLinkPreview.qml b/ui/imports/shared/controls/SocialLinkPreview.qml index 7e10b084d09..0e40ae1b738 100644 --- a/ui/imports/shared/controls/SocialLinkPreview.qml +++ b/ui/imports/shared/controls/SocialLinkPreview.qml @@ -57,6 +57,6 @@ Rectangle { anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor - onClicked: Global.openLink(root.url) + onClicked: Global.requestOpenLink(root.url) } } diff --git a/ui/imports/shared/popups/ConfirmExternalLinkPopup.qml b/ui/imports/shared/popups/ConfirmExternalLinkPopup.qml index eab41d650c5..d2547a9bd3d 100644 --- a/ui/imports/shared/popups/ConfirmExternalLinkPopup.qml +++ b/ui/imports/shared/popups/ConfirmExternalLinkPopup.qml @@ -1,9 +1,5 @@ import QtQuick -import QtQuick.Controls import QtQuick.Layouts -import QtQml.Models - -import utils import StatusQ.Core.Theme import StatusQ.Components @@ -11,6 +7,8 @@ import StatusQ.Controls import StatusQ.Popups.Dialog import StatusQ.Core +import shared.controls + StatusDialog { id: root @@ -20,10 +18,11 @@ StatusDialog { signal openExternalLink(string link) signal saveDomainToUnfurledWhitelist(string domain) - width: 521 + implicitWidth: 521 + padding: Theme.padding header: StatusDialogHeader { - headline.title: qsTr("Before you go") + headline.title: qsTr("Opening external link") actions.closeButton.onClicked: root.close() leftComponent: StatusRoundIcon { asset.name: "browser" @@ -32,11 +31,11 @@ StatusDialog { } contentItem: ColumnLayout { - spacing: 20 + spacing: Theme.padding StatusBaseText { Layout.fillWidth: true wrapMode: Text.WrapAtWordBoundaryOrAnywhere - text: qsTr("This link is taking you to the following site. Be careful to double check the URL before you go.") + text: qsTr("Status asks before opening links to protect your privacy, as websites may collect your IP address or device information. Copy the link to open it elsewhere, or tap Open to continue in your default browser.") } Rectangle { Layout.fillWidth: true @@ -44,21 +43,31 @@ StatusDialog { radius: Theme.halfPadding color: Theme.palette.baseColor4 - StatusBaseText { + RowLayout { anchors.fill: parent - anchors.leftMargin: Theme.padding - anchors.rightMargin: Theme.padding - anchors.topMargin: 11 - anchors.bottomMargin: Theme.halfPadding - text: root.link - wrapMode: Text.WrapAnywhere - elide: Text.ElideRight + anchors.margins: Theme.padding + + spacing: Theme.padding + + StatusBaseText { + Layout.fillWidth: true + text: root.link + wrapMode: Text.WrapAnywhere + elide: Text.ElideRight + } + CopyButton { + Layout.alignment: Qt.AlignTop + textToCopy: root.link + } + } } StatusCheckBox { id: trustDomainCheckbox + + Layout.margins: 12 Layout.fillWidth: true - text: qsTr("Trust %1 links from now on").arg(root.domain) + text: qsTr("Always trust links to %1").arg(root.domain) } } @@ -69,7 +78,7 @@ StatusDialog { onClicked: root.close() } StatusButton { - text: qsTr("Visit site") + text: qsTr("Open") onClicked: { // (optionally) save the domain to whitelist if (trustDomainCheckbox.checked) { diff --git a/ui/imports/shared/popups/DownloadPage.qml b/ui/imports/shared/popups/DownloadPage.qml index 56a18b6170f..56e1b4781b8 100644 --- a/ui/imports/shared/popups/DownloadPage.qml +++ b/ui/imports/shared/popups/DownloadPage.qml @@ -79,7 +79,7 @@ Rectangle { anchors.top: newVersionAvailableText.bottom anchors.topMargin: 32 onClicked: { - Global.openLink(root.downloadURL) + Global.requestOpenLink(root.downloadURL) root.closed() } } diff --git a/ui/imports/shared/popups/ImageContextMenu.qml b/ui/imports/shared/popups/ImageContextMenu.qml index 109a93a51f3..1cf362dfef1 100644 --- a/ui/imports/shared/popups/ImageContextMenu.qml +++ b/ui/imports/shared/popups/ImageContextMenu.qml @@ -10,7 +10,6 @@ StatusMenu { property string url property string imageSource property string domain - property bool requireConfirmationOnOpen: false property bool isGif: root.imageSource.toLowerCase().endsWith(".gif") property bool isVideo: root.imageSource.toLowerCase().endsWith(".mp4") @@ -48,6 +47,6 @@ StatusMenu { text: qsTr("Open link") icon.name: "browser" enabled: d.isUnfurled - onTriggered: requireConfirmationOnOpen ? Global.openLinkWithConfirmation(root.url, root.domain) : Global.openLink(root.url) + onTriggered: Global.requestOpenLink(root.url) } } diff --git a/ui/imports/shared/popups/addaccount/panels/AccountAddressSelection.qml b/ui/imports/shared/popups/addaccount/panels/AccountAddressSelection.qml index 9fa3d3f2109..af31a0aa51e 100644 --- a/ui/imports/shared/popups/addaccount/panels/AccountAddressSelection.qml +++ b/ui/imports/shared/popups/addaccount/panels/AccountAddressSelection.qml @@ -192,7 +192,7 @@ StatusMenu { icon.width: 16 icon.height: 16 onClicked: { - Global.openLink("https://etherscan.io/address/%1".arg(model.addressDetails.address)) + Global.requestOpenLink("https://etherscan.io/address/%1".arg(model.addressDetails.address)) } } } diff --git a/ui/imports/shared/popups/keycard/helpers/KeyPairUnknownItem.qml b/ui/imports/shared/popups/keycard/helpers/KeyPairUnknownItem.qml index 5a7d2a66b81..3e988ddc186 100644 --- a/ui/imports/shared/popups/keycard/helpers/KeyPairUnknownItem.qml +++ b/ui/imports/shared/popups/keycard/helpers/KeyPairUnknownItem.qml @@ -145,7 +145,7 @@ Rectangle { let link = Utils.getUrlForAddressOnNetwork(Constants.networkShortChainNames.mainnet, WalletStore.RootStore.areTestNetworksEnabled, model.account.address) - Global.openLink(link) + Global.requestOpenLink(link) } } } diff --git a/ui/imports/shared/popups/keycard/states/ManageAccounts.qml b/ui/imports/shared/popups/keycard/states/ManageAccounts.qml index ea441024345..e72bb60d9cf 100644 --- a/ui/imports/shared/popups/keycard/states/ManageAccounts.qml +++ b/ui/imports/shared/popups/keycard/states/ManageAccounts.qml @@ -190,7 +190,7 @@ Item { let link = Utils.getUrlForAddressOnNetwork(Constants.networkShortChainNames.mainnet, WalletStore.RootStore.areTestNetworksEnabled, root.sharedKeycardModule.keyPairHelper.observedAccount.address) - Global.openLink(link) + Global.requestOpenLink(link) } } } diff --git a/ui/imports/shared/popups/walletconnect/private/DAppCard.qml b/ui/imports/shared/popups/walletconnect/private/DAppCard.qml index 42ff6c19c29..c3520d5fa31 100644 --- a/ui/imports/shared/popups/walletconnect/private/DAppCard.qml +++ b/ui/imports/shared/popups/walletconnect/private/DAppCard.qml @@ -67,9 +67,7 @@ ColumnLayout { horizontalPadding: 0 verticalPadding: 0 text: StringUtils.extractDomainFromLink(dAppUrl) - onClicked: { - Global.openLinkWithConfirmation(dAppUrl, text) - } + onClicked: Global.requestOpenLink(dAppUrl) } ConnectionStatusTag { Layout.alignment: Qt.AlignHCenter diff --git a/ui/imports/shared/status/StatusChatInput.qml b/ui/imports/shared/status/StatusChatInput.qml index 452bce5a8d6..d7f4bdfc605 100644 --- a/ui/imports/shared/status/StatusChatInput.qml +++ b/ui/imports/shared/status/StatusChatInput.qml @@ -1259,7 +1259,7 @@ Rectangle { } onImageClicked: (chatImage) => Global.openImagePopup(chatImage, "", false) onLinkReload: (link) => control.linkPreviewReloaded(link) - onLinkClicked: (link) => Global.openLink(link) + onLinkClicked: (link) => Global.requestOpenLink(link) onEnableLinkPreview: () => control.enableLinkPreview() onEnableLinkPreviewForThisMessage: () => control.enableLinkPreviewForThisMessage() onDisableLinkPreview: () => control.disableLinkPreview() diff --git a/ui/imports/shared/views/HistoryView.qml b/ui/imports/shared/views/HistoryView.qml index 2da6560c886..02c10ed4357 100644 --- a/ui/imports/shared/views/HistoryView.qml +++ b/ui/imports/shared/views/HistoryView.qml @@ -98,7 +98,7 @@ ColumnLayout { onLinkActivated: { const explorerUrl = root.walletRootStore.showAllAccounts ? link : "%1/%2/%3".arg(link).arg(Constants.networkExplorerLinks.addressPath).arg(root.walletRootStore.selectedAddress) - Global.openLinkWithConfirmation(explorerUrl, SQUtils.StringUtils.extractDomainFromLink(explorerUrl)) + Global.requestOpenLink(explorerUrl) } } @@ -291,7 +291,7 @@ ColumnLayout { onViewTxOnExplorerRequested: { let link = Utils.getUrlForTxOnNetwork(networkShortName, isNetworkTestnet, modelData.transaction.hash) - Global.openLink(link) + Global.requestOpenLink(link) } } } diff --git a/ui/imports/shared/views/chat/LinksMessageView.qml b/ui/imports/shared/views/chat/LinksMessageView.qml index 1d6a3bdb1e1..78abe3b5973 100644 --- a/ui/imports/shared/views/chat/LinksMessageView.qml +++ b/ui/imports/shared/views/chat/LinksMessageView.qml @@ -125,7 +125,7 @@ Flow { } if(previewType === Constants.LinkPreviewType.Standard) { - Global.openLinkWithConfirmation(url, linkData.domain) + Global.requestOpenLink(url) return } diff --git a/ui/imports/shared/views/chat/MessageView.qml b/ui/imports/shared/views/chat/MessageView.qml index 3b2fa9b0f19..82bca918fa3 100644 --- a/ui/imports/shared/views/chat/MessageView.qml +++ b/ui/imports/shared/views/chat/MessageView.qml @@ -838,7 +838,7 @@ Loader { const linkPreviewType = root.linkPreviewModel.getLinkPreviewType(link) if (linkPreviewType === Constants.LinkPreviewType.Standard || !Utils.isStatusDeepLink(link)) { - Global.openLink(link) + Global.requestOpenLink(link) return } @@ -1033,7 +1033,7 @@ Loader { d.onImageClicked(image, mouse, imageSource, url) } onOpenContextMenu: (item, url, domain) => { - Global.openMenu(imageContextMenuComponent, item, { url: url, domain: domain, requireConfirmationOnOpen: true }) + Global.openMenu(imageContextMenuComponent, item, { url: url, domain: domain }) } onHoveredLinkChanged: delegate.highlightedLink = linksMessageView.hoveredLink gifUnfurlingEnabled: root.gifUnfurlingEnabled diff --git a/ui/imports/shared/views/profile/ProfileShowcaseAccountsView.qml b/ui/imports/shared/views/profile/ProfileShowcaseAccountsView.qml index 8ee3eea8d9e..23bf26c18b3 100644 --- a/ui/imports/shared/views/profile/ProfileShowcaseAccountsView.qml +++ b/ui/imports/shared/views/profile/ProfileShowcaseAccountsView.qml @@ -154,7 +154,7 @@ Item { flatNetworks: root.networksStore.activeNetworks onNetworkClicked: (shortname, isTestnet) => { let link = Utils.getUrlForAddressOnNetwork(shortname, isTestnet, contextMenu.accountAddress); - Global.openLinkWithConfirmation(link, StatusQUtils.StringUtils.extractDomainFromLink(link)); + Global.requestOpenLink(link) } } } diff --git a/ui/imports/shared/views/profile/ProfileShowcaseAssetsView.qml b/ui/imports/shared/views/profile/ProfileShowcaseAssetsView.qml index fb1a1e6ec6e..ffd733a7a3e 100644 --- a/ui/imports/shared/views/profile/ProfileShowcaseAssetsView.qml +++ b/ui/imports/shared/views/profile/ProfileShowcaseAssetsView.qml @@ -80,7 +80,7 @@ Item { enabled: root.sendToAccountEnabled onClicked: { //TODO check this open on CoinGecko - Global.openLink(model.url); + Global.requestOpenLink(model.url); } } } @@ -123,7 +123,7 @@ Item { onTriggered: { //TODO: Get coingecko link for token // let link = ""; - // Global.openLinkWithConfirmation(link, StatusQUtils.StringUtils.extractDomainFromLink(link)); + // Global.requestOpenLink(link); } } } diff --git a/ui/imports/shared/views/profile/ProfileShowcaseCollectiblesView.qml b/ui/imports/shared/views/profile/ProfileShowcaseCollectiblesView.qml index b2eb509562b..abedbcab679 100644 --- a/ui/imports/shared/views/profile/ProfileShowcaseCollectiblesView.qml +++ b/ui/imports/shared/views/profile/ProfileShowcaseCollectiblesView.qml @@ -59,13 +59,13 @@ Item { } function openCollectibleURL() { const link = getCollectibleURL(); - Global.openLinkWithConfirmation(link, StatusQUtils.StringUtils.extractDomainFromLink(link)); + Global.requestOpenLink(link) } function openCollectionURL() { const networkShortName = StatusQUtils.ModelUtils.getByKey(root.networksStore.activeNetworks, "chainId", model.chainId, "shortName") let link = root.walletStore.getOpenSeaCollectionUrl(networkShortName, model.contractAddress) - Global.openLinkWithConfirmation(link, StatusQUtils.StringUtils.extractDomainFromLink(link)); + Global.requestOpenLink(link) } width: GridView.view.cellWidth - Theme.padding @@ -206,7 +206,7 @@ Item { enabled: contextMenu.communityId === "" icon.name: "link" onTriggered: { - Global.openLinkWithConfirmation(contextMenu.url, StatusQUtils.StringUtils.extractDomainFromLink(contextMenu.url)); + Global.requestOpenLink(contextMenu.url) } } } diff --git a/ui/imports/shared/views/profile/ProfileShowcaseSocialLinksView.qml b/ui/imports/shared/views/profile/ProfileShowcaseSocialLinksView.qml index e0d96a8c612..180b88e5eef 100644 --- a/ui/imports/shared/views/profile/ProfileShowcaseSocialLinksView.qml +++ b/ui/imports/shared/views/profile/ProfileShowcaseSocialLinksView.qml @@ -77,7 +77,7 @@ Item { icon.color: socialLinksInfoDelegate.hovered && !hovered ? Theme.palette.baseColor1 : Theme.palette.directColor1 onClicked: { - Global.openLinkWithConfirmation(model.url, StatusQUtils.StringUtils.extractDomainFromLink(model.url)); + Global.requestOpenLink(model.url) } } } diff --git a/ui/imports/utils/Global.qml b/ui/imports/utils/Global.qml index 883e544effa..c2ac62d650c 100644 --- a/ui/imports/utils/Global.qml +++ b/ui/imports/utils/Global.qml @@ -10,8 +10,6 @@ QtObject { signal openPinnedMessagesPopupRequested(var store, var messageStore, var pinnedMessagesModel, string messageToPin, string chatId) signal openCommunityProfilePopupRequested(var store, var community, var chatCommunitySectionModule) - signal openLinkInBrowser(string link) - signal openChooseBrowserPopup(string link) signal openCreateChatView() signal closeCreateChatView() @@ -60,8 +58,7 @@ QtObject { signal openConfirmHideAssetPopup(string assetSymbol, string assetName, string assetImage, bool isCommunityToken) signal openConfirmHideCollectiblePopup(string collectibleSymbol, string collectibleName, string collectibleImage, bool isCommunityToken) - signal openLink(string link) - signal openLinkWithConfirmation(string link, string domain) + signal requestOpenLink(string link) signal activateDeepLink(string link) signal setNthEnabledSectionActive(int nthSection)