From e868f335aa687c2ca29652cd855bd8e42b5e93d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tinkl?= Date: Tue, 20 Aug 2024 17:51:18 +0200 Subject: [PATCH] feat(Settings/Privacy and security): add Privacy Policy popup - mention the "Privacy Policy" document in the text explaining "Help us improve Status", make a link to it and display it in a separate popup - add a standalone header button to the settings page, doing the same - extend storybook page with the "placement" param Fixes #16157 --- storybook/pages/MetricsEnablePopupPage.qml | 56 ++++++++++++++++--- test/e2e/gui/objects_map/names.py | 2 +- .../Profile/views/PrivacyAndSecurityView.qml | 26 ++++----- ui/app/mainui/Popups.qml | 24 ++++++++ .../shared/popups/MetricsEnablePopup.qml | 37 +++++++----- ui/imports/utils/Global.qml | 2 + ui/main.qml | 2 +- 7 files changed, 109 insertions(+), 40 deletions(-) diff --git a/storybook/pages/MetricsEnablePopupPage.qml b/storybook/pages/MetricsEnablePopupPage.qml index 8239f2d777..15cb8597be 100644 --- a/storybook/pages/MetricsEnablePopupPage.qml +++ b/storybook/pages/MetricsEnablePopupPage.qml @@ -1,4 +1,5 @@ import QtQuick 2.15 +import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import shared.popups 1.0 @@ -9,8 +10,9 @@ import Storybook 1.0 SplitView { orientation: Qt.Vertical - Item { + Logs { id: logs } + Item { SplitView.fillWidth: true SplitView.fillHeight: true @@ -24,14 +26,54 @@ SplitView { onClicked: popup.open() } + + MetricsEnablePopup { + id: popup + anchors.centerIn: parent + modal: false + visible: true + placement: ctrlPlacement.currentValue + onSetMetricsEnabledRequested: logs.logEvent("setMetricsEnabledRequested", ["enabled"], arguments) + onClosed: logs.logEvent("closed()") + } + + Connections { + target: Global + function onPrivacyPolicyRequested() { + logs.logEvent("Global::privacyPolicyRequested()") + } + } } - MetricsEnablePopup { - id: popup - anchors.centerIn: parent - modal: false - visible: true - placement: Constants.metricsEnablePlacement.unknown + LogsAndControlsPanel { + id: logsAndControlsPanel + + SplitView.minimumHeight: 100 + SplitView.preferredHeight: 200 + + logsView.logText: logs.logText + + ColumnLayout { + anchors.fill: parent + + RowLayout { + Layout.fillWidth: true + Label { + text: "Placement:" + } + ComboBox { + Layout.preferredWidth: 200 + id: ctrlPlacement + model: [ + Constants.metricsEnablePlacement.unknown, + Constants.metricsEnablePlacement.welcome, + Constants.metricsEnablePlacement.privacyAndSecurity, + Constants.metricsEnablePlacement.startApp + ] + } + } + Item { Layout.fillHeight: true } + } } } diff --git a/test/e2e/gui/objects_map/names.py b/test/e2e/gui/objects_map/names.py index d9626bfd54..fdff5e5284 100644 --- a/test/e2e/gui/objects_map/names.py +++ b/test/e2e/gui/objects_map/names.py @@ -128,7 +128,7 @@ headline_StatusTitleSubtitle = {"container": statusDesktop_mainWindow_overlay, " keys_exist_StatusBaseText = {"container": statusDesktop_mainWindow_overlay, "type": "StatusBaseText", "unnamed": 1, "visible": True} # Share Usage Data Popup -not_now_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "notShareMetricsButton", "type": "StatusButton", "visible": True} +not_now_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "notShareMetricsButton", "type": "StatusFlatButton", "visible": True} share_usage_data_StatusButton = {"checkable": False, "container": statusDesktop_mainWindow_overlay, "objectName": "shareMetricsButton", "type": "StatusButton", "visible": True} """ Communities """ diff --git a/ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml b/ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml index e68b607929..f9d2ee4a53 100644 --- a/ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml +++ b/ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml @@ -3,23 +3,10 @@ import QtQuick.Controls 2.15 import QtQuick.Layouts 1.15 import utils 1.0 -import shared.panels 1.0 -import shared.popups 1.0 -import shared.stores 1.0 -import StatusQ 0.1 -import StatusQ.Core 0.1 -import StatusQ.Core.Theme 0.1 -import StatusQ.Core.Utils 0.1 as StatusQUtils import StatusQ.Components 0.1 import StatusQ.Controls 0.1 -import AppLayouts.Profile.stores 1.0 - -import "../popups" - -import SortFilterProxyModel 0.2 - SettingsContentBase { id: root @@ -29,6 +16,11 @@ SettingsContentBase { enableMetricsSwitch.checked = Qt.binding(function() { return root.isCentralizedMetricsEnabled }) } + titleRowComponentLoader.sourceComponent: StatusButton { + text: qsTr("Privacy policy") + onClicked: Global.privacyPolicyRequested() + } + ColumnLayout { StatusListItem { Layout.preferredWidth: root.contentWidth @@ -38,13 +30,15 @@ SettingsContentBase { StatusSwitch { id: enableMetricsSwitch checked: root.isCentralizedMetricsEnabled - onClicked: { - Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, popup => popup.toggleMetrics.connect(refreshSwitch)) + onToggled: { + Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null) + refreshSwitch() } } ] onClicked: { - Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, popup => popup.toggleMetrics.connect(refreshSwitch)) + Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null) + refreshSwitch() } } } diff --git a/ui/app/mainui/Popups.qml b/ui/app/mainui/Popups.qml index c64f3d335f..46f1d28a69 100644 --- a/ui/app/mainui/Popups.qml +++ b/ui/app/mainui/Popups.qml @@ -8,6 +8,7 @@ import StatusQ.Core 0.1 import StatusQ.Controls 0.1 import StatusQ.Components 0.1 import StatusQ.Popups 0.1 +import StatusQ.Popups.Dialog 0.1 import StatusQ.Core.Theme 0.1 import StatusQ.Core.Utils 0.1 as SQUtils @@ -94,6 +95,7 @@ QtObject { Global.openCommunityMemberMessagesPopupRequested.connect(openCommunityMemberMessagesPopup) Global.openSwapModalRequested.connect(openSwapModal) Global.openBuyCryptoModalRequested.connect(openBuyCryptoModal) + Global.privacyPolicyRequested.connect(() => openPopup(privacyPolicyPopupComponent)) } property var currentPopup @@ -1257,6 +1259,28 @@ QtObject { } onClosed: destroy() } + }, + Component { + id: privacyPolicyPopupComponent + StatusDialog { + width: 600 + padding: 0 + title: qsTr("Status Software Privacy Policy") + StatusScrollView { + id: privacyDialogScrollView + anchors.fill: parent + contentWidth: availableWidth + StatusBaseText { + width: privacyDialogScrollView.availableWidth + wrapMode: Text.Wrap + textFormat: Text.MarkdownText + text: SQUtils.StringUtils.readTextFile(":/imports/assets/docs/privacy.mdwn") + onLinkActivated: Global.openLinkWithConfirmation(link, SQUtils.StringUtils.extractDomainFromLink(link)) + } + } + standardButtons: Dialog.Ok + destroyOnClose: true + } } ] } diff --git a/ui/imports/shared/popups/MetricsEnablePopup.qml b/ui/imports/shared/popups/MetricsEnablePopup.qml index d193c15c00..1c53fde040 100644 --- a/ui/imports/shared/popups/MetricsEnablePopup.qml +++ b/ui/imports/shared/popups/MetricsEnablePopup.qml @@ -16,7 +16,7 @@ StatusModal { property string placement: Constants.metricsEnablePlacement.unknown - signal toggleMetrics(bool enabled) + signal setMetricsEnabledRequested(bool enabled) width: 640 title: qsTr("Help us improve Status") @@ -83,31 +83,38 @@ StatusModal { Paragraph { Layout.fillWidth: true Layout.fillHeight: true - text: qsTr("Usage data will be shared from all profiles added to device. %1").arg(root.placement !== Constants.metricsEnablePlacement.privacyAndSecurity ? "Sharing usage data can be turned off anytime in Settings / Privacy and Security." : "") + textFormat: Text.RichText + text: qsTr("Usage data will be shared from all profiles added to device. %1 %2") + .arg(root.placement !== Constants.metricsEnablePlacement.privacyAndSecurity ? qsTr("Sharing usage data can be turned off anytime in Settings / Privacy and Security.") : "") + .arg(root.placement === Constants.metricsEnablePlacement.privacyAndSecurity ? qsTr("For more details refer to our %1.").arg(Utils.getStyledLink("Privacy Policy", "#", hoveredLink)) : "") + onLinkActivated: { + root.close() + Global.privacyPolicyRequested() + } + HoverHandler { + cursorShape: !!parent.hoveredLink ? Qt.PointingHandCursor : undefined + } } } } rightButtons: [ + StatusFlatButton { + text: qsTr("Do not share") + onClicked: { + root.setMetricsEnabledRequested(false) + close() + } + objectName: "notShareMetricsButton" + normalColor: "transparent" + }, StatusButton { text: qsTr("Share usage data") onClicked: { - root.toggleMetrics(true) + root.setMetricsEnabledRequested(true) close() } objectName: "shareMetricsButton" } ] - - leftButtons: [ - StatusButton { - text: qsTr("Not now") - onClicked: { - root.toggleMetrics(false) - close() - } - objectName: "notShareMetricsButton" - normalColor: "transparent" - } - ] } diff --git a/ui/imports/utils/Global.qml b/ui/imports/utils/Global.qml index 86f46f89a7..857824b06c 100644 --- a/ui/imports/utils/Global.qml +++ b/ui/imports/utils/Global.qml @@ -98,6 +98,8 @@ QtObject { signal openTestnetPopup() + signal privacyPolicyRequested() + // Swap signal openSwapModalRequested(var formDataParams) diff --git a/ui/main.qml b/ui/main.qml index 5149991bec..29225d2798 100644 --- a/ui/main.qml +++ b/ui/main.qml @@ -379,7 +379,7 @@ StatusWindow { sourceComponent: MetricsEnablePopup { visible: true onClosed: metricsPopupLoader.active = false - onToggleMetrics: { + onSetMetricsEnabledRequested: { applicationWindow.metricsStore.toggleCentralizedMetrics(enabled) if (enabled) { Global.addCentralizedMetricIfEnabled("usage_data_shared", {placement: metricsPopupLoader.item.placement})