Add AGS battery widget
This commit is contained in:
parent
69a1977e5a
commit
3f17a1a313
|
|
@ -44,14 +44,16 @@
|
||||||
|
|
||||||
.ws:hover,
|
.ws:hover,
|
||||||
.volume:hover,
|
.volume:hover,
|
||||||
.wifi:hover {
|
.wifi:hover,
|
||||||
|
.battery:hover {
|
||||||
background: transparentize($base05, 0.88);
|
background: transparentize($base05, 0.88);
|
||||||
}
|
}
|
||||||
|
|
||||||
.volume icon,
|
.volume icon,
|
||||||
.mute icon,
|
.mute icon,
|
||||||
.wifi icon,
|
.wifi icon,
|
||||||
.wifi-header icon {
|
.wifi-header icon,
|
||||||
|
.battery icon {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -156,3 +158,18 @@
|
||||||
.wifi-row:hover {
|
.wifi-row:hover {
|
||||||
background: transparentize($base05, 0.88);
|
background: transparentize($base05, 0.88);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.battery-percent {
|
||||||
|
font-size: 1.6em;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.battery-level {
|
||||||
|
font-size: 0.85em;
|
||||||
|
margin-left: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.battery-status {
|
||||||
|
font-size: 0.85em;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,19 +3,23 @@ import Workspaces from "./Workspaces"
|
||||||
import Clock from "./Clock"
|
import Clock from "./Clock"
|
||||||
import { VolumeWidget } from "./Volume"
|
import { VolumeWidget } from "./Volume"
|
||||||
import { WifiWidget } from "./Wifi"
|
import { WifiWidget } from "./Wifi"
|
||||||
|
import { BatteryWidget } from "./Battery"
|
||||||
|
|
||||||
export default function Bar(gdkmonitor: Gdk.Monitor) {
|
export default function Bar(gdkmonitor: Gdk.Monitor) {
|
||||||
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
|
const { TOP, LEFT, RIGHT } = Astal.WindowAnchor
|
||||||
const volume = VolumeWidget(gdkmonitor)
|
const volume = VolumeWidget(gdkmonitor)
|
||||||
const wifi = WifiWidget(gdkmonitor)
|
const wifi = WifiWidget(gdkmonitor)
|
||||||
|
const battery = BatteryWidget(gdkmonitor)
|
||||||
|
|
||||||
const right: Array<JSX.Element> = []
|
const right: Array<JSX.Element> = []
|
||||||
if (wifi.button) right.push(wifi.button)
|
if (wifi.button) right.push(wifi.button)
|
||||||
right.push(volume.button)
|
right.push(volume.button)
|
||||||
|
if (battery.button) right.push(battery.button)
|
||||||
|
|
||||||
const popups: Array<JSX.Element> = []
|
const popups: Array<JSX.Element> = []
|
||||||
if (wifi.popup) popups.push(wifi.popup)
|
if (wifi.popup) popups.push(wifi.popup)
|
||||||
popups.push(volume.popup)
|
popups.push(volume.popup)
|
||||||
|
if (battery.popup) popups.push(battery.popup)
|
||||||
|
|
||||||
return [
|
return [
|
||||||
(
|
(
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
import AstalBattery from "gi://AstalBattery"
|
||||||
|
import { Variable, bind } from "astal"
|
||||||
|
import Dropdown from "./Dropdown"
|
||||||
|
|
||||||
|
const battery = AstalBattery.get_default()
|
||||||
|
|
||||||
|
const CHARGING = 1
|
||||||
|
const DISCHARGING = 2
|
||||||
|
const FULLY_CHARGED = 4
|
||||||
|
|
||||||
|
function fmtTime(seconds: number) {
|
||||||
|
if (!seconds || seconds <= 0) return null
|
||||||
|
const h = Math.floor(seconds / 3600)
|
||||||
|
const m = Math.round((seconds % 3600) / 60)
|
||||||
|
return h > 0 ? `${h}h ${m}m` : `${m}m`
|
||||||
|
}
|
||||||
|
|
||||||
|
const status = Variable.derive(
|
||||||
|
[bind(battery, "state"), bind(battery, "time-to-empty"), bind(battery, "time-to-full")],
|
||||||
|
(state, toEmpty, toFull) => {
|
||||||
|
if (state === FULLY_CHARGED) return "fully charged"
|
||||||
|
if (state === CHARGING) {
|
||||||
|
const t = fmtTime(toFull)
|
||||||
|
return t ? `charging · ${t} to full` : "charging"
|
||||||
|
}
|
||||||
|
if (state === DISCHARGING) {
|
||||||
|
const t = fmtTime(toEmpty)
|
||||||
|
return t ? `${t} left` : "on battery"
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
export function BatteryWidget(gdkmonitor: Gdk.Monitor) {
|
||||||
|
if (!battery.isBattery) return { button: null, popup: null }
|
||||||
|
|
||||||
|
const open = Variable(false)
|
||||||
|
|
||||||
|
const button = (
|
||||||
|
<button
|
||||||
|
className="battery"
|
||||||
|
onClicked={() => open.set(!open.get())}
|
||||||
|
>
|
||||||
|
<box>
|
||||||
|
<icon icon={bind(battery, "icon-name")} />
|
||||||
|
<label
|
||||||
|
className="battery-level"
|
||||||
|
label={bind(battery, "percentage").as((p) => `${Math.round(p * 100)}%`)}
|
||||||
|
/>
|
||||||
|
</box>
|
||||||
|
</button>
|
||||||
|
)
|
||||||
|
|
||||||
|
const popup = (
|
||||||
|
<Dropdown gdkmonitor={gdkmonitor} target={button} open={open} width={180}>
|
||||||
|
<label
|
||||||
|
className="battery-percent"
|
||||||
|
label={bind(battery, "percentage").as((p) => `${Math.round(p * 100)}%`)}
|
||||||
|
/>
|
||||||
|
<label
|
||||||
|
className="battery-status"
|
||||||
|
label={status()}
|
||||||
|
visible={status().as((text) => text !== "")}
|
||||||
|
/>
|
||||||
|
</Dropdown>
|
||||||
|
)
|
||||||
|
|
||||||
|
return { button, popup }
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,6 @@
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
services = {
|
services = {
|
||||||
|
upower.enable = true;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue