From 17ddfc6fb1dc2ebb9b4ab0bbd3517ef7e1de97da Mon Sep 17 00:00:00 2001
From: 2 * r + 2 * t <61896496+soramanew@users.noreply.github.com>
Date: Wed, 26 Mar 2025 22:59:28 +1100
Subject: sidebar: media pane
---
scss/sidebar.scss | 223 ++++++++++++++++++++++------------
src/modules/sidebar/audio.tsx | 8 ++
src/modules/sidebar/index.tsx | 3 +-
src/modules/sidebar/modules/media.tsx | 149 +++++++++++++++++++++++
4 files changed, 306 insertions(+), 77 deletions(-)
create mode 100644 src/modules/sidebar/audio.tsx
create mode 100644 src/modules/sidebar/modules/media.tsx
diff --git a/scss/sidebar.scss b/scss/sidebar.scss
index 9bac679..83d1953 100644
--- a/scss/sidebar.scss
+++ b/scss/sidebar.scss
@@ -13,6 +13,57 @@
}
}
+@mixin button {
+ @include lib.element-decel;
+
+ background-color: color.change(scheme.$surface1, $alpha: 0.5);
+
+ &:hover,
+ &:focus {
+ background-color: color.change(scheme.$surface2, $alpha: 0.5);
+ }
+
+ &:active {
+ background-color: color.change(scheme.$overlay0, $alpha: 0.5);
+ }
+
+ &:disabled {
+ color: scheme.$subtext0;
+ }
+}
+
+@mixin button-active {
+ @include lib.element-decel;
+
+ background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 50%), $alpha: 0.5);
+
+ &:hover,
+ &:focus {
+ background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 30%), $alpha: 0.5);
+ }
+
+ &:active {
+ background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 20%), $alpha: 0.5);
+ }
+}
+
+@mixin media-button {
+ @include lib.element-decel;
+
+ &:disabled {
+ color: scheme.$overlay2;
+ }
+
+ &:hover,
+ &:focus {
+ color: color.mix(scheme.$subtext1, scheme.$subtext0, 50%);
+ }
+
+ &:active {
+ color: scheme.$subtext0;
+ }
+}
+
.sidebar {
@include font.mono;
@@ -155,21 +206,8 @@
margin-bottom: lib.s(5);
font-size: lib.s(24);
- & > * {
- @include lib.element-decel;
-
- &:disabled {
- color: scheme.$overlay0;
- }
-
- &:hover,
- &:focus {
- color: scheme.$subtext0;
- }
-
- &:active {
- color: scheme.$overlay2;
- }
+ & > button {
+ @include media-button;
}
}
@@ -219,20 +257,10 @@
@include lib.spacing;
& > button {
+ @include button;
@include lib.rounded(10);
- @include lib.element-decel;
padding: lib.s(5) lib.s(10);
- background-color: color.change(scheme.$surface1, $alpha: 0.5);
-
- &:hover,
- &:focus {
- background-color: color.change(scheme.$surface2, $alpha: 0.5);
- }
-
- &:active {
- background-color: color.change(scheme.$overlay0, $alpha: 0.5);
- }
}
}
}
@@ -288,6 +316,95 @@
}
}
+ .audio .media {
+ @include lib.spacing(40, true);
+
+ .cover-art {
+ @include lib.rounded(10);
+ @include lib.element-decel;
+ @include lib.shadow(scheme.$mantle, $blur: 5, $spread: 2);
+
+ background-position: center;
+ background-repeat: no-repeat;
+ background-size: cover;
+ min-width: lib.s(256);
+ min-height: lib.s(256);
+ font-size: lib.s(96);
+ font-weight: bold;
+ background-color: scheme.$base;
+ color: scheme.$subtext0;
+ margin-top: lib.s(20);
+ }
+
+ .progress {
+ margin: 0 lib.s(40);
+
+ .slider {
+ @include lib.rounded(8);
+ @include lib.fluent-decel(1000ms);
+
+ min-height: lib.s(15);
+ background-color: scheme.$overlay0;
+ color: scheme.$subtext1;
+ }
+
+ .time {
+ margin-top: lib.s(5);
+ font-size: lib.s(13);
+ color: scheme.$subtext1;
+ }
+ }
+
+ .details {
+ font-size: lib.s(14);
+ margin-top: lib.s(20);
+
+ @include lib.spacing(3, true);
+
+ .title {
+ font-size: lib.s(18);
+ color: scheme.$text;
+ font-weight: bold;
+ }
+
+ .artist {
+ color: scheme.$green;
+ }
+
+ .album {
+ color: scheme.$subtext0;
+ }
+ }
+
+ .controls {
+ margin-top: lib.s(-20);
+ margin-bottom: lib.s(5);
+
+ button {
+ @include media-button;
+
+ // Cause some nerd font icons don't have the correct width
+ &.needs-adjustment {
+ padding-right: lib.s(5);
+ }
+ }
+
+ .playback {
+ font-size: lib.s(32);
+
+ @include lib.spacing(40);
+ }
+
+ .options {
+ margin: 0 lib.s(40);
+ margin-top: lib.s(-10);
+ font-size: lib.s(20);
+
+ @include lib.spacing(20);
+ }
+ }
+ }
+
.networks {
.list {
@include lib.spacing(10, true);
@@ -305,16 +422,7 @@
background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 50%), $alpha: 0.4);
& > button {
- background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 50%), $alpha: 0.5);
-
- &:hover,
- &:focus {
- background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 30%), $alpha: 0.5);
- }
-
- &:active {
- background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 20%), $alpha: 0.5);
- }
+ @include button-active;
}
}
@@ -329,27 +437,13 @@
}
& > button {
+ @include button;
@include lib.rounded(1000);
- @include lib.element-decel;
@include font.icon;
font-size: lib.s(18);
min-width: lib.s(30);
min-height: lib.s(30);
- background-color: color.change(scheme.$surface1, $alpha: 0.5);
-
- &:hover,
- &:focus {
- background-color: color.change(scheme.$surface2, $alpha: 0.5);
- }
-
- &:active {
- background-color: color.change(scheme.$overlay0, $alpha: 0.5);
- }
-
- &:disabled {
- color: scheme.$subtext0;
- }
}
}
}
@@ -371,16 +465,7 @@
background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 50%), $alpha: 0.4);
& > button {
- background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 50%), $alpha: 0.5);
-
- &:hover,
- &:focus {
- background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 30%), $alpha: 0.5);
- }
-
- &:active {
- background-color: color.change(color.mix(scheme.$surface1, scheme.$primary, 20%), $alpha: 0.5);
- }
+ @include button-active;
}
}
@@ -395,27 +480,13 @@
}
& > button {
+ @include button;
@include lib.rounded(1000);
- @include lib.element-decel;
@include font.icon;
font-size: lib.s(18);
min-width: lib.s(30);
min-height: lib.s(30);
- background-color: color.change(scheme.$surface1, $alpha: 0.5);
-
- &:hover,
- &:focus {
- background-color: color.change(scheme.$surface2, $alpha: 0.5);
- }
-
- &:active {
- background-color: color.change(scheme.$overlay0, $alpha: 0.5);
- }
-
- &:disabled {
- color: scheme.$subtext0;
- }
}
}
}
diff --git a/src/modules/sidebar/audio.tsx b/src/modules/sidebar/audio.tsx
new file mode 100644
index 0000000..2b4c6e9
--- /dev/null
+++ b/src/modules/sidebar/audio.tsx
@@ -0,0 +1,8 @@
+import Media from "./modules/media";
+
+export default () => (
+
+
+
+
+);
diff --git a/src/modules/sidebar/index.tsx b/src/modules/sidebar/index.tsx
index 5b9a3a3..5ae7670 100644
--- a/src/modules/sidebar/index.tsx
+++ b/src/modules/sidebar/index.tsx
@@ -2,6 +2,7 @@ import type { Monitor } from "@/services/monitors";
import { bind, idle, register, Variable } from "astal";
import { App, Astal, Gdk, Gtk, Widget } from "astal/gtk3";
import { sidebar as config } from "config";
+import Audio from "./audio";
import Connectivity from "./connectivity";
import Dashboard from "./dashboard";
import NotifPane from "./notifpane";
@@ -21,7 +22,7 @@ export default class SideBar extends Widget.Window {
visible: false,
});
- const panes = [, , ];
+ const panes = [, , , ];
this.shown = Variable(panes[0].name);
this.add(
diff --git a/src/modules/sidebar/modules/media.tsx b/src/modules/sidebar/modules/media.tsx
new file mode 100644
index 0000000..4392aa7
--- /dev/null
+++ b/src/modules/sidebar/modules/media.tsx
@@ -0,0 +1,149 @@
+import Players from "@/services/players";
+import Slider from "@/widgets/slider";
+import { bind, Variable } from "astal";
+import { Gtk } from "astal/gtk3";
+import AstalMpris from "gi://AstalMpris";
+
+const lengthStr = (length: number) =>
+ `${Math.floor(length / 60)}:${Math.floor(length % 60)
+ .toString()
+ .padStart(2, "0")}`;
+
+const noNull = (s: string | null) => s ?? "-";
+
+const NoMedia = () => (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+);
+
+const Player = ({ player }: { player: AstalMpris.Player }) => {
+ const position = Variable.derive([bind(player, "position"), bind(player, "length")], (p, l) => p / l);
+
+ return (
+ position.drop()}>
+ `background-image: url("${a}");`)}
+ >
+ {bind(player, "coverArt").as(a => (a ? : ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ player.toggle_fullscreen()}
+ label={bind(player, "fullscreen").as(f => (f ? "" : ""))}
+ />
+ player.shuffle()}
+ label={bind(player, "shuffleStatus").as(s => (s === AstalMpris.Shuffle.ON ? "" : ""))}
+ />
+
+ player.loop()}
+ label={bind(player, "loopStatus").as(l =>
+ l === AstalMpris.Loop.TRACK ? "" : l === AstalMpris.Loop.PLAYLIST ? "" : ""
+ )}
+ />
+ player.raise()}
+ label=""
+ />
+
+
+
+ );
+};
+
+export default () => {
+ const active = Variable(Players.get_default().list[0]?.busName ?? "none");
+
+ return (
+
+
+
+ {bind(Players.get_default(), "list").as(ps => ps.map(p => ))}
+
+
+ );
+};
--
cgit v1.2.3-freya