onboarding: Fix theme selection in system mode (#36484)

Umesh Yadav created

Previously, selecting the "System" theme during onboarding would
hardcode the theme based on the device's current mode (e.g., Light or
Dark). This change ensures the "System" setting is saved correctly,
allowing the app to dynamically follow the OS theme by inserting the
correct theme in the config for both light and dark mode.

Release Notes:

- N/A

Signed-off-by: Umesh Yadav <git@umesh.dev>

Change summary

crates/onboarding/src/basics_page.rs | 32 ++++++++++++++++++++---------
1 file changed, 22 insertions(+), 10 deletions(-)

Detailed changes

crates/onboarding/src/basics_page.rs 🔗

@@ -16,6 +16,23 @@ use vim_mode_setting::VimModeSetting;
 
 use crate::theme_preview::{ThemePreviewStyle, ThemePreviewTile};
 
+const LIGHT_THEMES: [&'static str; 3] = ["One Light", "Ayu Light", "Gruvbox Light"];
+const DARK_THEMES: [&'static str; 3] = ["One Dark", "Ayu Dark", "Gruvbox Dark"];
+const FAMILY_NAMES: [SharedString; 3] = [
+    SharedString::new_static("One"),
+    SharedString::new_static("Ayu"),
+    SharedString::new_static("Gruvbox"),
+];
+
+fn get_theme_family_themes(theme_name: &str) -> Option<(&'static str, &'static str)> {
+    for i in 0..LIGHT_THEMES.len() {
+        if LIGHT_THEMES[i] == theme_name || DARK_THEMES[i] == theme_name {
+            return Some((LIGHT_THEMES[i], DARK_THEMES[i]));
+        }
+    }
+    None
+}
+
 fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement {
     let theme_selection = ThemeSettings::get_global(cx).theme_selection.clone();
     let system_appearance = theme::SystemAppearance::global(cx);
@@ -90,14 +107,6 @@ fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement
         };
         let current_theme_name = theme_selection.theme(appearance);
 
-        const LIGHT_THEMES: [&'static str; 3] = ["One Light", "Ayu Light", "Gruvbox Light"];
-        const DARK_THEMES: [&'static str; 3] = ["One Dark", "Ayu Dark", "Gruvbox Dark"];
-        const FAMILY_NAMES: [SharedString; 3] = [
-            SharedString::new_static("One"),
-            SharedString::new_static("Ayu"),
-            SharedString::new_static("Gruvbox"),
-        ];
-
         let theme_names = match appearance {
             Appearance::Light => LIGHT_THEMES,
             Appearance::Dark => DARK_THEMES,
@@ -184,10 +193,13 @@ fn render_theme_section(tab_index: &mut isize, cx: &mut App) -> impl IntoElement
         let theme = theme.into();
         update_settings_file::<ThemeSettings>(fs, cx, move |settings, cx| {
             if theme_mode == ThemeMode::System {
+                let (light_theme, dark_theme) =
+                    get_theme_family_themes(&theme).unwrap_or((theme.as_ref(), theme.as_ref()));
+
                 settings.theme = Some(ThemeSelection::Dynamic {
                     mode: ThemeMode::System,
-                    light: ThemeName(theme.clone()),
-                    dark: ThemeName(theme.clone()),
+                    light: ThemeName(light_theme.into()),
+                    dark: ThemeName(dark_theme.into()),
                 });
             } else {
                 let appearance = *SystemAppearance::global(cx);