added stuff

This commit is contained in:
Charlie Root 2024-04-09 23:11:33 +02:00
commit 9d0ebdfbd0
907 changed files with 70990 additions and 0 deletions

View file

@ -0,0 +1,71 @@
import { Widget } from "../../imports.js";
const { Window, Box, CenterBox } = Widget;
// Widgets
import { LauncherIcon } from "./modules/launcher.js";
import { Workspaces } from "./modules/workspaces.js";
import { Tray } from "./modules/tray.js";
import { BatteryWidget } from "./modules/battery.js";
import { Clock } from "./modules/clock.js";
import { PowerMenu } from "./modules/power.js";
import { Swallow } from "./modules/swallow.js";
import { BluetoothWidget } from "./modules/bluetooth.js";
import { AudioWidget } from "./modules/audio.js";
import { NetworkWidget } from "./modules/network.js";
import { SystemUsage } from "./modules/system.js";
import { Weather } from "./modules/weather.js";
const Top = () =>
Box({
className: "barTop",
vertical: true,
vpack: "start",
children: [LauncherIcon(), SystemUsage(), Weather()],
});
const Center = () =>
Box({
className: "barCenter",
vertical: true,
children: [Workspaces()],
});
const Bottom = () =>
Box({
className: "barBottom",
vertical: true,
vpack: "end",
children: [
Tray(),
Box({
className: "utilsBox",
vertical: true,
children: [
BluetoothWidget(),
AudioWidget(),
Swallow(),
BatteryWidget(),
NetworkWidget(),
],
}),
Clock(),
PowerMenu(),
],
});
export const Bar = ({ monitor } = {}) =>
Window({
name: "bar",
anchor: ["top", "bottom", "left"],
exclusivity: "exclusive",
layer: "top",
margins: [8, 0, 8, 8],
monitor,
child: CenterBox({
className: "bar",
vertical: true,
startWidget: Top(),
centerWidget: Center(),
endWidget: Bottom(),
}),
});

View file

@ -0,0 +1,22 @@
import { Audio, Widget } from "../../../imports.js";
import { getAudioIcon } from "../../../utils/audio.js";
import { launchApp } from "../../../utils/global.js";
const { Button, Icon } = Widget;
const AudioIcon = () =>
Icon({
setup: (self) => {
self.hook(Audio, getAudioIcon, "speaker-changed");
},
});
export const AudioWidget = () => {
return Button({
className: "audio",
cursor: "pointer",
visible: true,
child: AudioIcon(),
onClicked: () => launchApp("pavucontrol"),
});
};

View file

@ -0,0 +1,35 @@
import { Widget, Battery } from "../../../imports.js";
import {
getBatteryPercentage,
getBatteryTooltip,
getBatteryIcon,
} from "../../../utils/battery.js";
const { Button, Box, Label, Revealer } = Widget;
const BatIcon = () =>
Label({ className: "batIcon" })
// NOTE: label needs to be used instead of icon here
.bind("label", Battery, "percent", getBatteryIcon)
.bind("tooltip-text", Battery, "percent", getBatteryTooltip);
const BatStatus = () =>
Revealer({
transition: "slide_down",
transition_duration: 200,
child: Label().bind("label", Battery, "percent", getBatteryPercentage),
});
export const BatteryWidget = () =>
Button({
onPrimaryClick: (self) => {
self.child.children[1].revealChild =
!self.child.children[1].revealChild;
},
child: Box({
className: "battery",
cursor: "pointer",
vertical: true,
children: [BatIcon(), BatStatus()],
visible: Battery.bind("available"),
}),
});

View file

@ -0,0 +1,29 @@
import { Bluetooth, Widget, Utils } from "../../../imports.js";
import {
getBluetoothIcon,
getBluetoothLabel,
getBluetoothClass,
getBluetoothTooltip,
} from "../../../utils/bluetooth.js";
const { Button, Label } = Widget;
const BluetoothModule = () =>
Label({ className: "bluetoothIcon" })
.bind("label", Bluetooth, "connected-devices", getBluetoothIcon)
.bind("class", Bluetooth, "connected-devices", getBluetoothClass)
.bind("label", Bluetooth, "connected-devices", getBluetoothLabel)
.bind(
"tooltip-text",
Bluetooth,
"connected-devices",
getBluetoothTooltip,
);
export const BluetoothWidget = () =>
Button({
className: "bluetooth",
cursor: "pointer",
child: BluetoothModule(),
visible: Bluetooth.connectedDevices.length > 0,
onClicked: () => Utils.exec("blueman-applet"),
});

