mirror of
https://github.com/System-End/dotfiles.git
synced 2026-04-19 20:55:06 +00:00
- Add full AGS bar (GTK4/Astal/TypeScript) with all modules - Add wezterm config - Add niri config, starship, btop, xdg-portal, fish colors - Add gitignores for browser caches, JetBrains runtime, AGS node_modules - Exclude kdeconnect private/certificate pem files
60 lines
1.9 KiB
TypeScript
60 lines
1.9 KiB
TypeScript
import { Gtk } from "ags/gtk4"
|
|
import { execAsync } from "ags/process"
|
|
import { interval } from "ags/time"
|
|
import { createState } from "ags"
|
|
|
|
export default function Tailscale() {
|
|
const [status, setStatus] = createState({ up: false, ip: "", peers: 0 })
|
|
|
|
function poll() {
|
|
execAsync("tailscale status --json").then(out => {
|
|
try {
|
|
const j = JSON.parse(out)
|
|
setStatus({
|
|
up: j.BackendState === "Running",
|
|
ip: j.TailscaleIPs?.[0] ?? "",
|
|
peers: Object.keys(j.Peer ?? {}).length,
|
|
})
|
|
} catch {}
|
|
}).catch(() => {})
|
|
}
|
|
|
|
poll()
|
|
interval(5000, poll)
|
|
|
|
const popover = new Gtk.Popover()
|
|
popover.set_has_arrow(false)
|
|
|
|
const content = (
|
|
<box orientation={Gtk.Orientation.VERTICAL} spacing={8} widthRequest={200}>
|
|
<label label={status(s => s.up ? " Running" : " Stopped")} xalign={0} class="vpn-status-label" />
|
|
<label label={status(s => s.ip ? `IP: ${s.ip}` : "No IP")} xalign={0} class="vpn-detail" />
|
|
<label label={status(s => `Peers: ${s.peers}`)} xalign={0} class="vpn-detail" />
|
|
</box>
|
|
) as unknown as Gtk.Widget
|
|
|
|
popover.set_child(content)
|
|
|
|
const icon = new Gtk.Image({ iconName: "tailscale", pixelSize: 16 })
|
|
|
|
const btn = (
|
|
<button class={status(s => `module tailscale-module${s.up ? " on" : " off"}`)}
|
|
valign={Gtk.Align.CENTER}
|
|
onClicked={() => execAsync(
|
|
status().up
|
|
? "tailscale down"
|
|
: `bash -c "tailscale up && sudo ip route add 100.64.0.0/10 dev tailscale0 table main && sudo nft insert rule inet mullvad output ip daddr 100.64.0.0/10 accept && sudo nft insert rule inet mullvad output oif tailscale0 accept"`
|
|
).then(poll)}>
|
|
</button>
|
|
) as unknown as Gtk.Button
|
|
|
|
btn.set_child(icon)
|
|
|
|
const gesture = new Gtk.GestureClick()
|
|
gesture.button = 3
|
|
gesture.connect("pressed", () => popover.popup())
|
|
btn.add_controller(gesture)
|
|
popover.set_parent(btn)
|
|
|
|
return btn
|
|
}
|