max / audiofiles
1 file changed,
+73 insertions,
-65 deletions
| @@ -2,88 +2,96 @@ | |||
| 2 | 2 | ||
| 3 | 3 | use std::path::{Path, PathBuf}; | |
| 4 | 4 | ||
| 5 | + | use audiofiles_browser::ui::{theme, widgets}; | |
| 5 | 6 | use audiofiles_core::vault::{self, VaultRegistry}; | |
| 6 | 7 | use eframe::egui; | |
| 7 | 8 | ||
| 8 | 9 | use super::AudioFilesApp; | |
| 9 | 10 | ||
| 11 | + | const DEFAULT_VAULT_NAME: &str = "Library"; | |
| 12 | + | ||
| 10 | 13 | impl AudioFilesApp { | |
| 11 | 14 | /// Draw the vault setup screen (first-open flow, after activation). | |
| 12 | 15 | pub(crate) fn draw_vault_setup_screen(&mut self, ctx: &egui::Context) { | |
| 13 | 16 | let default_path = vault::default_vault_path(); | |
| 14 | 17 | let existing_db = default_path.join("audiofiles.db").exists(); | |
| 15 | 18 | ||
| 19 | + | // Pre-fill the vault-name field on first entry so the fallback is visible. | |
| 20 | + | if self.vault_setup_name.is_empty() { | |
| 21 | + | self.vault_setup_name = DEFAULT_VAULT_NAME.to_string(); | |
| 22 | + | } | |
| 23 | + | ||
| 16 | 24 | egui::CentralPanel::default().show(ctx, |ui| { | |
| 17 | 25 | let available = ui.available_size(); | |
| 18 | - | ui.add_space((available.y * 0.25).max(40.0)); | |
| 26 | + | ui.add_space((available.y * 0.20).max(40.0)); | |
| 19 | 27 | ||
| 20 | 28 | ui.vertical_centered(|ui| { | |
| 21 | - | ui.heading("Choose where to store your sample library"); | |
| 22 | - | ui.add_space(8.0); | |
| 23 | - | ||
| 24 | - | if existing_db { | |
| 25 | - | ui.label( | |
| 26 | - | egui::RichText::new(format!( | |
| 27 | - | "Your existing library was found at {}", | |
| 28 | - | default_path.display() | |
| 29 | - | )) | |
| 30 | - | .color(egui::Color32::from_rgb(120, 180, 120)), | |
| 31 | - | ); | |
| 32 | - | ui.add_space(8.0); | |
| 33 | - | } | |
| 34 | - | ||
| 35 | - | // Option 1: default location | |
| 36 | - | if ui.button("Use default location").clicked() { | |
| 37 | - | self.vault_setup_path = None; | |
| 38 | - | } | |
| 39 | - | ui.label( | |
| 40 | - | egui::RichText::new(format!("Default: {}", default_path.display())) | |
| 41 | - | .small() | |
| 42 | - | .color(egui::Color32::GRAY), | |
| 43 | - | ); | |
| 44 | - | ||
| 45 | - | ui.add_space(8.0); | |
| 46 | - | ||
| 47 | - | // Option 2: custom folder | |
| 48 | - | ui.horizontal(|ui| { | |
| 49 | - | if ui.button("Choose folder...").clicked() { | |
| 50 | - | if let Some(path) = rfd::FileDialog::new().pick_folder() { | |
| 51 | - | self.vault_setup_path = Some(path); | |
| 29 | + | let column_width = 480.0_f32.min(available.x - 40.0); | |
| 30 | + | ui.allocate_ui(egui::vec2(column_width, 0.0), |ui| { | |
| 31 | + | ui.vertical(|ui| { | |
| 32 | + | ui.heading("Where should we store your library?"); | |
| 33 | + | ui.add_space(theme::space::MD); | |
| 34 | + | ||
| 35 | + | if existing_db && self.vault_setup_path.is_none() { | |
| 36 | + | ui.label( | |
| 37 | + | egui::RichText::new(format!( | |
| 38 | + | "Your existing library at {} will be opened.", | |
| 39 | + | default_path.display() | |
| 40 | + | )) | |
| 41 | + | .color(theme::text_secondary()), | |
| 42 | + | ); | |
| 43 | + | ui.add_space(theme::space::SECTION); | |
| 44 | + | } else { | |
| 45 | + | ui.add_space(theme::space::SM); | |
| 52 | 46 | } | |
| 53 | - | } | |
| 54 | - | if self.vault_setup_path.is_some() | |
| 55 | - | && ui.small_button("Reset to default").clicked() | |
| 56 | - | { | |
| 57 | - | self.vault_setup_path = None; | |
| 58 | - | } | |
| 59 | - | }); | |
| 60 | - | ||
| 61 | - | if let Some(ref custom) = self.vault_setup_path { | |
| 62 | - | ui.label( | |
| 63 | - | egui::RichText::new(format!("Selected: {}", custom.display())) | |
| 64 | - | .small() | |
| 65 | - | .color(egui::Color32::from_rgb(150, 200, 255)), | |
| 66 | - | ); | |
| 67 | - | } | |
| 68 | 47 | ||
| 69 | - | ui.add_space(12.0); | |
| 70 | - | ||
| 71 | - | // Vault name input | |
| 72 | - | ui.horizontal(|ui| { | |
| 73 | - | ui.label("Vault name:"); | |
| 74 | - | ui.text_edit_singleline(&mut self.vault_setup_name); | |
| 48 | + | // Vault name | |
| 49 | + | ui.horizontal(|ui| { | |
| 50 | + | ui.label("Name:"); | |
| 51 | + | ui.text_edit_singleline(&mut self.vault_setup_name); | |
| 52 | + | }); | |
| 53 | + | ||
| 54 | + | ui.add_space(theme::space::MD); | |
| 55 | + | ||
| 56 | + | // Location: shown inline with the picker action. No | |
| 57 | + | // separate "Use default location" button — the default | |
| 58 | + | // is already the value displayed, and "Continue" | |
| 59 | + | // commits whatever is shown here. | |
| 60 | + | let chosen_path = self | |
| 61 | + | .vault_setup_path | |
| 62 | + | .clone() | |
| 63 | + | .unwrap_or_else(|| default_path.clone()); | |
| 64 | + | let is_custom = self.vault_setup_path.is_some(); | |
| 65 | + | ui.label("Location:"); | |
| 66 | + | ui.horizontal_wrapped(|ui| { | |
| 67 | + | let path_text = if is_custom { | |
| 68 | + | widgets::accent_strong(chosen_path.display().to_string()) | |
| 69 | + | } else { | |
| 70 | + | egui::RichText::new(chosen_path.display().to_string()) | |
| 71 | + | .color(theme::text_secondary()) | |
| 72 | + | }; | |
| 73 | + | ui.label(path_text); | |
| 74 | + | }); | |
| 75 | + | ui.add_space(theme::space::SM); | |
| 76 | + | ui.horizontal(|ui| { | |
| 77 | + | if ui.button("Choose different location...").clicked() { | |
| 78 | + | if let Some(path) = rfd::FileDialog::new().pick_folder() { | |
| 79 | + | self.vault_setup_path = Some(path); | |
| 80 | + | } | |
| 81 | + | } | |
| 82 | + | if is_custom && ui.button("Use default").clicked() { | |
| 83 | + | self.vault_setup_path = None; | |
| 84 | + | } | |
| 85 | + | }); | |
| 86 | + | ||
| 87 | + | ui.add_space(theme::space::XL); | |
| 88 | + | ||
| 89 | + | // Single primary action — the only path that advances. | |
| 90 | + | if widgets::primary_button(ui, "Continue").clicked() { | |
| 91 | + | self.finalize_vault_setup(chosen_path); | |
| 92 | + | } | |
| 93 | + | }); | |
| 75 | 94 | }); | |
| 76 | - | ||
| 77 | - | ui.add_space(16.0); | |
| 78 | - | ||
| 79 | - | // Continue button | |
| 80 | - | let chosen = self | |
| 81 | - | .vault_setup_path | |
| 82 | - | .clone() | |
| 83 | - | .unwrap_or_else(|| default_path.clone()); | |
| 84 | - | if ui.button("Continue").clicked() { | |
| 85 | - | self.finalize_vault_setup(chosen); | |
| 86 | - | } | |
| 87 | 95 | }); | |
| 88 | 96 | }); | |
| 89 | 97 | } | |
| @@ -91,7 +99,7 @@ impl AudioFilesApp { | |||
| 91 | 99 | /// Finalise vault setup: create registry, set data_dir, open browser. | |
| 92 | 100 | fn finalize_vault_setup(&mut self, vault_path: PathBuf) { | |
| 93 | 101 | let name = if self.vault_setup_name.trim().is_empty() { | |
| 94 | - | "Library".to_string() | |
| 102 | + | DEFAULT_VAULT_NAME.to_string() | |
| 95 | 103 | } else { | |
| 96 | 104 | self.vault_setup_name.trim().to_string() | |
| 97 | 105 | }; |