View file

@ -0,0 +1,26 @@
import { Widget, Utils } from "../../../imports.js";
const { exec, execAsync } = Utils;
const { Label, Box } = Widget;
const Time = () =>
Label({
className: "timeLabel",
setup: (self) => {
// the current quote syntax is the only one that works
// eslint-disable-next-line quotes
self.poll(1000, (self) => (self.label = exec('date "+%H%n%M"')));
self.poll(1000, (self) =>
execAsync(["date", "+%H%n%M"])
.then((time) => (self.label = time))
// eslint-disable-next-line no-undef
.catch(print.error),
);
},
});
export const Clock = () =>
Box({
className: "clock",
vertical: true,
children: [Time()],
});

View file

@ -0,0 +1,15 @@
import { Widget, App } from "../../../imports.js";
import { getLauncherIcon } from "../../../utils/launcher.js";
const { Button, Label } = Widget;
export const LauncherIcon = () =>
Button({
vexpand: false,
className: "launcherIcon",
cursor: "pointer",
child: Label("󱢦"),
onClicked: () => App.toggleWindow("launcher"),
setup: (self) => {
self.hook(App, getLauncherIcon, "window-toggled");
},
});

View file

@ -0,0 +1,10 @@
import { Widget, Utils } from "../../../imports.js";
const { Button, Label } = Widget;
export const Lock = () =>
Button({
className: "lock",
cursor: "pointer",
child: Label(""),
onClicked: () => Utils.exec("swaylock"),
});

View file

@ -0,0 +1,34 @@
import { Network, Widget, Utils } from "../../../imports.js";
import {
getWifiIcon,
getWifiTooltip,
getWiredIcon,
getWiredTooltip,
} from "../../../utils/network.js";
const { Stack, Button, Label } = Widget;
const WifiIndicator = () =>
Label({ has_tooltip: true })
.bind("label", Network.wifi, "strength", getWifiIcon)
.bind("tooltip-text", Network.wifi, "strength", getWifiTooltip);
const WiredIndicator = () =>
Label({ cursor: "pointer" })
.bind("label", Network.wired, "internet", getWiredIcon)
.bind("tooltip-text", Network.wired, "internet", getWiredTooltip);
export const NetworkWidget = () =>
Button({
className: "network",
cursor: "pointer",
onClicked: () => Utils.exec("nm-connection-editor"),
child: Stack({
shown: Network.bind("primary").as(
(/** @type {any} */ p) => p || "wifi",
),
children: {
wifi: WifiIndicator(),
wired: WiredIndicator(),
},
}),
});

View file

@ -0,0 +1,10 @@
import { Widget } from "../../../imports.js";
const { Button, Label } = Widget;
export const PowerMenu = () =>
Button({
vexpand: false,
className: "power",
cursor: "pointer",
child: Label(""),
});

View file

@ -0,0 +1,15 @@
import { Widget } from "../../../imports.js";
const { Label, Button } = Widget;
import { toggleSwallowStatus, status } from "../../../utils/swallow.js";
export const Swallow = () =>
Button({
className: "swallow",
cursor: "pointer",
tooltipText: `Swallow: ${status.value}`,
onPrimaryClick: toggleSwallowStatus,
child: Label({
label: "󰊰",
}),
}).hook(status, (self) => (self.tooltipText = `${status.value}`));

View file

