feat(ui): show ALSA device descriptions in audio badge tooltip

Load ALSA device descriptions from backend and display fancy names
in the tooltip, with fallback to heuristic names when unavailable
This commit is contained in:
vicrodh committed 2026-02-01 06:03:44 -06:00
1 parent 7a76973920
commit 62f2e3dffc
1 file changed
+24 -3
+24 -3
View File
@@ -31,6 +31,17 @@
is_active: boolean; is_active: boolean;
} }
interface AlsaDevice {
id: string;
name: string;
description: string | null;
is_default: boolean;
max_sample_rate: number | null;
supported_sample_rates: number[] | null;
device_bus: string | null;
is_hardware: boolean;
}
// Props // Props
interface Props { interface Props {
showTooltips?: boolean; showTooltips?: boolean;
@@ -43,6 +54,7 @@
let settings = $state<AudioSettings | null>(null); let settings = $state<AudioSettings | null>(null);
let outputStatus = $state<AudioOutputStatus | null>(null); let outputStatus = $state<AudioOutputStatus | null>(null);
let pipewireSinks = $state<PipewireSink[]>([]); let pipewireSinks = $state<PipewireSink[]>([]);
let alsaDevices = $state<AlsaDevice[]>([]);
let hardwareStatus = $state<HardwareAudioStatus | null>(null); let hardwareStatus = $state<HardwareAudioStatus | null>(null);
let isHovering = $state(false); let isHovering = $state(false);
@@ -69,6 +81,13 @@
return sink?.description ?? null; return sink?.description ?? null;
}); });
// Get ALSA description for current device (fancy name from aplay -L)
const alsaDescription = $derived.by(() => {
if (!currentDevice) return null;
const device = alsaDevices.find(d => d.id === currentDevice || d.name === currentDevice);
return device?.description ?? null;
});
// Get volume for current device from PipeWire // Get volume for current device from PipeWire
const currentVolume = $derived.by(() => { const currentVolume = $derived.by(() => {
if (!currentDevice) return null; if (!currentDevice) return null;
@@ -76,9 +95,9 @@
return sink?.volume ?? null; return sink?.volume ?? null;
}); });
// Use PipeWire description if available, otherwise fall back to heuristic // Use PipeWire/ALSA description if available, otherwise fall back to heuristic
const prettyDeviceName = $derived( const prettyDeviceName = $derived(
pipewireDescription ?? (currentDevice ? getDevicePrettyName(currentDevice) : 'No device') pipewireDescription ?? alsaDescription ?? (currentDevice ? getDevicePrettyName(currentDevice) : 'No device')
); );
const isExternal = $derived(currentDevice ? isExternalDevice(currentDevice) : false); const isExternal = $derived(currentDevice ? isExternalDevice(currentDevice) : false);
@@ -146,15 +165,17 @@
async function loadStatus() { async function loadStatus() {
try { try {
const [settingsResult, statusResult, sinksResult, hwStatus] = await Promise.all([ const [settingsResult, statusResult, sinksResult, alsaResult, hwStatus] = await Promise.all([
invoke<AudioSettings>('get_audio_settings'), invoke<AudioSettings>('get_audio_settings'),
invoke<AudioOutputStatus>('get_audio_output_status'), invoke<AudioOutputStatus>('get_audio_output_status'),
invoke<PipewireSink[]>('get_pipewire_sinks').catch(() => [] as PipewireSink[]), invoke<PipewireSink[]>('get_pipewire_sinks').catch(() => [] as PipewireSink[]),
invoke<AlsaDevice[]>('get_alsa_devices').catch(() => [] as AlsaDevice[]),
invoke<HardwareAudioStatus>('get_hardware_audio_status').catch(() => null) invoke<HardwareAudioStatus>('get_hardware_audio_status').catch(() => null)
]); ]);
settings = settingsResult; settings = settingsResult;
outputStatus = statusResult; outputStatus = statusResult;
pipewireSinks = sinksResult; pipewireSinks = sinksResult;
alsaDevices = alsaResult;
hardwareStatus = hwStatus; hardwareStatus = hwStatus;
} catch (err) { } catch (err) {
console.error('Failed to load audio status:', err); console.error('Failed to load audio status:', err);