summaryrefslogtreecommitdiff
path: root/src/modules/bar.tsx
diff options
context:
space:
mode:
author2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-02 19:24:46 +1100
committer2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>2025-04-02 19:24:46 +1100
commitc131a0425ea551776abeedeb872c06d86f949909 (patch)
tree62fedb99213b2730a4a068e9dba00a86c1450a14 /src/modules/bar.tsx
parentbar: embedded style (diff)
downloadcaelestia-shell-c131a0425ea551776abeedeb872c06d86f949909.tar.gz
caelestia-shell-c131a0425ea551776abeedeb872c06d86f949909.tar.bz2
caelestia-shell-c131a0425ea551776abeedeb872c06d86f949909.zip
bar: refactor to use visible not replace
Also fix gap after workspaces on embedded style
Diffstat (limited to 'src/modules/bar.tsx')
-rw-r--r--src/modules/bar.tsx174
1 files changed, 84 insertions, 90 deletions
diff --git a/src/modules/bar.tsx b/src/modules/bar.tsx
index 9d65191..02fc609 100644
--- a/src/modules/bar.tsx
+++ b/src/modules/bar.tsx
@@ -9,7 +9,7 @@ import type { AstalWidget } from "@/utils/types";
import { setupCustomTooltip } from "@/utils/widgets";
import ScreenCorner from "@/widgets/screencorner";
import { execAsync, Variable } from "astal";
-import Binding, { bind, kebabify } from "astal/binding";
+import { bind, kebabify } from "astal/binding";
import { App, Astal, Gtk, type Widget } from "astal/gtk3";
import { bar as config } from "config";
import AstalBattery from "gi://AstalBattery";
@@ -84,6 +84,7 @@ const spacerClassName = ({ beforeSpacer, afterSpacer }: SpacerClassNameProps) =>
const OSIcon = (props: SpacerClassNameProps) => (
<button
+ visible={bind(config.modules.osIcon.enabled)}
className={`module os-icon ${spacerClassName(props)}`}
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("dashboard")}
>
@@ -93,6 +94,7 @@ const OSIcon = (props: SpacerClassNameProps) => (
const ActiveWindow = (props: SpacerClassNameProps) => (
<box
+ visible={bind(config.modules.activeWindow.enabled)}
vertical={bind(config.vertical)}
className={`module active-window ${spacerClassName(props)}`}
setup={self => {
@@ -138,6 +140,7 @@ const MediaPlaying = (props: SpacerClassNameProps) => {
players.lastPlayer ? `${players.lastPlayer.title} - ${players.lastPlayer.artist}` : fallback;
return (
<button
+ visible={bind(config.modules.mediaPlaying.enabled)}
onClick={(_, event) => {
if (event.button === Astal.MouseButton.PRIMARY) switchPane("audio");
else if (event.button === Astal.MouseButton.SECONDARY) players.lastPlayer?.play_pause();
@@ -221,6 +224,7 @@ const Workspace = ({ idx }: { idx: number }) => {
const Workspaces = (props: SpacerClassNameProps) => (
<eventbox
+ visible={bind(config.modules.workspaces.enabled)}
onScroll={(_, event) => {
const activeWs = hyprland.focusedClient?.workspace.name;
if (activeWs?.startsWith("special:")) hyprland.dispatch("togglespecialworkspace", activeWs.slice(8));
@@ -249,15 +253,23 @@ const TrayItem = (item: AstalTray.TrayItem) => (
</menubutton>
);
-const Tray = (props: SpacerClassNameProps) => (
- <box
- vertical={bind(config.vertical)}
- className={`module tray ${spacerClassName(props)}`}
- visible={bind(AstalTray.get_default(), "items").as(i => i.length > 0)}
- >
- {bind(AstalTray.get_default(), "items").as(i => i.map(TrayItem))}
- </box>
-);
+const Tray = (props: SpacerClassNameProps) => {
+ const visible = Variable.derive(
+ [config.modules.tray.enabled, bind(AstalTray.get_default(), "items")],
+ (e, i) => e && i.length > 0
+ );
+
+ return (
+ <box
+ visible={bind(visible)}
+ vertical={bind(config.vertical)}
+ className={`module tray ${spacerClassName(props)}`}
+ onDestroy={() => visible.drop()}
+ >
+ {bind(AstalTray.get_default(), "items").as(i => i.map(TrayItem))}
+ </box>
+ );
+};
const Network = () => (
<button
@@ -429,7 +441,11 @@ const Bluetooth = () => (
);
const StatusIcons = (props: SpacerClassNameProps) => (
- <box vertical={bind(config.vertical)} className={`module status-icons ${spacerClassName(props)}`}>
+ <box
+ visible={bind(config.modules.statusIcons.enabled)}
+ vertical={bind(config.vertical)}
+ className={`module status-icons ${spacerClassName(props)}`}
+ >
<Network />
<Bluetooth />
</box>
@@ -437,6 +453,7 @@ const StatusIcons = (props: SpacerClassNameProps) => (
const PkgUpdates = (props: SpacerClassNameProps) => (
<button
+ visible={bind(config.modules.pkgUpdates.enabled)}
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("packages")}
setup={self =>
setupCustomTooltip(
@@ -454,6 +471,7 @@ const PkgUpdates = (props: SpacerClassNameProps) => (
const NotifCount = (props: SpacerClassNameProps) => (
<button
+ visible={bind(config.modules.notifCount.enabled)}
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("notifpane")}
setup={self =>
setupCustomTooltip(
@@ -483,6 +501,10 @@ const NotifCount = (props: SpacerClassNameProps) => (
);
const Battery = (props: SpacerClassNameProps) => {
+ const visible = Variable.derive(
+ [config.modules.battery.enabled, bind(AstalBattery.get_default(), "isBattery")],
+ (e, i) => e && i
+ );
const className = Variable.derive(
[bind(AstalBattery.get_default(), "percentage"), bind(AstalBattery.get_default(), "charging")],
(p, c) => `module battery ${c ? "charging" : p < 0.2 ? "low" : ""} ${spacerClassName(props)}`
@@ -494,10 +516,12 @@ const Battery = (props: SpacerClassNameProps) => {
return (
<box
+ visible={bind(visible)}
vertical={bind(config.vertical)}
className={bind(className)}
setup={self => setupCustomTooltip(self, bind(tooltip))}
onDestroy={() => {
+ visible.drop();
className.drop();
tooltip.drop();
}}
@@ -508,44 +532,42 @@ const Battery = (props: SpacerClassNameProps) => {
);
};
-const DateTime = (props: SpacerClassNameProps) => (
- <button
- onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("time")}
- setup={self =>
- setupCustomTooltip(self, bindCurrentTime(bind(config.modules.dateTime.detailedFormat), undefined, self))
- }
- >
- <box className={`module date-time ${spacerClassName(props)}`}>
- <label className="icon" label="calendar_month" />
- <label
- setup={self =>
- self.hook(
- bindCurrentTime(bind(config.modules.dateTime.format), undefined, self),
- (_, t) => (self.label = t)
- )
- }
- />
- </box>
- </button>
+const DateTimeHoriz = (props: SpacerClassNameProps) => (
+ <box className={`module date-time ${spacerClassName(props)}`}>
+ <label className="icon" label="calendar_month" />
+ <label
+ setup={self => {
+ const time = bindCurrentTime(bind(config.modules.dateTime.format), undefined, self);
+ self.label = time.get();
+ self.hook(time, (_, t) => (self.label = t));
+ }}
+ />
+ </box>
);
const DateTimeVertical = (props: SpacerClassNameProps) => (
+ <box vertical className={`module date-time ${spacerClassName(props)}`}>
+ <label className="icon" label="calendar_month" />
+ <label label={bindCurrentTime("%H")} />
+ <label label={bindCurrentTime("%M")} />
+ </box>
+);
+
+const DateTime = (props: SpacerClassNameProps) => (
<button
+ visible={bind(config.modules.dateTime.enabled)}
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && switchPane("time")}
setup={self =>
setupCustomTooltip(self, bindCurrentTime(bind(config.modules.dateTime.detailedFormat), undefined, self))
}
>
- <box vertical className={`module date-time ${spacerClassName(props)}`}>
- <label className="icon" label="calendar_month" />
- <label label={bindCurrentTime("%H")} />
- <label label={bindCurrentTime("%M")} />
- </box>
+ {bind(config.vertical).as(v => (v ? <DateTimeVertical {...props} /> : <DateTimeHoriz {...props} />))}
</button>
);
const Power = (props: SpacerClassNameProps) => (
<button
+ visible={bind(config.modules.power.enabled)}
className={`module power ${spacerClassName(props)}`}
label="power_settings_new"
onClick={(_, event) => event.button === Astal.MouseButton.PRIMARY && App.toggle_window("session")}
@@ -562,13 +584,21 @@ const Spacer = ({ onScroll }: { onScroll: (self: Widget.EventBox, event: Astal.S
</eventbox>
);
-const Dummy = () => <box visible={false} />; // Invisible box cause otherwise shows as text
-
-const bindWidget = (module: keyof typeof config.modules, Widget: () => JSX.Element) =>
- bind(config.modules[module].enabled).as(e => (e ? <Widget /> : <Dummy />));
+const BrightnessSpacer = ({ monitor }: { monitor: Monitor }) => (
+ <Spacer onScroll={(_, event) => (event.delta_y > 0 ? (monitor.brightness -= 0.1) : (monitor.brightness += 0.1))} />
+);
-const bindCompositeWidget = (module: keyof typeof config.modules, binding: Binding<JSX.Element>) =>
- bind(Variable.derive([config.modules[module].enabled, binding], (e, w) => (e ? w : <Dummy />)));
+const VolumeSpacer = () => (
+ <Spacer
+ onScroll={(_, event) => {
+ const speaker = AstalWp.get_default()?.audio.defaultSpeaker;
+ if (!speaker) return console.error("Unable to connect to WirePlumber.");
+ speaker.mute = false;
+ if (event.delta_y > 0) speaker.volume -= 0.1;
+ else speaker.volume += 0.1;
+ }}
+ />
+);
const Bar = ({ monitor }: { monitor: Monitor }) => {
const className = Variable.derive(
@@ -579,57 +609,21 @@ const Bar = ({ monitor }: { monitor: Monitor }) => {
return (
<centerbox vertical={bind(config.vertical)} className={bind(className)} onDestroy={() => className.drop()}>
<box vertical={bind(config.vertical)}>
- {bindWidget("osIcon", () => (
- <OSIcon />
- ))}
- {bindWidget("activeWindow", () => (
- <ActiveWindow />
- ))}
- {bindWidget("mediaPlaying", () => (
- <MediaPlaying beforeSpacer />
- ))}
- <Spacer
- onScroll={(_, event) =>
- event.delta_y > 0 ? (monitor.brightness -= 0.1) : (monitor.brightness += 0.1)
- }
- />
+ <OSIcon />
+ <ActiveWindow />
+ <MediaPlaying beforeSpacer />
+ <BrightnessSpacer monitor={monitor} />
</box>
- {bindWidget("workspaces", () => (
- <Workspaces beforeSpacer afterSpacer />
- ))}
+ <Workspaces beforeSpacer afterSpacer />
<box vertical={bind(config.vertical)}>
- <Spacer
- onScroll={(_, event) => {
- const speaker = AstalWp.get_default()?.audio.defaultSpeaker;
- if (!speaker) return console.error("Unable to connect to WirePlumber.");
- speaker.mute = false;
- if (event.delta_y > 0) speaker.volume -= 0.1;
- else speaker.volume += 0.1;
- }}
- />
- {bindWidget("tray", () => (
- <Tray afterSpacer />
- ))}
- {bindWidget("statusIcons", () => (
- <StatusIcons />
- ))}
- {bindWidget("pkgUpdates", () => (
- <PkgUpdates />
- ))}
- {bindWidget("notifCount", () => (
- <NotifCount />
- ))}
- {bindCompositeWidget(
- "battery",
- bind(AstalBattery.get_default(), "isBattery").as(b => (b ? <Battery /> : <Dummy />))
- )}
- {bindCompositeWidget(
- "dateTime",
- bind(config.vertical).as(v => (v ? <DateTimeVertical /> : <DateTime />))
- )}
- {bindWidget("power", () => (
- <Power />
- ))}
+ <VolumeSpacer />
+ <Tray afterSpacer />
+ <StatusIcons />
+ <PkgUpdates />
+ <NotifCount />
+ <Battery />
+ <DateTime />
+ <Power />
</box>
</centerbox>
);