Files

206 lines
8.1 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import qs.Common
import qs.Services
import qs.DCommon.Widgets
import qs.Modals.Common
import qs.Modules.Settings.Widgets
import qs.Modules.ControlCenter.Widgets
import qs.Modules.DDash.Wellbeing
import "../DDash/Wellbeing/Wellbeing.js" as Wellbeing
Item {
id: root
property var parentModal: null
property var days: []
readonly property date today: new Date()
readonly property date anchor: Wellbeing.addDays(today, chart.weekOffset * Wellbeing.weekLength)
readonly property var limits: SettingsData.wellbeingAppLimits ?? {}
readonly property var limitedApps: Object.keys(limits).filter(appId => Number(limits[appId]) > 0).sort((a, b) => WellbeingService.appName(a).localeCompare(WellbeingService.appName(b)))
readonly property bool available: WellbeingService.available
readonly property int revision: WellbeingService.revision
readonly property int firstDayOfWeek: SettingsData.firstDayOfWeek >= 7 || SettingsData.firstDayOfWeek < 0 ? Qt.locale().firstDayOfWeek : SettingsData.firstDayOfWeek
onAvailableChanged: refresh()
onRevisionChanged: refresh()
Component.onCompleted: refresh()
function toggleLimit(appId) {
WellbeingService.setAppLimit(appId, WellbeingService.appLimitMinutes(appId) > 0 ? 0 : WellbeingMetrics.defaultLimitMinutes);
}
function refresh() {
if (!available)
return;
WellbeingService.summary(result => root.days = result);
}
ConfirmModal {
id: clearConfirm
}
SettingsPage {
SettingsCard {
width: parent.width
visible: root.available && SettingsData.wellbeingEnabled
iconName: "show_chart"
title: I18n.tr("Weekly screen time", "chart title, screen time per day over the week")
settingKey: "wellbeingChart"
tab: "wellbeing"
tags: ["wellbeing", "screen time", "chart", "week"]
WeeklyChart {
id: chart
height: WellbeingMetrics.chartHeight
color: "transparent"
pad: 0
showTitle: false
days: root.days
today: root.today
firstDayOfWeek: root.firstDayOfWeek
limitSeconds: SettingsData.wellbeingDailyLimit * 60
}
}
SettingsCard {
width: parent.width
visible: root.available && SettingsData.wellbeingEnabled
iconName: "apps"
title: I18n.tr("Most used apps", "screen time card title, apps ranked by time")
settingKey: "wellbeingApps"
tab: "wellbeing"
tags: ["wellbeing", "screen time", "apps", "usage"]
AppUsageList {
height: implicitHeight
color: "transparent"
pad: 0
showTitle: false
fillHeight: false
days: root.days
firstDayOfWeek: root.firstDayOfWeek
anchor: root.anchor
today: root.today
onLimitRequested: appId => root.toggleLimit(appId)
}
}
SettingsCard {
width: parent.width
iconName: "digital_wellbeing"
title: I18n.tr("Screen time", "dashboard card and settings card title, time spent in apps")
settingKey: "wellbeing"
tab: "wellbeing"
tags: ["wellbeing", "screen time", "usage", "limit"]
SettingsToggleRow {
settingKey: "wellbeingEnabled"
tab: "wellbeing"
tags: ["wellbeing", "screen time", "tracking"]
text: I18n.tr("Track screen time", "digital wellbeing main toggle")
description: I18n.tr("Counts time in the focused app while the session is active. Stays on this device.", "track screen time toggle description")
checked: SettingsData.wellbeingEnabled
onToggled: checked => SettingsData.set("wellbeingEnabled", checked)
}
SettingsRow {
settingKey: "wellbeingDailyLimit"
tab: "wellbeing"
tags: ["wellbeing", "screen time", "limit", "daily"]
title: I18n.tr("Daily limit", "screen time limit per day, total or for one app")
subtitle: SettingsData.wellbeingDailyLimit > 0 ? I18n.tr("Notifies when today's screen time passes the limit", "daily screen time limit description") : I18n.tr("Off")
DurationSteppers {
anchors.verticalCenter: parent.verticalCenter
minutes: SettingsData.wellbeingDailyLimit
onCommitted: next => SettingsData.set("wellbeingDailyLimit", next)
}
}
}
SettingsCard {
width: parent.width
iconName: "timer"
title: I18n.tr("App limits", "settings card title, per-app screen time limits")
settingKey: "wellbeingAppLimits"
tab: "wellbeing"
tags: ["wellbeing", "screen time", "limit", "app"]
SettingsRow {
visible: root.limitedApps.length === 0
title: I18n.tr("No app limits", "empty state, per-app screen time limits list")
subtitle: I18n.tr("Pick an app from the list above or the dashboard tab", "app limits empty state description")
}
Repeater {
model: root.limitedApps
SettingsRow {
id: limitRow
required property string modelData
settingKey: "wellbeingAppLimits:" + modelData
resetKeys: []
title: WellbeingService.appName(modelData)
leading: CcAppIcon {
appId: limitRow.modelData
iconSize: Theme.iconSizeLarge
}
DurationSteppers {
anchors.verticalCenter: parent.verticalCenter
minutes: WellbeingService.appLimitMinutes(limitRow.modelData)
onCommitted: next => WellbeingService.setAppLimit(limitRow.modelData, next)
}
DActionButton {
anchors.verticalCenter: parent.verticalCenter
iconName: "close"
iconColor: Theme.surfaceVariantText
Accessible.name: I18n.tr("Remove")
onClicked: WellbeingService.setAppLimit(limitRow.modelData, 0)
}
}
}
}
SettingsCard {
width: parent.width
iconName: "history"
title: I18n.tr("History")
settingKey: "wellbeingHistory"
tab: "wellbeing"
tags: ["wellbeing", "screen time", "history", "clear"]
SettingsRow {
title: I18n.tr("Screen time history", "settings row title, stored screen time data")
subtitle: I18n.tr("Kept for %1 days on this device", "screen time history description, %1 is a number of days").arg(WellbeingMetrics.retentionDays)
DButton {
anchors.verticalCenter: parent.verticalCenter
buttonHeight: Theme.buttonHeightXS
text: I18n.tr("Clear")
backgroundColor: Theme.errorContainer
textColor: Theme.error
enabled: root.available
onClicked: clearConfirm.showWithOptions({
"title": I18n.tr("Clear History?"),
"message": I18n.tr("Deletes all stored screen time", "confirmation message before clearing screen time history"),
"confirmText": I18n.tr("Clear"),
"confirmColor": Theme.error,
"onConfirm": () => {
WellbeingService.clearHistory();
root.days = [];
}
})
}
}
}
}
}