fractal/session_list/
session_list_settings.rs

1use gtk::{glib, prelude::*, subclass::prelude::*};
2use indexmap::{IndexMap, IndexSet};
3use tracing::error;
4
5use crate::{
6    Application,
7    secret::SESSION_ID_LENGTH,
8    session::{SessionSettings, StoredSessionSettings},
9};
10
11mod imp {
12    use std::cell::RefCell;
13
14    use super::*;
15
16    #[derive(Debug, Default)]
17    pub struct SessionListSettings {
18        /// The settings of the sessions.
19        pub(super) sessions: RefCell<IndexMap<String, SessionSettings>>,
20    }
21
22    #[glib::object_subclass]
23    impl ObjectSubclass for SessionListSettings {
24        const NAME: &'static str = "SessionListSettings";
25        type Type = super::SessionListSettings;
26    }
27
28    impl ObjectImpl for SessionListSettings {}
29}
30
31glib::wrapper! {
32    /// The settings of the list of sessions.
33    pub struct SessionListSettings(ObjectSubclass<imp::SessionListSettings>);
34}
35
36impl SessionListSettings {
37    /// Create a new `SessionListSettings`.
38    pub fn new() -> Self {
39        glib::Object::new()
40    }
41
42    /// Load these settings from the application settings.
43    pub(crate) fn load(&self) {
44        let serialized = Application::default().settings().string("sessions");
45
46        let stored_sessions =
47            match serde_json::from_str::<Vec<(String, StoredSessionSettings)>>(&serialized) {
48                Ok(stored_sessions) => stored_sessions,
49                Err(error) => {
50                    error!(
51                        "Could not load sessions settings, fallback to default settings: {error}"
52                    );
53                    Default::default()
54                }
55            };
56
57        // Do we need to update the settings?
58        let mut needs_update = false;
59
60        let sessions = stored_sessions
61            .into_iter()
62            .map(|(mut session_id, stored_session)| {
63                // Session IDs have been truncated in version 6 of StoredSession.
64                if session_id.len() > SESSION_ID_LENGTH {
65                    session_id.truncate(SESSION_ID_LENGTH);
66                    needs_update = true;
67                }
68
69                let session = SessionSettings::restore(&session_id, stored_session);
70                (session_id, session)
71            })
72            .collect();
73
74        self.imp().sessions.replace(sessions);
75
76        if needs_update {
77            self.save();
78        }
79    }
80
81    /// Save these settings in the application settings.
82    pub(crate) fn save(&self) {
83        let stored_sessions = self
84            .imp()
85            .sessions
86            .borrow()
87            .iter()
88            .map(|(session_id, session)| (session_id.clone(), session.stored_settings()))
89            .collect::<Vec<_>>();
90
91        if let Err(error) = Application::default().settings().set_string(
92            "sessions",
93            &serde_json::to_string(&stored_sessions).unwrap(),
94        ) {
95            error!("Could not save sessions settings: {error}");
96        }
97    }
98
99    /// Get or create the settings for the session with the given ID.
100    pub(crate) fn get_or_create(&self, session_id: &str) -> SessionSettings {
101        let sessions = &self.imp().sessions;
102
103        if let Some(session) = sessions.borrow().get(session_id) {
104            return session.clone();
105        }
106
107        let session = SessionSettings::new(session_id);
108        sessions
109            .borrow_mut()
110            .insert(session_id.to_owned(), session.clone());
111        self.save();
112
113        session
114    }
115
116    /// Remove the settings of the session with the given ID.
117    pub(crate) fn remove(&self, session_id: &str) {
118        self.imp().sessions.borrow_mut().shift_remove(session_id);
119        self.save();
120    }
121
122    /// Get the list of session IDs stored in these settings.
123    pub(crate) fn session_ids(&self) -> IndexSet<String> {
124        self.imp().sessions.borrow().keys().cloned().collect()
125    }
126}
127
128impl Default for SessionListSettings {
129    fn default() -> Self {
130        Self::new()
131    }
132}