summaryrefslogtreecommitdiff
path: root/examples/js/simple-bar/widget/Bar.tsx
diff options
context:
space:
mode:
authorAylur <[email protected]>2024-09-07 20:05:52 +0000
committerAylur <[email protected]>2024-09-07 20:05:52 +0000
commit96757838fc1655ed9ad3118ae915c8cdf091fe35 (patch)
treea9cc9c8e19a145d039c9f9f188599ca7fe72fdce /examples/js/simple-bar/widget/Bar.tsx
parent639e92a2d35915aab8f7178be3fec7d099b16ee3 (diff)
add: js bar example
Diffstat (limited to 'examples/js/simple-bar/widget/Bar.tsx')
-rw-r--r--examples/js/simple-bar/widget/Bar.tsx130
1 files changed, 130 insertions, 0 deletions
diff --git a/examples/js/simple-bar/widget/Bar.tsx b/examples/js/simple-bar/widget/Bar.tsx
new file mode 100644
index 0000000..2b25258
--- /dev/null
+++ b/examples/js/simple-bar/widget/Bar.tsx
@@ -0,0 +1,130 @@
+import { Variable, Astal, Gtk, Gdk, GLib, bind } from "astal"
+import Hyprland from "gi://AstalHyprland"
+import Mpris from "gi://AstalMpris"
+import Battery from "gi://AstalBattery"
+import Wp from "gi://AstalWp"
+import Network from "gi://AstalNetwork"
+
+function Wifi() {
+ const { wifi } = Network.get_default()
+
+ return <icon
+ tooltipText={bind(wifi, "ssid").as(String)}
+ className="Wifi"
+ icon={bind(wifi, "iconName")}
+ />
+}
+
+function AudioSlider() {
+ const speaker = Wp.get_default_wp()?.audio.defaultSpeaker!
+
+ return <box className="AudioSlider" css="min-width: 140px">
+ <icon icon={bind(speaker, "volumeIcon")} />
+ <slider
+ hexpand
+ onDragged={({ value }) => speaker.volume = value}
+ value={bind(speaker, "volume")}
+ />
+ </box>
+}
+
+function BatteryLevel() {
+ const bat = Battery.get_default()
+
+ return <box className="Battery"
+ visible={bind(bat, "isPresent")}>
+ <icon icon={bind(bat, "iconName")} />
+ <label label={bind(bat, "percentage").as(p =>
+ `${Math.floor(p * 100)} %`
+ )} />
+ </box>
+}
+
+function Media() {
+ const player = Mpris.Player.new("spotify")
+
+ return <box className="Media">
+ <box
+ className="Cover"
+ valign={Gtk.Align.CENTER}
+ css={bind(player, "coverArt").as(cover =>
+ `background-image: url('${cover}');`
+ )}
+ />
+ <label
+ label={bind(player, "title").as(() =>
+ `${player.title} - ${player.artist}`
+ )}
+ />
+ </box>
+}
+
+function Workspaces() {
+ const hypr = Hyprland.get_default()
+
+ return <box className="Workspaces">
+ {bind(hypr, "workspaces").as(wss => wss
+ .sort((a, b) => a.id - b.id)
+ .map(ws => (
+ <button
+ className={bind(hypr, "focusedWorkspace").as(fw =>
+ ws === fw ? "focused" : "")}
+ onClicked={() => ws.focus()}>
+ {ws.id}
+ </button>
+ ))
+ )}
+ </box>
+}
+
+function FocusedClient() {
+ const hypr = Hyprland.get_default()
+ const focused = bind(hypr, "focusedClient")
+
+ return <box
+ className="Focused"
+ visible={focused.as(Boolean)}>
+ {focused.as(client => (
+ client && <label label={bind(client, "title").as(String)} />
+ ))}
+ </box>
+}
+
+function Time({ format = "%H:%M - %A %e." }) {
+ const time = Variable<string>("").poll(1000, () =>
+ GLib.DateTime.new_now_local().format(format)!)
+
+ return <label
+ className="Time"
+ onDestroy={() => time.drop()}
+ label={time()}
+ />
+}
+
+export default function Bar(monitor: Gdk.Monitor) {
+ const anchor = Astal.WindowAnchor.TOP
+ | Astal.WindowAnchor.LEFT
+ | Astal.WindowAnchor.RIGHT
+
+ return <window
+ className="Bar"
+ gdkmonitor={monitor}
+ exclusivity={Astal.Exclusivity.EXCLUSIVE}
+ anchor={anchor}>
+ <centerbox>
+ <box hexpand halign={Gtk.Align.START}>
+ <Workspaces />
+ <FocusedClient />
+ </box>
+ <box>
+ <Media />
+ </box>
+ <box hexpand halign={Gtk.Align.END} >
+ <Wifi />
+ <AudioSlider />
+ <BatteryLevel />
+ <Time />
+ </box>
+ </centerbox>
+ </window>
+}