fractal/session/model/
session_settings.rs1use std::collections::BTreeSet;
2
3use gtk::{glib, prelude::*, subclass::prelude::*};
4use serde::{Deserialize, Serialize};
5
6use super::SidebarSectionName;
7use crate::Application;
8
9#[derive(Debug, Clone, Serialize, Deserialize, glib::Boxed)]
10#[boxed_type(name = "StoredSessionSettings")]
11pub struct StoredSessionSettings {
12 #[serde(default, skip_serializing_if = "Vec::is_empty")]
14 explore_custom_servers: Vec<String>,
15
16 #[serde(
18 default = "ruma::serde::default_true",
19 skip_serializing_if = "ruma::serde::is_true"
20 )]
21 notifications_enabled: bool,
22
23 #[serde(
25 default = "ruma::serde::default_true",
26 skip_serializing_if = "ruma::serde::is_true"
27 )]
28 public_read_receipts_enabled: bool,
29
30 #[serde(
32 default = "ruma::serde::default_true",
33 skip_serializing_if = "ruma::serde::is_true"
34 )]
35 typing_enabled: bool,
36
37 #[serde(default)]
39 sections_expanded: SectionsExpanded,
40}
41
42impl Default for StoredSessionSettings {
43 fn default() -> Self {
44 Self {
45 explore_custom_servers: Default::default(),
46 notifications_enabled: true,
47 public_read_receipts_enabled: true,
48 typing_enabled: true,
49 sections_expanded: Default::default(),
50 }
51 }
52}
53
54mod imp {
55 use std::{
56 cell::{OnceCell, RefCell},
57 marker::PhantomData,
58 };
59
60 use super::*;
61
62 #[derive(Debug, Default, glib::Properties)]
63 #[properties(wrapper_type = super::SessionSettings)]
64 pub struct SessionSettings {
65 #[property(get, construct_only)]
67 pub session_id: OnceCell<String>,
68 #[property(get, construct_only)]
70 pub stored_settings: RefCell<StoredSessionSettings>,
71 #[property(get = Self::notifications_enabled, set = Self::set_notifications_enabled, explicit_notify, default = true)]
73 pub notifications_enabled: PhantomData<bool>,
74 #[property(get = Self::public_read_receipts_enabled, set = Self::set_public_read_receipts_enabled, explicit_notify, default = true)]
76 pub public_read_receipts_enabled: PhantomData<bool>,
77 #[property(get = Self::typing_enabled, set = Self::set_typing_enabled, explicit_notify, default = true)]
79 pub typing_enabled: PhantomData<bool>,
80 }
81
82 #[glib::object_subclass]
83 impl ObjectSubclass for SessionSettings {
84 const NAME: &'static str = "SessionSettings";
85 type Type = super::SessionSettings;
86 }
87
88 #[glib::derived_properties]
89 impl ObjectImpl for SessionSettings {}
90
91 impl SessionSettings {
92 fn notifications_enabled(&self) -> bool {
94 self.stored_settings.borrow().notifications_enabled
95 }
96
97 fn set_notifications_enabled(&self, enabled: bool) {
99 if self.notifications_enabled() == enabled {
100 return;
101 }
102
103 self.stored_settings.borrow_mut().notifications_enabled = enabled;
104 super::SessionSettings::save();
105 self.obj().notify_notifications_enabled();
106 }
107
108 fn public_read_receipts_enabled(&self) -> bool {
110 self.stored_settings.borrow().public_read_receipts_enabled
111 }
112
113 fn set_public_read_receipts_enabled(&self, enabled: bool) {
115 if self.public_read_receipts_enabled() == enabled {
116 return;
117 }
118
119 self.stored_settings
120 .borrow_mut()
121 .public_read_receipts_enabled = enabled;
122 super::SessionSettings::save();
123 self.obj().notify_public_read_receipts_enabled();
124 }
125
126 fn typing_enabled(&self) -> bool {
128 self.stored_settings.borrow().typing_enabled
129 }
130
131 fn set_typing_enabled(&self, enabled: bool) {
133 if self.typing_enabled() == enabled {
134 return;
135 }
136
137 self.stored_settings.borrow_mut().typing_enabled = enabled;
138 super::SessionSettings::save();
139 self.obj().notify_typing_enabled();
140 }
141 }
142}
143
144glib::wrapper! {
145 pub struct SessionSettings(ObjectSubclass<imp::SessionSettings>);
147}
148
149impl SessionSettings {
150 pub fn new(session_id: &str) -> Self {
152 glib::Object::builder()
153 .property("session-id", session_id)
154 .property("stored-settings", StoredSessionSettings::default())
155 .build()
156 }
157
158 pub fn restore(session_id: &str, stored_settings: &StoredSessionSettings) -> Self {
161 glib::Object::builder()
162 .property("session-id", session_id)
163 .property("stored-settings", stored_settings)
164 .build()
165 }
166
167 fn save() {
169 Application::default().session_list().settings().save();
170 }
171
172 pub fn delete(&self) {
174 Application::default()
175 .session_list()
176 .settings()
177 .remove(&self.session_id());
178 }
179
180 pub fn explore_custom_servers(&self) -> Vec<String> {
182 self.imp()
183 .stored_settings
184 .borrow()
185 .explore_custom_servers
186 .clone()
187 }
188
189 pub fn set_explore_custom_servers(&self, servers: Vec<String>) {
191 if self.explore_custom_servers() == servers {
192 return;
193 }
194
195 self.imp()
196 .stored_settings
197 .borrow_mut()
198 .explore_custom_servers = servers;
199 Self::save();
200 }
201
202 pub fn is_section_expanded(&self, section_name: SidebarSectionName) -> bool {
204 self.imp()
205 .stored_settings
206 .borrow()
207 .sections_expanded
208 .is_section_expanded(section_name)
209 }
210
211 pub fn set_section_expanded(&self, section_name: SidebarSectionName, expanded: bool) {
213 self.imp()
214 .stored_settings
215 .borrow_mut()
216 .sections_expanded
217 .set_section_expanded(section_name, expanded);
218 Self::save();
219 }
220}
221
222#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
224pub struct SectionsExpanded(BTreeSet<SidebarSectionName>);
225
226impl SectionsExpanded {
227 pub fn is_section_expanded(&self, section_name: SidebarSectionName) -> bool {
229 self.0.contains(§ion_name)
230 }
231
232 pub fn set_section_expanded(&mut self, section_name: SidebarSectionName, expanded: bool) {
234 if expanded {
235 self.0.insert(section_name);
236 } else {
237 self.0.remove(§ion_name);
238 }
239 }
240}
241
242impl Default for SectionsExpanded {
243 fn default() -> Self {
244 Self(BTreeSet::from([
245 SidebarSectionName::VerificationRequest,
246 SidebarSectionName::Invited,
247 SidebarSectionName::Favorite,
248 SidebarSectionName::Normal,
249 SidebarSectionName::LowPriority,
250 ]))
251 }
252}