Update Boot Flash Screen
This commit is contained in:
+28
-6
@@ -16,6 +16,34 @@
|
||||
font-family: "JetBrainsMono Nerd Font", sans-serif;
|
||||
}
|
||||
|
||||
.media-cover {
|
||||
min-width: 64px;
|
||||
min-height: 64px;
|
||||
border-radius: 4px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
}
|
||||
|
||||
.media-info-box {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.media-title {
|
||||
color: @foreground;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.media-artist {
|
||||
color: @foreground;
|
||||
font-size: 13px;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.media-controls {
|
||||
/* Box spacing is handled by the component */
|
||||
}
|
||||
|
||||
.media-btn {
|
||||
color: @color5;
|
||||
font-size: 16px;
|
||||
@@ -26,9 +54,3 @@
|
||||
.media-btn:hover {
|
||||
color: @color4;
|
||||
}
|
||||
|
||||
.media-text {
|
||||
color: @foreground;
|
||||
font-size: 14px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
+60
-27
@@ -6,9 +6,22 @@ import { createPoll } from "ags/time"
|
||||
export default function Media(gdkmonitor: Gdk.Monitor) {
|
||||
const { TOP, LEFT } = Astal.WindowAnchor
|
||||
|
||||
// Poll playerctl for metadata and status
|
||||
const mediaInfo = createPoll("No Media Playing", 1000, 'sh -c "playerctl metadata -f \'{{title}} - {{artist}}\' 2>/dev/null || echo \'No Media Playing\'"')
|
||||
const statusIcon = createPoll("▶", 1000, 'sh -c "s=\\$(playerctl status 2>/dev/null); if [ \\"\\$s\\" = \\"Playing\\" ]; then echo \\"⏸\\"; else echo \\"▶\\"; fi"')
|
||||
// Poll playerctl for complete metadata and status in one go
|
||||
const mediaState = createPoll({
|
||||
title: "No Media",
|
||||
artist: "",
|
||||
artUrl: "",
|
||||
status: "Stopped"
|
||||
}, 1000, "playerctl metadata -f '{{title}}|||{{artist}}|||{{mpris:artUrl}}|||{{status}}' 2>/dev/null || echo 'No Media||||||Stopped'", (stdout) => {
|
||||
const parts = stdout.split("|||");
|
||||
const title = parts[0]?.trim() || "No Media";
|
||||
const artist = parts[1]?.trim() || "";
|
||||
// GTK supports raw paths better than file:// URIs in background-image CSS
|
||||
const rawUrl = parts[2]?.trim() || "";
|
||||
const artUrl = rawUrl.replace(/^file:\/\//, '');
|
||||
const status = parts[3]?.trim() || "Stopped";
|
||||
return { title, artist, artUrl, status };
|
||||
});
|
||||
|
||||
return (
|
||||
<window
|
||||
@@ -20,30 +33,50 @@ export default function Media(gdkmonitor: Gdk.Monitor) {
|
||||
margin={20}
|
||||
application={app}
|
||||
>
|
||||
<box class="media-container" spacing={10}>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl previous").catch(print)}
|
||||
halign={Gtk.Align.CENTER}
|
||||
>
|
||||
<label label="⏮" />
|
||||
</button>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl play-pause").catch(print)}
|
||||
halign={Gtk.Align.CENTER}
|
||||
>
|
||||
<label label={statusIcon} />
|
||||
</button>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl next").catch(print)}
|
||||
halign={Gtk.Align.CENTER}
|
||||
>
|
||||
<label label="⏭" />
|
||||
</button>
|
||||
<label class="media-text" label={mediaInfo} />
|
||||
<box class="media-container" spacing={15}>
|
||||
<box
|
||||
class="media-cover"
|
||||
css={mediaState.as(s => s.artUrl ? `background-image: url('${s.artUrl}');` : 'background-color: alpha(@color0, 0.5);')}
|
||||
/>
|
||||
|
||||
<box vertical class="media-info-box" valign={Gtk.Align.CENTER}>
|
||||
<label
|
||||
class="media-title"
|
||||
label={mediaState.as(s => s.title)}
|
||||
halign={Gtk.Align.START}
|
||||
truncate
|
||||
maxWidthChars={20}
|
||||
/>
|
||||
<label
|
||||
class="media-artist"
|
||||
label={mediaState.as(s => s.artist)}
|
||||
halign={Gtk.Align.START}
|
||||
truncate
|
||||
maxWidthChars={25}
|
||||
/>
|
||||
|
||||
<box class="media-controls" spacing={10} halign={Gtk.Align.START} marginTop={5}>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl previous").catch(print)}
|
||||
>
|
||||
<label label="" />
|
||||
</button>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl play-pause").catch(print)}
|
||||
>
|
||||
<label label={mediaState.as(s => s.status === "Playing" ? "" : "")} />
|
||||
</button>
|
||||
<button
|
||||
class="media-btn"
|
||||
onClicked={() => execAsync("playerctl next").catch(print)}
|
||||
>
|
||||
<label label="" />
|
||||
</button>
|
||||
</box>
|
||||
</box>
|
||||
</box>
|
||||
</window>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user