feat(@desktop/metrics): Show metrics popup when starting application

Adding local setting: metrics_popup_seen
Small refactoring: showing popup from main.qml
Showing popup: 1. on welcome screen, 2. in Settings/Privacy page and 3. after login when the popup has not been shown yet

Issue #15628
This commit is contained in:
Michal Iskierko 2024-07-19 14:15:50 +02:00 committed by Michał Iskierko
parent 7ec4230a32
commit 52fe774975
12 changed files with 123 additions and 90 deletions

View File

@ -25,6 +25,8 @@ const LAS_KEY_TRANSLATIONS_ENABLED = "global/translations_enabled"
const DEFAULT_LAS_KEY_TRANSLATIONS_ENABLED = false
const DEFAULT_LAS_KEY_CREATE_COMMUNITIES_ENABLED = false
const LAS_KEY_REFRESH_TOKEN_ENABLED = "global/refresh_token_enabled"
const LAS_KEY_METRICS_POPUP_SEEN = "global/metrics_popup_seen"
const DEFAULT_LAS_KEY_METRICS_POPUP_SEEN = false
QtObject:
type LocalAppSettings* = ref object of QObject
@ -229,3 +231,16 @@ QtObject:
QtProperty[string] walletConnectProjectID:
read = getWalletConnectProjectID
proc refreshMetricsPopupSeen*(self: LocalAppSettings) {.signal.}
proc getMetricsPopupSeen*(self: LocalAppSettings): bool {.slot.} =
self.settings.value(LAS_KEY_METRICS_POPUP_SEEN, newQVariant(DEFAULT_LAS_KEY_METRICS_POPUP_SEEN)).boolVal
proc setMetricsPopupSeen*(self: LocalAppSettings, enabled: bool) {.slot.} =
self.settings.setValue(LAS_KEY_METRICS_POPUP_SEEN, newQVariant(enabled))
self.refreshMetricsPopupSeen()
QtProperty[bool] metricsPopupSeen:
read = getMetricsPopupSeen
write = setMetricsPopupSeen
notify = refreshMetricsPopupSeen

View File

@ -19,28 +19,6 @@ QtObject:
new(result, delete)
result.QObject.setup
proc toggleCentralizedMetrics*(self: MetricsService, enabled: bool) {.slot.} =
try:
let payload = %* {"enabled": enabled}
let response = status_go.toggleCentralizedMetrics($payload)
let jsonObj = response.parseJson
if jsonObj.hasKey("error"):
error "toggleCentralizedMetrics", errorMsg=jsonObj["error"].getStr
except Exception:
discard
proc isCentralizedMetricsEnabled*(self: MetricsService): bool {.slot.} =
try:
let response = status_go.centralizedMetricsInfo()
let jsonObj = response.parseJson
if jsonObj.hasKey("error"):
error "isCentralizedMetricsEnabled", errorMsg=jsonObj["error"].getStr
return false
let metricsInfo = toCentralizedMetricsInfoDto(jsonObj)
return metricsInfo.enabled
except Exception:
return false
# for testing, needs to be discussed
proc addCentralizedMetric*(self: MetricsService) =
try:
@ -58,4 +36,36 @@ QtObject:
if jsonObj.hasKey("error"):
error "addCentralizedMetric", errorMsg=jsonObj["error"].getStr
except Exception:
discard
discard
proc centralizedMetricsEnabledChaned*(self: MetricsService) {.signal.}
proc isCentralizedMetricsEnabled*(self: MetricsService): bool {.slot.} =
try:
let response = status_go.centralizedMetricsInfo()
let jsonObj = response.parseJson
if jsonObj.hasKey("error"):
error "isCentralizedMetricsEnabled", errorMsg=jsonObj["error"].getStr
return false
let metricsInfo = toCentralizedMetricsInfoDto(jsonObj)
return metricsInfo.enabled
except Exception:
return false
QtProperty[bool] isCentralizedMetricsEnabled:
read = isCentralizedMetricsEnabled
notify = centralizedMetricsEnabledChaned
proc toggleCentralizedMetrics*(self: MetricsService, enabled: bool) {.slot.} =
try:
let isEnabled = self.isCentralizedMetricsEnabled()
if enabled == isEnabled:
return
let payload = %* {"enabled": enabled}
let response = status_go.toggleCentralizedMetrics($payload)
let jsonObj = response.parseJson
if jsonObj{"error"}.getStr.len > 0:
error "toggleCentralizedMetrics", errorMsg=jsonObj["error"].getStr
else:
self.centralizedMetricsEnabledChaned()
except Exception as e:
error "toggleCentralizedMetrics", exceptionMsg = e.msg

