Add Ongoing to the Panama Daybook

This commit is contained in:
Gabriel Brown
2026-08-17 12:18:04 -04:00
parent 1ce5c732b7
commit a5450fdb6d
12 changed files with 483 additions and 47 deletions
@@ -0,0 +1,98 @@
pragma Singleton
// One presentation model for state that remains active until it is explicitly
// stopped or naturally completes. Transient confirmations stay in Signal Glass.
import Quickshell
import QtQuick
Singleton {
id: root
readonly property var activities: {
const result = [];
if (FocusSession.active) {
result.push({
kind: "focus",
glyph: "\u{F051F}",
label: "Focus session",
detail: (FocusSession.workspaceLabel || "Focused workspace") + " · " + FocusSession.statusText,
state: FocusSession.remainingText,
tone: FocusSession.paused ? "warn" : "accent",
action: FocusSession.paused ? "Resume" : "Pause"
});
}
if (Caffeine.enabled) {
result.push({
kind: "caffeine",
glyph: "\u{F0F2E}",
label: "Caffeine",
detail: "Automatic sleep is blocked",
state: "On",
tone: "ok",
action: "Turn off"
});
}
if (PrivacyState.recordingActive) {
result.push({
kind: "recording",
glyph: "\u{F044A}",
label: "Screen recording",
detail: "Panama · " + root.recordingElapsed,
state: "Live",
tone: "danger",
action: "Stop"
});
}
if (PrivacyState.screenSharingActive)
result.push(root.privacyActivity("screen", "\u{F0379}", "Screen sharing", PrivacyState.screenSharingApp));
if (PrivacyState.cameraActive)
result.push(root.privacyActivity("camera", "\u{F0100}", "Camera", PrivacyState.cameraApp));
if (PrivacyState.microphoneActive)
result.push(root.privacyActivity("microphone", "\u{F036C}", "Microphone", PrivacyState.microphoneApp));
return result;
}
readonly property int count: activities.length
readonly property string recordingElapsed: {
const total = Capture.recordingSeconds;
const seconds = String(total % 60).padStart(2, "0");
const minutes = Math.floor(total / 60) % 60;
const hours = Math.floor(total / 3600);
return hours > 0
? `${hours}:${String(minutes).padStart(2, "0")}:${seconds}`
: `${minutes}:${seconds}`;
}
function privacyActivity(kind: string, glyph: string, label: string, app: string): var {
return {
kind,
glyph,
label,
detail: app || "Managed by the application",
state: "In use",
tone: "warn",
action: ""
};
}
function activate(kind: string): void {
if (kind === "focus")
FocusSession.activateWorkspace();
else if (["recording", "screen", "camera", "microphone"].indexOf(kind) >= 0)
ShellState.open("activity");
}
function invoke(kind: string): void {
if (kind === "focus")
FocusSession.pauseOrResume();
else if (kind === "caffeine")
Caffeine.toggle();
else if (kind === "recording")
Capture.stopRecording();
}
}
@@ -138,6 +138,8 @@ Singleton {
root.applyStates(false, true, false, "", "Contract fixture", "", true);
else if (name === "screen-on")
root.applyStates(false, false, true, "", "", "Contract fixture", true);
else if (name === "all-on")
root.applyStates(true, true, true, "Contract fixture", "Contract fixture", "Contract fixture", true);
else if (name === "all-off")
root.applyStates(false, false, false, "", "", "", true);
}
@@ -35,8 +35,8 @@ Singleton {
readonly property bool anyOverlayOpen: activeOverlay !== ""
// The date menu is one surface with two deliberate entry points. The clock
// opens the Daybook; Super+B and notification actions open message history.
// The date menu keeps calendar context fixed while its right pane switches
// between the schedule, persistent activity and message history.
property string dateMenuPage: "agenda"
// 0 means "use the currently focused workspace". A positive value lets a
@@ -53,12 +53,12 @@ Singleton {
}
function openDateMenu(page: string): void {
root.dateMenuPage = page === "notifications" ? "notifications" : "agenda";
root.dateMenuPage = root.normalizedDateMenuPage(page);
root.activeOverlay = "notifications";
}
function toggleDateMenu(page: string): void {
const target = page === "notifications" ? "notifications" : "agenda";
const target = root.normalizedDateMenuPage(page);
if (root.activeOverlay === "notifications" && root.dateMenuPage === target) {
root.activeOverlay = "";
return;
@@ -67,6 +67,10 @@ Singleton {
root.activeOverlay = "notifications";
}
function normalizedDateMenuPage(page: string): string {
return ["agenda", "ongoing", "notifications"].indexOf(page) >= 0 ? page : "agenda";
}
function openOverview(workspaceId: int): void {
root.overviewWorkspaceId = Math.max(0, workspaceId);
root.overviewQuery = "";