nixos-configs/config/ags/js/media-player/player.js

163 lines
3.8 KiB
JavaScript

const { Mpris } = ags.Service;
const { Box, CenterBox, Label, Stack, EventBox } = ags.Widget;
const { Gtk } = imports.gi;
import * as mpris from './mpris.js';
import { Separator } from '../misc/separator.js';
const Top = player => Box({
className: 'top',
halign: 'start',
valign: 'start',
children: [
mpris.PlayerIcon(player, {
symbolic: false,
}),
],
});
const Center = player => Box({
className: 'center',
children: [
CenterBox({
vertical: true,
children: [
Box({
className: 'metadata',
vertical: true,
halign: 'start',
valign: 'center',
hexpand: true,
children: [
mpris.TitleLabel(player),
mpris.ArtistLabel(player),
],
}),
Label(),
Label(),
],
}),
CenterBox({
vertical: true,
children: [
Label(),
mpris.PlayPauseButton(player),
Label(),
],
}),
],
});
const Bottom = player => Box({
className: 'bottom',
children: [
mpris.PreviousButton(player, {
valign: 'end',
halign: 'start',
}),
Separator(8),
mpris.PositionSlider(player),
Separator(8),
mpris.NextButton(player),
Separator(8),
mpris.ShuffleButton(player),
Separator(8),
mpris.LoopButton(player),
],
});
const PlayerBox = player => mpris.CoverArt(player, {
className: `player ${player.name}`,
hexpand: true,
children: [
Top(player),
Center(player),
Bottom(player),
],
});
export default () => {
let widget = EventBox();
let gesture = Gtk.GestureDrag.new(widget)
widget.child = Stack({
className: 'media',
properties: [
['players', new Map()],
['previous', 'spotify'],
],
connections: [
[gesture, stack => {
const offset = gesture.get_offset()[1];
if (Math.abs(offset) > 200) {
let players = [];
stack._players.forEach((_, busName) => players.push(Mpris.getPlayer(busName).name));
let current = players.findIndex(player => player === stack.shown);
if (offset > 0) {
stack.transition = 'slide_right';
if (players[++current])
stack.shown = `${players[current]}`;
else
stack.shown = `${players[0]}`;
}
else {
stack.transition = 'slide_left';
if (players[--current])
stack.shown = `${players[current]}`;
else
stack.shown = `${players.at(-1)}`;
}
stack._previous = stack.shown;
}
}, 'drag-end'],
[Mpris, (stack, busName) => {
if (!busName || stack._players.has(busName))
return;
const player = Mpris.getPlayer(busName);
player.colors = ags.Variable();
stack._players.set(busName, PlayerBox(player));
let result = [];
stack._players.forEach((widget, busName) => {
result.push([`${Mpris.getPlayer(busName).name}`, widget]);
});
stack.items = result;
if (result.find(p => p[0] === stack._previous))
stack.shown = stack._previous;
else if (stack._players.has('org.mpris.MediaPlayer2.spotify'))
stack.shown = `spotify`;
}, 'player-added'],
[Mpris, (stack, busName) => {
if (!busName || !stack._players.has(busName))
return;
stack._players.delete(busName);
let result = [];
stack._players.forEach((widget, busName) => {
result.push([`${Mpris.getPlayer(busName).name}`, widget]);
});
stack.items = result;
if (result.find(p => p[0] === stack._previous))
stack.shown = stack._previous;
else if (stack._players.has('org.mpris.MediaPlayer2.spotify'))
stack.shown = `spotify`;
}, 'player-closed'],
],
});
return widget;
};