Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion config/Config.qml
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ Singleton {
mediaUpdateInterval: dashboard.mediaUpdateInterval,
resourceUpdateInterval: dashboard.resourceUpdateInterval,
dragThreshold: dashboard.dragThreshold,
showUpcoming: dashboard.showUpcoming,
performance: {
showBattery: dashboard.performance.showBattery,
showGpu: dashboard.performance.showGpu,
Expand Down Expand Up @@ -366,6 +367,7 @@ Singleton {
function serializeSidebar(): var {
return {
enabled: sidebar.enabled,
showUpcoming: sidebar.showUpcoming,
dragThreshold: sidebar.dragThreshold
};
}
Expand All @@ -385,7 +387,16 @@ Singleton {
defaultPlayer: services.defaultPlayer,
playerAliases: services.playerAliases,
showLyrics: services.showLyrics,
lyricsBackend: services.lyricsBackend
lyricsBackend: services.lyricsBackend,
calendar: {
enabled: services.calendar.enabled,
command: services.calendar.command,
agendaDays: services.calendar.agendaDays,
dashUpcomingHours: services.calendar.dashUpcomingHours,
sidebarUpcomingHours: services.calendar.sidebarUpcomingHours,
reminderMinutes: services.calendar.reminderMinutes,
refreshInterval: services.calendar.refreshInterval
}
};
}

Expand Down
1 change: 1 addition & 0 deletions config/DashboardConfig.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ JsonObject {
property bool showMedia: true
property bool showPerformance: true
property bool showWeather: true
property bool showUpcoming: false
property Sizes sizes: Sizes {}
property Performance performance: Performance {}

Expand Down
11 changes: 11 additions & 0 deletions config/ServiceConfig.qml
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,15 @@ JsonObject {
]
property bool showLyrics: false
property string lyricsBackend: "Auto"
property GCalendarConfig calendar: GCalendarConfig {}

component GCalendarConfig: JsonObject {
property bool enabled: false // Requires gws CLI in PATH
property string command: "gws" // Path or name of the gws CLI binary
property int agendaDays: 30 // How many days ahead to fetch events
property int dashUpcomingHours: 24 // Hours ahead to show in dashboard upcoming list
property int sidebarUpcomingHours: 120 // Hours ahead to show in sidebar upcoming list
property int reminderMinutes: 10 // Minutes before event to send notification, 0 to disable
property int refreshInterval: 900 // Refresh interval in seconds
}
}
1 change: 1 addition & 0 deletions config/SidebarConfig.qml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import Quickshell.Io

JsonObject {
property bool enabled: true
property bool showUpcoming: true
property int dragThreshold: 80
property Sizes sizes: Sizes {}

Expand Down
84 changes: 83 additions & 1 deletion modules/dashboard/Dash.qml
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pragma ComponentBehavior: Bound

import "dash"
import QtQuick.Layouts
import qs.components
Expand Down Expand Up @@ -86,7 +88,7 @@ GridLayout {
Rect {
Layout.row: 0
Layout.column: 5
Layout.rowSpan: 2
Layout.rowSpan: Config.dashboard.showUpcoming && GCalendar.upcomingDash.length > 0 ? 3 : 2
Layout.preferredWidth: media.implicitWidth
Layout.fillHeight: true

Expand All @@ -97,6 +99,86 @@ GridLayout {
}
}

// Upcoming events
Rect {
Layout.row: 2
Layout.column: 0
Layout.columnSpan: 5
Layout.fillWidth: true
Layout.preferredHeight: eventsCol.implicitHeight

visible: Config.dashboard.showUpcoming && GCalendar.upcomingDash.length > 0
radius: Appearance.rounding.large

ColumnLayout {
id: eventsCol

anchors.left: parent.left
anchors.right: parent.right
anchors.margins: Appearance.padding.large
spacing: Appearance.spacing.small

StyledText {
Layout.topMargin: Appearance.padding.small
text: qsTr("Upcoming")
color: Colours.palette.m3primary
font.pointSize: Appearance.font.size.small
font.weight: 600
}

Repeater {
model: GCalendar.upcomingDash // qmllint disable missing-property

RowLayout { // qmllint disable missing-property
id: eventRow

required property var modelData

Layout.fillWidth: true
spacing: Appearance.spacing.small

Rectangle {
Layout.preferredWidth: 3
Layout.fillHeight: true
radius: 1.5 // qmllint disable missing-property
color: Colours.palette.m3tertiary // qmllint disable missing-property
}

ColumnLayout {
Layout.fillWidth: true
spacing: 0

StyledText {
Layout.fillWidth: true
text: eventRow.modelData.summary
color: Colours.palette.m3onSurface
font.pointSize: Appearance.font.size.small
font.weight: 500
elide: Text.ElideRight // qmllint disable unqualified
}

StyledText {
Layout.fillWidth: true
text: {
let line = GCalendar.formatEventTime(eventRow.modelData, Config.services.calendar.dashUpcomingHours);
if (eventRow.modelData.location)
line += ` · ${eventRow.modelData.location}`;
return line;
}
color: Colours.palette.m3onSurfaceVariant
font.pointSize: Appearance.font.size.small * 0.9
elide: Text.ElideRight // qmllint disable unqualified
}
}
}
}

Item {
Layout.preferredHeight: Appearance.padding.small
}
}
}

component Rect: StyledRect {
color: Colours.tPalette.m3surfaceContainer
}
Expand Down
14 changes: 14 additions & 0 deletions modules/dashboard/dash/Calendar.qml
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ CustomMouseArea {

required property var model

readonly property bool hasEvent: GCalendar.hasEvent(model.date)

implicitWidth: implicitHeight
implicitHeight: text.implicitHeight + Appearance.padding.small * 2

Expand All @@ -187,6 +189,18 @@ CustomMouseArea {
font.pointSize: Appearance.font.size.normal
font.weight: 500
}

Rectangle {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 1
width: 4
height: 4
radius: 2
color: Colours.palette.m3tertiary
visible: dayItem.hasEvent
opacity: dayItem.model.today || dayItem.model.month === grid.month ? 1 : 0.4
}
}
}

Expand Down
109 changes: 109 additions & 0 deletions modules/sidebar/Content.qml
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
pragma ComponentBehavior: Bound

import QtQuick
import QtQuick.Layouts
import qs.components
import qs.components.containers
import qs.components.controls
import qs.services
import qs.config

Expand Down Expand Up @@ -29,6 +33,111 @@ Item {
}
}

// Upcoming events
StyledRect {
Layout.fillWidth: true
Layout.preferredHeight: Math.min(upcomingCol.implicitHeight, 300)

visible: Config.sidebar.showUpcoming && GCalendar.enabled && GCalendar.upcomingSidebar.length > 0
radius: Appearance.rounding.normal
color: Colours.tPalette.m3surfaceContainerLow

ColumnLayout {
id: upcomingHeader

anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.margins: Appearance.padding.normal

StyledText {
Layout.topMargin: Appearance.padding.small
text: qsTr("Upcoming Events")
color: Colours.palette.m3primary
font.pointSize: Appearance.font.size.small
font.weight: 600
}
}

StyledFlickable {
id: upcomingView

clip: true
anchors.top: upcomingHeader.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
anchors.margins: Appearance.padding.normal
anchors.topMargin: Appearance.spacing.small

flickableDirection: Flickable.VerticalFlick
contentWidth: width
contentHeight: upcomingCol.implicitHeight

StyledScrollBar.vertical: StyledScrollBar {
flickable: upcomingView
}

ColumnLayout {
id: upcomingCol

width: parent.width
spacing: Appearance.spacing.small

Repeater {
model: GCalendar.upcomingSidebar

RowLayout {
id: sidebarEventRow

required property var modelData

Layout.fillWidth: true
spacing: Appearance.spacing.small

Rectangle {
Layout.preferredWidth: 3
Layout.fillHeight: true
radius: 1.5
color: Colours.palette.m3tertiary
}

ColumnLayout {
Layout.fillWidth: true
spacing: 0

StyledText {
Layout.fillWidth: true
text: sidebarEventRow.modelData.summary
color: Colours.palette.m3onSurface
font.pointSize: Appearance.font.size.small
font.weight: 500
elide: Text.ElideRight
}

StyledText {
Layout.fillWidth: true
text: {
let line = GCalendar.formatEventTime(sidebarEventRow.modelData, Config.services.calendar.sidebarUpcomingHours);
if (sidebarEventRow.modelData.location)
line += ` · ${sidebarEventRow.modelData.location}`;
return line;
}
color: Colours.palette.m3onSurfaceVariant
font.pointSize: Appearance.font.size.small * 0.9
elide: Text.ElideRight
}
}
}
}

Item {
Layout.preferredHeight: Appearance.padding.small
}
}
}
}

StyledRect {
Layout.topMargin: Appearance.padding.large - layout.spacing
Layout.fillWidth: true
Expand Down
Loading