update ags

This commit is contained in:
sankalp committed 2024-06-26 00:10:21 +05:45
1 parent 88822cb8e8
commit a9c19bd2e1
134 files changed
+4732 -5813

No files matched your search

+178
View File
@@ -0,0 +1,178 @@
const { Gtk, GLib } = imports.gi;
const lock_command = `hyprlock`;
const logout_command = `loginctl kill-session $XDG_SESSION_ID`;
const shutdown_command = `systemctl poweroff`;
const reboot_command = `systemctl reboot`;
const suspend_command = `systemctl suspend`;
function LockButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Lock",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
class_name: "outline_button",
...props,
})
button.connect('clicked', () => {
clickCount++;
if (clickCount === 2) {
Utils.execAsync(lock_command).catch(print);
clickCount = 0;
}
});
button.connect('focus-out-event', () => {
clickCount = 0;
});
return button
}
function SuspendButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Suspend",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
class_name: "outline_button",
...props,
})
button.connect('clicked', () => {
clickCount++;
if (clickCount === 2) {
Utils.execAsync(`mpc -q pause`).catch();
Utils.execAsync(`playerctl pause`).catch();
Utils.execAsync(suspend_command).catch();
clickCount = 0;
}
});
button.connect('focus-out-event', () => {
clickCount = 0;
});
return button
}
function LogoutButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Logout",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
class_name: "outline_button",
...props,
})
button.connect('clicked', () => {
clickCount++;
if (clickCount === 2) {
Utils.execAsync(logout_command).catch();
clickCount = 0;
}
});
button.connect('focus-out-event', () => {
clickCount = 0;
});
return button
}
function RebootButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Reboot",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
class_name: "outline_button",
...props,
})
button.connect('clicked', () => {
clickCount++;
if (clickCount === 2) {
Utils.execAsync(reboot_command).catch();
clickCount = 0;
}
});
button.connect('focus-out-event', () => {
clickCount = 0;
});
return button
}
function ShutdownButton({ icon, ...props }) {
let clickCount = 0;
let button = Widget.Button({
tooltip_text: "Shutdown",
child: Widget.Label({
label: icon,
class_name: "awesome_icon"
}),
class_name: "outline_button",
...props,
})
button.connect('clicked', () => {
clickCount++;
if (clickCount === 2) {
Utils.execAsync(shutdown_command).catch();
clickCount = 0;
}
});
button.connect('focus-out-event', () => {
clickCount = 0;
});
return button
}
export function Buttons() {
return Widget.Box({
class_name: "sidebar_buttons",
hexpand: true,
spacing: 5,
children: [
LockButton({
icon: "",
hexpand: true,
}),
SuspendButton({
icon: "",
hexpand: true,
}),
LogoutButton({
icon: "",
hexpand: true,
}),
RebootButton({
icon: "",
hexpand: true,
}),
ShutdownButton({
icon: "",
hexpand: true,
})
]
})
}
+16
View File
@@ -0,0 +1,16 @@
import popupwindow from '../misc/popupwindow.js';
import { SideBar } from './sidebar.ts'
export const WINDOW_NAME = "sidebar"
export const sidebar = popupwindow({
name: WINDOW_NAME,
class_name: "sidebar",
visible: false,
keymode: "exclusive",
child: SideBar(),
anchor: ["top", "right", "bottom"],
css: "min-width: 443px;"
})
+387
View File
@@ -0,0 +1,387 @@
const notifications = await Service.import("notifications")
const network = await Service.import('network')
import { OpenSettings } from "apps/settings/main.ts";
import { WINDOW_NAME } from "./main.ts"
const { Gtk } = imports.gi;
const GLib = imports.gi.GLib;
const Gio = imports.gi.Gio;
const idle_inhibitor = Variable(false);
const night_light = Variable(false);
const screen_recorder = Variable(false);
const currentPage = Variable(0);
export const bluetooth_enabled = Variable('off', {
poll: [1000, `${App.configDir}/scripts/bluetooth.sh --get`]
})
const powerProfiles = await Service.import('powerprofiles');
const icons = {
'performance': ' ',
'balanced': ' ',
'power-saver': '󰡵 '
};
function WifiIndicator() {
return Widget.Box({
css: "padding-left: 15px; padding-right: 15px; padding-top: 5px; padding-bottom: 5px;",
children: [
Widget.Label({
label: "\udb82\udd28",
class_name: "awesome_icon",
css: `font-weight: bold; font-size: 20px; margin-right: 0.60em;`,
}),
Widget.Box({
visible: network.wifi.bind('enabled'),
orientation: Gtk.Orientation.VERTICAL,
children: [
Widget.Box([
Widget.Label({
label: "Internet",
}),
]),
Widget.Label({
label: network.wifi.bind('ssid')
.as(ssid => ssid || 'Unknown'),
class_name: "ssid",
xalign: 0,
vpack: "center",
truncate: "end",
}),
]
}),
Widget.Label({
visible: network.wifi.bind('enabled').as(enabled => !enabled),
label: "Internet",
}),
Widget.Box({
halign: Gtk.Align.END,
hexpand: true,
child: Widget.Label({
label: "",
class_name: "awesome_icon",
css: `font-weight: normal; font-size: 15px;`,
})
})
],
})
}
const WiredIndicator = () => Widget.Box({
css: "padding-left: 15px; padding-right: 15px; padding-top: 5px; padding-bottom: 5px;",
children: [
Widget.Icon({
icon: network.wired.bind('icon_name'),
}),
Widget.Label({
label: "Internet",
}),
]
})
const NetworkIndicator = () => Widget.Stack({
children: {
wifi: WifiIndicator(),
wired: WiredIndicator(),
},
shown: network.bind('primary').as(p => p || 'wifi'),
})
function IconAndName({ label, icon, padding = "0.3em", arrow = false }) {
let box = Widget.Box({
css: "padding-left: 15px; padding-right: 15px; padding-top: 5px; padding-bottom: 5px;",
children: [
Widget.Label({
label: icon,
class_name: "awesome_icon",
css: `font-weight: bold; font-size: 20px; margin-right: ${padding};`,
}),
Widget.Label({
label: label,
justification: "center",
}),
]
})
if (arrow) {
const arrow = Widget.Box({
halign: Gtk.Align.END,
hexpand: true,
child: Widget.Label({
label: "",
class_name: "awesome_icon",
css: `font-weight: normal; font-size: 15px;`,
})
})
// @ts-ignore
box.children = [...box.children, arrow]
}
return box
}
function isScreenRecordingOn() {
// Check if wf-recorder is running
// Bash command outputs 0 if yes or 1 if no
let state = Utils.execAsync('bash -c "pidof wf-recorder > /dev/null; echo $?"')
if (state == "0"){
return true
}
else{
return false
}
}
function Page1() {
return Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
spacing: 5,
hexpand: true,
class_name: "management_box",
children: [
Widget.Box({
orientation: Gtk.Orientation.HORIZONTAL,
hexpand: true,
spacing: 2.5,
children: [
Widget.Button({
hexpand: true,
class_name: network.wifi.bind("enabled")
.as(enabled => enabled ? "management_button active" : "management_button"),
child: NetworkIndicator(),
on_primary_click: () => {
network.toggleWifi();
},
on_secondary_click: () => {
App.closeWindow(WINDOW_NAME);
App.openWindow("network");
}
}),
Widget.Button({
hexpand: true,
class_name: bluetooth_enabled.bind()
.as(state => state.trim() == "yes" ? "management_button active" : "management_button"
),
child: IconAndName({
label: "Bluetooth",
icon: "󰂯",
arrow: true,
}),
on_primary_click: () => {
Utils.execAsync(`${App.configDir}/scripts/bluetooth.sh --toggle`)
.then(out => { bluetooth_enabled.setValue(out) })
},
on_secondary_click: () => {
Utils.execAsync("blueman-manager")
App.closeWindow(WINDOW_NAME)
}
})
]
}),
Widget.Box({
orientation: Gtk.Orientation.HORIZONTAL,
spacing: 2.5,
hexpand: true,
children: [
Widget.Button({
hexpand: true,
class_name: idle_inhibitor.bind()
.as(bool => bool ? "management_button active" : "management_button"),
child: IconAndName({
label: "Idle inhibitor",
icon: ""
}),
onClicked: () => {
idle_inhibitor.setValue(!idle_inhibitor.value)
if (idle_inhibitor.value) Utils.execAsync(['bash', '-c', `pidof wayland-idle-inhibitor.py || ${App.configDir}/scripts/wayland-idle-inhibitor.py`]).catch(print)
else Utils.execAsync('pkill -f wayland-idle-inhibitor.py').catch(print);
},
setup: () => {
idle_inhibitor.setValue(!!Utils.exec('pidof wayland-idle-inhibitor.py'));
},
}),
Widget.Button({
hexpand: true,
class_name: notifications.bind("dnd").as((bool) => {
return bool ? "management_button active" : "management_button";
}),
on_clicked: () => {
notifications.dnd = notifications.dnd ? false : true
},
child: IconAndName({
label: "Do Not Disturb",
icon: ""
})
})
]
}),
Widget.Box({
orientation: Gtk.Orientation.HORIZONTAL,
spacing: 2.5,
hexpand: true,
children: [
Widget.Button({
hexpand: true,
class_name: screen_recorder.bind()
.as(bool => bool ? "management_button active" : "management_button"),
on_clicked: (self) => {
screen_recorder.setValue(!screen_recorder.value)
// Adjust indicator
let isRecording = isScreenRecordingOn()
self.toggleClassName("active-button", !isRecording) // Toggles active indicator
self.toggleClassName("recording", !isRecording) // Toggles active indicator
// Starts screen recorder if not running
// Stops screen recorder if running
Utils.execAsync(['bash', '-c', 'mkdir ~/Videos/Screenrecordings; pkill wf-recorder; if [ $? -ne 0 ]; then wf-recorder -f ~/Videos/Screenrecordings/recording_"$(date +\'%b-%d-%Y-%I:%M:%S-%P\')".mp4 -g "$(slurp)" --pixel-format yuv420p; fi']).catch(logError);
},
child: IconAndName({
label: "Screen Recorder",
icon: "",
setup: self=>{}
})
}),
Widget.Button({
hexpand: true,
class_name: night_light.bind()
.as(mode => mode ? "management_button active" : "management_button"),
child: IconAndName({
label: "Night Light",
icon: ""
}),
onClicked: () => {
night_light.setValue(!night_light.value)
Utils.execAsync(`${App.configDir}/scripts/night-light.sh --toggle`)
.then(out => {
if (out.trim() == "enabled") night_light.setValue(true)
else if (out.trim() == "disabled") night_light.setValue(false)
})
.catch(err => {
night_light.setValue(!night_light.value);
});
},
setup: () => {
Utils.execAsync(`${App.configDir}/scripts/night-light.sh --get`)
.then(out => {
if (out.trim() == "enabled") night_light.setValue(true)
else if (out.trim() == "disabled") night_light.setValue(false)
})
.catch(print);
}
})
]
})
]
})
}
function Page2() {
return Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
spacing: 5,
hexpand: true,
class_name: "management_box",
children: [
Widget.Box({
orientation: Gtk.Orientation.HORIZONTAL,
spacing: 2.5,
children: [
Widget.Button({
hexpand: true,
class_name: "management_button",
child: IconAndName({
label: "Color picker",
icon: "",
arrow: true,
}),
on_primary_click: () => {
App.closeWindow(WINDOW_NAME);
Utils.execAsync("sleep 0.5")
.then(() =>
Utils.execAsync("hyprpicker -a").catch(print)
)
.catch(print);
}
}),
Widget.Button({
hexpand: true,
class_name: "management_button",
child: Widget.Box({
children: [
Widget.Label({
label: powerProfiles.bind('active_profile').as(x => icons[x])
}),
Widget.Label({
label: powerProfiles.bind('active_profile').as(x => x.toUpperCase())
})
]
}),
on_clicked: () => {
switch (powerProfiles.active_profile) {
case 'balanced':
powerProfiles.active_profile = 'performance';
break;
case 'power-saver':
powerProfiles.active_profile = 'balanced';
break;
default:
powerProfiles.active_profile = 'power-saver';
break;
};
},
}),
]
})
]
})
}
const createDotButton = (index: number) => Widget.Button({
label: '',
onClicked: () => currentPage.setValue(index),
class_name: currentPage.bind().as(v => v == index ? "dotbutton active" : "dotbutton"),
hexpand: false,
});
export function Management() {
let pages = {
"page1": Page1(),
"page2": Page2()
}
const numberOfPages = Object.keys(pages).length;
const pageNames = Array.from({ length: numberOfPages }, (_, i) => `page${i + 1}`);
const stack = Widget.Stack({
children: pages,
// @ts-ignore
shown: currentPage.bind().as(v => `page${v + 1}`),
transition: "slide_left_right",
transitionDuration: 200,
})
const dotButtons = pageNames.map((_, index) => createDotButton(index));
return Widget.EventBox({
onScrollUp: () => currentPage.setValue((currentPage.value + 1) % numberOfPages),
onScrollDown: () => {
if (currentPage.value - 1) {
currentPage.setValue(numberOfPages - 1)
return
}
currentPage.setValue(currentPage.value - 1);
},
child: Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
children: [
stack,
Widget.Box({
children: dotButtons,
class_name: "dotbuttons_box",
halign: Gtk.Align.CENTER,
})
]
})
})
}
+88
View File
@@ -0,0 +1,88 @@
const { Gtk } = imports.gi;
import { NotificationsBox } from "./notifications.ts"
import { SystemBox } from "./system.ts"
let shown = Variable("Messages");
type ButtonType = {
page: string,
label: string,
icon: string
}
function Button({ page, label, icon }: ButtonType) {
return Widget.Button({
class_name: shown.bind().as(_page => _page == page ? "navigation_button active" : "navigation_button"),
hexpand: true,
child: Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
class_name: "container_outer",
children: [
Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
halign: Gtk.Align.CENTER,
class_name: "container",
child: Widget.Label({
hpack: "center",
label: icon,
class_name: "awesome_icon icon"
}),
}),
Widget.Label({
label: label,
class_name: "label",
})
]
}),
on_clicked: () => {
shown.setValue(page)
}
})
}
export function Navigation() {
const messages_apps = ["discord", "materialgram", "Telegram Desktop"]
let stack = Widget.Stack({
children: {
"Messages": NotificationsBox({ include: messages_apps }),
"Notifications": NotificationsBox({ exclude: messages_apps }),
"System": SystemBox()
},
transition: "crossfade",
transitionDuration: 200,
// @ts-ignore
shown: shown.bind()
})
const buttons = Widget.Box({
class_name: "navigation",
hexpand: true,
children: [
Button({
page: "Messages",
label: "Messages",
icon: ""
}),
Button({
page: "Notifications",
label: "Notifs",
icon: ""
}),
Button({
page: "System",
label: "System",
icon: ""
})
]
})
return Widget.Box({
vexpand: true,
orientation: Gtk.Orientation.VERTICAL,
class_name: "sidebar_bottom",
children: [
stack,
buttons
]
})
}
@@ -0,0 +1,183 @@
import { Notification as NotificationType } from "types/service/notifications";
const notifications = await Service.import("notifications")
const { Gtk, Gdk } = imports.gi;
function NotificationIcon({ app_entry, app_icon, image }: NotificationType) {
if (image) {
return Widget.Box({
css: `background-image: url("${image}");`
+ "background-size: contain;"
+ "background-repeat: no-repeat;"
+ "background-position: center;",
})
}
let icon = "dialog-information-symbolic"
if (Utils.lookUpIcon(app_icon))
icon = app_icon
if (app_entry && Utils.lookUpIcon(app_entry))
icon = app_entry
return Widget.Box({
child: Widget.Icon(icon),
})
}
function Notification(n: NotificationType) {
const icon = Widget.Box({
vpack: "start",
class_name: "notification_sidebar_icon",
child: NotificationIcon(n),
})
const title = Widget.Label({
class_name: "notification_sidebar_title",
wrap: true,
label: n.summary,
use_markup: true,
hpack: "start",
xalign: 0
})
const body = Widget.Label({
class_name: "notification_sidebar_body",
label: n.body,
wrap: true,
use_markup: true,
hpack: "start",
xalign: 0
})
const actions = Widget.Box({
halign: Gtk.Align.END,
class_name: "notification_sidebar_actions",
children: n.actions.map(({ id, label }) => Widget.Button({
class_name: "notification_sidebar_button",
on_clicked: () => {
n.invoke(id)
},
hexpand: false,
child: Widget.Label(label),
})),
})
let Box = Widget.EventBox(
{
attribute: { id: n.id },
on_secondary_click: () => n.close(),
},
Widget.Box(
{
class_name: `notification_sidebar ${n.urgency}`,
vertical: true,
},
Widget.Box([
icon,
Widget.Box(
{
vertical: true,
hexpand: true,
},
title,
body,
),
]),
actions,
),
)
return Box
}
type NotificationsBoxType = {
exclude?: string[],
include?: string[]
}
export function NotificationsBox({ exclude = [], include = [] }: NotificationsBoxType) {
let isEmpty = Variable(false)
const list = Widget.Box({
vertical: true,
children: notifications.popups.map(Notification)
})
const _list = Widget.Box({
vertical: true,
children: [
list,
Widget.Label({
label: "Empty",
visible: isEmpty.bind(),
class_name: "empty"
})
],
class_name: "notifications_list_sidebar"
})
function setIsEmpty() {
if (list.children.length > 0) isEmpty.setValue(false)
else isEmpty.setValue(true)
}
function onNotified(_: any, id: number) {
const n = notifications.getNotification(id)
if (n) {
if (exclude.includes(n.app_name.trim()))
return
if (include.length == 0 || include.includes(n.app_name.trim())) {
const notificationWidget = Notification(n)
list.children = [notificationWidget, ...list.children]
setIsEmpty()
}
}
}
function onClosed(_: any, id: number) {
list.children.find(n => n.attribute.id === id)?.destroy()
setIsEmpty()
}
list.hook(notifications, onNotified, "notified")
.hook(notifications, onClosed, "closed")
const menu = Widget.Menu({
class_name: "notifications_menu",
children: [
Widget.MenuItem({
child: Widget.Label('Close all'),
class_name: "notifications_menu_item",
on_activate: () => {
for (let x of list.children) {
const n = notifications.getNotification(x.attribute.id)
if (n) {
n.dismiss()
n.close()
}
}
}
}),
],
})
return Widget.EventBox({
vexpand: true,
hexpand: true,
on_secondary_click: (_, event) => {
menu.popup_at_pointer(event)
},
child: Widget.Scrollable({
class_name: "notifications_sidebar_scrollable",
hscroll: "never",
child: _list,
hexpand: true
/** this is a simple one liner that could be used instead of
hooking into the 'notified' and 'dismissed' signals.
but its not very optimized becuase it will recreate
the whole list everytime a notification is added or dismissed */
// children: notifications.bind('popups')
// .as(popups => popups.map(Notification))
}),
})
}
@@ -0,0 +1,76 @@
import { Notification as NotificationType } from "types/service/notifications";
import { NotificationPopups, Notification } from "modules/notificationPopups";
import Box from "types/widgets/box";
const notifications = await Service.import("notifications")
const { Gtk, Gdk } = imports.gi;
type NotificationsBoxType = {
exclude?: string[],
include?: string[]
}
const NotificationNoReveal = (notification: NotificationType, visible = false, dismiss = true) => {
type BoxAttrs = {
destroyWithAnims: any,
count: number,
id: number,
}
const _notification = Notification(notification, dismiss);
let box: Box<any, BoxAttrs>;
const destroyWithAnims = () => {
box.destroy();
};
box = Widget.Box({
hexpand: true,
attribute: {
"destroyWithAnims": destroyWithAnims,
count: 0,
id: notification.id,
},
children: [_notification],
});
return box;
};
export function NotificationsBox({ exclude = [], include = [] }: NotificationsBoxType) {
const popups = NotificationPopups(
false, { exclude: exclude, include: include },
false, NotificationNoReveal
);
const menu = Widget.Menu({
class_name: "notifications_menu",
children: [
Widget.MenuItem({
child: Widget.Label('Close all'),
class_name: "notifications_menu_item",
on_activate: () => {
for (let n of notifications.notifications) {
if (n) {
n.dismiss()
n.close()
}
}
}
}),
],
})
return Widget.EventBox({
vexpand: true,
hexpand: true,
on_secondary_click: (_, event) => {
menu.popup_at_pointer(event)
},
child: Widget.Scrollable({
class_name: "notifications_sidebar_scrollable",
hscroll: "never",
child: popups,
hexpand: true
}),
})
}
+18
View File
@@ -0,0 +1,18 @@
import { Management } from "./management.ts"
import { Buttons } from "./buttons.ts";
import { Navigation } from "./navigation.ts";
const { Gtk } = imports.gi;
export function SideBar() {
return Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
class_name: "sidebar_main_box",
hexpand: true,
children: [
Management(),
Buttons(),
Navigation()
// NotificationsBox()
]
})
}
+210
View File
@@ -0,0 +1,210 @@
import { Variable as VariableType } from "types/variable";
const { Gtk } = imports.gi;
const cpu_name = await Utils.execAsync(`${App.configDir}/scripts/system.sh --cpu-name`);
const cpu_cores = await Utils.execAsync(`${App.configDir}/scripts/system.sh --cpu-cores`);
const amount_of_ram = await Utils.execAsync(`${App.configDir}/scripts/system.sh --ram`);
const kernel_name = await Utils.execAsync(`${App.configDir}/scripts/system.sh --kernel`);
type InfoType = {
cpu: string,
ram: string,
swap: string,
cpu_temp: string
}
async function SystemInfo(): Promise<InfoType> {
const cpu_usage = await Utils.execAsync(`${App.configDir}/scripts/system.sh --cpu-usage`)
.then(str => String(str))
.catch(err => {
print(err)
return "0"
});
const ram_usage = await Utils.execAsync(`${App.configDir}/scripts/system.sh --ram-usage`)
.then(str => String(str))
.catch(err => {
print(err)
return "0"
});
const swap_usage = await Utils.execAsync(`${App.configDir}/scripts/system.sh --swap-usage`)
.then(str => String(str))
.catch(err => {
print(err)
return "0"
});
const cpu_temp = await Utils.execAsync(`${App.configDir}/scripts/system.sh --cpu-temp`)
.then(str => String(str))
.catch(err => {
print(err)
return "0"
});
return {
cpu: cpu_usage,
ram: ram_usage,
swap: swap_usage,
cpu_temp: cpu_temp
}
}
const usage = Variable({
cpu: "0",
ram: "0",
swap: "0",
cpu_temp: "0"
} as unknown as Promise<InfoType>, {
poll: [1000, async () => {
const result = await SystemInfo()
.then(result => result)
return result
}]
})
function checkBacklight() {
const get = Utils.execAsync(`${App.configDir}/scripts/backlight.sh --get`)
.then(out => Number(out.trim()))
.catch(print);
return get
}
function checkBrightness() {
const get = Utils.execAsync(`${App.configDir}/scripts/brightness.sh --get`)
.then(out => Number(out.trim()))
.catch(print);
return get
}
const current_backlight = Variable(100, {
poll: [500, checkBacklight]
})
const current_brightness = Variable(100, {
poll: [500, checkBrightness]
})
const Usage = (
name: string, var_name: keyof InfoType,
class_name: string | undefined
) => {
const usage_progress_bar = Widget.ProgressBar({
class_name: "usage_bar",
value: usage.bind().as(usage => Number(usage[var_name]) / 100),
})
const usage_overlay = Widget.Overlay({
child: usage_progress_bar,
overlay: Widget.Box({
halign: Gtk.Align.END,
valign: Gtk.Align.CENTER,
class_name: "usage_bar_point"
})
})
const _usage = Widget.Box({
class_name: `${class_name} usage_box`,
orientation: Gtk.Orientation.VERTICAL,
children: [
Widget.Label({
label: usage.bind().as(usage => `${name}: ${usage[var_name]}%`),
hpack: "start",
vpack: "center"
}),
usage_overlay
]
})
return _usage
}
const InfoLabel = (name: string, var_name: keyof InfoType, end: string) => {
return Widget.Label({
class_name: "info_label",
truncate: "end",
hpack: "start",
label: usage.bind().as(usage => `${name}: ${usage[var_name]}${end}`)
})
}
const InfoLabelString = (name: string, value: string, end: string) => {
return Widget.Label({
class_name: "info_label",
truncate: "end",
hpack: "start",
label: `${name}: ${value}${end}`
})
}
export function SystemBox() {
const backlight = Widget.Slider({
min: 0,
max: 100,
draw_value: false,
class_name: "system_scale backlight",
// @ts-ignore
value: current_backlight.bind(),
on_change: self => {
current_backlight.setValue(Number(self.value));
Utils.execAsync(`${App.configDir}/scripts/backlight.sh --smooth ${self.value}`)
.catch(print);
},
tooltip_markup: "Backlight"
})
const brightness = Widget.Slider({
min: 0,
max: 1,
draw_value: false,
class_name: "system_scale brightness",
// @ts-ignore
value: current_brightness.bind(),
on_change: self => {
current_brightness.setValue(Number(self.value));
Utils.execAsync(`${App.configDir}/scripts/brightness.sh --set ${self.value}`)
.catch(print);
},
tooltip_markup: "Brightness"
})
const slider_box = Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
class_name: "slider_box",
children: [
backlight,
brightness
]
})
const usage_box = Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
class_name: "usage_box",
spacing: 0,
children: [
Usage("CPU", "cpu", "cpu_usage"),
Usage("RAM", "ram", "ram_usage"),
Usage("SWAP", "swap", "swap_usage")
]
})
const info_box = Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
class_name: "info_box",
spacing: 0,
children: [
InfoLabel("CPU temp", "cpu_temp", "°C"),
InfoLabelString("CPU name", cpu_name, ""),
InfoLabelString("CPU cores", cpu_cores, ""),
InfoLabelString("RAM amount", amount_of_ram, ""),
InfoLabelString("Kernel", kernel_name, "")
],
vexpand: true
})
return Widget.Scrollable({
child: Widget.Box({
orientation: Gtk.Orientation.VERTICAL,
class_name: "system_box",
spacing: 10,
children: [
slider_box,
usage_box,
info_box
]
})
})
}