270 lines
6.9 KiB
JavaScript
270 lines
6.9 KiB
JavaScript
import cpu from "./services/cpu.js";
|
|
import ram from "./services/ram.js";
|
|
import { launcher } from "./widgets/launcher/launcher.js";
|
|
const { speaker } = await Service.import("audio");
|
|
const mpris = await Service.import("mpris");
|
|
const sway = await Service.import("sway");
|
|
const players = mpris.bind("players");
|
|
const date = Variable("", {
|
|
poll: [1000, 'date "+%H %M %S %b %e"'],
|
|
});
|
|
|
|
App.addIcons(`${App.configDir}/assets`);
|
|
|
|
function Workspaces() {
|
|
return Widget.Box({
|
|
children: Array.from({ length: 10 }, (_, i) => {
|
|
i += 1;
|
|
return Widget.Box({
|
|
class_name: "workspace-button",
|
|
children: [Widget.Label({ hexpand: true, label: i.toString() })],
|
|
hpack: "center",
|
|
setup: (btn) => {
|
|
btn.hook(
|
|
sway,
|
|
(btn) => {
|
|
const ws = sway.getWorkspace(`${i}`);
|
|
btn.toggleClassName(
|
|
"occupied",
|
|
ws?.nodes.length + ws?.floating_nodes.length > 0,
|
|
);
|
|
},
|
|
"notify::workspaces",
|
|
);
|
|
|
|
btn.hook(sway.active.workspace, (btn) => {
|
|
btn.toggleClassName("active", sway.active.workspace.name == i);
|
|
});
|
|
},
|
|
});
|
|
}),
|
|
spacing: 4,
|
|
vertical: true,
|
|
});
|
|
}
|
|
|
|
function ProcessorUsage() {
|
|
return Widget.Box({
|
|
class_name: "system-stats",
|
|
css: cpu.bind("current-usage").as((usage) => {
|
|
let level = (usage * 100).toFixed(0);
|
|
return `
|
|
background: linear-gradient(
|
|
90deg, rgba(26, 27, 38, 0.6) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
|
)`;
|
|
}),
|
|
children: [
|
|
Widget.Icon({
|
|
class_names: ["system-stats-icon"],
|
|
icon: "microchip-symbolic",
|
|
size: 16,
|
|
}),
|
|
Widget.Label({
|
|
class_names: ["system-stats-text"],
|
|
hexpand: true,
|
|
label: cpu.bind("current-usage").as((usage) => {
|
|
return `${(usage * 100).toFixed(0)}%`;
|
|
}),
|
|
}),
|
|
],
|
|
vertical: true,
|
|
});
|
|
}
|
|
|
|
function MemoryUsage() {
|
|
return Widget.Box({
|
|
class_name: "system-stats",
|
|
css: ram.bind("current-usage-percentage").as((usage) => {
|
|
let level = (usage * 100).toFixed(0);
|
|
return `
|
|
background: linear-gradient(
|
|
90deg, rgba(26, 27, 38, 0.6) ${level}%, rgba(26, 27, 38, 0.4) ${level}%
|
|
)`;
|
|
}),
|
|
children: [
|
|
Widget.Icon({
|
|
class_names: ["system-stats-icon"],
|
|
icon: "ram-custom-symbolic",
|
|
size: 16,
|
|
}),
|
|
Widget.Label({
|
|
class_names: ["system-stats-text"],
|
|
hexpand: true,
|
|
label: ram.bind("current-usage-percentage").as((usage) => {
|
|
return `${(usage * 100).toFixed(0)}%`;
|
|
}),
|
|
}),
|
|
],
|
|
tooltip_text: ram.bind("current-usage").as((usage) => {
|
|
let usageGb = (usage / 1024 ** 2).toFixed(2);
|
|
let totalGb = (ram.total_available / 1024 ** 2).toFixed(2);
|
|
return `${usageGb}/${totalGb}GB (${(ram.current_usage_percentage * 100).toFixed(2)}%)`;
|
|
}),
|
|
vertical: true,
|
|
});
|
|
}
|
|
|
|
function CurrentSong(player) {
|
|
return Widget.Box({
|
|
class_name: "music-indicator",
|
|
children: [
|
|
Widget.Box({
|
|
class_name: "album-art",
|
|
css: player.bind("cover_path").as((url) => {
|
|
if (url == undefined) {
|
|
return `
|
|
background-color: rgba(0, 0, 0, 0.2);
|
|
background-image: url('${App.configDir}/assets/music-symbolic.svg');
|
|
background-size: 50% 50%;
|
|
background-repeat: no-repeat;
|
|
background-position: center;
|
|
`;
|
|
}
|
|
return `background-image: url('${url}'); background-size: cover;`;
|
|
}),
|
|
}),
|
|
Widget.Icon({
|
|
class_name: "playback-status",
|
|
icon: player.bind("play-back-status").as((status) => {
|
|
if (status == "Playing") {
|
|
return "media-playback-start";
|
|
} else if (status == "Paused") {
|
|
return "media-playback-pause";
|
|
}
|
|
return "";
|
|
}),
|
|
}),
|
|
],
|
|
// TODO: fill background based on track position
|
|
css: player.bind("position").as((position) => {
|
|
if (position == -1) {
|
|
return "";
|
|
}
|
|
return "";
|
|
}),
|
|
vertical: true,
|
|
});
|
|
}
|
|
|
|
function CTest() {
|
|
// TODO: only show active player
|
|
return Widget.Box({
|
|
vertical: true,
|
|
visible: players.as((p) => p.length > 0),
|
|
children: players.as((p) => p.map(CurrentSong)),
|
|
});
|
|
}
|
|
|
|
function ProfilePicture() {
|
|
return Widget.Box({
|
|
class_name: "profile-picture",
|
|
css: "background-image: url('/home/avery/.face.icon'); background-size: cover",
|
|
});
|
|
}
|
|
|
|
function VolumeWidget() {
|
|
return Widget.Box({
|
|
class_name: "volume-widget",
|
|
children: [
|
|
Widget.Icon({
|
|
icon: speaker.bind("volume").as((l) => {
|
|
let level = l.toFixed(2) * 100;
|
|
if (level == 0) {
|
|
return "audio-volume-muted";
|
|
} else if (level > 0 && level <= 30) {
|
|
return "audio-volume-low";
|
|
} else if (level > 30 && level <= 70) {
|
|
return "audio-volume-medium";
|
|
} else {
|
|
return "audio-volume-high";
|
|
}
|
|
}),
|
|
size: 10,
|
|
}),
|
|
Widget.Box({
|
|
class_name: "volume-box",
|
|
css: speaker.bind("volume").as((l) => {
|
|
let level = l.toFixed(2) * 100;
|
|
if (level >= 0 && level <= 100) {
|
|
return `
|
|
background: linear-gradient(
|
|
90deg, #7aa2f7 ${level}%, #24283b ${level}%
|
|
);
|
|
`;
|
|
} else if (level > 100 && level <= 200) {
|
|
return `
|
|
background: linear-gradient(
|
|
90deg, #f7768e ${level - 100}%, #7aa2f7 ${level - 100}%
|
|
);
|
|
`;
|
|
} else {
|
|
return "background: #f7768e";
|
|
}
|
|
}),
|
|
hpack: "fill",
|
|
}),
|
|
],
|
|
});
|
|
}
|
|
function ClockWidget() {
|
|
return Widget.Box({
|
|
children: [
|
|
Widget.Label({
|
|
class_name: "clock-hours",
|
|
label: date.bind().as((d) => {
|
|
return d.split(" ")[0];
|
|
}),
|
|
}),
|
|
Widget.Label({
|
|
class_name: "clock-minutes",
|
|
label: date.bind().as((d) => {
|
|
return d.split(" ")[1];
|
|
}),
|
|
}),
|
|
Widget.Label({
|
|
class_name: "clock-seconds",
|
|
label: date.bind().as((d) => {
|
|
return d.split(" ")[2];
|
|
}),
|
|
}),
|
|
],
|
|
class_name: "clock",
|
|
vertical: true,
|
|
});
|
|
}
|
|
|
|
const barContainer = Widget.Box({
|
|
class_name: "bar",
|
|
vpack: "fill",
|
|
spacing: 6,
|
|
vertical: true,
|
|
children: [
|
|
Workspaces(),
|
|
Widget.Box({ expand: true, vpack: "fill" }), // Separator
|
|
CTest(),
|
|
ProcessorUsage(),
|
|
MemoryUsage(),
|
|
ClockWidget(),
|
|
],
|
|
});
|
|
|
|
const bar = Widget.Window({
|
|
name: "bar",
|
|
anchor: ["left", "top", "bottom"],
|
|
exclusivity: "exclusive",
|
|
child: barContainer,
|
|
});
|
|
|
|
Utils.monitorFile(
|
|
`${App.configDir}/style.css`,
|
|
|
|
function () {
|
|
App.resetCss;
|
|
App.applyCss(`${App.configDir}/style.css`);
|
|
},
|
|
);
|
|
|
|
App.config({
|
|
style: "./style.css",
|
|
windows: [bar, launcher],
|
|
});
|