aboutsummaryrefslogtreecommitdiff
path: root/linux/home/.config/ags/widget/datemenu
diff options
context:
space:
mode:
Diffstat (limited to 'linux/home/.config/ags/widget/datemenu')
-rw-r--r--linux/home/.config/ags/widget/datemenu/DateColumn.ts58
-rw-r--r--linux/home/.config/ags/widget/datemenu/DateMenu.ts36
-rw-r--r--linux/home/.config/ags/widget/datemenu/NotificationColumn.ts113
-rw-r--r--linux/home/.config/ags/widget/datemenu/datemenu.scss110
4 files changed, 317 insertions, 0 deletions
diff --git a/linux/home/.config/ags/widget/datemenu/DateColumn.ts b/linux/home/.config/ags/widget/datemenu/DateColumn.ts
new file mode 100644
index 0000000..a462302
--- /dev/null
+++ b/linux/home/.config/ags/widget/datemenu/DateColumn.ts
@@ -0,0 +1,58 @@
+import { clock, uptime } from 'lib/variables';
+import GLib from 'gi://GLib';
+import Gtk from 'gi://Gtk';
+
+function up(up: number) {
+ const h = Math.floor(up / 60);
+ const m = Math.floor(up % 60);
+ return `uptime: ${h}:${m < 10 ? '0' + m : m}`;
+}
+
+export default () =>
+ Widget.Box({
+ vertical: true,
+ class_name: 'date-column vertical',
+ children: [
+ Widget.Box({
+ class_name: 'clock-box',
+ vertical: true,
+ children: [
+ Widget.Label({
+ class_name: 'clock',
+ label: clock.bind().as(t => t.format('%H:%M')!),
+ }),
+ Widget.Label({
+ class_name: 'uptime',
+ label: uptime.bind().as(up),
+ }),
+ ],
+ }),
+ Widget.Box({
+ class_name: 'calendar',
+ children: [
+ (() => {
+ const calendar = Widget.Calendar({
+ hexpand: true,
+ hpack: 'center',
+ });
+
+ // Get today's date and mark it
+ const today = new Date();
+ calendar.select_day(today.getDate());
+ calendar.select_month(today.getMonth(), today.getFullYear());
+ calendar.mark_day(today.getDate()); // This should trigger styling
+
+ // Prevent scrolling from triggering GNOME Calendar
+ const eventBox = Widget.EventBox({
+ child: calendar,
+ onPrimaryClick: () => {
+ GLib.spawn_command_line_async('gnome-calendar');
+ },
+ });
+
+ return eventBox;
+ })(),
+ ],
+ }),
+ ],
+ });
diff --git a/linux/home/.config/ags/widget/datemenu/DateMenu.ts b/linux/home/.config/ags/widget/datemenu/DateMenu.ts
new file mode 100644
index 0000000..f7fdf6d
--- /dev/null
+++ b/linux/home/.config/ags/widget/datemenu/DateMenu.ts
@@ -0,0 +1,36 @@
+import PopupWindow from "widget/PopupWindow"
+import NotificationColumn from "./NotificationColumn"
+import DateColumn from "./DateColumn"
+import options from "options"
+
+const { bar, datemenu } = options
+const pos = bar.position.bind()
+const layout = Utils.derive([bar.position, datemenu.position], (bar, qs) =>
+ `${bar}-${qs}` as const,
+)
+
+const Settings = () => Widget.Box({
+ class_name: "datemenu horizontal",
+ vexpand: false,
+ children: [
+ NotificationColumn(),
+ Widget.Separator({ orientation: 1 }),
+ DateColumn(),
+ ],
+})
+
+const DateMenu = () => PopupWindow({
+ name: "datemenu",
+ exclusivity: "exclusive",
+ transition: pos.as(pos => pos === "top" ? "slide_down" : "slide_up"),
+ layout: layout.value,
+ child: Settings(),
+})
+
+export function setupDateMenu() {
+ App.addWindow(DateMenu())
+ layout.connect("changed", () => {
+ App.removeWindow("datemenu")
+ App.addWindow(DateMenu())
+ })
+}
diff --git a/linux/home/.config/ags/widget/datemenu/NotificationColumn.ts b/linux/home/.config/ags/widget/datemenu/NotificationColumn.ts
new file mode 100644
index 0000000..07d6829
--- /dev/null
+++ b/linux/home/.config/ags/widget/datemenu/NotificationColumn.ts
@@ -0,0 +1,113 @@
+import { type Notification as Notif } from "types/service/notifications"
+import Notification from "widget/notifications/Notification"
+import options from "options"
+import icons from "lib/icons"
+
+const notifications = await Service.import("notifications")
+const notifs = notifications.bind("notifications")
+
+const Animated = (n: Notif) => Widget.Revealer({
+ transition_duration: options.transition.value,
+ transition: "slide_down",
+ child: Notification(n),
+ setup: self => Utils.timeout(options.transition.value, () => {
+ if (!self.is_destroyed)
+ self.reveal_child = true
+ }),
+})
+
+const ClearButton = () => Widget.Button({
+ on_clicked: notifications.clear,
+ sensitive: notifs.as(n => n.length > 0),
+ child: Widget.Box({
+ children: [
+ Widget.Label("Clear "),
+ Widget.Icon({
+ icon: notifs.as(n => icons.trash[n.length > 0 ? "full" : "empty"]),
+ }),
+ ],
+ }),
+})
+
+const Header = () => Widget.Box({
+ class_name: "header",
+ children: [
+ Widget.Label({ label: "Notifications", hexpand: true, xalign: 0 }),
+ ClearButton(),
+ ],
+})
+
+const NotificationList = () => {
+ const map: Map<number, ReturnType<typeof Animated>> = new Map
+ const box = Widget.Box({
+ vertical: true,
+ children: notifications.notifications.map(n => {
+ const w = Animated(n)
+ map.set(n.id, w)
+ return w
+ }),
+ visible: notifs.as(n => n.length > 0),
+ })
+
+ function remove(_: unknown, id: number) {
+ const n = map.get(id)
+ if (n) {
+ n.reveal_child = false
+ Utils.timeout(options.transition.value, () => {
+ n.destroy()
+ map.delete(id)
+ })
+ }
+ }
+
+ return box
+ .hook(notifications, remove, "closed")
+ .hook(notifications, (_, id: number) => {
+ if (id !== undefined) {
+ if (map.has(id))
+ remove(null, id)
+
+ const n = notifications.getNotification(id)!
+
+ const w = Animated(n)
+ map.set(id, w)
+ box.children = [w, ...box.children]
+ }
+ }, "notified")
+}
+
+const Placeholder = () => Widget.Box({
+ class_name: "placeholder",
+ vertical: true,
+ vpack: "center",
+ hpack: "center",
+ vexpand: true,
+ hexpand: true,
+ visible: notifs.as(n => n.length === 0),
+ children: [
+ Widget.Icon(icons.notifications.silent),
+ Widget.Label("Your inbox is empty"),
+ ],
+})
+
+export default () => Widget.Box({
+ class_name: "notifications",
+ css: options.notifications.width.bind().as(w => `min-width: ${w}px`),
+ vertical: true,
+ children: [
+ Header(),
+ Widget.Scrollable({
+ vexpand: true,
+ hscroll: "never",
+ class_name: "notification-scrollable",
+ child: Widget.Box({
+ class_name: "notification-list vertical",
+ vertical: true,
+ children: [
+ NotificationList(),
+ Placeholder(),
+ ],
+ }),
+ }),
+ ],
+})
diff --git a/linux/home/.config/ags/widget/datemenu/datemenu.scss b/linux/home/.config/ags/widget/datemenu/datemenu.scss
new file mode 100644
index 0000000..6fd9257
--- /dev/null
+++ b/linux/home/.config/ags/widget/datemenu/datemenu.scss
@@ -0,0 +1,110 @@
+@import "../notifications/notifications.scss";
+
+@mixin calendar {
+ @include widget;
+ padding: $padding*2 $padding*2 0;
+
+ calendar {
+ all: unset;
+
+ &.button {
+ @include button($flat: true);
+ }
+
+ &:selected {
+ box-shadow: inset 0 -8px 0 0 transparentize($primary-bg, 0.5),
+ inset 0 0 0 1px $primary-bg;
+ border-radius: $radius*0.6;
+ }
+
+ &.header {
+ background-color: transparent;
+ border: none;
+ color: transparentize($fg, 0.5);
+ }
+
+ &.highlight {
+ background-color: transparent;
+ color: transparentize($primary-bg, 0.5);
+ }
+
+ &:indeterminate {
+ color: transparentize($fg, 0.9);
+ }
+
+ font-size: 1.1em;
+ padding: .2em;
+ }
+}
+
+window#datemenu .datemenu {
+ @include floating-widget;
+
+ .notifications {
+ .header {
+ margin-bottom: $spacing;
+ margin-right: $spacing;
+
+ >label {
+ margin-left: $radius * .5;
+ }
+
+ button {
+ @include button;
+ padding: $padding*.7 $padding;
+ }
+ }
+
+ .notification-scrollable {
+ @include scrollable($top: true, $bottom: true);
+ }
+
+ .notification-list {
+ margin-right: $spacing;
+ }
+
+ .notification {
+ @include notification;
+ @include widget;
+ padding: $padding;
+ margin-bottom: $spacing;
+ }
+
+ .placeholder {
+ image {
+ font-size: 7em;
+ }
+
+ label {
+ font-size: 1.2em;
+ }
+ }
+ }
+
+
+ separator {
+ background-color: $popover-border-color;
+ border-radius: $radius;
+ margin-right: $spacing;
+ }
+
+ .datemenu {
+ @include spacing;
+ }
+
+ .clock-box {
+ padding: $padding;
+
+ .clock {
+ font-size: 5em;
+ }
+
+ .uptime {
+ color: transparentize($fg, 0.2);
+ }
+ }
+
+ .calendar {
+ @include calendar;
+ }
+}