summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--scss/sidebar.scss164
-rw-r--r--src/modules/sidebar/modules/media.tsx39
2 files changed, 134 insertions, 69 deletions
diff --git a/scss/sidebar.scss b/scss/sidebar.scss
index 83d1953..9f72ca8 100644
--- a/scss/sidebar.scss
+++ b/scss/sidebar.scss
@@ -171,7 +171,7 @@
}
}
- .dashboard .media {
+ .media {
@include lib.spacing(15);
.cover-art {
@@ -316,91 +316,129 @@
}
}
- .audio .media {
- @include lib.spacing(40, true);
+ .players {
+ .player {
+ @include lib.spacing(40, true);
- .cover-art {
- @include lib.rounded(10);
- @include lib.element-decel;
- @include lib.shadow(scheme.$mantle, $blur: 5, $spread: 2);
+ .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);
- }
+ 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);
+ .progress {
+ margin: 0 lib.s(40);
- .slider {
- @include lib.rounded(8);
- @include lib.fluent-decel(1000ms);
+ .slider {
+ @include lib.rounded(8);
+ @include lib.fluent-decel(1000ms);
- min-height: lib.s(15);
- background-color: scheme.$overlay0;
- color: scheme.$subtext1;
- }
+ 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;
+ .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);
+ .details {
+ font-size: lib.s(14);
+ margin-top: lib.s(20);
- @include lib.spacing(3, true);
+ @include lib.spacing(3, true);
- .title {
- font-size: lib.s(18);
- color: scheme.$text;
- font-weight: bold;
- }
+ .title {
+ font-size: lib.s(18);
+ color: scheme.$text;
+ font-weight: bold;
+ }
- .artist {
- color: scheme.$green;
+ .artist {
+ color: scheme.$green;
+ }
+
+ .album {
+ color: scheme.$subtext0;
+ }
}
- .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);
+ }
}
}
- .controls {
- margin-top: lib.s(-20);
- margin-bottom: lib.s(5);
+ .indicators {
+ @include lib.spacing(10);
- button {
- @include media-button;
+ & > button {
+ @include lib.rounded(1000);
+ @include lib.element-decel;
- // Cause some nerd font icons don't have the correct width
- &.needs-adjustment {
- padding-right: lib.s(5);
+ min-width: lib.s(10);
+ min-height: lib.s(10);
+
+ background-color: color.change(scheme.$overlay0, $alpha: 0.5);
+
+ &:hover,
+ &:focus {
+ background-color: color.change(scheme.$overlay1, $alpha: 0.5);
}
- }
- .playback {
- font-size: lib.s(32);
+ &:active {
+ background-color: color.change(scheme.$overlay2, $alpha: 0.5);
+ }
- @include lib.spacing(40);
- }
+ &.active {
+ background-color: color.change(scheme.$primary, $alpha: 0.9);
- .options {
- margin: 0 lib.s(40);
- margin-top: lib.s(-10);
- font-size: lib.s(20);
+ &:hover,
+ &:focus {
+ background-color: color.change(scheme.$primary, $alpha: 0.7);
+ }
- @include lib.spacing(20);
+ &:active {
+ background-color: color.change(scheme.$primary, $alpha: 0.6);
+ }
+ }
}
}
}
diff --git a/src/modules/sidebar/modules/media.tsx b/src/modules/sidebar/modules/media.tsx
index 4392aa7..e14590e 100644
--- a/src/modules/sidebar/modules/media.tsx
+++ b/src/modules/sidebar/modules/media.tsx
@@ -1,6 +1,6 @@
import Players from "@/services/players";
import Slider from "@/widgets/slider";
-import { bind, Variable } from "astal";
+import { bind, timeout, Variable } from "astal";
import { Gtk } from "astal/gtk3";
import AstalMpris from "gi://AstalMpris";
@@ -12,7 +12,7 @@ const lengthStr = (length: number) =>
const noNull = (s: string | null) => s ?? "-";
const NoMedia = () => (
- <box vertical className="media" name="none">
+ <box vertical className="player" name="none">
<box homogeneous halign={Gtk.Align.CENTER} className="cover-art">
<label xalign={0.4} label="" />
</box>
@@ -50,7 +50,7 @@ const Player = ({ player }: { player: AstalMpris.Player }) => {
const position = Variable.derive([bind(player, "position"), bind(player, "length")], (p, l) => p / l);
return (
- <box vertical className="media" name={player.busName} onDestroy={() => position.drop()}>
+ <box vertical className="player" name={player.busName} onDestroy={() => position.drop()}>
<box
homogeneous
halign={Gtk.Align.CENTER}
@@ -131,19 +131,46 @@ const Player = ({ player }: { player: AstalMpris.Player }) => {
);
};
+const Indicator = ({ active, player }: { active: Variable<string>; player: AstalMpris.Player }) => (
+ <button
+ className={bind(active).as(a => (a === player.busName ? "active" : ""))}
+ cursor="pointer"
+ onClicked={() => active.set(player.busName)}
+ />
+);
+
export default () => {
- const active = Variable(Players.get_default().list[0]?.busName ?? "none");
+ const players = Players.get_default();
+ const active = Variable(players.lastPlayer?.busName ?? "none");
+
+ active.observe(players, "notify::list", () => {
+ const prev = active.get();
+ timeout(10, () => {
+ if (players.list.some(p => p.busName === prev)) active.set(prev);
+ else active.set(players.lastPlayer?.busName ?? "none");
+ });
+ return "none";
+ });
return (
- <box vertical>
+ <box vertical className="players" onDestroy={() => active.drop()}>
<stack
transitionType={Gtk.StackTransitionType.SLIDE_LEFT_RIGHT}
transitionDuration={150}
shown={bind(active)}
>
<NoMedia />
- {bind(Players.get_default(), "list").as(ps => ps.map(p => <Player player={p} />))}
+ {bind(players, "list").as(ps => ps.map(p => <Player player={p} />))}
</stack>
+ <revealer
+ transitionType={Gtk.RevealerTransitionType.SLIDE_DOWN}
+ transitionDuration={120}
+ revealChild={bind(players, "list").as(l => l.length > 1)}
+ >
+ <box halign={Gtk.Align.CENTER} className="indicators">
+ {bind(players, "list").as(ps => ps.map(p => <Indicator active={active} player={p} />))}
+ </box>
+ </revealer>
</box>
);
};