mirror of
https://github.com/zoriya/flake.git
synced 2026-06-07 04:16:21 +00:00
Update mpris player for new version
This commit is contained in:
@@ -1,8 +1,7 @@
|
||||
import { Bar } from "./layouts/bar.js";
|
||||
import { Notifications } from "./layouts/notifications.js";
|
||||
// import { OSD } from "./layouts/osd.js";
|
||||
// import { Powermenu } from "./layouts/powermenu.js";
|
||||
// import { Quicksettings } from "./layouts/quicksettings.js";
|
||||
import { Quicksettings } from "./layouts/quicksettings.js";
|
||||
|
||||
import Gtk from "gi://Gtk?version=3.0";
|
||||
import Gdk from "gi://Gdk";
|
||||
@@ -23,9 +22,8 @@ App.config({
|
||||
style: `${App.configDir}/style.css`,
|
||||
windows: [
|
||||
...forMonitors(Bar),
|
||||
// Quicksettings(),
|
||||
Quicksettings(),
|
||||
Notifications(),
|
||||
// OSD(),
|
||||
// Powermenu(),
|
||||
],
|
||||
});
|
||||
|
||||
@@ -1,18 +1,38 @@
|
||||
{pkgs, ...}: let
|
||||
# covercolors = pkgs.stdenv.mkDerivation {
|
||||
# name = "covercolors";
|
||||
# dontUnpack = true;
|
||||
{
|
||||
pkgs,
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
covercolors = pkgs.stdenv.mkDerivation {
|
||||
name = "covercolors";
|
||||
dontUnpack = true;
|
||||
propagatedBuildInputs = [
|
||||
(pkgs.python3.withPackages (pyPkgs:
|
||||
with pyPkgs; [
|
||||
material-color-utilities
|
||||
pillow
|
||||
]))
|
||||
];
|
||||
installPhase = "install -Dm755 ${./covercolors.py} $out/bin/covercolors";
|
||||
};
|
||||
# ags = pkgs.stdenv.mkDerivation rec {
|
||||
# name = "ags";
|
||||
# nativeBuildInputs = with pkgs; [makeWrapper];
|
||||
# propagatedBuildInputs = [
|
||||
# (pkgs.python3.withPackages (pyPkgs:
|
||||
# with pyPkgs; [
|
||||
# material-color-utilities
|
||||
# pillow
|
||||
# ]))
|
||||
# covercolors
|
||||
# ];
|
||||
# installPhase = "install -Dm755 ${./covercolors.py} $out/bin/covercolors";
|
||||
# dontUnpack = true;
|
||||
# installPhase = "
|
||||
# wrapProgram ${pkgs.ags}/bin/ags --prefix PATH : '${lib.makeBinPath propagatedBuildInputs}'
|
||||
# ";
|
||||
# };
|
||||
ags = pkgs.ags.overrideAttrs (oldAttrs: {
|
||||
runtimeDependencies = [covercolors];
|
||||
});
|
||||
systemdTarget = "graphical-session.target";
|
||||
in {
|
||||
# TODO: Remove this after testing
|
||||
home.packages = [ags];
|
||||
systemd.user.services.ags = {
|
||||
Unit = {
|
||||
Description = " A customizable and extensible shell ";
|
||||
@@ -23,7 +43,7 @@ in {
|
||||
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = "${pkgs.ags}/bin/ags";
|
||||
ExecStart = "${ags}/bin/ags";
|
||||
Restart = "always";
|
||||
};
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ export const Notifications = () =>
|
||||
min-width: 600px;
|
||||
margin: 10px;
|
||||
padding: 12px;
|
||||
border-radius: 40px;
|
||||
border-radius: 20px;
|
||||
`,
|
||||
children:
|
||||
/** @type {any} */
|
||||
|
||||
@@ -1,111 +1,115 @@
|
||||
import * as audio from "../modules/audio.js";
|
||||
import * as brightness from "../modules/brightness.js";
|
||||
import * as network from "../modules/network.js";
|
||||
import * as bluetooth from "../modules/bluetooth.js";
|
||||
import * as darkmode from "../modules/darkmode.js";
|
||||
import * as nightmode from "../modules/nightmode.js";
|
||||
// import * as audio from "../modules/audio.js";
|
||||
// import * as brightness from "../modules/brightness.js";
|
||||
// import * as network from "../modules/network.js";
|
||||
// import * as bluetooth from "../modules/bluetooth.js";
|
||||
// import * as darkmode from "../modules/darkmode.js";
|
||||
// import * as nightmode from "../modules/nightmode.js";
|
||||
import * as mpris from "../modules/mpris.js";
|
||||
import { opened, Arrow } from "../services/quicksettings.js";
|
||||
import { FontIcon, PopupOverlay } from "../misc.js";
|
||||
import PopupWindow from "../misc/popup.js";
|
||||
// import { opened, Arrow } from "../services/quicksettings.js";
|
||||
// import { FontIcon, PopupOverlay } from "../misc.js";
|
||||
|
||||
import { Window, Revealer, Icon, Box, Button, Label } from 'resource:///com/github/Aylur/ags/widget.js'
|
||||
import { execAsync } from 'resource:///com/github/Aylur/ags/utils.js'
|
||||
|
||||
const Submenu = ({ menuName, icon, title, contentType }) =>
|
||||
Revealer({
|
||||
transition: "slide_down",
|
||||
connections: [[opened, (r) => (r.reveal_child = menuName === opened.value)]],
|
||||
child: Box({
|
||||
className: "qs-submenu surface",
|
||||
vertical: true,
|
||||
children: [
|
||||
Box({ className: "qs-sub-title accent", children: [icon, Label({ label: title, className: "bold f16" })] }),
|
||||
contentType({ className: "qs-sub-content", hexpand: true }),
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
const VolumeBox = () =>
|
||||
Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Box({
|
||||
className: "qs-slider",
|
||||
children: [
|
||||
Button({
|
||||
child: audio.SpeakerIndicator(),
|
||||
onClicked: () => execAsync("pactl set-sink-mute @DEFAULT_SINK@ toggle"),
|
||||
}),
|
||||
audio.SpeakerSlider({ hexpand: true }),
|
||||
audio.SpeakerPercentLabel(),
|
||||
Arrow({ name: "stream-selector" }),
|
||||
],
|
||||
}),
|
||||
Submenu({
|
||||
menuName: "stream-selector",
|
||||
icon: Icon("audio-volume-medium-symbolic"),
|
||||
title: "Audio Stream",
|
||||
contentType: audio.StreamSelector,
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const BrightnessBox = () =>
|
||||
Box({
|
||||
className: "qs-slider",
|
||||
children: [
|
||||
brightness.Indicator(),
|
||||
brightness.BrightnessSlider({ hexpand: true }),
|
||||
brightness.PercentLabel(),
|
||||
Box({ className: "qs-icon", css: "margin-right: 18px;" }),
|
||||
],
|
||||
});
|
||||
const mprisService = await Service.import("mpris");
|
||||
|
||||
// const Submenu = ({ menuName, icon, title, contentType }) =>
|
||||
// Revealer({
|
||||
// transition: "slide_down",
|
||||
// connections: [
|
||||
// [opened, (r) => (r.reveal_child = menuName === opened.value)],
|
||||
// ],
|
||||
// child: Box({
|
||||
// className: "qs-submenu surface",
|
||||
// vertical: true,
|
||||
// children: [
|
||||
// Box({
|
||||
// className: "qs-sub-title accent",
|
||||
// children: [icon, Label({ label: title, className: "bold f16" })],
|
||||
// }),
|
||||
// contentType({ className: "qs-sub-content", hexpand: true }),
|
||||
// ],
|
||||
// }),
|
||||
// });
|
||||
//
|
||||
// const VolumeBox = () =>
|
||||
// Box({
|
||||
// vertical: true,
|
||||
// children: [
|
||||
// Box({
|
||||
// className: "qs-slider",
|
||||
// children: [
|
||||
// Button({
|
||||
// child: audio.SpeakerIndicator(),
|
||||
// onClicked: () =>
|
||||
// execAsync("pactl set-sink-mute @DEFAULT_SINK@ toggle"),
|
||||
// }),
|
||||
// audio.SpeakerSlider({ hexpand: true }),
|
||||
// audio.SpeakerPercentLabel(),
|
||||
// Arrow({ name: "stream-selector" }),
|
||||
// ],
|
||||
// }),
|
||||
// Submenu({
|
||||
// menuName: "stream-selector",
|
||||
// icon: Icon("audio-volume-medium-symbolic"),
|
||||
// title: "Audio Stream",
|
||||
// contentType: audio.StreamSelector,
|
||||
// }),
|
||||
// ],
|
||||
// });
|
||||
//
|
||||
// const BrightnessBox = () =>
|
||||
// Box({
|
||||
// className: "qs-slider",
|
||||
// children: [
|
||||
// brightness.Indicator(),
|
||||
// brightness.BrightnessSlider({ hexpand: true }),
|
||||
// brightness.PercentLabel(),
|
||||
// Box({ className: "qs-icon", css: "margin-right: 18px;" }),
|
||||
// ],
|
||||
// });
|
||||
|
||||
export const Quicksettings = () =>
|
||||
Window({
|
||||
PopupWindow({
|
||||
name: "quicksettings",
|
||||
popup: true,
|
||||
visible: false,
|
||||
anchor: ["top", "right", "bottom", "left"],
|
||||
child: PopupOverlay(
|
||||
"quicksettings",
|
||||
"top right",
|
||||
Box({
|
||||
vertical: true,
|
||||
className: "bgcont qs-container",
|
||||
children: [
|
||||
VolumeBox(),
|
||||
BrightnessBox(),
|
||||
Box({
|
||||
children: [network.Toggle({}), bluetooth.Toggle({})],
|
||||
}),
|
||||
Submenu({
|
||||
menuName: "network",
|
||||
icon: Icon("network-wireless-symbolic"),
|
||||
title: "Network",
|
||||
contentType: network.Selection,
|
||||
}),
|
||||
Submenu({
|
||||
menuName: "bluetooth",
|
||||
icon: Icon("bluetooth-symbolic"),
|
||||
title: "Bluetooth",
|
||||
contentType: bluetooth.Devices,
|
||||
}),
|
||||
Box({
|
||||
children: [darkmode.DarkToggle(), nightmode.NightToggle()],
|
||||
}),
|
||||
Box({
|
||||
children: [audio.AppMixerToggle(), audio.MuteToggle()],
|
||||
}),
|
||||
Submenu({
|
||||
menuName: "app-mixer",
|
||||
icon: FontIcon({ icon: "" }),
|
||||
title: "App Mixer",
|
||||
contentType: audio.AppMixer,
|
||||
}),
|
||||
mpris.MprisPlayer(),
|
||||
],
|
||||
})
|
||||
),
|
||||
exclusivity: "exclusive",
|
||||
transition: "slide_down",
|
||||
layout: "top-right",
|
||||
child: Widget.Box({
|
||||
vertical: true,
|
||||
className: "bgcont qs-container",
|
||||
children:
|
||||
mprisService
|
||||
.bind("players")
|
||||
.as((x) => x.map((player) => mpris.MprisPlayer({ player }))),
|
||||
// children: [
|
||||
// VolumeBox(),
|
||||
// BrightnessBox(),
|
||||
// Widget.Box({
|
||||
// children: [network.Toggle({}), bluetooth.Toggle({})],
|
||||
// }),
|
||||
// Submenu({
|
||||
// menuName: "network",
|
||||
// icon: "network-wireless-symbolic",
|
||||
// title: "Network",
|
||||
// contentType: network.Selection,
|
||||
// }),
|
||||
// Submenu({
|
||||
// menuName: "bluetooth",
|
||||
// icon: "bluetooth-symbolic",
|
||||
// title: "Bluetooth",
|
||||
// contentType: bluetooth.Devices,
|
||||
// }),
|
||||
// Box({
|
||||
// children: [darkmode.DarkToggle(), nightmode.NightToggle()],
|
||||
// }),
|
||||
// Box({
|
||||
// children: [audio.AppMixerToggle(), audio.MuteToggle()],
|
||||
// }),
|
||||
// Submenu({
|
||||
// menuName: "app-mixer",
|
||||
// icon: FontIcon({ icon: "" }),
|
||||
// title: "App Mixer",
|
||||
// contentType: audio.AppMixer,
|
||||
// }),
|
||||
// ],
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -1,126 +1,26 @@
|
||||
import Service from 'resource:///com/github/Aylur/ags/service.js';
|
||||
import { Box, Stack, Button, Icon } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||
import { execAsync, timeout } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js';
|
||||
/** @param {import("types/service/mpris").MprisPlayer} player */
|
||||
export const getMaterialColors = (player) => {
|
||||
const ret = Variable({
|
||||
primary: "#222222",
|
||||
onPrimary: "#ffffff",
|
||||
background: "#222222",
|
||||
onBackground: "#ffffff",
|
||||
coverPath: "",
|
||||
});
|
||||
|
||||
class MaterialcolorsService extends Service {
|
||||
static {
|
||||
Service.register(this);
|
||||
}
|
||||
|
||||
getColors(url) {
|
||||
if (url) {
|
||||
timeout(100, () => {
|
||||
execAsync(["covercolors", url])
|
||||
.then((colors) => {
|
||||
const col = JSON.parse(colors);
|
||||
if (!col) return;
|
||||
this._colors = col;
|
||||
this.emit("changed");
|
||||
})
|
||||
.catch(print);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._colors = {
|
||||
primary: "#222222",
|
||||
onPrimary: "#ffffff",
|
||||
background: "#222222",
|
||||
onBackground: "#ffffff",
|
||||
};
|
||||
|
||||
Mpris.connect("changed", () => {
|
||||
this._mprisPlayer = Mpris.getPlayer("YoutubeMusic");
|
||||
this._coverPath = this._mprisPlayer?.coverPath;
|
||||
this.getColors(this.coverPath);
|
||||
this.emit("changed");
|
||||
player.bind("cover_path").as((cover) => {
|
||||
Utils.timeout(100, () => {
|
||||
Utils.execAsync(["covercolors", cover])
|
||||
.then((colors) => {
|
||||
const col = JSON.parse(colors);
|
||||
if (!col) return;
|
||||
col.coverPath = cover;
|
||||
ret.setValue(col);
|
||||
})
|
||||
.catch(print);
|
||||
});
|
||||
}
|
||||
|
||||
get colors() {
|
||||
return this._colors;
|
||||
}
|
||||
get coverPath() {
|
||||
return this._coverPath;
|
||||
}
|
||||
}
|
||||
|
||||
export const Materialcolors = new MaterialcolorsService();
|
||||
|
||||
export const PlayPause = ({ player, ...props }) =>
|
||||
Button({
|
||||
child: Stack({
|
||||
items: [
|
||||
["Playing", Icon("media-playback-pause-symbolic")],
|
||||
["Paused", Icon("media-playback-start-symbolic")],
|
||||
["Stopped", Icon("media-playback-start-symbolic")],
|
||||
],
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
(stack) => {
|
||||
const mpris = Mpris.getPlayer(player);
|
||||
stack.shown = mpris?.playBackStatus ?? "Stopped";
|
||||
},
|
||||
],
|
||||
],
|
||||
}),
|
||||
onClicked: () => Mpris.getPlayer(player)?.playPause(),
|
||||
connections: [
|
||||
[
|
||||
Materialcolors,
|
||||
(icon) => {
|
||||
icon.setCss(`
|
||||
background-color: ${Materialcolors.colors.primary};
|
||||
color: ${Materialcolors.colors.onPrimary};
|
||||
`);
|
||||
},
|
||||
],
|
||||
[
|
||||
Mpris,
|
||||
(button) => {
|
||||
const mpris = Mpris.getPlayer(player);
|
||||
if (!mpris || !mpris.canPlay) return button.hide();
|
||||
|
||||
button.show();
|
||||
},
|
||||
],
|
||||
],
|
||||
...props,
|
||||
});
|
||||
|
||||
export const CoverArt = (props) =>
|
||||
Box({
|
||||
...props,
|
||||
className: `mpris-cover-art ${props.className}`,
|
||||
connections: [
|
||||
[
|
||||
Materialcolors,
|
||||
(box) => {
|
||||
box.setCss(`
|
||||
background-image: radial-gradient(circle, rgba(0, 0, 0, 0.4) 30%, ${Materialcolors.colors.primary}), url("${Materialcolors.coverPath}"); \
|
||||
color: ${Materialcolors.colors.onBackground};
|
||||
`);
|
||||
},
|
||||
],
|
||||
...(props.connections ?? []),
|
||||
],
|
||||
});
|
||||
return ret;
|
||||
};
|
||||
|
||||
export const BackgroundBox = (props = {}) =>
|
||||
Box({
|
||||
...props,
|
||||
connections: [
|
||||
[
|
||||
Materialcolors,
|
||||
(box) => {
|
||||
box.setCss(`
|
||||
color: ${Materialcolors.colors.onBackground};
|
||||
`);
|
||||
},
|
||||
],
|
||||
],
|
||||
});
|
||||
|
||||
+131
-111
@@ -1,151 +1,179 @@
|
||||
import { BackgroundBox, CoverArt, PlayPause } from "./materialcolors.js";
|
||||
import { addElipsis } from "../misc.js";
|
||||
import { getMaterialColors } from "./materialcolors.js";
|
||||
|
||||
import { Box, Button, Slider, Icon, CenterBox, Label } from 'resource:///com/github/Aylur/ags/widget.js';
|
||||
import Mpris from 'resource:///com/github/Aylur/ags/service/mpris.js'
|
||||
import { lookUpIcon } from 'resource:///com/github/Aylur/ags/utils.js';
|
||||
const mpris = await Service.import("mpris");
|
||||
|
||||
const PlayerIcon = ({ player, symbolic = false, ...props }) =>
|
||||
Icon({
|
||||
...props,
|
||||
/** @param {{player: import("types/service/mpris").MprisPlayer} & import("types/widgets/icon").IconProps} props */
|
||||
const PlayerIcon = ({ player, ...props }) =>
|
||||
Widget.Icon({
|
||||
size: 24,
|
||||
hpack: "start",
|
||||
vpack: "start",
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
(icon) => {
|
||||
const name = `${Mpris.getPlayer(player)?.entry}${symbolic ? "-symbolic" : ""}`;
|
||||
lookUpIcon(name) ? (icon.icon_name = name) : (icon.icon_name = "audio-x-generic-symbolic");
|
||||
},
|
||||
],
|
||||
],
|
||||
tooltipText: player.identity || "",
|
||||
icon: player.bind("entry").transform((entry) => {
|
||||
const name = `${entry}-symbolic`;
|
||||
return Utils.lookUpIcon(name)
|
||||
? name
|
||||
: Utils.lookUpIcon(entry)
|
||||
? entry
|
||||
: "audio-x-generic-symbolic";
|
||||
}),
|
||||
...props,
|
||||
});
|
||||
|
||||
const TitleLabel = ({ player, ...props } = {}) =>
|
||||
Label({
|
||||
...props,
|
||||
truncate: "end",
|
||||
/** @param {{player: import("types/service/mpris").MprisPlayer} & import("types/widgets/label").LabelProps} props */
|
||||
const TitleLabel = ({ player, ...props }) =>
|
||||
Widget.Label({
|
||||
wrap: true,
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
(label) => {
|
||||
label.label = addElipsis(Mpris.getPlayer(player)?.trackTitle || "", 25);
|
||||
},
|
||||
],
|
||||
],
|
||||
});
|
||||
|
||||
const ArtistLabel = ({ player, ...props }) =>
|
||||
Label({
|
||||
...props,
|
||||
truncate: "end",
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
(label) => {
|
||||
label.label = addElipsis(Mpris.getPlayer(player)?.trackArtists.join(", ") || "", 25);
|
||||
},
|
||||
],
|
||||
],
|
||||
hpack: "start",
|
||||
label: player.bind("track_title"),
|
||||
...props,
|
||||
});
|
||||
|
||||
/** @param {{player: import("types/service/mpris").MprisPlayer} & import("types/widgets/label").LabelProps} props */
|
||||
const ArtistLabel = ({ player, ...props }) =>
|
||||
Widget.Label({
|
||||
wrap: true,
|
||||
truncate: "end",
|
||||
hpack: "start",
|
||||
label: player.bind("track_artists").transform((x) => x.join(", ")),
|
||||
...props,
|
||||
});
|
||||
|
||||
/** @param {{player: import("types/service/mpris").MprisPlayer} & import("types/widgets/button").ButtonProps} props */
|
||||
export const PlayPause = ({ player, ...props }) =>
|
||||
Widget.Button({
|
||||
child: Widget.Icon({
|
||||
icon: player.bind("play_back_status").as(
|
||||
(x) =>
|
||||
({
|
||||
Playing: "media-playback-pause-symbolic",
|
||||
Paused: "media-playback-start-symbolic",
|
||||
Stopped: "media-playback-start-symbolic",
|
||||
})[x],
|
||||
),
|
||||
}),
|
||||
onClicked: () => player.playPause(),
|
||||
visible: player.bind("can_play"),
|
||||
...props,
|
||||
});
|
||||
|
||||
/** @param {{player: import("types/service/mpris").MprisPlayer} & import("types/widgets/button").ButtonProps} props */
|
||||
const PreviousButton = ({ player, ...props }) =>
|
||||
Button({
|
||||
child: Icon("media-skip-backward-symbolic"),
|
||||
onClicked: () => Mpris.getPlayer(player)?.previous(),
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
(button) => {
|
||||
const mpris = Mpris.getPlayer(player);
|
||||
if (!mpris || !mpris.canGoPrev) return button.hide();
|
||||
|
||||
button.show();
|
||||
},
|
||||
],
|
||||
],
|
||||
Widget.Button({
|
||||
child: Widget.Icon({ icon: "media-skip-backward-symbolic" }),
|
||||
onClicked: () => player.previous(),
|
||||
visible: player.bind("can_go_prev"),
|
||||
...props,
|
||||
});
|
||||
|
||||
/** @param {{player: import("types/service/mpris").MprisPlayer} & import("types/widgets/button").ButtonProps} props */
|
||||
const NextButton = ({ player, ...props }) =>
|
||||
Button({
|
||||
child: Icon("media-skip-forward-symbolic"),
|
||||
onClicked: () => Mpris.getPlayer(player)?.next(),
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
(button) => {
|
||||
const mpris = Mpris.getPlayer(player);
|
||||
if (!mpris || !mpris.canGoNext) return button.hide();
|
||||
|
||||
button.show();
|
||||
},
|
||||
],
|
||||
],
|
||||
Widget.Button({
|
||||
child: Widget.Icon({ icon: "media-skip-forward-symbolic" }),
|
||||
onClicked: () => player.next(),
|
||||
visible: player.bind("can_go_next"),
|
||||
...props,
|
||||
});
|
||||
|
||||
const PositionSlider = ({ player, ...props }) => {
|
||||
const update = (slider) => {
|
||||
if (slider._dragging) return;
|
||||
|
||||
const mpris = Mpris.getPlayer(player);
|
||||
// Only set opacity and not change the visible bool to keep it expanded.
|
||||
slider.opacity = mpris?.length > 0 ? 1 : 0;
|
||||
if (mpris && mpris.length > 0) slider.adjustment.value = mpris.position / mpris.length;
|
||||
};
|
||||
|
||||
return Slider({
|
||||
drawValue: false,
|
||||
/** @param {{player: import("types/service/mpris").MprisPlayer} & import("types/widgets/slider").SliderProps} props */
|
||||
const PositionSlider = ({ player, ...props }) =>
|
||||
Widget.Slider({
|
||||
className: "mpris-position-slider",
|
||||
onChange: (value) => {
|
||||
const mpris = Mpris.getPlayer(player);
|
||||
if (mpris && mpris.length >= 0) Mpris.getPlayer(player).position = mpris.length * value;
|
||||
drawValue: false,
|
||||
onChange: ({ value }) => {
|
||||
player.position = value * player.length;
|
||||
},
|
||||
visible: player.bind("length").as((l) => l > 0),
|
||||
setup: (self) => {
|
||||
function update() {
|
||||
const value = player.position / player.length;
|
||||
self.value = value > 0 ? value : 0;
|
||||
}
|
||||
self.hook(player, update);
|
||||
self.hook(player, update, "position");
|
||||
self.poll(1000, update);
|
||||
},
|
||||
connections: [
|
||||
[Mpris, update],
|
||||
[1000, update],
|
||||
],
|
||||
...props,
|
||||
});
|
||||
};
|
||||
|
||||
export const MprisPlayer = ({ player = "YoutubeMusic", ...props } = {}) =>
|
||||
CoverArt({
|
||||
// export const currentPlayer = Utils.watch(
|
||||
// null,
|
||||
// [
|
||||
// [mpris, "player-added"],
|
||||
// [mpris, "player-changed"],
|
||||
// ],
|
||||
// /** @param {any} name */
|
||||
// (name) => mpris.getPlayer(name),
|
||||
// );
|
||||
|
||||
/** @param {{player?: import("types/service/mpris").MprisPlayer | null} & import("types/widgets/box").BoxProps} props */
|
||||
export const MprisPlayer = ({ player, ...props }) => {
|
||||
if (!player) return Widget.Box({ visible: false });
|
||||
const colors = getMaterialColors(player);
|
||||
|
||||
return Widget.Box({
|
||||
visible: player.bind("play_back_status").as((x) => x !== "Stopped"),
|
||||
className: `mpris-cover-art ${props.className}`,
|
||||
css: colors.bind().as(
|
||||
(x) => `
|
||||
background-image: radial-gradient(circle, rgba(0, 0, 0, 0.4) 30%, ${x.primary}), url("${x.coverPath}"); \
|
||||
color: ${x.onBackground};
|
||||
`,
|
||||
),
|
||||
vexpand: false,
|
||||
children: [
|
||||
CenterBox({
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
hexpand: true,
|
||||
children: [
|
||||
BackgroundBox({
|
||||
Widget.Box({
|
||||
vertical: true,
|
||||
vexpand: true,
|
||||
css: colors.bind().as((x) => `color: ${x.onBackground}`),
|
||||
child: PlayerIcon({ player }),
|
||||
}),
|
||||
Box({
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
children: [
|
||||
BackgroundBox({
|
||||
Widget.Box({
|
||||
css: colors.bind().as((x) => `color: ${x.onBackground}`),
|
||||
vertical: true,
|
||||
vpack: "center",
|
||||
hexpand: true,
|
||||
children: [
|
||||
TitleLabel({ player, css: "font-weight: 600; font-size: 19px;" }),
|
||||
ArtistLabel({ player, css: "font-weight: 400; font-size: 17px;" }),
|
||||
TitleLabel({
|
||||
player,
|
||||
css: "font-weight: 600; font-size: 19px;",
|
||||
}),
|
||||
ArtistLabel({
|
||||
player,
|
||||
css: "font-weight: 400; font-size: 17px;",
|
||||
}),
|
||||
],
|
||||
}),
|
||||
Box({
|
||||
children: [PlayPause({ player, hpack: "end", className: "mpris-play" })],
|
||||
Widget.Box({
|
||||
children: [
|
||||
PlayPause({
|
||||
player,
|
||||
hpack: "end",
|
||||
className: "mpris-play",
|
||||
css: colors.bind().as(
|
||||
(x) => `
|
||||
background-color: ${x.primary};
|
||||
color: ${x.onPrimary};
|
||||
`,
|
||||
),
|
||||
}),
|
||||
],
|
||||
}),
|
||||
],
|
||||
}),
|
||||
BackgroundBox({
|
||||
Widget.Box({
|
||||
css: colors.bind().as((x) => `color: ${x.onBackground}`),
|
||||
vpack: "end",
|
||||
children: [
|
||||
Box({
|
||||
Widget.Box({
|
||||
hexpand: true,
|
||||
children: [
|
||||
PreviousButton({ player, css: "margin-left: 16px;" }),
|
||||
@@ -158,14 +186,6 @@ export const MprisPlayer = ({ player = "YoutubeMusic", ...props } = {}) =>
|
||||
],
|
||||
}),
|
||||
],
|
||||
connections: [
|
||||
[
|
||||
Mpris,
|
||||
(widget) => {
|
||||
const mpris = Mpris.getPlayer(player);
|
||||
widget.visible = mpris !== null && mpris.playBackStatus !== "Stopped";
|
||||
},
|
||||
],
|
||||
],
|
||||
...props,
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{pkgs, inputs, ...}: {
|
||||
{pkgs, ...}: {
|
||||
services.xserver = {
|
||||
enable = true;
|
||||
displayManager.gdm = {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
{pkgs, inputs, ...}: {
|
||||
{pkgs, ...}: {
|
||||
services.greetd = {
|
||||
enable = true;
|
||||
settings = {
|
||||
|
||||
+16
-17
@@ -3,20 +3,19 @@
|
||||
lib,
|
||||
...
|
||||
}: let
|
||||
guesspath =
|
||||
pkgs.stdenv.mkDerivation rec {
|
||||
name = "guesspath";
|
||||
nativeBuildInputs = with pkgs; [makeWrapper];
|
||||
propagatedBuildInputs = with pkgs; [
|
||||
python3Packages.guessit
|
||||
transmission_4
|
||||
];
|
||||
dontUnpack = true;
|
||||
installPhase = "
|
||||
install -Dm755 ${./guesspath.sh} $out/bin/guesspath
|
||||
wrapProgram $out/bin/guesspath --prefix PATH : '${lib.makeBinPath propagatedBuildInputs}'
|
||||
";
|
||||
};
|
||||
guesspath = pkgs.stdenv.mkDerivation rec {
|
||||
name = "guesspath";
|
||||
nativeBuildInputs = with pkgs; [makeWrapper];
|
||||
propagatedBuildInputs = with pkgs; [
|
||||
python3Packages.guessit
|
||||
transmission_4
|
||||
];
|
||||
dontUnpack = true;
|
||||
installPhase = "
|
||||
install -Dm755 ${./guesspath.sh} $out/bin/guesspath
|
||||
wrapProgram $out/bin/guesspath --prefix PATH : '${lib.makeBinPath propagatedBuildInputs}'
|
||||
";
|
||||
};
|
||||
|
||||
smartrss = pkgs.stdenv.mkDerivation rec {
|
||||
name = "smartrss";
|
||||
@@ -28,9 +27,9 @@
|
||||
];
|
||||
dontUnpack = true;
|
||||
installPhase = "
|
||||
install -Dm755 ${./smartrss.sh} $out/bin/smartrss
|
||||
wrapProgram $out/bin/smartrss --prefix PATH : '${lib.makeBinPath propagatedBuildInputs}'
|
||||
";
|
||||
install -Dm755 ${./smartrss.sh} $out/bin/smartrss
|
||||
wrapProgram $out/bin/smartrss --prefix PATH : '${lib.makeBinPath propagatedBuildInputs}'
|
||||
";
|
||||
};
|
||||
in {
|
||||
# Make it use predictable interface names starting with eth0
|
||||
|
||||
Reference in New Issue
Block a user