import { createBinding, For } from "ags";
import { register } from "ags/gobject";
import { Astal, Gtk } from "ags/gtk4";
import { Clipboard } from "../../../modules/clipboard";
import { pathToURI, variableToBoolean } from "../../../modules/utils";
import { tr } from "../../../i18n/intl";
import Media from "../../../modules/media";
import AstalMpris from "gi://AstalMpris";
import Pango from "gi://Pango?version=1.0";
import Adw from "gi://Adw?version=1";
import GLib from "gi://GLib?version=2.0";
export const BigMedia = () => {
const availablePlayers = createBinding(AstalMpris.get_default(), "players").as(pls =>
pls.filter(p => p.available));
const carousel = {
const page = self.get_nth_page(num);
if(page instanceof PlayerWidget && Media.getDefault().player.busName !== page.player.busName)
Media.getDefault().player = page.player;
}}>
players.sort(pl =>
pl.busName === Media.getDefault().player.busName ? -1 : 1))}>
{(player: AstalMpris.Player) => }
as Adw.Carousel;
return
{carousel}
pls.length > 1)} transitionDuration={300}
transitionType={Gtk.RevealerTransitionType.SLIDE_UP}>
as Gtk.Box;
}
@register({ GTypeName: "PlayerWidget" })
class PlayerWidget extends Gtk.Box {
#player!: AstalMpris.Player;
#copyClickTimeout?: GLib.Source;
#dragTimer?: GLib.Source;
get player() { return this.#player; }
constructor({ player }: { player: AstalMpris.Player }) {
super();
this.setPlayer(player);
this.set_orientation(Gtk.Orientation.VERTICAL);
this.set_hexpand(true);
this.append(
`background-image: url("${pathToURI(art)}");`)}
hexpand={false} vexpand={false} widthRequest={132} heightRequest={128}
valign={Gtk.Align.START} halign={Gtk.Align.CENTER}
/>
as Gtk.Revealer
);
this.append(
title ?? tr("media.no_title"))
} label={
createBinding(player, "title").as(title => title ?? tr("media.no_title"))
} ellipsize={Pango.EllipsizeMode.END} maxWidthChars={25}
/>
artist ?? tr("media.no_artist"))
} label={
createBinding(player, "artist").as(artist => artist ?? tr("media.no_artist"))
} ellipsize={Pango.EllipsizeMode.END} maxWidthChars={28}
/>
as Gtk.Box
);
this.append(
{
if(type == null) return;
if(!this.#dragTimer) {
this.#dragTimer = setTimeout(() =>
player.position = Math.floor(value)
, 200);
return;
}
this.#dragTimer?.destroy();
this.#dragTimer = setTimeout(() =>
player.position = Math.floor(value)
, 200);
}}
/>
as Gtk.Box
);
this.append(
{
const sec = Math.floor(pos % 60);
return pos > 0 && player.length > 0 ?
`${Math.floor(pos / 60)}:${sec < 10 ? "0" : ""}${sec}`
: "0:00";
})} $type="start"
/>
status !== AstalMpris.Shuffle.UNSUPPORTED)} iconName={
createBinding(player, "shuffleStatus").as(status => status === AstalMpris.Shuffle.ON ?
"media-playlist-shuffle-symbolic"
: "media-playlist-consecutive-symbolic")} tooltipText={
createBinding(player, "shuffleStatus").as(status => status === AstalMpris.Shuffle.ON ?
tr("media.shuffle")
: tr("media.follow_order"))} onClicked={() => player.shuffle()}
/>
player.canGoPrevious && player.previous()}
/>
status === AstalMpris.PlaybackStatus.PLAYING ? tr("media.pause") : tr("media.play"))}
iconName={createBinding(player, "playbackStatus").as(status =>
status === AstalMpris.PlaybackStatus.PLAYING ?
"media-playback-pause-symbolic"
: "media-playback-start-symbolic")} onClicked={() => player.play_pause()}
/>
player.canGoNext && player.next()}
/>
{
if(status === AstalMpris.Loop.TRACK)
return "media-playlist-repeat-song-symbolic";
if(status === AstalMpris.Loop.PLAYLIST)
return "media-playlist-repeat-symbolic";
return "loop-arrow-symbolic";
})} visible={createBinding(player, "loopStatus").as(status =>
status !== AstalMpris.Loop.UNSUPPORTED)}
tooltipText={createBinding(player, "loopStatus").as(status => {
if(status === AstalMpris.Loop.TRACK)
return tr("media.song_loop");
if(status === AstalMpris.Loop.PLAYLIST)
return tr("media.loop");
return tr("media.no_loop");
})} onClicked={() => player.loop()}
/>
{ /* bananananananana */
const sec = Math.floor(len % 60);
return (len > 0 && Number.isFinite(len)) ?
`${Math.floor(len / 60)}:${sec < 10 ? "0" : ""}${sec}`
: "0:00";
})} $type="end"
/>
as Gtk.CenterBox
);
}
setPlayer(player: AstalMpris.Player) {
this.#player = player;
}
}