Files
nixos-config/modules/user/lucid/CalendarSource.qml
T

99 lines
2.8 KiB
QML

import QtQuick
import Quickshell
import Quickshell.Io
import qs
pragma Singleton
// Read-only events already synchronized by Thunderbird. This deliberately does
// not connect to DAV or store credentials; Thunderbird remains the DAV client.
Singleton {
id: source
property var events: []
property int tick: 0
property string error: ""
property real updatedAt: 0
function refresh() {
if (reader.running)
return;
reader.command = ["python3", Quickshell.env("HOME") + "/.config/quickshell/thunderbird-calendar.py"];
reader.running = true;
}
function forDay(year, month, day) {
source.tick;
return source.events.filter((event) => {
const date = new Date(event.startMs);
return date.getFullYear() === year && date.getMonth() === month && date.getDate() === day;
});
}
function upcoming(limit) {
source.tick;
const now = Loc.nowMs();
return source.events.filter((event) => event.startMs >= now).slice(0, limit || source.events.length).map((event) => ({
"item": source.asAgendaItem(event),
"at": new Date(event.startMs)
}));
}
function hasOn(year, month, day) {
return source.forDay(year, month, day).length > 0;
}
function asAgendaItem(event) {
const date = new Date(event.startMs);
return {
"id": "thunderbird:" + event.id,
"name": event.name,
"calendar": event.calendar,
"source": "thunderbird",
"startMs": event.startMs,
"endMs": event.endMs,
"hour": date.getHours(),
"minute": date.getMinutes(),
"repeat": ""
};
}
Process {
id: reader
command: []
stdout: StdioCollector {
onStreamFinished: {
if (this.text.trim() === "")
return;
try {
const result = JSON.parse(this.text);
if (!result.error) {
source.events = result.events || [];
source.error = "";
source.updatedAt = Date.now();
source.tick++;
} else {
source.error = result.error;
}
} catch (e) {
source.error = "Could not read Thunderbird calendar cache";
}
}
}
onExited: (code) => {
if (code !== 0 && source.error === "")
source.error = "Could not read Thunderbird calendar cache";
}
}
Timer {
interval: 300000
repeat: true
running: true
triggeredOnStart: true
onTriggered: source.refresh()
}
}