shell: own the right sidebar, move garden into the drawer
Garden was welded onto the notification list in CenterWidgetGroup — always on, unrelated, stealing space from notifications that said "Nothing". Moved it into the BottomWidgetGroup drawer as a fifth tab alongside Calendar, To Do, Pomodoro, and Stopwatch. CenterWidgetGroup is now just the notification list. Lens events (note_created, synced) emit through notify-send so they land in the notification system properly. Forked calendar, todo, pomodoro, notifications out of ii-base into our tree — the right sidebar no longer borrows any widget files from ii. Toggle dialogs (bluetooth, wifi, nightLight) still symlinked as infrastructure.
This commit is contained in:
parent
7e6633a290
commit
b8e76c4e9e
22 changed files with 2043 additions and 13 deletions
|
|
@ -0,0 +1,187 @@
|
|||
import qs.services
|
||||
import qs.modules.common
|
||||
import qs.modules.common.widgets
|
||||
import Qt5Compat.GraphicalEffects
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import Quickshell
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
||||
implicitHeight: contentColumn.implicitHeight
|
||||
implicitWidth: contentColumn.implicitWidth
|
||||
readonly property color stateColor: TimerService.pomodoroBreak ? Appearance.colors.colTertiaryContainer : Appearance.colors.colSecondaryContainer
|
||||
readonly property color stateTextColor: TimerService.pomodoroBreak ? Appearance.colors.colOnTertiaryContainer : Appearance.colors.colOnSecondaryContainer
|
||||
readonly property string stateLabel: TimerService.pomodoroLongBreak ? Translation.tr("Long break") : TimerService.pomodoroBreak ? Translation.tr("Break") : Translation.tr("Focus")
|
||||
readonly property int cyclePosition: TimerService.pomodoroCycle + 1
|
||||
|
||||
ColumnLayout {
|
||||
id: contentColumn
|
||||
anchors.fill: parent
|
||||
spacing: 10
|
||||
|
||||
// The Pomodoro timer circle
|
||||
CircularProgress {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
lineWidth: 10
|
||||
value: {
|
||||
return TimerService.pomodoroSecondsLeft / TimerService.pomodoroLapDuration;
|
||||
}
|
||||
implicitSize: 200
|
||||
colPrimary: root.stateTextColor
|
||||
colSecondary: root.stateColor
|
||||
enableAnimation: true
|
||||
|
||||
ColumnLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 2
|
||||
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: 150
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: {
|
||||
let minutes = Math.floor(TimerService.pomodoroSecondsLeft / 60).toString().padStart(2, '0');
|
||||
let seconds = Math.floor(TimerService.pomodoroSecondsLeft % 60).toString().padStart(2, '0');
|
||||
return `${minutes}:${seconds}`;
|
||||
}
|
||||
font.family: Appearance.font.family.monospace
|
||||
font.pixelSize: 40
|
||||
font.weight: Font.DemiBold
|
||||
color: Appearance.m3colors.m3onSurface
|
||||
}
|
||||
StyledText {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
text: root.stateLabel
|
||||
font.pixelSize: Appearance.font.pixelSize.normal
|
||||
color: Appearance.colors.colSubtext
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
radius: Appearance.rounding.full
|
||||
color: root.stateColor
|
||||
|
||||
anchors {
|
||||
right: parent.right
|
||||
bottom: parent.bottom
|
||||
}
|
||||
implicitWidth: 58
|
||||
implicitHeight: 36
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 3
|
||||
|
||||
MaterialSymbol {
|
||||
text: "repeat"
|
||||
iconSize: 14
|
||||
color: root.stateTextColor
|
||||
}
|
||||
|
||||
StyledText {
|
||||
id: cycleText
|
||||
font.family: Appearance.font.family.monospace
|
||||
font.weight: Font.DemiBold
|
||||
color: root.stateTextColor
|
||||
text: `${root.cyclePosition}/${TimerService.cyclesBeforeLongBreak}`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
Layout.preferredWidth: 210
|
||||
Layout.preferredHeight: 30
|
||||
radius: Appearance.rounding.full
|
||||
color: Appearance.colors.colLayer2
|
||||
|
||||
RowLayout {
|
||||
anchors.centerIn: parent
|
||||
spacing: 6
|
||||
|
||||
MaterialSymbol {
|
||||
text: TimerService.pomodoroBreak ? "coffee" : "search_activity"
|
||||
iconSize: Appearance.font.pixelSize.larger
|
||||
color: root.stateTextColor
|
||||
}
|
||||
|
||||
StyledText {
|
||||
text: root.stateLabel
|
||||
font.pixelSize: Appearance.font.pixelSize.normal
|
||||
color: Appearance.colors.colOnLayer2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 5
|
||||
|
||||
Repeater {
|
||||
model: TimerService.cyclesBeforeLongBreak
|
||||
|
||||
Rectangle {
|
||||
required property int index
|
||||
implicitWidth: index === TimerService.pomodoroCycle ? 18 : 8
|
||||
implicitHeight: 8
|
||||
radius: Appearance.rounding.full
|
||||
color: index <= TimerService.pomodoroCycle ? root.stateTextColor : Appearance.colors.colLayer2
|
||||
|
||||
Behavior on implicitWidth {
|
||||
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
|
||||
}
|
||||
Behavior on color {
|
||||
animation: Appearance.animation.elementMoveFast.colorAnimation.createObject(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The Start/Stop and Reset buttons
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter
|
||||
spacing: 10
|
||||
|
||||
RippleButton {
|
||||
buttonRadius: Appearance.rounding.full
|
||||
contentItem: StyledText {
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: TimerService.pomodoroRunning ? Translation.tr("Pause") : (TimerService.pomodoroSecondsLeft === TimerService.focusTime) ? Translation.tr("Start") : Translation.tr("Resume")
|
||||
color: TimerService.pomodoroRunning ? Appearance.colors.colOnSecondaryContainer : Appearance.colors.colOnPrimary
|
||||
}
|
||||
implicitHeight: 38
|
||||
implicitWidth: 96
|
||||
font.pixelSize: Appearance.font.pixelSize.larger
|
||||
onClicked: TimerService.togglePomodoro()
|
||||
colBackground: TimerService.pomodoroRunning ? Appearance.colors.colSecondaryContainer : Appearance.colors.colPrimary
|
||||
colBackgroundHover: TimerService.pomodoroRunning ? Appearance.colors.colSecondaryContainer : Appearance.colors.colPrimary
|
||||
}
|
||||
|
||||
RippleButton {
|
||||
buttonRadius: Appearance.rounding.full
|
||||
implicitHeight: 38
|
||||
implicitWidth: 96
|
||||
|
||||
onClicked: TimerService.resetPomodoro()
|
||||
enabled: (TimerService.pomodoroSecondsLeft < TimerService.pomodoroLapDuration) || TimerService.pomodoroCycle > 0 || TimerService.pomodoroBreak
|
||||
|
||||
font.pixelSize: Appearance.font.pixelSize.larger
|
||||
colBackground: Appearance.colors.colErrorContainer
|
||||
colBackgroundHover: Appearance.colors.colErrorContainerHover
|
||||
colRipple: Appearance.colors.colErrorContainerActive
|
||||
|
||||
contentItem: StyledText {
|
||||
anchors.centerIn: parent
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: Translation.tr("Reset")
|
||||
color: Appearance.colors.colOnErrorContainer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue