Files
custum-hyprpanel/modules/menus/dashboard/stats/index.ts
Rubin Bhandari 37ab13a829 fix: dont hardcode file manager and make use of $TERM (#361)
* feat: make executables dynamic

* feat: make executables dynamic

* Update modules/menus/dashboard/stats/index.ts

Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>

* Update widget/settings/pages/config/general/index.ts

Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>

* Update options.ts

Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>

* Update modules/menus/dashboard/stats/index.ts

Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>

* fix: var to term

---------

Co-authored-by: Jas Singh <jaskiratpal.singh@outlook.com>
2024-10-25 23:12:33 -07:00

266 lines
11 KiB
TypeScript

import options from 'options';
import Ram from 'services/Ram';
import { GPU_Stat } from 'lib/types/gpustat';
import { dependencies } from 'lib/utils';
import { BoxWidget } from 'lib/types/widget';
import Cpu from 'services/Cpu';
import Storage from 'services/Storage';
import { renderResourceLabel } from 'customModules/utils';
const { terminal } = options;
const { enable_gpu, interval } = options.menus.dashboard.stats;
const ramService = new Ram();
const cpuService = new Cpu();
const storageService = new Storage();
ramService.setShouldRound(true);
storageService.setShouldRound(true);
interval.connect('changed', () => {
ramService.updateTimer(interval.value);
cpuService.updateTimer(interval.value);
storageService.updateTimer(interval.value);
});
const handleClick = (): void => {
App.closeWindow('dashboardmenu');
Utils.execAsync(`bash -c "${terminal} -e btop"`).catch((err) => `Failed to open btop: ${err}`);
};
const Stats = (): BoxWidget => {
const divide = ([total, free]: number[]): number => free / total;
const gpu = Variable(0);
const GPUStat = Widget.Box({
child: enable_gpu.bind('value').as((gpStat) => {
if (!gpStat || !dependencies('gpustat')) {
return Widget.Box();
}
return Widget.Box({
vertical: true,
children: [
Widget.Box({
class_name: 'stat gpu',
hexpand: true,
vpack: 'center',
setup: (self) => {
const getGpuUsage = (): void => {
if (!enable_gpu.value) {
gpu.value = 0;
return;
}
Utils.execAsync('gpustat --json')
.then((out) => {
if (typeof out !== 'string') {
return 0;
}
try {
const data = JSON.parse(out);
const totalGpu = 100;
const usedGpu =
data.gpus.reduce((acc: number, gpu: GPU_Stat) => {
return acc + gpu['utilization.gpu'];
}, 0) / data.gpus.length;
gpu.value = divide([totalGpu, usedGpu]);
} catch (e) {
console.error('Error getting GPU stats:', e);
gpu.value = 0;
}
})
.catch((err) => {
console.error(`An error occurred while fetching GPU stats: ${err}`);
});
};
self.poll(2000, getGpuUsage);
Utils.merge([gpu.bind('value'), enable_gpu.bind('value')], (gpu, enableGpu) => {
if (!enableGpu) {
return (self.children = []);
}
return (self.children = [
Widget.Button({
on_primary_click: () => {
handleClick();
},
child: Widget.Label({
class_name: 'txt-icon',
label: '󰢮',
}),
}),
Widget.Button({
on_primary_click: () => {
handleClick();
},
child: Widget.LevelBar({
class_name: 'stats-bar',
hexpand: true,
vpack: 'center',
value: gpu,
}),
}),
]);
});
},
}),
Widget.Box({
hpack: 'end',
children: Utils.merge([gpu.bind('value'), enable_gpu.bind('value')], (gpuUsed, enableGpu) => {
if (!enableGpu) {
return [];
}
return [
Widget.Label({
class_name: 'stat-value gpu',
label: `${Math.floor(gpuUsed * 100)}%`,
}),
];
}),
}),
],
});
}),
});
return Widget.Box({
class_name: 'dashboard-card stats-container',
vertical: true,
vpack: 'fill',
hpack: 'fill',
expand: true,
children: [
Widget.Box({
vertical: true,
children: [
Widget.Box({
class_name: 'stat cpu',
hexpand: true,
vpack: 'center',
children: [
Widget.Button({
on_primary_click: () => {
handleClick();
},
child: Widget.Label({
class_name: 'txt-icon',
label: '',
}),
}),
Widget.Button({
on_primary_click: () => {
handleClick();
},
child: Widget.LevelBar({
class_name: 'stats-bar',
hexpand: true,
vpack: 'center',
bar_mode: 'continuous',
max_value: 1,
value: cpuService.cpu.bind('value').as((cpuUsage) => Math.round(cpuUsage) / 100),
}),
}),
],
}),
Widget.Label({
hpack: 'end',
class_name: 'stat-value cpu',
label: cpuService.cpu.bind('value').as((cpuUsage) => `${Math.round(cpuUsage)}%`),
}),
],
}),
Widget.Box({
vertical: true,
children: [
Widget.Box({
class_name: 'stat ram',
vpack: 'center',
hexpand: true,
children: [
Widget.Button({
on_primary_click: () => {
handleClick();
},
child: Widget.Label({
class_name: 'txt-icon',
label: '',
}),
}),
Widget.Button({
on_primary_click: () => {
handleClick();
},
child: Widget.LevelBar({
class_name: 'stats-bar',
hexpand: true,
vpack: 'center',
value: ramService.ram.bind('value').as((ramUsage) => {
return ramUsage.percentage / 100;
}),
}),
}),
],
}),
Widget.Label({
hpack: 'end',
class_name: 'stat-value ram',
label: ramService.ram
.bind('value')
.as((ramUsage) => `${renderResourceLabel('used/total', ramUsage, true)}`),
}),
],
}),
GPUStat,
Widget.Box({
vertical: true,
children: [
Widget.Box({
class_name: 'stat storage',
hexpand: true,
vpack: 'center',
children: [
Widget.Button({
on_primary_click: () => {
handleClick();
},
child: Widget.Label({
class_name: 'txt-icon',
label: '󰋊',
}),
}),
Widget.Button({
on_primary_click: () => {
handleClick();
},
child: Widget.LevelBar({
class_name: 'stats-bar',
hexpand: true,
vpack: 'center',
value: storageService.storage
.bind('value')
.as((storageUsage) => storageUsage.percentage / 100),
}),
}),
],
}),
Widget.Label({
hpack: 'end',
class_name: 'stat-value storage',
label: storageService.storage
.bind('value')
.as((storageUsage) => `${renderResourceLabel('used/total', storageUsage, true)}`),
}),
],
}),
],
});
};
export { Stats };