diff --git a/nebula/ui/components/MZHelpSheet.qml b/nebula/ui/components/MZHelpSheet.qml index 1b085573172..f0beb567431 100644 --- a/nebula/ui/components/MZHelpSheet.qml +++ b/nebula/ui/components/MZHelpSheet.qml @@ -82,7 +82,7 @@ MZBottomSheet { id: icon anchors.centerIn: parent - sourceSize.width: MZTheme.theme.iconSize + sourceSize.width: MZTheme.theme.iconSize * 1.5 mirror: MZLocalizer.isRightToLeft fillMode: Image.PreserveAspectFit @@ -107,13 +107,18 @@ MZBottomSheet { } MZIconButton { - id: iconButton - Layout.rightMargin: MZTheme.theme.windowMargin / 2 Layout.preferredHeight: MZTheme.theme.rowHeight Layout.preferredWidth: MZTheme.theme.rowHeight + //Hacky workaround because for some reason, when opening a sheet via + //the right menu button in MZMenu, this close button is in a + //"Hovered" state, even though it wasn't hovered + //Likely something to do with both icon buttons being in the same position + //Relative to their parent (top right corner) + mouseArea.hoverEnabled: bottomSheet.opened + onClicked: bottomSheet.close() accessibleName: MZI18n.GlobalClose diff --git a/nebula/ui/components/MZIconButton.qml b/nebula/ui/components/MZIconButton.qml index 8e602a46e8e..6ebdda9b7e6 100644 --- a/nebula/ui/components/MZIconButton.qml +++ b/nebula/ui/components/MZIconButton.qml @@ -12,6 +12,7 @@ MZButtonBase { property bool skipEnsureVisible: false property var accessibleName property var buttonColorScheme: MZTheme.theme.iconButtonLightBackground + property alias mouseArea: mouseArea property alias backgroundRadius: uiStates.radius property alias uiStatesVisible: uiStates.visible diff --git a/nebula/ui/resources/CMakeLists.txt b/nebula/ui/resources/CMakeLists.txt index c780ca5f244..6243591928b 100644 --- a/nebula/ui/resources/CMakeLists.txt +++ b/nebula/ui/resources/CMakeLists.txt @@ -71,5 +71,7 @@ qt_add_qml_module(resources info.svg lock.svg startup.svg + question.svg + tip-filled.svg ) diff --git a/nebula/ui/resources/question.svg b/nebula/ui/resources/question.svg new file mode 100644 index 00000000000..bc8c9e258db --- /dev/null +++ b/nebula/ui/resources/question.svg @@ -0,0 +1,3 @@ + + + diff --git a/nebula/ui/resources/tip-filled.svg b/nebula/ui/resources/tip-filled.svg new file mode 100644 index 00000000000..6eede736d69 --- /dev/null +++ b/nebula/ui/resources/tip-filled.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/featurelist.h b/src/featurelist.h index ee1cc02b05e..1704b8136b1 100644 --- a/src/featurelist.h +++ b/src/featurelist.h @@ -89,6 +89,13 @@ FEATURE(gleanRust, // Feature ID QStringList(), // feature dependencies FeatureCallback_true) +FEATURE(helpSheets, // Feature ID + "Help sheets", // Feature name + FeatureCallback_true, // Can be flipped on + FeatureCallback_true, // Can be flipped off + QStringList(), // feature dependencies + FeatureCallback_false) + FEATURE(inAppAccountCreate, // Feature ID "In-app Account Creation", // Feature name FeatureCallback_true, // Can be flipped on diff --git a/src/mozillavpn.cpp b/src/mozillavpn.cpp index 9e46ec46ab0..707b9dacf13 100644 --- a/src/mozillavpn.cpp +++ b/src/mozillavpn.cpp @@ -1381,6 +1381,10 @@ void MozillaVPN::registerUrlOpenerLabels() { uo->registerUrlLabel("upgradeToAnnualUrl", []() -> QString { return Constants::upgradeToAnnualUrl(); }); + + uo->registerUrlLabel("sumoDns", []() -> QString { + return "https://support.mozilla.org/en-US/kb/how-do-i-change-my-dns-settings"; + }); } void MozillaVPN::errorHandled() { diff --git a/src/translations/strings.yaml b/src/translations/strings.yaml index 12666de5b15..233c9d3581e 100644 --- a/src/translations/strings.yaml +++ b/src/translations/strings.yaml @@ -928,6 +928,20 @@ devices: value: My devices comment: Title for the menu bar when viewing the devices or device limit pages +helpSheets: + dnsTitle: + value: Custom DNS settings + comment: Title label for the custom dns help sheet + dnsHeader: + value: What is custom DNS? + comment: Header label for the custom dns help sheet + dnsBody1: + value: Whenever you connect to a website, a DNS (domain name system) first turns the domain name (e.g. www.mozilla.org) into an IP address that allows your internet traffic to reach that destination. + comment: Body text for the custom dns help sheet + dnsBody2: + value: Mozilla VPN allows you to choose a custom DNS server if you prefer. If you use one, you won’t be able to use other privacy features in the VPN like tracker blocking. + comment: Body text for the custom dns help sheet + global: expand: value: Expand @@ -977,6 +991,12 @@ global: getStarted: value: Get started comment: Label for a button used to begin something / proceed + help: + value: Help + comment: Action taken that will help the user + learnMore: + value: Learn more + comment: Label for link to allow the user to learn more about a topic getHelp: helpCenter: Help Center diff --git a/src/ui/screens/settings/ViewDNSSettings.qml b/src/ui/screens/settings/ViewDNSSettings.qml index 98e5b549326..82821363549 100644 --- a/src/ui/screens/settings/ViewDNSSettings.qml +++ b/src/ui/screens/settings/ViewDNSSettings.qml @@ -21,6 +21,27 @@ MZViewBase { property bool privacyDialogNeeded: true property bool dnsSelectionChanged: false readonly property string telemetryScreenId : "dns_settings" + property Component rightMenuButton: Component { + Loader { + active: MZFeatureList.get("helpSheets").isSupported + sourceComponent: MZIconButton { + id: iconButton + + onClicked: helpSheetLoader.active = true + + accessibleName: MZI18n.GlobalHelp + Accessible.ignored: !visible + + Image { + anchors.centerIn: parent + + source: "qrc:/nebula/resources/question.svg" + fillMode: Image.PreserveAspectFit + } + } + } + } + function applyFrontendChanges(settingValue) { if (settingValue === MZSettings.Gateway) { @@ -73,7 +94,7 @@ MZViewBase { function reset() { root.customDNS = MZSettings.dnsProviderFlags === MZSettings.Custom; root.privacyDialogNeeded = MZSettings.dnsProviderFlags !== MZSettings.Custom && - MZSettings.dnsProviderFlags !== MZSettings.Gateway; + MZSettings.dnsProviderFlags !== MZSettings.Gateway; ipInput.text = MZSettings.userDNS; } @@ -224,9 +245,9 @@ MZViewBase { } onActiveFocusChanged: { - if (!activeFocus && !ipInput.focusReasonA11y) { - maybeSaveChange(); - } + if (!activeFocus && !ipInput.focusReasonA11y) { + maybeSaveChange(); + } } } @@ -258,8 +279,8 @@ MZViewBase { Component.onCompleted: { Glean.impression.dnsSettingsScreen.record({ - screen: telemetryScreenId, - }); + screen: telemetryScreenId, + }); reset(); } @@ -268,11 +289,11 @@ MZViewBase { } onVisibleChanged: { - if (!visible) { - maybeSaveChange(); - } else { - reset(); - } + if (!visible) { + maybeSaveChange(); + } else { + reset(); + } } Loader { @@ -315,5 +336,27 @@ MZViewBase { onActiveChanged: if (active) { item.open() } } + + Loader { + id: helpSheetLoader + + active: false + + onActiveChanged: if (active) item.open() + + sourceComponent: MZHelpSheet { + title: MZI18n.HelpSheetsDnsTitle + iconSource: "qrc:/nebula/resources/tip-filled.svg" + + model: [ + {type: MZHelpSheet.BlockType.Title, text: MZI18n.HelpSheetsDnsHeader}, + {type: MZHelpSheet.BlockType.Text, text: MZI18n.HelpSheetsDnsBody1, margin: 8}, + {type: MZHelpSheet.BlockType.Text, text:MZI18n.HelpSheetsDnsBody2, margin: 16}, + {type: MZHelpSheet.BlockType.LinkButton, text: MZI18n.GlobalLearnMore, margin: 16, action: () => { MZUrlOpener.openUrlLabel("sumoDns") } }, + ] + + onClosed: helpSheetLoader.active = false + } + } }