settings: Get available audio devices lazily when first required (#49115)

Jakub Konka created

Release Notes:

- Get available audio devices lazily when first required.

Change summary

crates/audio/src/audio.rs                                | 12 ++++++++-
crates/settings_ui/src/pages/audio_input_output_setup.rs |  3 +
2 files changed, 12 insertions(+), 3 deletions(-)

Detailed changes

crates/audio/src/audio.rs 🔗

@@ -54,13 +54,21 @@ pub const REPLAY_DURATION: Duration = Duration::from_secs(30);
 
 pub fn init(cx: &mut App) {
     LIVE_SETTINGS.initialize(cx);
-    // TODO(jk): this is currently cached only once at startup - we should observe and react instead
+}
+
+// TODO(jk): this is currently cached only once - we should observe and react instead
+pub fn ensure_devices_initialized(cx: &mut App) {
+    if cx.has_global::<AvailableAudioDevices>() {
+        return;
+    }
+    cx.default_global::<AvailableAudioDevices>();
     let task = cx
         .background_executor()
         .spawn(async move { get_available_audio_devices() });
     cx.spawn(async move |cx: &mut AsyncApp| {
         let devices = task.await;
-        cx.update(|cx| cx.set_global(AvailableAudioDevices(devices)))
+        cx.update(|cx| cx.set_global(AvailableAudioDevices(devices)));
+        cx.refresh();
     })
     .detach();
 }

crates/settings_ui/src/pages/audio_input_output_setup.rs 🔗

@@ -35,7 +35,8 @@ pub(crate) fn render_audio_device_dropdown<F>(
 where
     F: Fn(Option<DeviceId>, &mut Window, &mut App) + Clone + 'static,
 {
-    let devices = cx.default_global::<AvailableAudioDevices>().0.clone();
+    audio::ensure_devices_initialized(cx);
+    let devices = cx.global::<AvailableAudioDevices>().0.clone();
     let current_device = get_current_device(current_device_id.as_ref(), is_input, &devices);
 
     let menu = ContextMenu::build(window, cx, {