summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scss/sidebar.scss9
-rw-r--r--src/modules/bar.tsx16
-rw-r--r--src/modules/sidebar/dashboard.tsx2
-rw-r--r--src/modules/sidebar/index.tsx35
-rw-r--r--src/modules/sidebar/modules/notifications.tsx28
-rw-r--r--src/modules/sidebar/modules/upcoming.tsx22
-rw-r--r--src/modules/sidebar/notifpane.tsx7
7 files changed, 94 insertions, 25 deletions
diff --git a/scss/sidebar.scss b/scss/sidebar.scss
index 249f516..8f4d6d7 100644
--- a/scss/sidebar.scss
+++ b/scss/sidebar.scss
@@ -73,6 +73,15 @@
}
}
+ .empty {
+ color: scheme.$subtext0;
+ font-size: lib.s(18);
+
+ .icon {
+ font-size: lib.s(48);
+ }
+ }
+
.user {
@include lib.spacing(15);
diff --git a/src/modules/bar.tsx b/src/modules/bar.tsx
index 85d2add..65a2727 100644
--- a/src/modules/bar.tsx
+++ b/src/modules/bar.tsx
@@ -1,3 +1,4 @@
+import type SideBar from "@/modules/sidebar";
import type { Monitor } from "@/services/monitors";
import Players from "@/services/players";
import Updates from "@/services/updates";
@@ -72,10 +73,19 @@ const togglePopup = (self: JSX.Element, event: Astal.ClickEvent, name: string) =
}
};
+const switchPane = (name: string) => {
+ const sidebar = App.get_window("sidebar") as SideBar | null;
+ if (sidebar) {
+ if (sidebar.visible && sidebar.shown.get() === name) sidebar.hide();
+ else sidebar.show();
+ sidebar.shown.set(name);
+ }
+};
+
const OSIcon = () => (
<button
className="module os-icon"
- onClick={(self, event) => event.button === Astal.MouseButton.PRIMARY && togglePopup(self, event, "sideleft")}
+ onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("dashboard")}
>
{osIcon}
</button>
@@ -446,9 +456,7 @@ const PkgUpdates = () => (
const NotifCount = () => (
<button
- onClick={(self, event) =>
- event.button === Astal.MouseButton.PRIMARY && togglePopup(self, event, "notifications")
- }
+ onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("notifpane")}
setup={self =>
setupCustomTooltip(
self,
diff --git a/src/modules/sidebar/dashboard.tsx b/src/modules/sidebar/dashboard.tsx
index 936502b..d1d1185 100644
--- a/src/modules/sidebar/dashboard.tsx
+++ b/src/modules/sidebar/dashboard.tsx
@@ -127,7 +127,7 @@ export default () => (
<Media player={p} />
))}
<box className="separator" />
- <Notifications />
+ <Notifications compact />
<box className="separator" />
<Upcoming />
</box>
diff --git a/src/modules/sidebar/index.tsx b/src/modules/sidebar/index.tsx
index 3b62d82..a908430 100644
--- a/src/modules/sidebar/index.tsx
+++ b/src/modules/sidebar/index.tsx
@@ -1,7 +1,8 @@
import type { Monitor } from "@/services/monitors";
import { bind, register, Variable } from "astal";
-import { App, Astal, Gtk, Widget } from "astal/gtk3";
+import { App, Astal, Gdk, Gtk, Widget } from "astal/gtk3";
import Dashboard from "./dashboard";
+import NotifPane from "./notifpane";
@register()
export default class SideBar extends Widget.Window {
@@ -18,17 +19,29 @@ export default class SideBar extends Widget.Window {
// visible: false,
});
+ const panes = [<Dashboard />, <NotifPane />];
+
this.add(
- <box vertical className="sidebar">
- <stack
- vexpand
- transitionType={Gtk.StackTransitionType.SLIDE_UP_DOWN}
- transitionDuration={200}
- shown={bind(this.shown)}
- >
- <Dashboard />
- </stack>
- </box>
+ <eventbox
+ onScroll={(_, event) => {
+ if (event.modifier & Gdk.ModifierType.BUTTON1_MASK) {
+ const index = panes.findIndex(p => p.name === this.shown.get()) + (event.delta_y < 0 ? -1 : 1);
+ if (index < 0 || index >= panes.length) return;
+ this.shown.set(panes[index].name);
+ }
+ }}
+ >
+ <box vertical className="sidebar">
+ <stack
+ vexpand
+ transitionType={Gtk.StackTransitionType.SLIDE_UP_DOWN}
+ transitionDuration={200}
+ shown={bind(this.shown)}
+ >
+ {panes}
+ </stack>
+ </box>
+ </eventbox>
);
}
}
diff --git a/src/modules/sidebar/modules/notifications.tsx b/src/modules/sidebar/modules/notifications.tsx
index eb8f0aa..9a9f440 100644
--- a/src/modules/sidebar/modules/notifications.tsx
+++ b/src/modules/sidebar/modules/notifications.tsx
@@ -3,7 +3,7 @@ import { bind } from "astal";
import { Astal, Gtk } from "astal/gtk3";
import AstalNotifd from "gi://AstalNotifd";
-const List = () => (
+const List = ({ compact }: { compact?: boolean }) => (
<box
vertical
valign={Gtk.Align.START}
@@ -13,7 +13,7 @@ const List = () => (
const map = new Map<number, Notification>();
const addNotification = (notification: AstalNotifd.Notification) => {
- const notif = (<Notification notification={notification} compact />) as Notification;
+ const notif = (<Notification notification={notification} compact={compact} />) as Notification;
notif.connect("destroy", () => map.get(notification.id) === notif && map.delete(notification.id));
map.get(notification.id)?.destroyWithAnims();
map.set(notification.id, notif);
@@ -42,7 +42,16 @@ const List = () => (
/>
);
-export default () => (
+const NoNotifs = () => (
+ <box homogeneous name="empty">
+ <box vertical halign={Gtk.Align.CENTER} valign={Gtk.Align.CENTER} className="empty">
+ <label className="icon" label="mark_email_unread" />
+ <label label="All caught up!" />
+ </box>
+ </box>
+);
+
+export default ({ compact }: { compact?: boolean }) => (
<box vertical className="notifications">
<box className="header-bar">
<label
@@ -63,8 +72,15 @@ export default () => (
label="󰎟 Clear"
/>
</box>
- <scrollable expand hscroll={Gtk.PolicyType.NEVER}>
- <List />
- </scrollable>
+ <stack
+ transitionType={Gtk.StackTransitionType.CROSSFADE}
+ transitionDuration={200}
+ shown={bind(AstalNotifd.get_default(), "notifications").as(n => (n.length > 0 ? "list" : "empty"))}
+ >
+ <NoNotifs />
+ <scrollable expand hscroll={Gtk.PolicyType.NEVER} name="list">
+ <List compact={compact} />
+ </scrollable>
+ </stack>
</box>
);
diff --git a/src/modules/sidebar/modules/upcoming.tsx b/src/modules/sidebar/modules/upcoming.tsx
index e2389e8..76dea56 100644
--- a/src/modules/sidebar/modules/upcoming.tsx
+++ b/src/modules/sidebar/modules/upcoming.tsx
@@ -61,6 +61,15 @@ const List = () => (
</box>
);
+const NoEvents = () => (
+ <box homogeneous name="empty">
+ <box vertical halign={Gtk.Align.CENTER} valign={Gtk.Align.CENTER} className="empty">
+ <label className="icon" label="calendar_month" />
+ <label label="No upcoming events" />
+ </box>
+ </box>
+);
+
export default () => (
<box vertical className="upcoming">
<box className="header-bar">
@@ -76,8 +85,15 @@ export default () => (
label="󰑓 Reload"
/>
</box>
- <scrollable className="list" hscroll={Gtk.PolicyType.NEVER}>
- <List />
- </scrollable>
+ <stack
+ transitionType={Gtk.StackTransitionType.CROSSFADE}
+ transitionDuration={200}
+ shown={bind(Calendar.get_default(), "numUpcoming").as(n => (n > 0 ? "list" : "empty"))}
+ >
+ <NoEvents />
+ <scrollable expand hscroll={Gtk.PolicyType.NEVER} name="list">
+ <List />
+ </scrollable>
+ </stack>
</box>
);
diff --git a/src/modules/sidebar/notifpane.tsx b/src/modules/sidebar/notifpane.tsx
new file mode 100644
index 0000000..79290e2
--- /dev/null
+++ b/src/modules/sidebar/notifpane.tsx
@@ -0,0 +1,7 @@
+import Notifications from "./modules/notifications";
+
+export default () => (
+ <box vertical className="pane notifpane" name="notifpane">
+ <Notifications />
+ </box>
+);