#!/usr/bin/env fish
# Watches pulseaudio for volume changes and displays notifications

function type_target -a type
    switch $type
        case sink
            echo ""
        case source
            echo --default-source
        case '*'
            echo ""
    end
end

function get_title -a type muted
    switch $type
        case sink
            if test -n "$muted"
                echo "󰓄 Output"
            else
                echo "󰓃 Output"
            end
        case source
            if test -n "$muted"
                echo "󰍭 Input"
            else
                echo "󰍬 Input"
            end
        case '*'
            if test -n "$muted"
                echo "󰖁 Volume"
            else
                echo "󰕾 Volume"
            end
    end
end

function cache_state
    set -l type $argv[1]
    set -l target (type_target $type)

    set -l muted (pamixer $target --get-mute 2>/dev/null)
    set -l volume (pamixer $target --get-volume 2>/dev/null)

    if test -z "$volume"
        return 1
    end

    set -g last_volume_$type $volume
    set -g last_muted_$type $muted
end

function notify -a type
    set -l volume_var last_volume_$type
    set -l muted_var last_muted_$type
    set -l prev_volume $$volume_var
    set -l prev_muted $$muted_var

    cache_state $type; or return

    set -l volume $$volume_var
    set -l muted $$muted_var

    # skip if unchanged
    if test "$volume" = "$prev_volume"; and test "$muted" = "$prev_muted"
        return
    end

    if test "$muted" = true
        set -l title (get_title $type muted)
        notify-send -a progress -t 1000 -h "int:value:$volume" -h "string:x-dunst-stack-tag:volume-$type" "$title muted"
    else
        set -l title (get_title $type)
        notify-send -a progress -t 1000 -h "int:value:$volume" -h "string:x-dunst-stack-tag:volume-$type" "$title volume $volume%"
    end
end

cache_state sink
cache_state source

# HACK: this is a hack to make sure that notifications don't show up on startup
sleep 0.5

pactl subscribe 2>/dev/null | while read -l line
    if string match -q "*Event 'change' on sink*" "$line"
        notify sink
    else if string match -q "*Event 'change' on source*" "$line"
        notify source
    end
end
