237 lines
9.4 KiB
JavaScript
237 lines
9.4 KiB
JavaScript
// This is for the right pills of the bar.
|
|
import Widget from 'resource:///com/github/Aylur/ags/widget.js';
|
|
import * as Utils from 'resource:///com/github/Aylur/ags/utils.js';
|
|
const { Box, Label, Button, Overlay, Revealer, Scrollable, Stack, EventBox } = Widget;
|
|
const { exec, execAsync } = Utils;
|
|
const { GLib } = imports.gi;
|
|
import Battery from 'resource:///com/github/Aylur/ags/service/battery.js';
|
|
import { MaterialIcon } from '../../.commonwidgets/materialicon.js';
|
|
import { AnimatedCircProg } from "../../.commonwidgets/cairo_circularprogress.js";
|
|
import { WWO_CODE, WEATHER_SYMBOL, NIGHT_WEATHER_SYMBOL } from '../../.commondata/weather.js';
|
|
|
|
const WEATHER_CACHE_FOLDER = `${GLib.get_user_cache_dir()}/ags/weather`;
|
|
Utils.exec(`mkdir -p ${WEATHER_CACHE_FOLDER}`);
|
|
|
|
const BarBatteryProgress = () => {
|
|
const _updateProgress = (circprog) => { // Set circular progress value
|
|
circprog.css = `font-size: ${Math.abs(Battery.percent)}px;`
|
|
|
|
circprog.toggleClassName('bar-batt-circprog-low', Battery.percent <= userOptions.battery.low);
|
|
circprog.toggleClassName('bar-batt-circprog-full', Battery.charged);
|
|
}
|
|
return AnimatedCircProg({
|
|
className: 'bar-batt-circprog',
|
|
vpack: 'center', hpack: 'center',
|
|
extraSetup: (self) => self
|
|
.hook(Battery, _updateProgress)
|
|
,
|
|
})
|
|
}
|
|
|
|
const time = Variable('', {
|
|
poll: [
|
|
userOptions.time.interval,
|
|
() => GLib.DateTime.new_now_local().format(userOptions.time.format),
|
|
],
|
|
})
|
|
|
|
const date = Variable('', {
|
|
poll: [
|
|
userOptions.time.dateInterval,
|
|
() => GLib.DateTime.new_now_local().format(userOptions.time.dateFormatLong),
|
|
],
|
|
})
|
|
|
|
const BarClock = () => Widget.Box({
|
|
vpack: 'center',
|
|
className: 'spacing-h-4 bar-clock-box',
|
|
children: [
|
|
Widget.Label({
|
|
className: 'bar-time',
|
|
label: time.bind(),
|
|
}),
|
|
Widget.Label({
|
|
className: 'txt-norm txt-onLayer1',
|
|
label: '•',
|
|
}),
|
|
Widget.Label({
|
|
className: 'txt-smallie bar-date',
|
|
label: date.bind(),
|
|
}),
|
|
],
|
|
});
|
|
|
|
const UtilButton = ({ name, icon, onClicked }) => Button({
|
|
vpack: 'center',
|
|
tooltipText: name,
|
|
onClicked: onClicked,
|
|
className: 'bar-util-btn icon-material txt-norm',
|
|
label: `${icon}`,
|
|
})
|
|
|
|
const Utilities = () => Box({
|
|
hpack: 'center',
|
|
className: 'spacing-h-4',
|
|
children: [
|
|
UtilButton({
|
|
name: 'Screen snip', icon: 'screenshot_region', onClicked: () => {
|
|
Utils.execAsync(`${App.configDir}/scripts/grimblast.sh copy area`)
|
|
.catch(print)
|
|
}
|
|
}),
|
|
UtilButton({
|
|
name: 'Color picker', icon: 'colorize', onClicked: () => {
|
|
Utils.execAsync(['hyprpicker', '-a']).catch(print)
|
|
}
|
|
}),
|
|
UtilButton({
|
|
name: 'Toggle on-screen keyboard', icon: 'keyboard', onClicked: () => {
|
|
toggleWindowOnAllMonitors('osk');
|
|
}
|
|
}),
|
|
]
|
|
})
|
|
|
|
const BarBattery = () => Box({
|
|
className: 'spacing-h-4 bar-batt-txt',
|
|
children: [
|
|
Revealer({
|
|
transitionDuration: userOptions.animations.durationSmall,
|
|
revealChild: false,
|
|
transition: 'slide_right',
|
|
child: MaterialIcon('bolt', 'norm', { tooltipText: "Charging" }),
|
|
setup: (self) => self.hook(Battery, revealer => {
|
|
self.revealChild = Battery.charging;
|
|
}),
|
|
}),
|
|
Label({
|
|
className: 'txt-smallie',
|
|
setup: (self) => self.hook(Battery, label => {
|
|
label.label = `${Number.parseFloat(Battery.percent.toFixed(1))}%`;
|
|
}),
|
|
}),
|
|
Overlay({
|
|
child: Widget.Box({
|
|
vpack: 'center',
|
|
className: 'bar-batt',
|
|
homogeneous: true,
|
|
children: [
|
|
MaterialIcon('battery_full', 'small'),
|
|
],
|
|
setup: (self) => self.hook(Battery, box => {
|
|
box.toggleClassName('bar-batt-low', Battery.percent <= userOptions.battery.low);
|
|
box.toggleClassName('bar-batt-full', Battery.charged);
|
|
}),
|
|
}),
|
|
overlays: [
|
|
BarBatteryProgress(),
|
|
]
|
|
}),
|
|
]
|
|
});
|
|
|
|
const BarGroup = ({ child }) => Widget.Box({
|
|
className: 'bar-group-margin bar-sides',
|
|
children: [
|
|
Widget.Box({
|
|
className: 'bar-group bar-group-standalone bar-group-pad-system',
|
|
children: [child],
|
|
}),
|
|
]
|
|
});
|
|
const BatteryModule = () => Stack({
|
|
transition: 'slide_up_down',
|
|
transitionDuration: userOptions.animations.durationLarge,
|
|
children: {
|
|
'laptop': Box({
|
|
className: 'spacing-h-4', children: [
|
|
BarGroup({ child: Utilities() }),
|
|
BarGroup({ child: BarBattery() }),
|
|
]
|
|
}),
|
|
'desktop': BarGroup({
|
|
child: Box({
|
|
hexpand: true,
|
|
hpack: 'center',
|
|
className: 'spacing-h-4 txt-onSurfaceVariant',
|
|
children: [
|
|
MaterialIcon('device_thermostat', 'small'),
|
|
Label({
|
|
label: 'Weather',
|
|
})
|
|
],
|
|
setup: (self) => self.poll(900000, async (self) => {
|
|
const WEATHER_CACHE_PATH = WEATHER_CACHE_FOLDER + '/wttr.in.txt';
|
|
const updateWeatherForCity = (city) => execAsync(`curl https://wttr.in/${city.replace(/ /g, '%20')}?format=j1`)
|
|
.then(output => {
|
|
const weather = JSON.parse(output);
|
|
Utils.writeFile(JSON.stringify(weather), WEATHER_CACHE_PATH)
|
|
.catch(print);
|
|
const weatherCode = weather.current_condition[0].weatherCode;
|
|
const weatherDesc = weather.current_condition[0].weatherDesc[0].value;
|
|
const temperature = weather.current_condition[0][`temp_${userOptions.weather.preferredUnit}`];
|
|
const feelsLike = weather.current_condition[0][`FeelsLike${userOptions.weather.preferredUnit}`];
|
|
const weatherSymbol = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
|
|
self.children[0].label = weatherSymbol;
|
|
self.children[1].label = `${temperature}°${userOptions.weather.preferredUnit} • Feels like ${feelsLike}°${userOptions.weather.preferredUnit}`;
|
|
self.tooltipText = weatherDesc;
|
|
}).catch((err) => {
|
|
try { // Read from cache
|
|
const weather = JSON.parse(
|
|
Utils.readFile(WEATHER_CACHE_PATH)
|
|
);
|
|
const weatherCode = weather.current_condition[0].weatherCode;
|
|
const weatherDesc = weather.current_condition[0].weatherDesc[0].value;
|
|
const temperature = weather.current_condition[0][`temp_${userOptions.weather.preferredUnit}`];
|
|
const feelsLike = weather.current_condition[0][`FeelsLike${userOptions.weather.preferredUnit}`];
|
|
const weatherSymbol = WEATHER_SYMBOL[WWO_CODE[weatherCode]];
|
|
self.children[0].label = weatherSymbol;
|
|
self.children[1].label = `${temperature}°${userOptions.weather.preferredUnit} • Feels like ${feelsLike}°${userOptions.weather.preferredUnit}`;
|
|
self.tooltipText = weatherDesc;
|
|
} catch (err) {
|
|
print(err);
|
|
}
|
|
});
|
|
if (userOptions.weather.city != '' && userOptions.weather.city != null) {
|
|
updateWeatherForCity(userOptions.weather.city.replace(/ /g, '%20'));
|
|
}
|
|
else {
|
|
Utils.execAsync('curl ipinfo.io')
|
|
.then(output => {
|
|
return JSON.parse(output)['city'].toLowerCase();
|
|
})
|
|
.then(updateWeatherForCity)
|
|
.catch(print)
|
|
}
|
|
}),
|
|
})
|
|
}),
|
|
},
|
|
setup: (stack) => Utils.timeout(10, () => {
|
|
if (!Battery.available) stack.shown = 'desktop';
|
|
else stack.shown = 'laptop';
|
|
})
|
|
})
|
|
|
|
const switchToRelativeWorkspace = async (self, num) => {
|
|
try {
|
|
const Hyprland = (await import('resource:///com/github/Aylur/ags/service/hyprland.js')).default;
|
|
Hyprland.messageAsync(`dispatch workspace ${num > 0 ? '+' : ''}${num}`).catch(print);
|
|
} catch {
|
|
execAsync([`${App.configDir}/scripts/sway/swayToRelativeWs.sh`, `${num}`]).catch(print);
|
|
}
|
|
}
|
|
|
|
export default () => Widget.EventBox({
|
|
onScrollUp: (self) => switchToRelativeWorkspace(self, -1),
|
|
onScrollDown: (self) => switchToRelativeWorkspace(self, +1),
|
|
onPrimaryClick: () => App.toggleWindow('sideright'),
|
|
child: Widget.Box({
|
|
className: 'spacing-h-4',
|
|
children: [
|
|
BarGroup({ child: BarClock() }),
|
|
BatteryModule(),
|
|
]
|
|
})
|
|
});
|