summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-01-16 23:17:31 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-01-16 23:17:31 +1100
commit828da2ce9e88c6a0cc0c33f22f764c4283a1f651 (patch)
tree0d558f99f2615c87dd69c40f0cebdc4cfe73750a
parentbar: unread -> notif count (diff)
downloadcaelestia-shell-828da2ce9e88c6a0cc0c33f22f764c4283a1f651.tar.gz
caelestia-shell-828da2ce9e88c6a0cc0c33f22f764c4283a1f651.tar.bz2
caelestia-shell-828da2ce9e88c6a0cc0c33f22f764c4283a1f651.zip
base popdown window
-rw-r--r--scss/_lib.scss55
-rw-r--r--scss/notifications.scss49
-rw-r--r--scss/updates.scss43
-rw-r--r--src/modules/notifications.tsx56
-rw-r--r--src/modules/updates.tsx52
-rw-r--r--src/widgets/popdownwindow.tsx44
6 files changed, 143 insertions, 156 deletions
diff --git a/scss/_lib.scss b/scss/_lib.scss
index d2ad3d0..63bf618 100644
--- a/scss/_lib.scss
+++ b/scss/_lib.scss
@@ -1,5 +1,6 @@
@use "sass:color";
@use "scheme";
+@use "font";
$scale: 0.068rem;
@function s($value: 1) {
@@ -42,3 +43,57 @@ $scale: 0.068rem;
@mixin ease-in-out {
transition-timing-function: cubic-bezier(0.85, 0, 0.15, 1);
}
+
+@mixin popdown-window($colour) {
+ @include rounded(8);
+ @include border($colour, 0.4, 2);
+ @include shadow;
+ @include font.mono;
+
+ background-color: scheme.$base;
+ color: $colour;
+ padding: s(10) s(12);
+ font-size: s(14);
+
+ .header {
+ @include spacing(8);
+
+ padding: 0 s(5);
+ margin-bottom: s(8);
+ font-size: s(15);
+
+ button {
+ @include rounded(5);
+ @include element-decel;
+
+ padding: s(3) s(8);
+
+ &:hover,
+ &:focus {
+ background-color: scheme.$surface0;
+ }
+
+ &:active {
+ background-color: scheme.$surface1;
+ }
+
+ &.enabled {
+ background-color: $colour;
+ color: scheme.$base;
+
+ &:hover,
+ &:focus {
+ background-color: color.mix($colour, scheme.$base, 80%);
+ }
+
+ &:active {
+ background-color: color.mix($colour, scheme.$base, 70%);
+ }
+ }
+ }
+ }
+
+ .icon {
+ font-size: s(32);
+ }
+}
diff --git a/scss/notifications.scss b/scss/notifications.scss
index f9cb7ce..e955a4c 100644
--- a/scss/notifications.scss
+++ b/scss/notifications.scss
@@ -14,57 +14,10 @@
}
.notifications {
- @include lib.rounded(8);
- @include lib.border(scheme.$mauve, 0.4, 2);
- @include lib.shadow;
- @include font.mono;
+ @include lib.popdown-window(scheme.$mauve);
min-width: lib.s(400);
min-height: lib.s(600);
- background-color: scheme.$base;
- color: scheme.$mauve;
- padding: lib.s(10) lib.s(12);
-
- .header {
- @include lib.spacing(8);
-
- padding: 0 lib.s(5);
- margin-bottom: lib.s(8);
-
- button {
- @include lib.rounded(5);
- @include lib.element-decel;
-
- padding: lib.s(3) lib.s(8);
-
- &:hover,
- &:focus {
- background-color: scheme.$surface0;
- }
-
- &:active {
- background-color: scheme.$surface1;
- }
-
- &.enabled {
- background-color: scheme.$mauve;
- color: scheme.$base;
-
- &:hover,
- &:focus {
- background-color: color.mix(scheme.$mauve, scheme.$base, 80%);
- }
-
- &:active {
- background-color: color.mix(scheme.$mauve, scheme.$base, 70%);
- }
- }
- }
- }
-
- .icon {
- font-size: lib.s(32);
- }
.notification {
.wrapper {
diff --git a/scss/updates.scss b/scss/updates.scss
index 11f9a3e..12da977 100644
--- a/scss/updates.scss
+++ b/scss/updates.scss
@@ -3,60 +3,27 @@
@use "lib";
@use "font";
+$accent: scheme.$blue;
+
.updates {
- @include lib.rounded(8);
- @include lib.border(scheme.$blue, 0.4, 2);
- @include lib.shadow;
- @include font.mono;
+ @include lib.popdown-window($accent);
min-width: lib.s(600);
min-height: lib.s(400);
- background-color: scheme.$base;
- color: scheme.$blue;
- padding: lib.s(10) lib.s(12);
- font-size: lib.s(14);
.wrapper {
@include lib.element-decel;
&:hover,
&:focus {
- color: color.mix(scheme.$blue, scheme.$base, 80%);
+ color: color.mix($accent, scheme.$base, 80%);
}
&:active {
- color: color.mix(scheme.$blue, scheme.$base, 60%);
+ color: color.mix($accent, scheme.$base, 60%);
}
}
- .header {
- @include lib.spacing(8);
-
- padding: 0 lib.s(5);
- margin-bottom: lib.s(8);
- font-size: lib.s(15);
-
- button {
- @include lib.rounded(5);
- @include lib.element-decel;
-
- padding: lib.s(3) lib.s(8);
-
- &:hover,
- &:focus {
- background-color: scheme.$surface0;
- }
-
- &:active {
- background-color: scheme.$surface1;
- }
- }
- }
-
- .icon {
- font-size: lib.s(32);
- }
-
.repos {
@include lib.spacing($vertical: true);
diff --git a/src/modules/notifications.tsx b/src/modules/notifications.tsx
index 8b50a12..85747ce 100644
--- a/src/modules/notifications.tsx
+++ b/src/modules/notifications.tsx
@@ -2,7 +2,7 @@ import { bind } from "astal";
import { Astal, Gtk } from "astal/gtk3";
import AstalNotifd from "gi://AstalNotifd";
import Notification from "../widgets/notification";
-import PopupWindow from "../widgets/popupwindow";
+import PopdownWindow from "../widgets/popdownwindow";
const List = () => (
<box
@@ -44,40 +44,22 @@ const List = () => (
);
export default () => (
- <PopupWindow name="notifications">
- <box vertical className="notifications">
- <box className="header">
- <label
- label={bind(AstalNotifd.get_default(), "notifications").as(
- n => `${n.length} notification${n.length === 1 ? "" : "s"}`
- )}
- />
- <box hexpand />
- <button
- cursor="pointer"
- onClicked={() => (AstalNotifd.get_default().dontDisturb = !AstalNotifd.get_default().dontDisturb)}
- label="Silence"
- className={bind(AstalNotifd.get_default(), "dontDisturb").as(d => (d ? "enabled" : ""))}
- />
- <button
- cursor="pointer"
- onClicked={() => AstalNotifd.get_default().notifications.forEach(n => n.dismiss())}
- label="Clear"
- />
- </box>
- <stack
- transitionType={Gtk.StackTransitionType.CROSSFADE}
- transitionDuration={150}
- shown={bind(AstalNotifd.get_default(), "notifications").as(n => (n.length > 0 ? "list" : "empty"))}
- >
- <box vertical valign={Gtk.Align.CENTER} name="empty">
- <label className="icon" label="notifications_active" />
- <label label="All caught up!" />
- </box>
- <scrollable expand hscroll={Gtk.PolicyType.NEVER} name="list">
- <List />
- </scrollable>
- </stack>
- </box>
- </PopupWindow>
+ <PopdownWindow
+ name="notifications"
+ count={bind(AstalNotifd.get_default(), "notifications").as(n => n.length)}
+ headerButtons={[
+ {
+ label: "Silence",
+ onClicked: () => (AstalNotifd.get_default().dontDisturb = !AstalNotifd.get_default().dontDisturb),
+ className: bind(AstalNotifd.get_default(), "dontDisturb").as(d => (d ? "enabled" : "")),
+ },
+ {
+ label: "Clear",
+ onClicked: () => AstalNotifd.get_default().notifications.forEach(n => n.dismiss()),
+ },
+ ]}
+ emptyIcon="notifications_active"
+ emptyLabel="All caught up!"
+ list={<List />}
+ />
);
diff --git a/src/modules/updates.tsx b/src/modules/updates.tsx
index 0a8cbea..feaa3cd 100644
--- a/src/modules/updates.tsx
+++ b/src/modules/updates.tsx
@@ -2,7 +2,7 @@ import { bind, execAsync, Variable } from "astal";
import { App, Astal, Gtk } from "astal/gtk3";
import Updates, { Repo as IRepo, Update as IUpdate } from "../services/updates";
import { MenuItem } from "../utils/widgets";
-import PopupWindow from "../widgets/popupwindow";
+import PopdownWindow from "../widgets/popdownwindow";
const constructItem = (label: string, exec: string, quiet = true) =>
new MenuItem({
@@ -67,36 +67,22 @@ const List = () => (
);
export default () => (
- <PopupWindow name="updates">
- <box vertical className="updates">
- <box className="header">
- <label label={bind(Updates.get_default(), "numUpdates").as(n => `${n} update${n === 1 ? "" : "s"}`)} />
- <box hexpand />
- <button
- cursor="pointer"
- onClicked={() =>
- execAsync("uwsm app -T -- yay")
- .then(() => Updates.get_default().getUpdates())
- // Ignore errors
- .catch(() => {})
- }
- label="Update all"
- />
- <button cursor="pointer" onClicked={() => Updates.get_default().getUpdates()} label="Reload" />
- </box>
- <stack
- transitionType={Gtk.StackTransitionType.CROSSFADE}
- transitionDuration={150}
- shown={bind(Updates.get_default(), "numUpdates").as(n => (n > 0 ? "list" : "empty"))}
- >
- <box vertical valign={Gtk.Align.CENTER} name="empty">
- <label className="icon" label="deployed_code_history" />
- <label label="All packages up to date!" />
- </box>
- <scrollable expand hscroll={Gtk.PolicyType.NEVER} name="list">
- <List />
- </scrollable>
- </stack>
- </box>
- </PopupWindow>
+ <PopdownWindow
+ name="updates"
+ count={bind(Updates.get_default(), "numUpdates")}
+ headerButtons={[
+ {
+ label: "Update all",
+ onClicked: () =>
+ execAsync("uwsm app -T -- yay")
+ .then(() => Updates.get_default().getUpdates())
+ // Ignore errors
+ .catch(() => {}),
+ },
+ { label: "Reload", onClicked: () => Updates.get_default().getUpdates() },
+ ]}
+ emptyIcon="deployed_code_history"
+ emptyLabel="All packages up to date!"
+ list={<List />}
+ />
);
diff --git a/src/widgets/popdownwindow.tsx b/src/widgets/popdownwindow.tsx
new file mode 100644
index 0000000..8710a59
--- /dev/null
+++ b/src/widgets/popdownwindow.tsx
@@ -0,0 +1,44 @@
+import type { Binding } from "astal";
+import { Gtk } from "astal/gtk3";
+import PopupWindow from "./popupwindow";
+
+export default ({
+ name,
+ count,
+ headerButtons,
+ emptyIcon,
+ emptyLabel,
+ list,
+}: {
+ name: string;
+ count: Binding<number>;
+ headerButtons: { label: string; onClicked: () => void; className?: Binding<string> }[];
+ emptyIcon: string;
+ emptyLabel: string;
+ list: JSX.Element;
+}) => (
+ <PopupWindow name={name}>
+ <box vertical className={name}>
+ <box className="header">
+ <label label={count.as(c => `${c} ${name.slice(0, -1)}${c === 1 ? "" : "s"}`)} />
+ <box hexpand />
+ {headerButtons.map(({ label, onClicked, className }) => (
+ <button cursor="pointer" onClicked={onClicked} label={label} className={className} />
+ ))}
+ </box>
+ <stack
+ transitionType={Gtk.StackTransitionType.CROSSFADE}
+ transitionDuration={150}
+ shown={count.as(c => (c > 0 ? "list" : "empty"))}
+ >
+ <box vertical valign={Gtk.Align.CENTER} name="empty">
+ <label className="icon" label={emptyIcon} />
+ <label label={emptyLabel} />
+ </box>
+ <scrollable expand hscroll={Gtk.PolicyType.NEVER} name="list">
+ {list}
+ </scrollable>
+ </stack>
+ </box>
+ </PopupWindow>
+);