diff --git a/.config/quickshell/ii/modules/common/Persistent.qml b/.config/quickshell/ii/modules/common/Persistent.qml index a650dc0bb..f0cbcafab 100644 --- a/.config/quickshell/ii/modules/common/Persistent.qml +++ b/.config/quickshell/ii/modules/common/Persistent.qml @@ -50,6 +50,11 @@ Singleton { property bool running: false property int start: 0 } + property JsonObject stopwatch: JsonObject { + property bool running: false + property int start: 0 + property list laps: [] + } } } } diff --git a/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroTimer.qml b/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroTimer.qml index 60a0cefbd..1534adb1f 100644 --- a/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroTimer.qml +++ b/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroTimer.qml @@ -76,7 +76,7 @@ Item { implicitHeight: 35 implicitWidth: 90 - onClicked: Pomodoro.pomodoroReset() + onClicked: Pomodoro.resetPomodoro() enabled: (Pomodoro.pomodoroSecondsLeft < Pomodoro.focusTime) font.pixelSize: Appearance.font.pixelSize.larger @@ -95,82 +95,101 @@ Item { } // The SpinBoxes for adjusting duration - GridLayout { - Layout.alignment: Qt.AlignHCenter - columns: 2 - uniformCellWidths: true - columnSpacing: 20 - rowSpacing: 4 + // GridLayout { + // Layout.alignment: Qt.AlignHCenter + // columns: 2 + // uniformCellWidths: true + // columnSpacing: 20 + // rowSpacing: 4 - StyledText { - Layout.alignment: Qt.AlignHCenter - text: Translation.tr("Focus") - } + // StyledText { + // Layout.alignment: Qt.AlignHCenter + // text: Translation.tr("Focus") + // } - StyledText { - Layout.alignment: Qt.AlignHCenter - text: Translation.tr("Break") - } + // StyledText { + // Layout.alignment: Qt.AlignHCenter + // text: Translation.tr("Break") + // } - ConfigSpinBox { - id: focusSpinBox - spacing: 0 - Layout.leftMargin: 0 - Layout.rightMargin: 0 - value: Config.options.time.pomodoro.focus / 60 - onValueChanged: { - Config.options.time.pomodoro.focus = value * 60 - if (Pomodoro.isPomodoroReset) { // Special case for Pomodoro in Reset state - Pomodoro.pomodoroSecondsLeft = Pomodoro.focusTime - Pomodoro.timeLeft = Pomodoro.focusTime - } - } - } + // ConfigSpinBox { + // id: focusSpinBox + // spacing: 0 + // Layout.leftMargin: 0 + // Layout.rightMargin: 0 + // from: 0 + // to: 120 + // Connections { + // target: Config + // function onReadyChanged() { + // focusSpinBox.valueChanged() + // } + // } + // value: { + // console.log("New focus time: " + (Config.options.time.pomodoro.focus / 60)) + // return Config.options.time.pomodoro.focus / 60 + // } + // onValueChanged: { + // console.log("New focus time is " + value + " minutes, Config is ready:", Config.ready) + // if (!Config.ready) return; + // console.log("Setting focus time to " + value + " minutes") + // Config.options.time.pomodoro.focus = value * 60 + // if (Pomodoro.isPomodoroReset) { // Special case for Pomodoro in Reset state + // Pomodoro.pomodoroSecondsLeft = Pomodoro.focusTime + // Pomodoro.timeLeft = Pomodoro.focusTime + // } + // } + // } - ConfigSpinBox { - id: breakSpinBox - spacing: 0 - Layout.leftMargin: 0 - Layout.rightMargin: 0 - value: Config.options.time.pomodoro.breakTime / 60 - onValueChanged: { - Config.options.time.pomodoro.breakTime = value * 60 - } - } + // ConfigSpinBox { + // id: breakSpinBox + // value: Config.options.time.pomodoro.breakTime / 60 + // spacing: 0 + // from: 0 + // to: 120 + // Layout.leftMargin: 0 + // Layout.rightMargin: 0 + // onValueChanged: { + // Config.options.time.pomodoro.breakTime = value * 60 + // } + // } - StyledText { - Layout.topMargin: 6 - Layout.alignment: Qt.AlignHCenter - text: Translation.tr("Cycle") - } - StyledText { - Layout.topMargin: 6 - Layout.alignment: Qt.AlignHCenter - text: Translation.tr("Long break") - } + // StyledText { + // Layout.topMargin: 6 + // Layout.alignment: Qt.AlignHCenter + // text: Translation.tr("Cycle") + // } + // StyledText { + // Layout.topMargin: 6 + // Layout.alignment: Qt.AlignHCenter + // text: Translation.tr("Long break") + // } - ConfigSpinBox { - id: cycleSpinBox - spacing: 0 - from: 1 - Layout.leftMargin: 0 - Layout.rightMargin: 0 - value: Config.options.time.pomodoro.cycle - onValueChanged: { - Config.options.time.pomodoro.cycle = value - } - } + // ConfigSpinBox { + // id: cycleSpinBox + // value: Config.options.time.pomodoro.cycle + // spacing: 0 + // from: 1 + // to: 20 + // Layout.leftMargin: 0 + // Layout.rightMargin: 0 + // onValueChanged: { + // Config.options.time.pomodoro.cycle = value + // } + // } - ConfigSpinBox { - id: longBreakSpinBox - spacing: 0 - Layout.leftMargin: 0 - Layout.rightMargin: 0 - value: Config.options.time.pomodoro.longBreak / 60 - onValueChanged: { - Config.options.time.pomodoro.longBreak = value * 60 - } - } - } + // ConfigSpinBox { + // id: longBreakSpinBox + // spacing: 0 + // Layout.leftMargin: 0 + // Layout.rightMargin: 0 + // value: Config.options.time.pomodoro.longBreak / 60 + // from: 0 + // to: 120 + // onValueChanged: { + // Config.options.time.pomodoro.longBreak = value * 60 + // } + // } + // } } } \ No newline at end of file diff --git a/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroWidget.qml b/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroWidget.qml index 594533f72..242b1ceb8 100644 --- a/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroWidget.qml +++ b/.config/quickshell/ii/modules/sidebarRight/pomodoro/PomodoroWidget.qml @@ -34,7 +34,7 @@ Item { } else if (event.key === Qt.Key_R) { // Reset with R key if (currentTab === 0) { - Pomodoro.pomodoroReset() + Pomodoro.resetPomodoro() } else { Pomodoro.stopwatchReset() } diff --git a/.config/quickshell/ii/modules/sidebarRight/pomodoro/Stopwatch.qml b/.config/quickshell/ii/modules/sidebarRight/pomodoro/Stopwatch.qml index 90ea1ef78..8f5d65295 100644 --- a/.config/quickshell/ii/modules/sidebarRight/pomodoro/Stopwatch.qml +++ b/.config/quickshell/ii/modules/sidebarRight/pomodoro/Stopwatch.qml @@ -31,7 +31,7 @@ Item { Layout.alignment: Qt.AlignHCenter spacing: 0 StyledText { - Layout.preferredWidth: elapsedIndicator.width * 0.6 // Prevent shakiness + // Layout.preferredWidth: elapsedIndicator.width * 0.6 // Prevent shakiness font.pixelSize: 40 color: Appearance.m3colors.m3onSurface text: { @@ -100,12 +100,12 @@ Item { id: lapsList Layout.fillWidth: true Layout.fillHeight: true - spacing: lapsListItemSpacing + spacing: 4 clip: true popin: true model: ScriptModel { - values: Pomodoro.stopwatchLaps + values: Pomodoro.stopwatchLaps.map((v, i, arr) => arr[arr.length - 1 - i]) } delegate: Rectangle { @@ -139,11 +139,11 @@ Item { StyledText { font.pixelSize: Appearance.font.pixelSize.small text: { - let lapTime = lapItem.modelData - let _10ms = (Math.floor(lapTime) % 100).toString().padStart(2, '0') - let totalSeconds = Math.floor(lapTime) / 100 - let minutes = Math.floor(totalSeconds / 60).toString().padStart(2, '0') - let seconds = Math.floor(totalSeconds % 60).toString().padStart(2, '0') + const lapTime = lapItem.modelData + const _10ms = (Math.floor(lapTime) % 100).toString().padStart(2, '0') + const totalSeconds = Math.floor(lapTime) / 100 + const minutes = Math.floor(totalSeconds / 60).toString().padStart(2, '0') + const seconds = Math.floor(totalSeconds % 60).toString().padStart(2, '0') return `${minutes}:${seconds}.${_10ms}` } } @@ -154,12 +154,13 @@ Item { font.pixelSize: Appearance.font.pixelSize.smaller color: Appearance.colors.colPrimary text: { - let lastTime = (lapItem.index != Pomodoro.stopwatchLaps.length - 1) ? Pomodoro.stopwatchLaps[lapItem.index + 1] : 0 - let lapTime = lapItem.modelData - lastTime - let _10ms = (Math.floor(lapTime) % 100).toString().padStart(2, '0') - let totalSeconds = Math.floor(lapTime) / 100 - let minutes = Math.floor(totalSeconds / 60).toString().padStart(2, '0') - let seconds = Math.floor(totalSeconds % 60).toString().padStart(2, '0') + const originalIndex = Pomodoro.stopwatchLaps.length - lapItem.index - 1 + const lastTime = originalIndex > 0 ? Pomodoro.stopwatchLaps[originalIndex - 1] : 0 + const lapTime = lapItem.modelData - lastTime + const _10ms = (Math.floor(lapTime) % 100).toString().padStart(2, '0') + const totalSeconds = Math.floor(lapTime) / 100 + const minutes = Math.floor(totalSeconds / 60).toString().padStart(2, '0') + const seconds = Math.floor(totalSeconds % 60).toString().padStart(2, '0') return `+${minutes == "00" ? "" : minutes + ":"}${seconds}.${_10ms}` } } diff --git a/.config/quickshell/ii/services/Pomodoro.qml b/.config/quickshell/ii/services/Pomodoro.qml index 5a08709b3..87fe046be 100644 --- a/.config/quickshell/ii/services/Pomodoro.qml +++ b/.config/quickshell/ii/services/Pomodoro.qml @@ -25,13 +25,17 @@ Singleton { property bool isPomodoroReset: !isPomodoroRunning property int timeLeft: focusTime property int pomodoroSecondsLeft: focusTime - property int pomodoroStartTime: Persistent.states.timer.pomodoro.start + property int pomodoroStart: Persistent.states.timer.pomodoro.start property int pomodoroCycle: 1 - property bool isStopwatchRunning: false + property bool isStopwatchRunning: Persistent.states.timer.stopwatch.running property int stopwatchTime: 0 - property int stopwatchStart: 0 - property var stopwatchLaps: [] + property int stopwatchStart: Persistent.states.timer.stopwatch.start + property var stopwatchLaps: Persistent.states.timer.stopwatch.laps + + Component.onCompleted: { + if (!isStopwatchRunning) stopwatchReset() + } // Start and Stop button function togglePomodoro() { @@ -40,12 +44,12 @@ Singleton { if (isPomodoroRunning) { // Pressed Start button Persistent.states.timer.pomodoro.start = getCurrentTimeInSeconds() } else { // Pressed Stop button - timeLeft -= (getCurrentTimeInSeconds() - pomodoroStartTime) + timeLeft -= (getCurrentTimeInSeconds() - pomodoroStart) } } // Reset button - function pomodoroReset() { + function resetPomodoro() { Persistent.states.timer.pomodoro.running = false isBreak = false isPomodoroReset = true @@ -56,7 +60,7 @@ Singleton { } function refreshPomodoro() { - if (getCurrentTimeInSeconds() >= pomodoroStartTime + timeLeft) { + if (getCurrentTimeInSeconds() >= pomodoroStart + timeLeft) { isBreak = !isBreak Persistent.states.timer.pomodoro.start += timeLeft timeLeft = isBreak ? breakTime : focusTime @@ -74,12 +78,12 @@ Singleton { Quickshell.execDetached(["notify-send", "Pomodoro", notificationMessage, "-a", "Shell"]) if (alertSound) { // Play sound only if alertSound is explicitly specified - Quickshell.execDetached(["bash", "-c", `ffplay -nodisp -autoexit ${alertSound}`]) + Quickshell.execDetached(["ffplay", "-nodisp", "-autoexit", alertSound]) } } // A nice abstraction for resume logic by updating the TimeStarted - pomodoroSecondsLeft = (pomodoroStartTime + timeLeft) - getCurrentTimeInSeconds() + pomodoroSecondsLeft = (pomodoroStart + timeLeft) - getCurrentTimeInSeconds() } function getCurrentTimeInSeconds() { // Pomodoro uses Seconds @@ -96,31 +100,31 @@ Singleton { // Stopwatch functions function toggleStopwatch() { - isStopwatchRunning = !isStopwatchRunning + Persistent.states.timer.stopwatch.running = !isStopwatchRunning if (isStopwatchRunning) { // Resume from paused time by adjusting start time - stopwatchStart = getCurrentTimeIn10ms() - stopwatchTime + Persistent.states.timer.stopwatch.start = getCurrentTimeIn10ms() - stopwatchTime } } function stopwatchResetOrLaps() { - if (isStopwatchRunning) { // Clicked on Lap + if (isStopwatchRunning) { recordLaps() - } else { // Clicked on Reset + } else { stopwatchReset() } } function stopwatchReset() { - isStopwatchRunning = false - stopwatchTime = 0 - stopwatchStart = 0 - stopwatchLaps = [] + Persistent.states.timer.stopwatch.running = false + stopwatchTime = 0 + stopwatchStart = getCurrentTimeIn10ms() + Persistent.states.timer.stopwatch.laps = [] } function recordLaps() { - stopwatchLaps.unshift(stopwatchTime) // Last lap goes first on list - // Reassign to trigger onListChanged, idk copied from Todo.qml - root.stopwatchLaps = stopwatchLaps.slice(0) + Persistent.states.timer.stopwatch.laps.push(stopwatchTime) + // Reassign to trigger change + // Persistent.states.timer.stopwatch.laps = Persistent.states.timer.stopwatch.laps.slice(0) } }