From d64195b40cf06c625f4b63adc2954a90036da216 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 7 Jul 2024 11:23:14 +0700 Subject: [PATCH] Update mpris player for new version --- modules/common/ags/config.js | 6 +- modules/common/ags/default.nix | 42 +++- modules/common/ags/layouts/notifications.js | 2 +- modules/common/ags/layouts/quicksettings.js | 212 ++++++++-------- modules/common/ags/modules/materialcolors.js | 142 ++--------- modules/common/ags/modules/mpris.js | 242 ++++++++++--------- modules/dwl/default.nix | 2 +- modules/river/default.nix | 2 +- modules/server/default.nix | 33 ++- 9 files changed, 312 insertions(+), 371 deletions(-) diff --git a/modules/common/ags/config.js b/modules/common/ags/config.js index f239267..ff29fc4 100644 --- a/modules/common/ags/config.js +++ b/modules/common/ags/config.js @@ -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(), ], }); diff --git a/modules/common/ags/default.nix b/modules/common/ags/default.nix index 09c63e0..2a714e8 100644 --- a/modules/common/ags/default.nix +++ b/modules/common/ags/default.nix @@ -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"; }; diff --git a/modules/common/ags/layouts/notifications.js b/modules/common/ags/layouts/notifications.js index 82b0488..68e7a1e 100644 --- a/modules/common/ags/layouts/notifications.js +++ b/modules/common/ags/layouts/notifications.js @@ -38,7 +38,7 @@ export const Notifications = () => min-width: 600px; margin: 10px; padding: 12px; - border-radius: 40px; + border-radius: 20px; `, children: /** @type {any} */ diff --git a/modules/common/ags/layouts/quicksettings.js b/modules/common/ags/layouts/quicksettings.js index 238554b..3a5bf5d 100644 --- a/modules/common/ags/layouts/quicksettings.js +++ b/modules/common/ags/layouts/quicksettings.js @@ -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, + // }), + // ], + }), }); diff --git a/modules/common/ags/modules/materialcolors.js b/modules/common/ags/modules/materialcolors.js index c09946e..4ab31d0 100644 --- a/modules/common/ags/modules/materialcolors.js +++ b/modules/common/ags/modules/materialcolors.js @@ -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}; - `); - }, - ], - ], - }); diff --git a/modules/common/ags/modules/mpris.js b/modules/common/ags/modules/mpris.js index 7a36d4f..307127b 100644 --- a/modules/common/ags/modules/mpris.js +++ b/modules/common/ags/modules/mpris.js @@ -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, }); +}; diff --git a/modules/dwl/default.nix b/modules/dwl/default.nix index 2f6c7de..95ef977 100644 --- a/modules/dwl/default.nix +++ b/modules/dwl/default.nix @@ -1,4 +1,4 @@ -{pkgs, inputs, ...}: { +{pkgs, ...}: { services.xserver = { enable = true; displayManager.gdm = { diff --git a/modules/river/default.nix b/modules/river/default.nix index ca4693f..7d22f7d 100644 --- a/modules/river/default.nix +++ b/modules/river/default.nix @@ -1,4 +1,4 @@ -{pkgs, inputs, ...}: { +{pkgs, ...}: { services.greetd = { enable = true; settings = { diff --git a/modules/server/default.nix b/modules/server/default.nix index 36308b5..167f774 100644 --- a/modules/server/default.nix +++ b/modules/server/default.nix @@ -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