This commit is contained in:
Benjamin Palko 2025-06-13 17:21:59 -04:00
parent 23f28f03fe
commit e62a7afa60
5 changed files with 141 additions and 66 deletions

View file

@ -1,15 +1,16 @@
import { App, Astal, Gdk, Gtk } from "astal/gtk4";
import Bluetooth from "./Bluetooth";
import Calendar from "./Calendar";
import Hyprland from "./Hyprland";
import Workspaces from "./Hyprland/workspaces";
import Internet from "./Internet";
import Memory from "./Memory";
import Mpris from "./Mpris";
import OS from "./OS";
import Pywal from "./Pywal";
import Tray from "./Tray";
import SwayNC from "./SwayNC";
import Tray from "./Tray";
import WirePlumber from "./WirePlumber";
import Memory from "./Memory";
import Workspaces from "./Hyprland/workspaces";
export default function Bar(gdkmonitor: Gdk.Monitor) {
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor;
@ -37,6 +38,7 @@ export default function Bar(gdkmonitor: Gdk.Monitor) {
<Pywal />
<WirePlumber />
<Internet />
<Bluetooth />
<Memory />
<Calendar />
<SwayNC />

48
widget/Bluetooth.tsx Normal file
View file

@ -0,0 +1,48 @@
import { Binding } from "astal";
import { bind, derive } from "astal";
import AstalBluetooth from "gi://AstalBluetooth";
const DeviceList = function ({
devices,
}: {
devices: Binding<AstalBluetooth.Device[]>;
}) {
return (
<box vertical>
{devices.as((devices) => {
return devices.map((device) => {
const name = bind(device, "name");
const connected = bind(device, "connected");
return (
<button
label={bind(
derive(
[name, connected],
(name, connected) => `${connected ? "󰂱" : ""} ${name}`,
),
)}
/>
);
});
})}
</box>
);
};
const Bluetooth = function () {
const bluetooth = AstalBluetooth.get_default();
const devices = bind(bluetooth, "devices");
return (
<menubutton>
<label label={"󰂯"} />
<popover>
<DeviceList devices={devices} />
</popover>
</menubutton>
);
};
export default Bluetooth;

View file

@ -4,81 +4,81 @@ import AstalMpris from "gi://AstalMpris";
import { Mathf } from "../util/Mathf";
function IntegerToMinuteSeconds(value: number) {
const minutes = Math.floor(value / 60);
const seconds = Math.floor(value - minutes * 60);
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
const minutes = Math.floor(value / 60);
const seconds = Math.floor(value - minutes * 60);
return `${String(minutes).padStart(2, "0")}:${String(seconds).padStart(2, "0")}`;
}
function FormatLabel(player: {
title: string;
artist: string;
position: number;
length: number;
status: AstalMpris.PlaybackStatus;
title: string;
artist: string;
position: number;
length: number;
status: AstalMpris.PlaybackStatus;
}) {
return `${player.status === AstalMpris.PlaybackStatus.PLAYING ? "" : ""} ${player.title} - ${player.artist} [${IntegerToMinuteSeconds(player.position)}/${IntegerToMinuteSeconds(player.length)}]`;
return `${player.status === AstalMpris.PlaybackStatus.PLAYING ? "" : ""} ${player.title} - ${player.artist} [${IntegerToMinuteSeconds(player.position)}/${IntegerToMinuteSeconds(player.length)}]`;
}
const Mpris = function () {
const mpris = AstalMpris.get_default();
const mpris = AstalMpris.get_default();
const players = bind(mpris, "players");
const activeIndex = Variable(0);
const players = bind(mpris, "players");
const activeIndex = Variable(0);
bind(
derive([players, activeIndex], (players, index) => players[index]),
).subscribe((value) => print(value.title));
bind(
derive([players, activeIndex], (players, index) => players[index]),
).subscribe((value) => print(value.title));
return (
<box>
{bind(
derive([players, activeIndex], (players, index) => {
const activePlayer = players[index];
return (
<box>
{bind(
derive([players, activeIndex], (players, index) => {
const activePlayer = players[index];
if (!activePlayer) {
return <></>;
}
if (!activePlayer) {
return <></>;
}
return (
<button
cursor={Gdk.Cursor.new_from_name("pointer", null)}
onClicked={() =>
activePlayer.playbackStatus ===
AstalMpris.PlaybackStatus.PLAYING
? activePlayer.pause()
: activePlayer.play()
}
onScroll={(_, __, dy) => {
activeIndex.set(
Mathf.clamp(
activeIndex.get() - Mathf.sign(dy),
0,
players.length - 1,
),
);
}}
>
<label
label={bind(
derive(
[
bind(activePlayer, "title"),
bind(activePlayer, "artist"),
bind(activePlayer, "position"),
bind(activePlayer, "length"),
bind(activePlayer, "playback_status"),
],
(title, artist, position, length, status) =>
FormatLabel({ title, artist, position, length, status }),
),
)}
/>
</button>
);
}),
)}
</box>
);
return (
<button
cursor={Gdk.Cursor.new_from_name("pointer", null)}
onClicked={() =>
activePlayer.playbackStatus ===
AstalMpris.PlaybackStatus.PLAYING
? activePlayer.pause()
: activePlayer.play()
}
onScroll={(_, __, dy) => {
activeIndex.set(
Mathf.clamp(
activeIndex.get() - Mathf.sign(dy),
0,
players.length - 1,
),
);
}}
>
<label
label={bind(
derive(
[
bind(activePlayer, "title"),
bind(activePlayer, "artist"),
bind(activePlayer, "position"),
bind(activePlayer, "length"),
bind(activePlayer, "playback_status"),
],
(title, artist, position, length, status) =>
FormatLabel({ title, artist, position, length, status }),
),
)}
/>
</button>
);
}),
)}
</box>
);
};
export default Mpris;

14
widget/Notifications.tsx Normal file
View file

@ -0,0 +1,14 @@
import { Gdk, Gtk } from "astal/gtk4";
const Notifications = function () {
return (
<menubutton hexpand halign={Gtk.Align.END}>
<label cursor={Gdk.Cursor.new_from_name("pointer", null)} label={""} />
<popover>
<Gtk.Grid></Gtk.Grid>
</popover>
</menubutton>
);
};
export default Notifications;

View file

@ -2,6 +2,16 @@ import { bind } from "astal";
import { Gdk } from "astal/gtk4";
import AstalTray from "gi://AstalTray";
const TrayItemPopover = function ({ item }: { item: AstalTray.TrayItem }) {
const actionGroup = bind(item, "actionGroup");
return (
<popover>
<box>{actionGroup.get()}</box>
</popover>
);
};
const Tray = function () {
const tray = AstalTray.get_default();
@ -19,6 +29,7 @@ const Tray = function () {
(iconName) => iconName || "NONE",
)}
/>
<TrayItemPopover item={item} />
</menubutton>
);
}),