Files
Panama/config/dot/quickshell/modules/datemenu/DateMenuPanel.qml
T

274 lines
8.8 KiB
QML

// The approved A · Daybook: month context on the left, the selected day's
// schedule or grouped notification history on the right.
import QtQuick
import Quickshell
import qs.config
import qs.services
import qs.widgets
Item {
id: root
implicitWidth: 760
implicitHeight: frame.implicitHeight + Theme.popoverPadding * 2
function prepare(page: string): void {
calendar.showToday();
CalendarAgenda.selectDate(clock.date);
CalendarAgenda.setVisibleMonth(clock.date.getFullYear(), clock.date.getMonth());
if (page === "notifications")
Notifs.markAllRead();
}
function reset(): void {
notifications.reset();
}
SystemClock {
id: clock
precision: SystemClock.Minutes
}
Column {
id: frame
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: Theme.popoverPadding
spacing: 0
Item {
id: header
width: parent.width
height: 42
Text {
anchors.left: parent.left
anchors.leftMargin: 4
anchors.right: headerActions.left
anchors.rightMargin: Theme.itemSpacing
anchors.verticalCenter: parent.verticalCenter
text: Qt.formatDateTime(clock.date, "dddd, MMMM d")
color: Theme.fg
elide: Text.ElideRight
font.family: Theme.fontFamily
font.features: Theme.tabularFigures
font.pixelSize: Theme.fontSizeTitle
font.weight: Font.DemiBold
}
Row {
id: headerActions
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
spacing: 6
HeaderPill {
visible: ShellState.dateMenuPage === "notifications"
text: "← Back to agenda"
onClicked: ShellState.dateMenuPage = "agenda"
}
HeaderPill {
text: "Do Not Disturb"
active: Notifs.doNotDisturb
icon: "notifications-disabled-symbolic"
onClicked: Notifs.doNotDisturb = !Notifs.doNotDisturb
}
HeaderPill {
visible: ShellState.dateMenuPage === "agenda"
text: "Open Calendar ↗"
onClicked: CalendarAgenda.openCalendar(CalendarAgenda.selectedDate)
}
HeaderPill {
visible: ShellState.dateMenuPage === "notifications" && Notifs.hasNotifications
text: "Clear all"
onClicked: Notifs.dismissAll()
}
}
}
Rectangle {
width: parent.width
height: 1
border.width: 0
color: Theme.alpha(Theme.fg, 0.10)
}
Row {
id: body
width: parent.width
height: Math.min(620, Math.max(438, leftContent.implicitHeight + 28, rightContentHeight + 28))
Item {
id: leftColumn
width: 310
height: body.height
Column {
id: leftContent
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 14
spacing: 12
CalendarGrid {
id: calendar
width: parent.width
selectedDate: CalendarAgenda.selectedDate
onDateActivated: date => CalendarAgenda.selectDate(date)
onVisibleMonthChanged: (year, month) => CalendarAgenda.setVisibleMonth(year, month)
}
Rectangle {
width: parent.width
height: 1
border.width: 0
visible: media.visible || Weather.available
color: Theme.alpha(Theme.fg, 0.08)
}
MediaCard {
id: media
width: parent.width
}
WeatherCard {
width: parent.width
visible: Weather.available
}
}
}
Rectangle {
width: 1
height: body.height
border.width: 0
color: Theme.alpha(Theme.fg, 0.10)
}
Item {
id: rightColumn
width: body.width - leftColumn.width - 1
height: body.height
readonly property real availableWidth: width - 28
AgendaPane {
id: agenda
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 14
visible: ShellState.dateMenuPage === "agenda"
onRequestNotifications: {
ShellState.dateMenuPage = "notifications";
Notifs.markAllRead();
}
}
Column {
id: notificationPane
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
anchors.margins: 14
spacing: 10
visible: ShellState.dateMenuPage === "notifications"
Item {
width: parent.width
height: 28
Text {
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
text: "Notifications"
color: Theme.fg
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeLarge
font.weight: Font.DemiBold
}
Text {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
text: Notifs.history.length + (Notifs.history.length === 1 ? " item" : " items")
color: Theme.fgDim
font.family: Theme.fontFamily
font.features: Theme.tabularFigures
font.pixelSize: Theme.fontSizeSmall
}
}
NotificationList {
id: notifications
width: parent.width
maxHeight: body.height - 76
}
}
}
}
}
readonly property real rightContentHeight: ShellState.dateMenuPage === "notifications"
? notificationPane.implicitHeight
: agenda.implicitHeight
component HeaderPill: Rectangle {
id: pill
required property string text
property string icon: ""
property bool active: false
signal clicked
width: pillRow.implicitWidth + 20
height: 28
radius: Theme.pillRadius
border.width: 0
color: {
if (pill.active)
return pillMouse.containsMouse ? Theme.alpha(Theme.accent, 0.38) : Theme.alpha(Theme.accent, 0.24);
return pillMouse.containsMouse ? Theme.alpha(Theme.fg, 0.15) : Theme.alpha(Theme.fg, 0.07);
}
Behavior on color { ColorAnimation { duration: Theme.durFast } }
Row {
id: pillRow
anchors.centerIn: parent
spacing: 6
ThemedIcon {
anchors.verticalCenter: parent.verticalCenter
visible: pill.icon !== ""
size: visible ? 14 : 0
icon: pill.icon
tint: pill.active ? Theme.accent : Theme.fgDim
}
Text {
anchors.verticalCenter: parent.verticalCenter
text: pill.text
color: pill.active ? Theme.accent : Theme.fg
font.family: Theme.fontFamily
font.pixelSize: Theme.fontSizeSmall
font.weight: Font.Medium
}
}
MouseArea {
id: pillMouse
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: pill.clicked()
}
}
}