nix/home/util/local-webapp.nix
2024-05-02 10:52:19 +10:00

119 lines
3.3 KiB
Nix

{
config,
pkgs,
lib,
...
}: let
inherit (lib) mkOption;
inherit (lib.attrsets) mapAttrs mapAttrs' nameValuePair;
make-firefox = cfg:
mapAttrs' (
name: cfg:
nameValuePair "${name}-client"
{
inherit (cfg) name id;
url = "http://127.0.0.1:${builtins.toString cfg.port}";
extraSettings = config.programs.firefox.profiles.default.settings;
hidden = true;
}
)
cfg;
make-systemd = cfg:
mapAttrs (
name: cfg: {
Unit.Description = "${cfg.name} Backend";
Service = cfg.service;
}
)
cfg;
make-xdg = cfg:
mapAttrs (
name: cfg: {
name = cfg.name;
type = "Application";
icon = cfg.icon;
exec = "${let
notify-send = "${lib.getExe' pkgs.libnotify "notify-send"} -a \"${cfg.name}\"";
systemctl = "${lib.getExe' pkgs.systemd "systemctl"}";
dex = "${lib.getExe pkgs.dex}";
curl = "${lib.getExe pkgs.curl}";
in
pkgs.writeShellScript "${name}"
''
${notify-send} "Launching backend.." "Please be patient."
${systemctl} --user start ${name}
attempts=0
success=false
while [[ $attempts -lt $((20*9)) ]]; do
if [[ $(${curl} http://127.0.0.1:${builtins.toString cfg.port}) ]]; then
${notify-send} "Backend up." "Launching client.."
success=true
break
else
attempts=$((attempts+1))
if [[ $(($attempts % 20)) -eq 0 ]]; then
${notify-send} "Launching backend.." "Still launching.. ($((attempts/2))s)"
fi
fi
sleep 0.5
done
if [[ ! $success ]]; then
${notify-send} "Failure" "Failed to launch backend!"
${systemctl} --user kill ${name}
exit 1
fi
${dex} -w ~/.nix-profile/share/applications/${name}-client.desktop
${notify-send} "Goodbye" "Shutting down."
${systemctl} --user stop ${name}
exit 0
''}";
}
)
cfg;
in {
options.localWebApps = mkOption {
default = {};
type = with lib.types;
attrsOf (submodule {
options = {
name = mkOption {
type = str;
description = "Display name of the webapp.";
};
icon = mkOption {
type = either str path;
description = "Path to a file to use for application icon.";
default = "";
};
id = mkOption {
type = int;
description = "Firefox profile ID for the webapp's client";
};
port = mkOption {
type = int;
description = "Local port the webapp should host on.";
};
service = mkOption {
type = attrsOf string;
description = "The service settings for systemd user service. Requires at least ExecStart.";
};
};
});
};
config = {
programs.firefox.webapps = make-firefox config.localWebApps;
systemd.user.services = make-systemd config.localWebApps;
xdg.desktopEntries = make-xdg config.localWebApps;
};
}