aboutsummaryrefslogtreecommitdiffstats
path: root/desktop/island/Logic.js
blob: 24458cd841d38754d7a2490da4df296a40641ab4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
.pragma library

// Copyright (C) 2026 Danilo M. <danix@danix.xyz>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.

// The default sink's icon name. Thresholds in thirds, as waybar's wb-icon did.
function volumeIcon(volume, muted) {
    // !(> 0) also catches a volume not populated yet (undefined, NaN), which
    // would otherwise fall through every test and read as high.
    if (muted || !(volume > 0)) return "audio-volume-muted";
    if (volume < 0.33) return "audio-volume-low";
    if (volume < 0.66) return "audio-volume-medium";
    return "audio-volume-high";
}

// A VM's dot colour as a Theme property name, or "" for no dot. States are
// the names Virsh._stateName gives libvirt's enum: "blocked" is what virsh
// list prints as idle, "suspended" is pmsuspended. A shut-off VM only gets a
// dot when it carries a managed save, because starting it is then a restore.
function vmRole(vm) {
    if (!vm || !vm.state) return "";
    if (vm.state === "shut off") return vm.saved ? "blue" : "";
    return ({
        "running": "green",
        "paused": "yellow",
        "blocked": "yellow",
        "shutting down": "yellow",
        "suspended": "accent",
        "crashed": "red",
    })[vm.state] || "";
}

// Flag image for a Hyprland active_keymap string, wb-lang's mapping.
function flagFor(keymap) {
    if (!keymap || keymap.startsWith("Italian")) return "flag-it.svg";
    return "burger.svg";
}

// Active capture kinds as Theme property names, in a fixed order so the
// sliver's segments do not shuffle.
function privacyRoles(mic, cam, loc, scr) {
    const out = [];
    if (mic) out.push("green");
    if (cam) out.push("yellow");
    if (loc) out.push("blue");
    if (scr) out.push("red");
    return out;
}

// Hyprland's openwindow event data: "address,workspace,class,title". The
// title is last and may contain commas, so only the first three fields are
// read.
function parseOpenWindow(data) {
    const p = String(data || "").split(",");
    return { address: p[0] || "", workspace: p[1] || "", appClass: p[2] || "" };
}

// OBS's outputDuration (ms) as mm:ss, or h:mm:ss past an hour.
function obsElapsed(ms) {
    const s = Math.floor((ms > 0 ? ms : 0) / 1000);
    const two = n => String(n).padStart(2, "0");
    const h = Math.floor(s / 3600);
    const mmss = `${two(Math.floor(s / 60) % 60)}:${two(s % 60)}`;
    return h ? `${h}:${mmss}` : mmss;
}