add blocker presets

This commit is contained in:
timka123 committed 2026-10-19 11:54:15 +03:00
1 parent 2be074f191
commit 772fdbfded
12 files changed
+426 -83

No files matched your search

+35 -77
View File
@@ -29,27 +29,21 @@ ScrollView {
controller.patchSettings({ notifications: { telegram: patch } })
}
// Presets are a saved list on the server (`pomodoro.presets`), each one a
// name plus its own work/short/long minutes — editable here, not baked
// into the UI. `_merge` on the backend replaces list fields wholesale, so
// editing one preset's number means resending the whole list.
function patchPreset(index, key, value) {
if (!page.pomodoro || !page.pomodoro.presets) return
var presets = page.pomodoro.presets.map(function (p) { return Object.assign({}, p) })
presets[index][key] = value
controller.patchSettings({ pomodoro: { presets: presets } })
}
function applyPreset(index) {
if (!page.pomodoro || !page.pomodoro.presets) return
var preset = page.pomodoro.presets[index]
controller.patchSettings({
pomodoro: {
work_minutes: preset.work_minutes,
short_break_minutes: preset.short_break_minutes,
long_break_minutes: preset.long_break_minutes,
cycles_before_long_break: preset.cycles_before_long_break
}
})
// The Focus/Short break/Long break fields always show and edit the live
// settings. When they still match a saved preset, the edit also rewrites
// that preset's own numbers, so picking it again later gets you back to
// where you left off rather than to some older saved value.
function patchDuration(key, value) {
if (!page.pomodoro) return
var patch = {}; patch[key] = value
var idx = controller.activePresetIndex
if (idx >= 0 && page.pomodoro.presets) {
var presets = page.pomodoro.presets.map(function (p) { return Object.assign({}, p) })
presets[idx] = Object.assign(presets[idx], patch)
controller.patchSettings({ pomodoro: Object.assign({ presets: presets }, patch) })
} else {
controller.patchSettings({ pomodoro: patch })
}
}
component Field: ColumnLayout {
@@ -127,68 +121,32 @@ ScrollView {
spacing: 12
SectionTitle { text: "Timer" }
// Presets: a saved list of work/short/long combos. "Apply" copies
// one onto the live settings below; the numbers on each row are
// the preset's own and edit it in place.
ColumnLayout {
// The preset switcher: pick one and it applies at once. The fields
// below always belong to whichever one is lit — there is nothing
// to show for the others until you switch to them.
RowLayout {
Layout.fillWidth: true
spacing: 8
Repeater {
model: page.pomodoro && page.pomodoro.presets ? page.pomodoro.presets : []
RowLayout {
id: presetRow
delegate: PresetChip {
required property var modelData
required property int index
Layout.fillWidth: true
spacing: 16
readonly property bool isActive: page.pomodoro
&& page.pomodoro.work_minutes === modelData.work_minutes
&& page.pomodoro.short_break_minutes === modelData.short_break_minutes
&& page.pomodoro.long_break_minutes === modelData.long_break_minutes
Label {
text: presetRow.modelData.name
color: presetRow.isActive ? Theme.ember : Theme.ink
font.pixelSize: 13
font.weight: presetRow.isActive ? Font.DemiBold : Font.Medium
font.family: Theme.sansFamily
Layout.preferredWidth: 70
}
Field {
label: "Focus"
SpinBox {
from: 1; to: 240
value: presetRow.modelData.work_minutes
onValueModified: page.patchPreset(presetRow.index, "work_minutes", value)
}
}
Field {
label: "Short break"
SpinBox {
from: 1; to: 120
value: presetRow.modelData.short_break_minutes
onValueModified: page.patchPreset(presetRow.index, "short_break_minutes", value)
}
}
Field {
label: "Long break"
SpinBox {
from: 1; to: 240
value: presetRow.modelData.long_break_minutes
onValueModified: page.patchPreset(presetRow.index, "long_break_minutes", value)
}
}
GhostButton {
text: presetRow.isActive ? "Active" : "Apply"
enabled: !presetRow.isActive
onClicked: page.applyPreset(presetRow.index)
}
Item { Layout.fillWidth: true }
text: modelData.name
active: controller.activePresetIndex === index
onClicked: controller.applyPreset(index)
}
}
Label {
visible: controller.activePresetIndex === -1
text: "Custom"
color: Theme.muted
font.pixelSize: 12
font.family: Theme.sansFamily
leftPadding: 6
}
Item { Layout.fillWidth: true }
}
Flow {
@@ -199,7 +157,7 @@ ScrollView {
SpinBox {
from: 1; to: 240
value: page.pomodoro ? page.pomodoro.work_minutes : 25
onValueModified: page.patchPomodoro("work_minutes", value)
onValueModified: page.patchDuration("work_minutes", value)
}
}
Field {
@@ -207,7 +165,7 @@ ScrollView {
SpinBox {
from: 1; to: 120
value: page.pomodoro ? page.pomodoro.short_break_minutes : 5
onValueModified: page.patchPomodoro("short_break_minutes", value)
onValueModified: page.patchDuration("short_break_minutes", value)
}
}
Field {
@@ -215,7 +173,7 @@ ScrollView {
SpinBox {
from: 1; to: 240
value: page.pomodoro ? page.pomodoro.long_break_minutes : 15
onValueModified: page.patchPomodoro("long_break_minutes", value)
onValueModified: page.patchDuration("long_break_minutes", value)
}
}
Field {