added stuff
This commit is contained in:
parent
e8d9044d2b
commit
9d0ebdfbd0
907 changed files with 70990 additions and 0 deletions
21
nyx/homes/notashelf/services/wayland/ags/js/utils/appIcon.js
Normal file
21
nyx/homes/notashelf/services/wayland/ags/js/utils/appIcon.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import { Widget } from "../imports.js";
|
||||
import { queryExact } from "./global.js";
|
||||
const { Button, Icon } = Widget;
|
||||
|
||||
export default ({
|
||||
appName,
|
||||
onClicked = () => queryExact(appName).launch(),
|
||||
icon = queryExact(appName).iconName,
|
||||
size = 36,
|
||||
...props
|
||||
}) => {
|
||||
const appIcon = Button({
|
||||
onClicked,
|
||||
child: Icon({
|
||||
icon,
|
||||
size,
|
||||
...props,
|
||||
}),
|
||||
});
|
||||
return appIcon;
|
||||
};
|
62
nyx/homes/notashelf/services/wayland/ags/js/utils/audio.js
Normal file
62
nyx/homes/notashelf/services/wayland/ags/js/utils/audio.js
Normal file
|
@ -0,0 +1,62 @@
|
|||
import { Audio, Widget } from "../imports.js";
|
||||
const { Slider, Label } = Widget;
|
||||
const { speaker } = Audio;
|
||||
|
||||
const audio = {
|
||||
mixer: "",
|
||||
mic: {
|
||||
muted: "microphone-disabled-symbolic",
|
||||
low: "microphone-sensitivity-low-symbolic",
|
||||
medium: "microphone-sensitivity-medium-symbolic",
|
||||
high: "microphone-sensitivity-high-symbolic",
|
||||
},
|
||||
volume: {
|
||||
muted: "audio-volume-muted-symbolic",
|
||||
low: "audio-volume-low-symbolic",
|
||||
medium: "audio-volume-medium-symbolic",
|
||||
high: "audio-volume-high-symbolic",
|
||||
overamplified: "audio-volume-overamplified-symbolic",
|
||||
},
|
||||
type: {
|
||||
headset: "audio-headphones-symbolic",
|
||||
speaker: "audio-speakers-symbolic",
|
||||
card: "audio-card-symbolic",
|
||||
},
|
||||
};
|
||||
|
||||
export const getAudioIcon = (self) => {
|
||||
if (!Audio.speaker) return;
|
||||
|
||||
const { muted, low, medium, high, overamplified } = audio.volume;
|
||||
|
||||
if (Audio.speaker.is_muted) return (self.icon = muted);
|
||||
|
||||
/** @type {Array<[number, string]>} */
|
||||
const cons = [
|
||||
[101, overamplified],
|
||||
[67, high],
|
||||
[34, medium],
|
||||
[1, low],
|
||||
[0, muted],
|
||||
];
|
||||
|
||||
self.icon = cons.find(([n]) => n <= Audio.speaker.volume * 100)?.[1] || "";
|
||||
};
|
||||
|
||||
export const getSliderIcon = () =>
|
||||
Label({
|
||||
className: "volPopupIcon",
|
||||
label: speaker.bind("volume").as((/** @type {number} */ v) => {
|
||||
return ["", "", "", ""][
|
||||
speaker.stream?.isMuted ? 0 : Math.floor((v * 100) / 26)
|
||||
];
|
||||
}),
|
||||
});
|
||||
|
||||
export const volumePercentBar = () =>
|
||||
Slider({
|
||||
className: "volPopupBar",
|
||||
drawValue: false,
|
||||
value: speaker.bind("volume"),
|
||||
onChange: ({ value }) => (speaker.volume = value),
|
||||
});
|
57
nyx/homes/notashelf/services/wayland/ags/js/utils/battery.js
Normal file
57
nyx/homes/notashelf/services/wayland/ags/js/utils/battery.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import { Battery } from "../imports.js";
|
||||
|
||||
/**
|
||||
* toTime converts a given value to a human-readable
|
||||
* format where the number of hours and minutes are
|
||||
* inferred from time, which is assumed to be in seconds.
|
||||
*
|
||||
* @param {number} time - time in seconds
|
||||
*/
|
||||
export const toTime = (time) => {
|
||||
const MINUTE = 60;
|
||||
const HOUR = MINUTE * 60;
|
||||
|
||||
if (time > 24 * HOUR) return "";
|
||||
|
||||
const hours = Math.round(time / HOUR);
|
||||
const minutes = Math.round((time - hours * HOUR) / MINUTE);
|
||||
|
||||
const hoursDisplay = hours > 0 ? `${hours}h ` : "";
|
||||
const minutesDisplay = minutes > 0 ? `${minutes}m ` : "";
|
||||
|
||||
return `${hoursDisplay}${minutesDisplay}`;
|
||||
};
|
||||
|
||||
export const getBatteryTime = () => {
|
||||
const timeRemaining = Battery.timeRemaining;
|
||||
return timeRemaining > 0 && toTime(timeRemaining) != ""
|
||||
? `${toTime(timeRemaining)}remaining`
|
||||
: "";
|
||||
};
|
||||
|
||||
export const getBatteryPercentage = () => {
|
||||
const percent = Battery.percent;
|
||||
return percent > 0 && percent < 100 ? `${percent}%` : "";
|
||||
};
|
||||
|
||||
export const getBatteryTooltip = () => {
|
||||
const time = getBatteryTime();
|
||||
const percent = Battery.percent;
|
||||
|
||||
return `${percent}% | ${time}`;
|
||||
};
|
||||
|
||||
export const getBatteryIcon = () => {
|
||||
// if Battery.percent is not between 0 and 100, handle the error
|
||||
if (Battery.percent < 0 || Battery.percent > 100)
|
||||
return "Battery percentage is not a valid value!";
|
||||
|
||||
const icons = [
|
||||
["", "", "", "", "", "", "", "", "", "", ""],
|
||||
["", "", "", "", "", "", "", "", "", "", ""],
|
||||
];
|
||||
|
||||
const chargingIndex = Battery.charging ? 1 : 0;
|
||||
const percentIndex = Math.floor(Battery.percent / 10);
|
||||
return icons[chargingIndex][percentIndex].toString();
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
import { Bluetooth, Icons } from "../imports.js";
|
||||
|
||||
export const getBluetoothDevice = (addr) =>
|
||||
Bluetooth.getDevice(addr).alias ?? Bluetooth.getDevice(addr).name;
|
||||
|
||||
export const getBluetoothIcon = (connected) => {
|
||||
if (!Bluetooth.enabled) return Icons.bluetooth.disabled;
|
||||
if (connected.length > 0) return Icons.bluetooth.active;
|
||||
return Icons.bluetooth.disconnected;
|
||||
};
|
||||
|
||||
export const getBluetoothTooltip = (connected) => {
|
||||
if (!Bluetooth.enabled) return "Bluetooth off";
|
||||
|
||||
if (connected.length > 0) {
|
||||
const dev = Bluetooth.getDevice(connected[0].address);
|
||||
let battery_str = "";
|
||||
|
||||
if (dev.battery_percentage > 0) {
|
||||
battery_str += ` ${dev.battery_percentage}%`;
|
||||
}
|
||||
|
||||
return dev.name + battery_str;
|
||||
}
|
||||
|
||||
return "Bluetooth on";
|
||||
};
|
||||
|
||||
export const getBluetoothClass = (connected) => {
|
||||
if (!Bluetooth.enabled) return "bluetooth-disabled";
|
||||
|
||||
if (connected.length > 0) {
|
||||
const dev = Bluetooth.getDevice(connected.at(0).address);
|
||||
|
||||
if (dev.battery_percentage <= 25) return "bluetooth-active-low-battery";
|
||||
|
||||
if (dev.battery_percentage > 25) return "bluetooth-paired";
|
||||
}
|
||||
|
||||
return "bluetooth-active";
|
||||
};
|
||||
|
||||
export const getBluetoothLabel = (connected) => {
|
||||
if (!Bluetooth.enabled) return "";
|
||||
|
||||
if (connected.length > 0) {
|
||||
const dev = Bluetooth.getDevice(connected.at(0).address);
|
||||
|
||||
if (dev.battery_percentage <= 25) return "";
|
||||
}
|
||||
|
||||
return "";
|
||||
};
|
36
nyx/homes/notashelf/services/wayland/ags/js/utils/desktop.js
Normal file
36
nyx/homes/notashelf/services/wayland/ags/js/utils/desktop.js
Normal file
|
@ -0,0 +1,36 @@
|
|||
import { Widget } from "../imports.js";
|
||||
import { queryExact } from "./global.js";
|
||||
const { Box, Icon, Label, Button } = Widget;
|
||||
|
||||
/**
|
||||
* Builds a desktop item with a specific name and label.
|
||||
* It uses the `queryExact` function to find the exact application based on its name.
|
||||
* Then, it creates a button widget with the application's icon and label.
|
||||
* When the button is clicked, it launches the application.
|
||||
*
|
||||
* @function buildDesktopItem
|
||||
* @param {string} name - The name of the application.
|
||||
* @param {string} label - The label of the desktop item.
|
||||
* @returns {Object} The desktop item widget.
|
||||
*/
|
||||
export const buildDesktopItem = (name, label) => {
|
||||
const app = queryExact(name);
|
||||
return Button({
|
||||
className: "desktopIcon",
|
||||
cursor: "pointer",
|
||||
onClicked: () => app.launch(),
|
||||
child: Box({
|
||||
vertical: true,
|
||||
children: [
|
||||
Icon({
|
||||
icon: app.iconName,
|
||||
size: 48,
|
||||
}),
|
||||
Label({
|
||||
className: "desktopIconLabel",
|
||||
label,
|
||||
}),
|
||||
],
|
||||
}),
|
||||
});
|
||||
};
|
38
nyx/homes/notashelf/services/wayland/ags/js/utils/global.js
Normal file
38
nyx/homes/notashelf/services/wayland/ags/js/utils/global.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { Applications, Utils } from "../imports.js";
|
||||
const { execAsync } = Utils;
|
||||
const { list, query } = Applications;
|
||||
|
||||
/**
|
||||
* Queries the exact application based on its name.
|
||||
* First tries to find the application in the list of applications.
|
||||
* If it doesn't find it, then it queries the application by its name.
|
||||
*
|
||||
* @function queryExact
|
||||
* @param {string} appName - The name of the application to query.
|
||||
* @returns {Object} The queried application object. Returns null if the application is not found.
|
||||
*/
|
||||
export function queryExact(appName) {
|
||||
return (
|
||||
list.filter(
|
||||
(app) => app.name.toLowerCase() === appName.toLowerCase(),
|
||||
)[0] ?? query(appName)[0]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to launch an application based on its name.
|
||||
* First it tries to kill the application if it's already running.
|
||||
* Regardless of whether the killing has been successful or not, it
|
||||
* tries to launch the application.
|
||||
*
|
||||
* @function launchApp
|
||||
* @param {string} appName - The name of the application to launch.
|
||||
* @returns {void}
|
||||
*/
|
||||
export function launchApp(appName) {
|
||||
if (queryExact(appName)) {
|
||||
execAsync(["sh", "-c", `killall ${appName}`]);
|
||||
}
|
||||
|
||||
execAsync(["sh", "-c", `${appName}`]);
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
import { Hyprland } from "../imports.js";
|
||||
|
||||
export const getFocusedWorkspace = (self) =>
|
||||
self.children.forEach((btn) => {
|
||||
btn.className =
|
||||
btn.attribute.index === Hyprland.active.workspace.id
|
||||
? "focused"
|
||||
: "";
|
||||
btn.visible = Hyprland.workspaces.some(
|
||||
(ws) => ws.id === btn.attribute.index,
|
||||
);
|
||||
});
|
56
nyx/homes/notashelf/services/wayland/ags/js/utils/icons.js
Normal file
56
nyx/homes/notashelf/services/wayland/ags/js/utils/icons.js
Normal file
|
@ -0,0 +1,56 @@
|
|||
export default {
|
||||
bluetooth: {
|
||||
active: "bluetooth-active-symbolic",
|
||||
disabled: "bluetooth-disabled-symbolic",
|
||||
disconnected: "bluetooth-disconnected-symbolic",
|
||||
},
|
||||
|
||||
brightness: "display-brightness-symbolic",
|
||||
|
||||
media: {
|
||||
play: "media-playback-start-symbolic",
|
||||
pause: "media-playback-pause-symbolic",
|
||||
next: "media-skip-forward-symbolic",
|
||||
previous: "media-skip-backward-symbolic",
|
||||
player: "multimedia-player-symbolic",
|
||||
},
|
||||
|
||||
volume: {
|
||||
muted: "audio-volume-muted-symbolic",
|
||||
low: "audio-volume-low-symbolic",
|
||||
medium: "audio-volume-medium-symbolic",
|
||||
high: "audio-volume-high-symbolic",
|
||||
overamplified: "audio-volume-overamplified-symbolic",
|
||||
},
|
||||
|
||||
speaker: {
|
||||
overamplified: "\uf14b",
|
||||
high: "\ue050",
|
||||
medium: "\ue04d",
|
||||
low: "\ue04e",
|
||||
muted: "\ue04f",
|
||||
},
|
||||
|
||||
microphone: {
|
||||
overamplified: "\ue029",
|
||||
high: "\ue029",
|
||||
medium: "\ue029",
|
||||
low: "\ue029",
|
||||
muted: "\ue02b",
|
||||
},
|
||||
|
||||
wired: {
|
||||
power: "",
|
||||
poweroff: "",
|
||||
},
|
||||
|
||||
wifi: {
|
||||
none: "",
|
||||
bad: "",
|
||||
low: "",
|
||||
normal: "",
|
||||
good: "",
|
||||
},
|
||||
|
||||
powerButton: "system-shutdown-symbolic",
|
||||
};
|
|
@ -0,0 +1,3 @@
|
|||
export const getLauncherIcon = (self, windowName, visible) => {
|
||||
windowName === "launcher" && (self.child.label = visible ? "" : "");
|
||||
};
|
46
nyx/homes/notashelf/services/wayland/ags/js/utils/mpris.js
Normal file
46
nyx/homes/notashelf/services/wayland/ags/js/utils/mpris.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { Icons, Utils } from "../imports.js";
|
||||
import GLib from "gi://GLib";
|
||||
|
||||
export const findPlayer = (players) => {
|
||||
// try to get the first active player
|
||||
const activePlayer = players.find((p) => p.playBackStatus == "Playing");
|
||||
if (activePlayer != null) return activePlayer;
|
||||
|
||||
// otherwise get the first "working" player
|
||||
for (const p of players) {
|
||||
if (p.title != "undefined") return p;
|
||||
}
|
||||
};
|
||||
|
||||
export const mprisStateIcon = (status) => {
|
||||
const state = status == "Playing" ? "pause" : "play";
|
||||
return Icons.media[state];
|
||||
};
|
||||
|
||||
export const MEDIA_CACHE_PATH = Utils.CACHE_DIR + "/media";
|
||||
export const blurredPath = MEDIA_CACHE_PATH + "/blurred";
|
||||
|
||||
export const generateBackground = (cover_path) => {
|
||||
const url = cover_path;
|
||||
if (!url) return "";
|
||||
|
||||
const makeBg = (bg) => `background: center/cover url('${bg}')`;
|
||||
|
||||
const blurred = blurredPath + url.substring(MEDIA_CACHE_PATH.length);
|
||||
|
||||
if (GLib.file_test(blurred, GLib.FileTest.EXISTS)) {
|
||||
return makeBg(blurred);
|
||||
}
|
||||
|
||||
Utils.ensureDirectory(blurredPath);
|
||||
Utils.exec(`convert ${url} -blur 0x22 ${blurred}`);
|
||||
|
||||
return makeBg(blurred);
|
||||
};
|
||||
|
||||
export function lengthStr(length) {
|
||||
const min = Math.floor(length / 60);
|
||||
const sec = Math.floor(length % 60);
|
||||
const sec0 = sec < 10 ? "0" : "";
|
||||
return `${min}:${sec0}${sec}`;
|
||||
}
|
40
nyx/homes/notashelf/services/wayland/ags/js/utils/network.js
Normal file
40
nyx/homes/notashelf/services/wayland/ags/js/utils/network.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { Network } from "../imports.js";
|
||||
|
||||
import { Icon } from "../icons.js";
|
||||
const { wifi, wired } = Icon;
|
||||
|
||||
export const getWifiIcon = (strength) => {
|
||||
if (strength < 0.1) return wifi.none;
|
||||
if (strength < 0.26) return wifi.bad;
|
||||
if (strength < 0.51) return wifi.low;
|
||||
if (strength < 0.76) return wifi.normal;
|
||||
if (strength > 0.76) return wifi.good;
|
||||
else return wifi.none;
|
||||
};
|
||||
|
||||
export const getWifiTooltip = (strength, ssid) => {
|
||||
const wifi = Network.wifi;
|
||||
const wifiStrength = `Strength: ${strength * 100}`;
|
||||
|
||||
switch (wifi.internet) {
|
||||
case "connected":
|
||||
return `Connected to ${ssid} | Strength: ${wifiStrength}`;
|
||||
case "connecting":
|
||||
return `Connecting to ${ssid} | Strength: ${wifiStrength}`;
|
||||
case "disconnected":
|
||||
return `Disconnected from ${ssid} | Strength: ${wifiStrength}`;
|
||||
default:
|
||||
return `No connection | Strength: ${wifiStrength}`;
|
||||
}
|
||||
};
|
||||
|
||||
export const getWiredIcon = (internet) => {
|
||||
if (internet === "connected") return wired.power;
|
||||
if (internet === "connecting") return wired.poweroff;
|
||||
if (internet === "disconnected") return wired.poweroff;
|
||||
return wired.poweroff;
|
||||
};
|
||||
|
||||
export const getWiredTooltip = (internet) => {
|
||||
return `Status: ${internet}`;
|
||||
};
|
|
@ -0,0 +1,53 @@
|
|||
import { App, Widget, Utils } from "../imports.js";
|
||||
const { Box, Revealer, Window } = Widget;
|
||||
|
||||
export default ({
|
||||
onOpen = () => {},
|
||||
onClose = () => {},
|
||||
|
||||
name,
|
||||
child,
|
||||
transition = "slide_up",
|
||||
transitionDuration = 250,
|
||||
...props
|
||||
}) => {
|
||||
const window = Window({
|
||||
name,
|
||||
visible: false,
|
||||
...props,
|
||||
|
||||
child: Box({
|
||||
css: `
|
||||
min-height: 2px;
|
||||
min-width: 2px;
|
||||
`,
|
||||
child: Revealer({
|
||||
transition,
|
||||
transitionDuration,
|
||||
child: child || Box(),
|
||||
setup: (self) => {
|
||||
self.hook(App, (rev, currentName, isOpen) => {
|
||||
if (currentName === name) {
|
||||
rev.revealChild = isOpen;
|
||||
|
||||
if (isOpen) {
|
||||
onOpen(window);
|
||||
} else {
|
||||
Utils.timeout(transitionDuration, () => {
|
||||
onClose(window);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
}),
|
||||
}),
|
||||
});
|
||||
window.getChild = () => window.child.children[0].child;
|
||||
window.setChild = (newChild) => {
|
||||
window.child.children[0].child = newChild;
|
||||
window.child.children[0].show_all();
|
||||
};
|
||||
|
||||
return window;
|
||||
};
|
25
nyx/homes/notashelf/services/wayland/ags/js/utils/swallow.js
Normal file
25
nyx/homes/notashelf/services/wayland/ags/js/utils/swallow.js
Normal file
|
@ -0,0 +1,25 @@
|
|||
import { App, Utils } from "../imports.js";
|
||||
const { exec, execAsync } = Utils;
|
||||
|
||||
function genCommand(arg) {
|
||||
return ["sh", "-c", `${App.configDir}/bin/hyprctl_swallow ${arg}`];
|
||||
}
|
||||
|
||||
const swallowQuery = genCommand("query");
|
||||
const swallowToggle = genCommand("toggle");
|
||||
|
||||
export const getSwallowStatus = () => {
|
||||
execAsync(swallowQuery);
|
||||
|
||||
let result = exec("hyprctl -j getoption misc:enable_swallow");
|
||||
return JSON.parse(result).set;
|
||||
};
|
||||
|
||||
export const status = Variable(getSwallowStatus());
|
||||
|
||||
export const toggleSwallowStatus = () => {
|
||||
execAsync(swallowToggle);
|
||||
|
||||
// toggle swallow status
|
||||
status.value = !status.value;
|
||||
};
|
17
nyx/homes/notashelf/services/wayland/ags/js/utils/tray.js
Normal file
17
nyx/homes/notashelf/services/wayland/ags/js/utils/tray.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
import { Widget, SystemTray } from "../imports.js";
|
||||
const { Button, Icon } = Widget;
|
||||
|
||||
export const getTrayItems = (self) => {
|
||||
self.children = SystemTray.items.map((item) =>
|
||||
Button({
|
||||
className: "trayIcon",
|
||||
child: Icon({
|
||||
setup: (self) => self.bind("icon", item, "icon"),
|
||||
}),
|
||||
setup: (self) =>
|
||||
self.bind("tooltip-markup", item, "tooltip-markup"),
|
||||
onPrimaryClick: (_, event) => item.activate(event),
|
||||
onSecondaryClick: (_, event) => item.openMenu(event),
|
||||
}),
|
||||
);
|
||||
};
|
15
nyx/homes/notashelf/services/wayland/ags/js/utils/weather.js
Normal file
15
nyx/homes/notashelf/services/wayland/ags/js/utils/weather.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
import { Variable, App } from "../imports.js";
|
||||
|
||||
export const WeatherValue = Variable(
|
||||
{},
|
||||
{
|
||||
poll: [
|
||||
36000,
|
||||
["sh", "-c", `python ${App.configDir}/bin/weather`],
|
||||
(out) => JSON.parse(out),
|
||||
],
|
||||
},
|
||||
);
|
||||
|
||||
export const getWeatherIcon = (value) => value.text || "...";
|
||||
export const getWeatherTooltip = (value) => value.tooltip || "...";
|
Loading…
Add table
Add a link
Reference in a new issue