@ -0,0 +1,134 @@
import { Variable, Widget } from "../../../imports.js";
const { Button, Revealer, Box, Label, CircularProgress } = Widget;
const getMemClass = (v) => {
const val = v * 100;
const className = [
[100, "memCritical"],
[75, "memHigh"],
[35, "memMod"],
[5, "memLow"],
[0, "memIdle"],
[-1, "memRevealer"],
].find(([threshold]) => threshold <= val)[1];
return className;
};
const getCpuClass = (v) => {
const val = v * 100;
const className = [
[100, "cpuCritical"],
[75, "cpuHigh"],
[35, "cpuMod"],
[5, "cpuLow"],
[0, "cpuIdle"],
[-1, "cpuRevealer"],
].find(([threshold]) => threshold <= val)[1];
return className;
};
const divide = ([total, free]) => free / total;
const cpu = Variable(0, {
poll: [
2000,
"top -b -n 1",
(out) =>
divide([
100,
out
.split("\n")
.find((line) => line.includes("Cpu(s)"))
.split(/\s+/)[1]
.replace(",", "."),
]),
],
});
const mem = Variable(0, {
poll: [
2000,
"free",
(out) =>
divide(
out
.split("\n")
.find((line) => line.includes("Mem:"))
.split(/\s+/)
.splice(1, 2),
),
],
});
/**
* @param {string} name
* @param {typeof cpu | typeof ram} process
* @param {Array<any>} extraChildren
* @param {() => void} onPrimary
*/
const systemWidget = (name, process, extraChildren = [], onPrimary) =>
Button({
className: name + "Button",
onPrimaryClick: onPrimary,
child: Box({
className: name,
vertical: true,
children: [
CircularProgress({
className: name + "Progress",
// binds: [["value", process]],
rounded: true,
inverted: false,
startAt: 0.27,
}).bind("value", process),
...extraChildren,
],
}),
});
const CPU = systemWidget(
"cpu",
cpu,
[
Revealer({
transition: "slide_down",
child: Label()
.bind("label", cpu, "value", (v) => `${Math.floor(v * 100)}%`)
.bind("className", cpu, "value", getCpuClass),
transition_duration: 250,
}),
],
(self) => {
self.child.children[1].revealChild =
!self.child.children[1].revealChild;
},
);
const MEM = systemWidget(
"mem",
mem,
[
Revealer({
transition: "slide_down",
child: Label()
.bind("label", mem, "value", (v) => `${Math.floor(v * 100)}%`)
.bind("className", cpu, "value", getMemClass),
transition_duration: 250,
}),
],
(self) => {
self.child.children[1].revealChild =
!self.child.children[1].revealChild;
},
);
export const SystemUsage = () =>
Box({
className: "systemUsage",
vertical: true,
cursor: "pointer",
children: [CPU, MEM],
});

View file

@ -0,0 +1,40 @@
import { Widget, SystemTray } from "../../../imports.js";
import { getTrayItems } from "../../../utils/tray.js";
const { Box, EventBox, Label, Revealer } = Widget;
const RevIcon = () =>
Label({
className: "trayChevron",
label: "",
});
const TrayItems = () =>
Box({
className: "trayIcons",
vertical: true,
setup: (self) => {
self.hook(SystemTray, getTrayItems);
},
});
export const Tray = () =>
EventBox({
onPrimaryClick: (self) => {
self.child.children[0].label = self.child.children[1].revealChild
? ""
: "";
self.child.children[1].revealChild =
!self.child.children[1].revealChild;
},
child: Box({
className: "tray",
vertical: true,
children: [
RevIcon(),
Revealer({
transition: "slide_up",
child: TrayItems(),
}),
],
}),
});

View file

@ -0,0 +1,24 @@
import { Widget } from "../../../imports.js";
import {
WeatherValue,
getWeatherIcon,
getWeatherTooltip,
} from "../../../utils/weather.js";
const { Label } = Widget;
const weatherWidget = () =>
Label({
hexpand: false,
vexpand: false,
class_name: "weather",
setup: (self) => {
self.bind("label", WeatherValue, "value", getWeatherIcon);
self.bind("tooltip-text", WeatherValue, "value", getWeatherTooltip);
},
});
export const Weather = () =>
Widget.CenterBox({
vertical: true,
centerWidget: weatherWidget(),
});

View file

@ -0,0 +1,25 @@
import { Widget, Hyprland } from "../../../imports.js";
import { getFocusedWorkspace } from "../../../utils/hyprland.js";
const { Box, Button } = Widget;
const { messageAsync } = Hyprland;
export const Workspaces = () =>
Box({
className: "workspaces",
child: Box({
vertical: true,
children: Array.from({ length: 10 }, (_, i) => i + 1).map((i) =>
Button({
cursor: "pointer",
attribute: { index: i },
onClicked: () => messageAsync(`dispatch workspace ${i}`),
onSecondaryClick: () =>
messageAsync(`dispatch movetoworkspacesilent ${i}`),
}),
),
setup: (self) => {
self.hook(Hyprland, getFocusedWorkspace);
},
}),
});