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)