View File

@ -19,7 +19,6 @@ OnboardingBasePage {
id: root
property var startupStore: StartupStore {}
property var metricsStore: MetricsStore {}
backButtonVisible: root.startupStore.currentStartupState ? root.startupStore.currentStartupState.displayBackButton
: false
@ -235,7 +234,6 @@ following the \"Add existing Status user\" flow, using your seed phrase.")
id: keysMainViewComponent
KeysMainView {
startupStore: root.startupStore
metricsStore: root.metricsStore
}
}

View File

@ -23,7 +23,6 @@ Item {
id: root
property StartupStore startupStore
property MetricsStore metricsStore
Component.onCompleted: {
if (button1.visible) {
@ -39,17 +38,8 @@ Item {
readonly property int infoTextWidth: d.infoWidth - 2 * d.infoMargin
readonly property int imgKeysWH: 160
readonly property int imgSeedPhraseWH: 257
function showMetricsAndRunAction(action) {
if (root.startupStore.currentStartupState.stateType === Constants.startupState.welcomeNewStatusUser) {
metricsEnablePopup.actionOnClose = action
metricsEnablePopup.visible = true
} else {
action()
}
}
}
ColumnLayout {
anchors.centerIn: parent
height: Constants.onboarding.loginHeight
@ -233,12 +223,12 @@ Item {
Layout.alignment: Qt.AlignHCenter
visible: text !== ""
onClicked: {
d.showMetricsAndRunAction(root.startupStore.doPrimaryAction)
root.startupStore.doPrimaryAction()
}
Keys.onPressed: {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
event.accepted = true
d.showMetricsAndRunAction(root.startupStore.doPrimaryAction)
root.startupStore.doPrimaryAction()
}
}
}
@ -261,7 +251,7 @@ Item {
parent.font.underline = false
}
onClicked: {
d.showMetricsAndRunAction(root.startupStore.doSecondaryAction)
root.startupStore.doSecondaryAction()
}
}
}
@ -297,7 +287,7 @@ Item {
Qt.openUrlExternally(button3.link)
return
}
d.showMetricsAndRunAction(root.startupStore.doTertiaryAction)
root.startupStore.doTertiaryAction()
}
}
}
@ -321,24 +311,6 @@ Item {
}
}
component MetricsEnablePopupWithActionOnClose: MetricsEnablePopup {
property var actionOnClose
}
MetricsEnablePopupWithActionOnClose {
id: metricsEnablePopup
isOnboarding: true
function finalAction(enable) {
if (!!actionOnClose)
actionOnClose()
root.metricsStore.toggleCentralizedMetrics(enable)
}
onAccepted: finalAction(true)
onRejected: finalAction(false)
}
states: [
State {
name: Constants.startupState.welcomeOldStatusUser

View File

@ -24,6 +24,14 @@ Item {
btnNewUser.forceActiveFocus()
}
QtObject {
id: d
function showMetricsAndRunAction(action) {
Global.openMetricsEnablePopupRequested(true, popup => popup.closed.connect(() => action()))
}
}
BeforeGetStartedModal {
id: beforeGetStartedModal
onClosed: {
@ -81,12 +89,12 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
text: qsTr("I am new to Status")
onClicked: {
root.startupStore.doPrimaryAction()
d.showMetricsAndRunAction(root.startupStore.doPrimaryAction)
}
Keys.onPressed: {
if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) {
event.accepted = true
root.startupStore.doPrimaryAction()
d.showMetricsAndRunAction(root.startupStore.doPrimaryAction)
}
}
}
@ -98,7 +106,7 @@ Item {
anchors.topMargin: Style.current.bigPadding
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
root.startupStore.doSecondaryAction()
d.showMetricsAndRunAction(root.startupStore.doSecondaryAction)
}
}
}

