diff --git a/flake.nix b/flake.nix index bc26fb4..04dd0b7 100644 --- a/flake.nix +++ b/flake.nix @@ -30,6 +30,7 @@ network notifd wireplumber + cava ]; extraPackages = diff --git a/style/_bar.scss b/style/_bar.scss index f2e10f7..3d1c30d 100644 --- a/style/_bar.scss +++ b/style/_bar.scss @@ -104,4 +104,8 @@ window.Bar { border-radius: 10px; } } + + .cava { + color: $accent; + } } diff --git a/widgets/bar/cava.tsx b/widgets/bar/cava.tsx new file mode 100644 index 0000000..d81acf5 --- /dev/null +++ b/widgets/bar/cava.tsx @@ -0,0 +1,49 @@ +import AstalCava from "gi://AstalCava"; +import { createState } from "ags"; + +const blocks = [ + "\u2581", + "\u2582", + "\u2583", + "\u2584", + "\u2585", + "\u2586", + "\u2587", + "\u2588", +]; + +const CAVA_BARS = 14; + +export const Cava = () => { + const cava = AstalCava.get_default()!; + cava.set_bars(CAVA_BARS); + + const [visible, setVisible] = createState(false); + const [visuals, setVisuals] = createState(""); + + cava.connect("notify::values", ({ values }) => { + const isVisible = shouldVisualize(CAVA_BARS, values); + if (isVisible) { + setVisible(true); + setVisuals( + values + .map( + (val) => blocks[Math.min(Math.floor(val * 8), blocks.length - 1)], + ) + .join(""), + ); + } else { + setVisible(false); + } + }); + + return ( + + + ); +}; + +const shouldVisualize = (bars: number, values: number[]): boolean => { + return !(bars === 0 || values.length === 0 || values.every((v) => v < 0.001)); +}; diff --git a/widgets/bar/index.tsx b/widgets/bar/index.tsx index b17aab7..10cdba1 100644 --- a/widgets/bar/index.tsx +++ b/widgets/bar/index.tsx @@ -7,6 +7,7 @@ import { Time } from "./time"; import { Tray } from "./tray"; import { WorkspaceButton } from "./workspace"; import { Bluetooth } from "./bluetooth"; +import { Cava } from "./cava"; export const WINDOW_NAME = "bar"; @@ -32,7 +33,9 @@ export const Bar = (gdkmonitor: Gdk.Monitor) => { + +