{ lib, config, inputs, pkgs, ... }: let in with lib; { options = { waybar = { enable = mkEnableOption "enables waybar"; configPath = lib.mkOption { type = lib.types.path; default = ./waybar.jsonc; description = "The path to the waybar config"; }; stylePath = lib.mkOption { type = lib.types.path; default = ./waybar-latte.css; description = "The path to the waybar config"; }; }; }; config = mkIf config.waybar.enable { programs = { waybar = { enable = true; systemd = { enable = true; }; }; }; xdg.configFile."waybar/config.jsonc".source = config.waybar.configPath; xdg.configFile."waybar/style.css".source = config.waybar.stylePath; xdg.configFile."waybar/scripts/tailscale.sh" = { text = '' #!${pkgs.bash}/bin/bash PATH=${ lib.makeBinPath [ pkgs.coreutils pkgs.jq pkgs.tailscale ] } STATE_FILE="/tmp/waybar_tailscale_state" CONNECTING_DURATION=2 # seconds to show transition states get_tailscale_status() { local status_json if status_json=$(tailscale status --json 2>/dev/null); then local backend_state=$(echo "$status_json" | jq -r '.BackendState // "NoState"') case "$backend_state" in "Running") echo "connected" ;; "Stopped"|"NoState"|"NeedsLogin") echo "stopped" ;; *) echo "stopped" ;; esac else echo "stopped" fi } get_tooltip() { local status_json if ! status_json=$(tailscale status --json 2>/dev/null); then echo "" return fi local backend_state=$(echo "$status_json" | jq -r '.BackendState // "NoState"') if [[ "$backend_state" != "Running" ]]; then echo "" return fi local hostname=$(echo "$status_json" | jq -r '.Self.HostName // "Unknown"') local tooltip="Hostname: $hostname\n" tooltip+="\nPeers:\n" local peers=$(echo "$status_json" | jq -r '.Peer // {} | to_entries[] | "\(.value.HostName):\(.value.Online)"' | sort) if [[ -n "$peers" ]]; then while IFS=: read -r peer_name peer_online; do if [[ "$peer_online" == "true" ]]; then tooltip+="\n $peer_name" else tooltip+="\n $peer_name" fi done <<< "$peers" else tooltip+="\nNo peers" fi echo "$tooltip" } show_status() { local status=$(get_tailscale_status) local text="" local alt="" local tooltip="" case $status in "connected") text="" alt="connected" tooltip=$(get_tooltip) ;; "stopped") text="" alt="stopped" tooltip="Tailscale is turned off" ;; esac if [[ -n "$tooltip" ]]; then echo "{\"text\":\"$text\",\"class\":\"$status\",\"alt\":\"$alt\",\"tooltip\":\"$tooltip\"}" else echo "{\"text\":\"$text\",\"class\":\"$status\",\"alt\":\"$alt\"}" fi } show_connecting() { echo "{\"text\":\"\",\"class\":\"connecting\",\"alt\":\"connecting\",\"tooltip\":\"Connecting...\"}" } show_disconnecting() { echo "{\"text\":\"\",\"class\":\"disconnecting\",\"alt\":\"disconnecting\",\"tooltip\":\"Disconnecting...\"}" } is_in_transition() { if [[ -f "$STATE_FILE" ]]; then local state_info=$(cat "$STATE_FILE") local state_time=$(echo "$state_info" | cut -d: -f1) local current_time=$(date +%s) if (( current_time - state_time < CONNECTING_DURATION )); then return 0 else rm -f "$STATE_FILE" return 1 fi fi return 1 } case "$1" in --status) if is_in_transition; then state_info=$(cat "$STATE_FILE") state_action=$(echo "$state_info" | cut -d: -f2) if [[ "$state_action" == "connecting" ]]; then show_connecting exit 0 elif [[ "$state_action" == "disconnecting" ]]; then show_disconnecting exit 0 fi fi show_status ;; --toggle) if is_in_transition; then state_info=$(cat "$STATE_FILE") state_action=$(echo "$state_info" | cut -d: -f2) if [[ "$state_action" == "connecting" ]]; then show_connecting elif [[ "$state_action" == "disconnecting" ]]; then show_disconnecting fi exit 0 fi current_status=$(get_tailscale_status) if [[ "$current_status" == "connected" ]]; then tailscale down show_status else echo "$(date +%s):connecting" > "$STATE_FILE" tailscale up show_connecting fi ;; *) echo "Usage: $0 {--status|--toggle}" exit 1 ;; esac ''; executable = true; }; xdg.configFile."waybar/scripts/netbird.sh" = { text = '' #!${pkgs.bash}/bin/bash PATH=${ lib.makeBinPath [ pkgs.coreutils pkgs.netbird ] } STATE_FILE="/tmp/waybar_netbird_state" CONNECTING_DURATION=2 # seconds to show transition states get_netbird_status() { local status_output local management_status="" if ! status_output=$(netbird status -d 2>/dev/null); then echo "stopped" return fi while IFS= read -r line; do case "$line" in "Management:"*) management_status="''${line#Management: }" ;; esac done <<< "$status_output" case "$management_status" in *Connected*) echo "connected" ;; *) echo "stopped" ;; esac } get_tooltip() { local status_output local management_status="" local signal_status="" local relays_available=0 local relays_total=0 local nameservers_available=0 local nameservers_total=0 local netbird_ip="" local peers_count="" local interface_type="" local section="" if ! status_output=$(netbird status -d 2>/dev/null); then echo "" return fi while IFS= read -r line; do case "$line" in "Management:"*) management_status="''${line#Management: }" section="" ;; "Signal:"*) signal_status="''${line#Signal: }" section="" ;; "Relays:"*) section="relays" ;; "Nameservers:"*) section="nameservers" ;; "NetBird IP:"*) netbird_ip="''${line#NetBird IP: }" section="" ;; "Interface type:"*) interface_type="''${line#Interface type: }" section="" ;; "Peers count:"*) peers_count="''${line#Peers count: }" section="" ;; "Peers detail:"*) section="" ;; " ["*) if [[ "$section" == "relays" ]]; then relays_total=$((relays_total + 1)) if [[ "$line" == *"Available"* ]]; then relays_available=$((relays_available + 1)) fi elif [[ "$section" == "nameservers" ]]; then nameservers_total=$((nameservers_total + 1)) if [[ "$line" == *"Available"* ]]; then nameservers_available=$((nameservers_available + 1)) fi fi ;; esac done <<< "$status_output" if [[ -z "$management_status" ]]; then echo "" return fi local tooltip="Management: $management_status" if [[ -n "$signal_status" ]]; then tooltip+="\nSignal: $signal_status" fi if (( relays_total > 0 )); then tooltip+="\nRelays: $relays_available/$relays_total Available" fi if (( nameservers_total > 0 )); then tooltip+="\nNameservers: $nameservers_available/$nameservers_total Available" fi if [[ -n "$netbird_ip" ]]; then tooltip+="\nNetBird IP: $netbird_ip" fi if [[ -n "$interface_type" ]]; then tooltip+="\nInterface: $interface_type" fi if [[ -n "$peers_count" ]]; then tooltip+="\nPeers: $peers_count" fi echo "$tooltip" } show_status() { local status=$(get_netbird_status) local text="" local alt="" local tooltip="" case $status in "connected") text="" alt="connected" tooltip=$(get_tooltip) ;; "stopped") text="" alt="stopped" tooltip="NetBird is turned off" ;; esac if [[ -n "$tooltip" ]]; then echo "{\"text\":\"$text\",\"class\":\"$status\",\"alt\":\"$alt\",\"tooltip\":\"$tooltip\"}" else echo "{\"text\":\"$text\",\"class\":\"$status\",\"alt\":\"$alt\"}" fi } show_connecting() { echo "{\"text\":\"\",\"class\":\"connecting\",\"alt\":\"connecting\",\"tooltip\":\"Connecting...\"}" } show_disconnecting() { echo "{\"text\":\"\",\"class\":\"disconnecting\",\"alt\":\"disconnecting\",\"tooltip\":\"Disconnecting...\"}" } is_in_transition() { if [[ -f "$STATE_FILE" ]]; then local state_info=$(cat "$STATE_FILE") local state_time=$(echo "$state_info" | cut -d: -f1) local current_time=$(date +%s) if (( current_time - state_time < CONNECTING_DURATION )); then return 0 else rm -f "$STATE_FILE" return 1 fi fi return 1 } case "$1" in --status) if is_in_transition; then state_info=$(cat "$STATE_FILE") state_action=$(echo "$state_info" | cut -d: -f2) if [[ "$state_action" == "connecting" ]]; then show_connecting exit 0 elif [[ "$state_action" == "disconnecting" ]]; then show_disconnecting exit 0 fi fi show_status ;; --toggle) if is_in_transition; then state_info=$(cat "$STATE_FILE") state_action=$(echo "$state_info" | cut -d: -f2) if [[ "$state_action" == "connecting" ]]; then show_connecting elif [[ "$state_action" == "disconnecting" ]]; then show_disconnecting fi exit 0 fi current_status=$(get_netbird_status) if [[ "$current_status" == "connected" ]]; then netbird down show_status else echo "$(date +%s):connecting" > "$STATE_FILE" netbird up show_connecting fi ;; *) echo "Usage: $0 {--status|--toggle}" exit 1 ;; esac ''; executable = true; }; }; # catppuccin.waybar = { # enable = true; # flavor = "latte"; # }; }