View File

@ -44,7 +44,7 @@ StatusSectionLayout {
required property WalletAssetsStore walletAssetsStore
required property CollectiblesStore collectiblesStore
required property SharedStores.CurrenciesStore currencyStore
required property SharedStores.MetricsStore metricsStore
required property bool isCentralizedMetricsEnabled
backButtonName: root.store.backButtonName
notificationCount: activityCenterStore.unreadNotificationsCount
@ -463,8 +463,7 @@ StatusSectionLayout {
active: false
asynchronous: true
sourceComponent: PrivacyAndSecurityView {
metricsStore: root.metricsStore
isCentralizedMetricsEnabled: root.isCentralizedMetricsEnabled
implicitWidth: parent.width
implicitHeight: parent.height

View File

@ -23,39 +23,28 @@ import SortFilterProxyModel 0.2
SettingsContentBase {
id: root
required property MetricsStore metricsStore
required property bool isCentralizedMetricsEnabled
Component.onCompleted: {
enableMetricsSwitch.checked = metricsStore.isCentralizedMetricsEnabled()
}
function enableMetrics(enable) {
enableMetricsSwitch.checked = enable
metricsStore.toggleCentralizedMetrics(enable)
function refreshSwitch() {
enableMetricsSwitch.checked = Qt.binding(function() { return root.isCentralizedMetricsEnabled })
}
ColumnLayout {
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
onClicked: {
Global.openPopup(metricsEnabledPopupComponent)
Global.openMetricsEnablePopupRequested(false, popup => popup.toggleMetrics.connect(refreshSwitch))
}
}
]
onClicked: {
Global.openPopup(metricsEnabledPopupComponent)
}
}
Component {
id: metricsEnabledPopupComponent
MetricsEnablePopup {
onAccepted: root.enableMetrics(true)
onRejected: root.enableMetrics(false)
Global.openMetricsEnablePopupRequested(false, popup => popup.toggleMetrics.connect(refreshSwitch))
}
}
}

View File

@ -72,7 +72,6 @@ Item {
property NetworkConnectionStore networkConnectionStore: NetworkConnectionStore {}
property CommunityTokensStore communityTokensStore: CommunityTokensStore {}
property CommunitiesStore communitiesStore: CommunitiesStore {}
property MetricsStore metricsStore: MetricsStore {}
readonly property WalletStore.TokensStore tokensStore: WalletStore.RootStore.tokensStore
readonly property WalletStore.WalletAssetsStore walletAssetsStore: WalletStore.RootStore.walletAssetsStore
readonly property WalletStore.CollectiblesStore walletCollectiblesStore: WalletStore.RootStore.collectiblesStore
@ -82,6 +81,7 @@ Item {
tokensStore: appMain.tokensStore
currencyStore: appMain.currencyStore
}
required property bool isCentralizedMetricsEnabled
// set from main.qml
property var sysPalette
@ -1441,7 +1441,7 @@ Item {
walletAssetsStore: appMain.walletAssetsStore
collectiblesStore: appMain.walletCollectiblesStore
currencyStore: appMain.currencyStore
metricsStore: appMain.metricsStore
isCentralizedMetricsEnabled: appMain.isCentralizedMetricsEnabled
}
}

View File

@ -16,6 +16,8 @@ StatusModal {
property bool isOnboarding: false
signal toggleMetrics(bool enabled)
width: 640
title: qsTr("Help us improve Status")
hasCloseButton: true
@ -90,7 +92,8 @@ StatusModal {
StatusButton {
text: qsTr("Share usage data")
onClicked: {
root.accept()
root.toggleMetrics(true)
close()
}
objectName: "shareMetricsButton"
}
@ -100,7 +103,8 @@ StatusModal {
StatusButton {
text: qsTr("Not now")
onClicked: {
root.reject()
root.toggleMetrics(false)
close()
}
objectName: "notShareMetricsButton"
normalColor: "transparent"

View File

@ -7,7 +7,5 @@ QtObject {
metrics.toggleCentralizedMetrics(enabled)
}
function isCentralizedMetricsEnabled() {
return metrics.isCentralizedMetricsEnabled()
}
readonly property bool isCentralizedMetricsEnabled : metrics.isCentralizedMetricsEnabled
}

View File

@ -109,6 +109,9 @@ QtObject {
// BuyCrypto
signal openBuyCryptoModalRequested()
// Metrics
signal openMetricsEnablePopupRequested(bool isOnboarding, var cb)
/////////////////////////////////////////////////////
// WalletConnect POC - to remove
signal popupWalletConnect()

View File

@ -11,6 +11,7 @@ import utils 1.0
import shared 1.0
import shared.panels 1.0
import shared.popups 1.0
import shared.stores 1.0
import mainui 1.0
import AppLayouts.Onboarding 1.0
@ -19,11 +20,14 @@ import StatusQ 0.1 // Force import StatusQ plugin to load all StatusQ resources
import StatusQ.Core.Theme 0.1
StatusWindow {
id: applicationWindow
property bool appIsReady: false
property MetricsStore metricsStore: MetricsStore {}
Universal.theme: Universal.System
id: applicationWindow
objectName: "mainWindow"
minimumWidth: 1200
minimumHeight: 680
@ -285,6 +289,8 @@ StatusWindow {
Style.changeTheme(Universal.System, systemPalette.isCurrentSystemThemeDark());
restoreAppState();
Global.openMetricsEnablePopupRequested.connect(openMetricsEnablePopup)
}
signal navigateTo(string path)
@ -296,6 +302,17 @@ StatusWindow {
applicationWindow.requestActivate()
}
function openMetricsEnablePopup(isOnboarding, cb = null) {
metricsPopupLoader.active = true
metricsPopupLoader.item.visible = true
metricsPopupLoader.item.isOnboarding = isOnboarding
if (cb)
cb(metricsPopupLoader.item)
if(!localAppSettings.metricsPopupSeen) {
localAppSettings.metricsPopupSeen = true
}
}
StatusTrayIcon {
id: systemTray
objectName: "systemTray"
@ -320,6 +337,7 @@ StatusWindow {
AppMain {
sysPalette: systemPalette
visible: !appLoadingAnimation.active
isCentralizedMetricsEnabled: metricsStore.isCentralizedMetricsEnabled
}
}
@ -339,6 +357,15 @@ StatusWindow {
}
}
}
onActiveChanged: {
if (!active) {
// animation is finished, app main will be shown
// open metrics popup only if it has not been seen
if(!localAppSettings.metricsPopupSeen) {
openMetricsEnablePopup(true, null)
}
}
}
}
OnboardingLayout {
@ -347,6 +374,16 @@ StatusWindow {
anchors.fill: parent
}
Loader {
id: metricsPopupLoader
active: false
sourceComponent: MetricsEnablePopup {
visible: true
onClosed: metricsPopupLoader.active = false
onToggleMetrics: applicationWindow.metricsStore.toggleCentralizedMetrics(enabled)
}
}
MacTrafficLights { // FIXME should be a direct part of StatusAppNavBar
anchors.left: parent.left
anchors.top: parent.top