Skip to main content

romm_cli/tui/screens/settings/
console.rs

1use crate::core::utils;
2use crate::tui::path_picker::{PathPicker, PathPickerMode};
3use crate::types::Platform;
4
5use crate::endpoints::device::DeviceSchema;
6
7use super::types::{ConsolePathKind, SettingsScreen};
8use crate::tui::theme::MessageTone;
9
10impl SettingsScreen {
11    pub(crate) fn platform_display_name(platform: &Platform) -> String {
12        platform
13            .custom_name
14            .as_deref()
15            .filter(|s| !s.is_empty())
16            .unwrap_or(platform.name.as_str())
17            .to_string()
18    }
19
20    fn auto_console_dir_preview(&self, kind: ConsolePathKind, platform: &Platform) -> String {
21        let slug = platform.fs_slug.as_str();
22        let base = match kind {
23            ConsolePathKind::Roms => self.download_dir.trim_end_matches(['/', '\\']),
24            ConsolePathKind::Saves => self.save_dir.trim_end_matches(['/', '\\']),
25        };
26        format!("{}/{}", base, utils::sanitize_filename(slug))
27    }
28
29    pub(crate) fn console_dir_preview(&self, kind: ConsolePathKind, platform: &Platform) -> String {
30        self.console_dirs(kind)
31            .get(&platform.id)
32            .map(|s| s.trim())
33            .filter(|s| !s.is_empty())
34            .map(str::to_string)
35            .unwrap_or_else(|| self.auto_console_dir_preview(kind, platform))
36    }
37
38    pub fn open_console_picker(&mut self, kind: ConsolePathKind) {
39        self.console_selected_index = 0;
40        self.console_picker_open = true;
41        self.active_console_kind = Some(kind);
42        self.console_path_picker = None;
43        self.console_picker_loading = true;
44        self.console_picker_error = None;
45        self.console_platforms.clear();
46    }
47
48    pub fn set_console_platforms(&mut self, platforms: Vec<Platform>) {
49        self.console_platforms = platforms;
50        self.console_picker_loading = false;
51        self.console_picker_error = None;
52        self.console_selected_index = self
53            .console_selected_index
54            .min(self.console_platforms.len().saturating_sub(1));
55    }
56
57    pub fn set_console_platform_error(&mut self, error: String) {
58        self.console_picker_loading = false;
59        self.console_picker_error = Some(error);
60    }
61
62    pub fn clear_console_path(&mut self, platform_id: u64) {
63        let Some(kind) = self.active_console_kind else {
64            return;
65        };
66        self.console_dirs_mut(kind).remove(&platform_id);
67        self.message = Some((
68            "Custom path cleared (press S to save)".to_string(),
69            MessageTone::Success,
70        ));
71    }
72
73    pub fn console_next(&mut self) {
74        if !self.console_platforms.is_empty() {
75            self.console_selected_index =
76                (self.console_selected_index + 1).min(self.console_platforms.len() - 1);
77        }
78    }
79
80    pub fn console_previous(&mut self) {
81        self.console_selected_index = self.console_selected_index.saturating_sub(1);
82    }
83
84    pub fn open_console_path_picker(&mut self) {
85        let Some(kind) = self.active_console_kind else {
86            return;
87        };
88        let Some(platform) = self.console_platforms.get(self.console_selected_index) else {
89            return;
90        };
91        let initial = self.console_dir_preview(kind, platform);
92        self.console_path_picker = Some((
93            platform.id,
94            PathPicker::new(PathPickerMode::Directory, &initial),
95        ));
96    }
97
98    pub fn confirm_console_path(&mut self, platform_id: u64, path: String) {
99        let Some(kind) = self.active_console_kind else {
100            return;
101        };
102        self.console_dirs_mut(kind).insert(platform_id, path);
103        self.console_path_picker = None;
104        let label = match kind {
105            ConsolePathKind::Roms => "Custom console path updated (press S to save)",
106            ConsolePathKind::Saves => "Custom save path updated (press S to save)",
107        };
108        self.message = Some((label.to_string(), MessageTone::Success));
109    }
110    pub fn set_devices(&mut self, devices: Vec<DeviceSchema>) {
111        self.devices = devices;
112        self.device_picker_loading = false;
113        self.device_picker_error = None;
114        self.device_selected_index = self
115            .sync_device_id
116            .as_ref()
117            .and_then(|id| self.devices.iter().position(|d| &d.id == id))
118            .unwrap_or(0)
119            .min(self.devices.len().saturating_sub(1));
120    }
121
122    pub fn set_device_error(&mut self, error: String) {
123        self.device_picker_loading = false;
124        self.device_picker_error = Some(error);
125    }
126
127    pub fn device_next(&mut self) {
128        if !self.devices.is_empty() {
129            self.device_selected_index =
130                (self.device_selected_index + 1).min(self.devices.len() - 1);
131        }
132    }
133
134    pub fn device_previous(&mut self) {
135        self.device_selected_index = self.device_selected_index.saturating_sub(1);
136    }
137
138    pub fn confirm_device(&mut self) {
139        if let Some(device) = self.devices.get(self.device_selected_index) {
140            self.sync_device_id = Some(device.id.clone());
141            self.device_picker_open = false;
142            self.message = Some((
143                "Sync device updated (press S to save)".to_string(),
144                MessageTone::Success,
145            ));
146        }
147    }
148}