Skip to content

Commit 6be2ff4

Browse files
feat(@desktop/extermnalLinks): Added flow for removing and viewing
trusted sites in the Privacy and Security view
1 parent a144e35 commit 6be2ff4

File tree

10 files changed

+386
-95
lines changed

10 files changed

+386
-95
lines changed

storybook/pages/PrivacyAndSecurityViewPage.qml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ SplitView {
2121
SplitView.fillHeight: true
2222
contentWidth: parent.width
2323

24+
whitelistedDomainsModel: ["example1.com", "example2.com", "example3.com"]
2425
isStatusNewsViaRSSEnabled: true
2526
isCentralizedMetricsEnabled: true
2627
thirdpartyServicesEnabled: ctrlThirdpartyServicesEnabled.checked

ui/app/AppLayouts/Profile/ProfileLayout.qml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@ StatusSectionLayout {
8787

8888
required property int theme // Theme.Style.xxx
8989
required property int fontSize // Theme.FontSize.xxx
90+
91+
required property var whitelistedDomainsModel
9092

9193
signal addressWasShownRequested(string address)
9294
signal connectUsernameRequested(string ensName, string ownerAddress)
@@ -101,6 +103,7 @@ StatusSectionLayout {
101103

102104
signal openThirdpartyServicesInfoPopupRequested()
103105
signal openDiscussPageRequested()
106+
signal removeWhitelistedDomain(int index)
104107

105108
backButtonName: d.backButtonName
106109
onBackButtonClicked: {
@@ -115,6 +118,9 @@ StatusSectionLayout {
115118
case Constants.settingsSubsection.wallet:
116119
walletView.item.resetStack()
117120
break;
121+
case Constants.settingsSubsection.privacyAndSecurity:
122+
privacyAndSecurityView.item.resetStack()
123+
break;
118124
case Constants.settingsSubsection.keycard:
119125
keycardView.item.handleBackAction()
120126
break;
@@ -204,6 +210,8 @@ StatusSectionLayout {
204210
d.backButtonName = settingsEntriesModel.getNameForSubsection(Constants.settingsSubsection.about)
205211
} else if (currentIndex === Constants.settingsSubsection.wallet) {
206212
walletView.item.resetStack()
213+
} else if (currentIndex === Constants.settingsSubsection.privacyAndSecurity) {
214+
privacyAndSecurityView.item.resetStack()
207215
} else if (currentIndex === Constants.settingsSubsection.keycard) {
208216
keycardView.item.handleBackAction()
209217
}
@@ -583,24 +591,30 @@ StatusSectionLayout {
583591
}
584592

585593
Loader {
594+
id: privacyAndSecurityView
595+
586596
active: false
587597
asynchronous: true
588598
sourceComponent: PrivacyAndSecurityView {
599+
whitelistedDomainsModel: root.whitelistedDomainsModel
589600
isStatusNewsViaRSSEnabled: root.privacyStore.isStatusNewsViaRSSEnabled
590601
isCentralizedMetricsEnabled: root.isCentralizedMetricsEnabled
591602
thirdpartyServicesEnabled: root.privacyStore.thirdpartyServicesEnabled
592603
privacyModeFeatureEnabled: root.privacyModeFeatureEnabled
593604
implicitWidth: parent.width
594605
implicitHeight: parent.height
595606

596-
sectionTitle: settingsEntriesModel.getNameForSubsection(Constants.settingsSubsection.privacyAndSecurity)
607+
privacySectionTitle: settingsEntriesModel.getNameForSubsection(Constants.settingsSubsection.privacyAndSecurity)
597608
contentWidth: d.contentWidth
598609

599610
onSetNewsRSSEnabledRequested: function (isStatusNewsViaRSSEnabled) {
600611
root.privacyStore.setNewsRSSEnabled(isStatusNewsViaRSSEnabled)
601612
}
602613
onOpenThirdpartyServicesInfoPopupRequested: root.openThirdpartyServicesInfoPopupRequested()
603614
onOpenDiscussPageRequested: root.openDiscussPageRequested()
615+
616+
onBackButtonTextChanged: d.backButtonName = backButtonText
617+
onRemoveWhitelistedDomain: index => root.removeWhitelistedDomain(index)
604618
}
605619
}
606620

ui/app/AppLayouts/Profile/views/PrivacyAndSecurityView.qml

Lines changed: 171 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import utils
66

77
import StatusQ.Components
88
import StatusQ.Controls
9+
import StatusQ.Core
910
import StatusQ.Core.Theme
1011

1112
import shared.controls
@@ -17,117 +18,198 @@ SettingsContentBase {
1718
required property bool isCentralizedMetricsEnabled
1819
required property bool thirdpartyServicesEnabled
1920
required property bool privacyModeFeatureEnabled
21+
required property var whitelistedDomainsModel
22+
required property string privacySectionTitle
23+
24+
property string backButtonText
2025

2126
signal setNewsRSSEnabledRequested(bool isStatusNewsViaRSSEnabled)
2227
signal openThirdpartyServicesInfoPopupRequested()
2328
signal openDiscussPageRequested()
29+
signal removeWhitelistedDomain(int index)
2430

2531
function refreshSwitch() {
2632
enableMetricsSwitch.checked = Qt.binding(function() { return root.isCentralizedMetricsEnabled })
2733
}
2834

29-
titleRowComponentLoader.sourceComponent: StatusButton {
30-
text: qsTr("Privacy policy")
31-
onClicked: Global.privacyPolicyRequested()
35+
function resetStack() {
36+
stackContainer.currentIndex = 0
3237
}
3338

34-
ColumnLayout {
35-
StatusListItem {
36-
Layout.preferredWidth: root.contentWidth
37-
title: qsTr("Receive Status News via RSS")
38-
subTitle: qsTr("Your IP address will be exposed to https://status.app")
39-
components: [
40-
StatusSwitch {
41-
id: statusNewsSwitch
42-
checked: root.isStatusNewsViaRSSEnabled
43-
onToggled: root.setNewsRSSEnabledRequested(statusNewsSwitch.checked)
44-
}
45-
]
46-
onClicked: root.setNewsRSSEnabledRequested(!statusNewsSwitch.checked)
47-
enabled: root.thirdpartyServicesEnabled
48-
}
49-
50-
// Divider
51-
Rectangle {
52-
Layout.preferredWidth: root.contentWidth
53-
Layout.preferredHeight: 1
54-
color: Theme.palette.baseColor2
55-
}
39+
StackLayout {
40+
id: stackContainer
41+
42+
// Main Security & Privacy Page
43+
ColumnLayout {
44+
StatusListItem {
45+
Layout.preferredWidth: root.contentWidth
46+
title: qsTr("Receive Status News via RSS")
47+
subTitle: qsTr("Your IP address will be exposed to https://status.app")
48+
components: [
49+
StatusSwitch {
50+
id: statusNewsSwitch
51+
checked: root.isStatusNewsViaRSSEnabled
52+
onToggled: root.setNewsRSSEnabledRequested(statusNewsSwitch.checked)
53+
}
54+
]
55+
onClicked: root.setNewsRSSEnabledRequested(!statusNewsSwitch.checked)
56+
enabled: root.thirdpartyServicesEnabled
57+
}
5658

57-
StatusListItem {
58-
Layout.preferredWidth: root.contentWidth
59-
title: qsTr("Third-party services")
60-
subTitle: qsTr("Enable/disable all third-party services")
61-
components: [
62-
StatusSwitch {
63-
checkable: false
64-
checked: root.thirdpartyServicesEnabled
65-
onClicked: root.openThirdpartyServicesInfoPopupRequested()
66-
}
67-
]
68-
onClicked: root.openThirdpartyServicesInfoPopupRequested()
69-
visible: root.privacyModeFeatureEnabled
70-
}
59+
// Divider
60+
Rectangle {
61+
Layout.preferredWidth: root.contentWidth
62+
Layout.preferredHeight: 1
63+
color: Theme.palette.baseColor2
64+
}
7165

72-
InformationTag {
73-
id: infoTag
66+
StatusListItem {
67+
Layout.preferredWidth: root.contentWidth
68+
title: qsTr("Third-party services")
69+
subTitle: qsTr("Enable/disable all third-party services")
70+
components: [
71+
StatusSwitch {
72+
checkable: false
73+
checked: root.thirdpartyServicesEnabled
74+
onClicked: root.openThirdpartyServicesInfoPopupRequested()
75+
}
76+
]
77+
onClicked: root.openThirdpartyServicesInfoPopupRequested()
78+
visible: root.privacyModeFeatureEnabled
79+
}
7480

75-
Layout.preferredWidth: root.contentWidth
76-
Layout.preferredHeight: 40
77-
Layout.alignment: Qt.AlignHCenter
78-
79-
leftInset: Theme.padding
80-
rightInset: Theme.padding
81-
leftPadding: horizontalPadding + Theme.padding
82-
rightPadding: horizontalPadding + Theme.padding
83-
84-
backgroundColor: Theme.palette.primaryColor3
85-
bgBorderColor: Theme.palette.primaryColor2
86-
bgRadius: 12
87-
asset.name: "info"
88-
tagPrimaryLabel.wrapMode: Text.WordWrap
89-
tagPrimaryLabel.textFormat: Text.RichText
90-
tagPrimaryLabel.font.pixelSize: Theme.additionalTextSize
91-
tagPrimaryLabel.text: qsTr("Share feedback or suggest improvements on our %1.")
92-
.arg(Utils.getStyledLink("Discuss page", "#", tagPrimaryLabel.hoveredLink, Theme.palette.primaryColor1, Theme.palette.primaryColor1, false))
93-
tagPrimaryLabel.onLinkActivated: root.openDiscussPageRequested()
94-
visible: root.privacyModeFeatureEnabled
95-
}
81+
InformationTag {
82+
id: infoTag
83+
84+
Layout.preferredWidth: root.contentWidth
85+
Layout.preferredHeight: 40
86+
Layout.alignment: Qt.AlignHCenter
87+
88+
leftInset: Theme.padding
89+
rightInset: Theme.padding
90+
leftPadding: horizontalPadding + Theme.padding
91+
rightPadding: horizontalPadding + Theme.padding
92+
93+
backgroundColor: Theme.palette.primaryColor3
94+
bgBorderColor: Theme.palette.primaryColor2
95+
bgRadius: 12
96+
asset.name: "info"
97+
tagPrimaryLabel.wrapMode: Text.WordWrap
98+
tagPrimaryLabel.textFormat: Text.RichText
99+
tagPrimaryLabel.font.pixelSize: Theme.additionalTextSize
100+
tagPrimaryLabel.text: qsTr("Share feedback or suggest improvements on our %1.")
101+
.arg(Utils.getStyledLink("Discuss page", "#", tagPrimaryLabel.hoveredLink, Theme.palette.primaryColor1, Theme.palette.primaryColor1, false))
102+
tagPrimaryLabel.onLinkActivated: root.openDiscussPageRequested()
103+
visible: root.privacyModeFeatureEnabled
104+
}
96105

97-
// Divider
98-
Rectangle {
99-
Layout.preferredWidth: root.contentWidth
100-
Layout.preferredHeight: 1
101-
color: Theme.palette.baseColor2
102-
visible: root.privacyModeFeatureEnabled
103-
}
106+
// Divider
107+
Rectangle {
108+
Layout.preferredWidth: root.contentWidth
109+
Layout.preferredHeight: 1
110+
color: Theme.palette.baseColor2
111+
visible: root.privacyModeFeatureEnabled
112+
}
104113

105-
StatusListItem {
106-
Layout.preferredWidth: root.contentWidth
107-
title: qsTr("Share usage data with Status")
108-
subTitle: qsTr("From all profiles on device")
109-
components: [
110-
StatusSwitch {
111-
id: enableMetricsSwitch
112-
checked: root.isCentralizedMetricsEnabled
113-
onToggled: {
114-
Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null)
115-
refreshSwitch()
114+
StatusListItem {
115+
Layout.preferredWidth: root.contentWidth
116+
title: qsTr("Share usage data with Status")
117+
subTitle: qsTr("From all profiles on device")
118+
components: [
119+
StatusSwitch {
120+
id: enableMetricsSwitch
121+
checked: root.isCentralizedMetricsEnabled
122+
onToggled: {
123+
Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null)
124+
refreshSwitch()
125+
}
116126
}
127+
]
128+
onClicked: {
129+
Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null)
130+
refreshSwitch()
117131
}
118-
]
119-
onClicked: {
120-
Global.openMetricsEnablePopupRequested(Constants.metricsEnablePlacement.privacyAndSecurity, null)
121-
refreshSwitch()
132+
enabled: root.thirdpartyServicesEnabled
133+
}
134+
135+
// Divider
136+
Rectangle {
137+
Layout.preferredWidth: root.contentWidth
138+
Layout.preferredHeight: 1
139+
color: Theme.palette.baseColor2
140+
}
141+
142+
// Trusted Sites
143+
StatusListItem {
144+
Layout.preferredWidth: root.contentWidth
145+
title: qsTr("Trusted sites")
146+
subTitle: qsTr("Manage trusted sites. Their links open without confirmation.")
147+
components: [
148+
StatusIcon {
149+
icon: "next"
150+
color: Theme.palette.baseColor1
151+
}
152+
]
153+
onClicked: stackContainer.currentIndex = 1
154+
}
155+
156+
// Divider
157+
Rectangle {
158+
Layout.preferredWidth: root.contentWidth
159+
Layout.preferredHeight: 1
160+
color: Theme.palette.baseColor2
122161
}
123-
enabled: root.thirdpartyServicesEnabled
124162
}
125163

126-
// Divider
127-
Rectangle {
164+
// Whitelisted Domains Page
165+
WhitelistedDomainsView {
128166
Layout.preferredWidth: root.contentWidth
129-
Layout.preferredHeight: 1
130-
color: Theme.palette.baseColor2
167+
whitelistedDomainsModel: root.whitelistedDomainsModel
168+
onRemoveWhitelistedDomain: index => root.removeWhitelistedDomain(index)
169+
}
170+
171+
}
172+
173+
Component {
174+
id: privacyPolicyButton
175+
StatusButton {
176+
text: qsTr("Privacy policy")
177+
onClicked: Global.privacyPolicyRequested()
131178
}
132179
}
180+
181+
states: [
182+
State {
183+
name: "mainView"
184+
when: stackContainer.currentIndex === 0
185+
PropertyChanges {
186+
target: root
187+
backButtonText: ""
188+
}
189+
PropertyChanges {
190+
target: titleRowComponentLoader
191+
sourceComponent: privacyPolicyButton
192+
}
193+
PropertyChanges {
194+
target: root
195+
sectionTitle: root.privacySectionTitle
196+
}
197+
},
198+
State {
199+
name: "whitelistedDomainsView"
200+
when: stackContainer.currentIndex === 1
201+
PropertyChanges {
202+
target: root
203+
backButtonText: root.privacySectionTitle
204+
}
205+
PropertyChanges {
206+
target: titleRowComponentLoader
207+
sourceComponent: undefined
208+
}
209+
PropertyChanges {
210+
target: root
211+
sectionTitle: ""
212+
}
213+
}
214+
]
133215
}

0 commit comments

Comments
 (0)