Kaynağa Gözat

Clean up appdata

Rain 1 ay önce
ebeveyn
işleme
062a8763f7
5 değiştirilmiş dosya ile 72 ekleme ve 85 silme
  1. 10 10
      client/src/actions.rs
  2. 5 22
      client/src/main.rs
  3. 2 2
      client/src/message.rs
  4. 23 19
      client/src/persistence.rs
  5. 32 32
      client/src/ui.rs

+ 10 - 10
client/src/actions.rs

@@ -5,19 +5,19 @@ use crate::{get_appdata, message::Message, ui, Appdata};
 
 // TODO (low): Create proper user objects. Related: add a way to verify a user.
 pub fn on_user_click(siv: &mut Cursive, user: &str) {
-    let language = get_appdata(siv).language;
+    let language = get_appdata(siv).persistent_data.language;
     ui::alert(siv, ui::Labels::User.localize(language), user.into());
 }
 
 pub fn on_message_click(siv: &mut Cursive, message_id: &str) {
     let appdata = get_appdata(siv);
-    let language = appdata.language;
+    let language = appdata.persistent_data.language;
     let message = appdata.messages.get(message_id);
 
     if let Some(message) = message {
         ui::copyable(
             siv,
-            ui::Labels::Message.localize(appdata.language),
+            ui::Labels::Message.localize(appdata.persistent_data.language),
             // TODO: Use labels
             format!(
                 "{}: {}\n{}: {}\n{}: {}\n{}: {}",
@@ -38,10 +38,10 @@ pub fn on_input_submit(siv: &mut Cursive, input_field_id: &str) {
         .expect("Failed to retrieve input field content.");
 
     let appdata = get_appdata(siv);
-    let language = appdata.language;
-    let channel = appdata.current_channel;
+    let language = appdata.persistent_data.language;
+    let channel = appdata.persistent_data.current_channel;
 
-    let message = Message::new(&appdata.username, &text, &channel);
+    let message = Message::new(&appdata.persistent_data.username, &text, &channel);
     if message.is_valid() {
         // NOTE:
         // If an error was shown during send, it's likely that loading will fail too
@@ -111,8 +111,8 @@ fn fix_url(url: &str) -> Result<String, NetworkError> {
 
 pub fn send_message(siv: &mut Cursive, message: Message) -> Result<(), NetworkError> {
     let appdata = get_appdata(siv);
-    let url = fix_url(&appdata.api_endpoint)?;
-    let password = appdata.api_password;
+    let url = fix_url(&appdata.persistent_data.api_endpoint)?;
+    let password = appdata.persistent_data.api_password;
 
     let mut bytes = message.serialize_checked();
     utils::aes::encrypt_cbc(&mut bytes, &password);
@@ -134,8 +134,8 @@ pub fn send_message(siv: &mut Cursive, message: Message) -> Result<(), NetworkEr
 
 pub fn load_messages(siv: &mut Cursive) -> Result<(), NetworkError> {
     let appdata = get_appdata(siv);
-    let url = fix_url(&appdata.api_endpoint)?;
-    let password = appdata.api_password;
+    let url = fix_url(&appdata.persistent_data.api_endpoint)?;
+    let password = appdata.persistent_data.api_password;
 
     let resp = reqwest::blocking::Client::new()
         .get(url)

+ 5 - 22
client/src/main.rs

@@ -17,6 +17,8 @@ use utils::serialize::Serialize;
 
 use ui::INPUT_FIELD_ID;
 
+use crate::persistence::Savedata;
+
 const MAX_MESSAGE_LENGTH: usize = 512;
 const MAX_USERNAME_LENGTH: usize = 16;
 const DEFAULT_USERNAME_PREFIX: &str = "Myst";
@@ -30,15 +32,7 @@ const SAVE_FILE_FUZZY: u64 = 0b0110110001101001011001110110110101100001001000000
 
 #[derive(Clone)]
 pub struct Appdata {
-    pub username: String,
-    pub language: ui::Language,
-    pub blocked_phrases: Vec<String>,
-    pub blocked_phrases_censor_char: char,
-    pub api_endpoint: String,
-    pub api_refresh_rate: usize,
-    // TODO: Support multiple passwords for decryption.
-    pub api_password: String,
-    pub current_channel: String,
+    pub persistent_data: Savedata,
 
     pub messages: HashMap<String, Message>,
     pub quick_close_window_count: usize,
@@ -56,21 +50,10 @@ impl Appdata {
     pub fn new() -> Self {
         Self {
             messages: HashMap::new(),
-            username: format!(
-                "{}#{}",
-                DEFAULT_USERNAME_PREFIX,
-                utils::rng::random_numeric_string(4)
-            ),
-            language: ui::Language::English,
             quick_close_window_count: 0,
-            api_endpoint: String::new(),
-            api_refresh_rate: 10,
-            blocked_phrases: Vec::new(),
-            blocked_phrases_censor_char: '*',
-            current_channel: DEFAULT_CHANNEL.to_string(),
             local_channels: vec![DEFAULT_CHANNEL.to_string()],
-            api_password: DEFAULT_PASSWORD.to_string(),
             intro_screen_shown_until: 0,
+            persistent_data: Savedata::new(),
         }
     }
 }
@@ -168,7 +151,7 @@ fn main() {
 
                         ui::visual_update(siv);
 
-                        if timer % appdata.api_refresh_rate == 0 {
+                        if timer % appdata.persistent_data.api_refresh_rate == 0 {
                             // TODO (low): Add a notice when automatic refresh fails.
                             let _ = actions::load_messages(siv);
                         }

+ 2 - 2
client/src/message.rs

@@ -104,8 +104,8 @@ pub struct MessageSanitized {
 impl MessageSanitized {
     pub fn remove_blocked_phrases(&mut self, siv: &mut cursive::Cursive) {
         let appdata = get_appdata(siv);
-        let wordlist = appdata.blocked_phrases;
-        let censor_char = appdata.blocked_phrases_censor_char;
+        let wordlist = appdata.persistent_data.blocked_phrases;
+        let censor_char = appdata.persistent_data.blocked_phrases_censor_char;
         self.sender = utils::strings::remove_bad_words(&self.sender, &wordlist, censor_char);
         self.content = utils::strings::remove_bad_words(&self.content, &wordlist, censor_char);
         self.channel = utils::strings::remove_bad_words(&self.channel, &wordlist, censor_char);

+ 23 - 19
client/src/persistence.rs

@@ -1,7 +1,8 @@
 use utils::serialize::{DeserializationError, Serialize, SetOfSerializedObjects};
 
-use crate::{ui, Appdata};
+use crate::{Appdata, DEFAULT_CHANNEL, DEFAULT_PASSWORD, DEFAULT_USERNAME_PREFIX, ui};
 
+#[derive(Clone)]
 pub struct Savedata {
     pub username: String,
     pub language: ui::Language,
@@ -13,33 +14,36 @@ pub struct Savedata {
     pub api_password: String,
 }
 
-impl From<Appdata> for Savedata {
-    fn from(value: Appdata) -> Self {
+impl Savedata {
+    pub fn new() -> Self {
         Self {
-            username: value.username,
-            language: value.language,
-            blocked_phrases: value.blocked_phrases,
-            blocked_phrases_censor_char: value.blocked_phrases_censor_char,
-            api_endpoint: value.api_endpoint,
-            api_refresh_rate: value.api_refresh_rate as u64,
-            api_password: value.api_password,
-            current_channel: value.current_channel,
+            username: format!(
+                "{}#{}",
+                DEFAULT_USERNAME_PREFIX,
+                utils::rng::random_numeric_string(4)
+            ),
+            language: ui::Language::English,
+            api_endpoint: String::new(),
+            api_refresh_rate: 10,
+            blocked_phrases: Vec::new(),
+            blocked_phrases_censor_char: '*',
+            current_channel: DEFAULT_CHANNEL.to_string(),
+            api_password: DEFAULT_PASSWORD.to_string(),
         }
     }
 }
 
+impl From<Appdata> for Savedata {
+    fn from(value: Appdata) -> Self {
+        value.persistent_data
+    }
+}
+
 impl From<Savedata> for Appdata {
     fn from(value: Savedata) -> Self {
         let mut s = Self::new();
 
-        s.username = value.username;
-        s.language = value.language;
-        s.blocked_phrases = value.blocked_phrases;
-        s.blocked_phrases_censor_char = value.blocked_phrases_censor_char;
-        s.api_endpoint = value.api_endpoint;
-        s.api_refresh_rate = value.api_refresh_rate as usize;
-        // s.current_channel = value.current_channel;
-        s.api_password = value.api_password;
+        s.persistent_data = value;
 
         s
     }

+ 32 - 32
client/src/ui.rs

@@ -299,7 +299,7 @@ pub fn alert<S>(siv: &mut Cursive, title: S, text: S)
 where
     S: Into<String>,
 {
-    let language = get_appdata(siv).language;
+    let language = get_appdata(siv).persistent_data.language;
 
     keybind_setup_close_once(siv);
 
@@ -317,7 +317,7 @@ pub fn copyable<S>(siv: &mut Cursive, title: S, text: S)
 where
     S: Into<String> + Clone,
 {
-    let language = get_appdata(siv).language;
+    let language = get_appdata(siv).persistent_data.language;
 
     keybind_setup_close_once(siv);
 
@@ -345,7 +345,7 @@ pub fn error<S>(siv: &mut Cursive, text: S)
 where
     S: Into<String>,
 {
-    let language = get_appdata(siv).language;
+    let language = get_appdata(siv).persistent_data.language;
     alert(siv, Labels::Error.localize(language), text.into());
 }
 
@@ -380,8 +380,8 @@ pub fn keybind_close_manual_end(siv: &mut Cursive, close_all: bool) {
 
 pub fn visual_update(siv: &mut Cursive) {
     let appdata = get_appdata(siv);
-    let current_channel = appdata.current_channel;
-    let language = get_appdata(siv).language;
+    let current_channel = appdata.persistent_data.current_channel;
+    let language = get_appdata(siv).persistent_data.language;
 
     // --- Messages ---
 
@@ -496,7 +496,7 @@ pub fn visual_update(siv: &mut Cursive) {
         |view: &mut NamedView<Panel<TextView>>| {
             view.get_mut()
                 .get_inner_mut()
-                .set_content(appdata_c.current_channel);
+                .set_content(appdata_c.persistent_data.current_channel);
 
             view.get_mut().set_title(Labels::Channel.localize(language));
         },
@@ -507,7 +507,7 @@ pub fn visual_update(siv: &mut Cursive) {
     siv.call_on_name(
         CURRENT_USERNAME_PANEL_ID,
         |view: &mut NamedView<Panel<TextView>>| {
-            view.get_mut().get_inner_mut().set_content(appdata.username);
+            view.get_mut().get_inner_mut().set_content(appdata.persistent_data.username);
         },
     );
 
@@ -581,7 +581,7 @@ pub fn visual_update(siv: &mut Cursive) {
 
 pub fn change_language(siv: &mut Cursive, language: Language) {
     siv.with_user_data(|appdata: &mut Appdata| {
-        appdata.language = language;
+        appdata.persistent_data.language = language;
     })
     .expect("Failed to set language.");
 
@@ -598,7 +598,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
         let mut view: SelectView<String> = SelectView::new();
         view.set_on_submit(move |siv, channel_id: &str| {
             siv.with_user_data(|appdata: &mut Appdata| {
-                appdata.current_channel = channel_id.to_string();
+                appdata.persistent_data.current_channel = channel_id.to_string();
             });
 
             visual_update(siv);
@@ -614,7 +614,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
     let channels_new_button = Button::new("", move |siv| {
         keybind_setup_close_once(siv);
 
-        let language = get_appdata(siv).language;
+        let language = get_appdata(siv).persistent_data.language;
 
         siv.add_layer(
             cursive::views::Dialog::new()
@@ -637,7 +637,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                         // Valid
                         siv.with_user_data(|appdata: &mut Appdata| {
                             appdata.local_channels.push(input.to_string());
-                            appdata.current_channel = input.to_string();
+                            appdata.persistent_data.current_channel = input.to_string();
                         });
 
                         save_appdata(siv);
@@ -700,13 +700,13 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
     // Language selector
     let language_button = Button::new("", move |siv| {
         // NOTE: This must match the order in the SelectView
-        let current_language_index = match get_appdata(siv).language {
+        let current_language_index = match get_appdata(siv).persistent_data.language {
             Language::English => 0,
             Language::Dutch => 1,
             Language::Japanese => 2,
         };
 
-        let language = get_appdata(siv).language;
+        let language = get_appdata(siv).persistent_data.language;
 
         keybind_setup_close_once(siv);
 
@@ -736,15 +736,15 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
 
     // Current username panel
     let current_username_panel = {
-        let current_username = get_appdata(siv).username.clone();
+        let current_username = get_appdata(siv).persistent_data.username.clone();
         let view = TextView::new(current_username);
         Panel::new(view).with_name(CURRENT_USERNAME_PANEL_ID)
     };
 
     // Set username
     let username_button = Button::new("", move |siv| {
-        let current_name = get_appdata(siv).username.clone();
-        let language = get_appdata(siv).language;
+        let current_name = get_appdata(siv).persistent_data.username.clone();
+        let language = get_appdata(siv).persistent_data.language;
 
         keybind_setup_close_once(siv);
 
@@ -767,7 +767,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                     if message::is_valid_username(&input) {
                         // Valid
                         siv.with_user_data(|appdata: &mut Appdata| {
-                            appdata.username = input.to_string();
+                            appdata.persistent_data.username = input.to_string();
                         });
 
                         save_appdata(siv);
@@ -775,7 +775,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                         keybind_close_manual_end(siv, false);
                     } else {
                         // Invalid
-                        let language = get_appdata(siv).language;
+                        let language = get_appdata(siv).persistent_data.language;
                         keybind_close_manual_end(siv, false); // NOTE: Error dialogue overwrites this one, so end it here beforehand.
                         error(siv, Labels::InvalidUsernameExplination.localize(language));
                     }
@@ -791,7 +791,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
     // Refresh button
     let refresh_button = Button::new("", move |siv| {
         if let Err(e) = actions::load_messages(siv) {
-            let language = get_appdata(siv).language;
+            let language = get_appdata(siv).persistent_data.language;
             error(siv, Labels::FailedToLoadMessages(e).localize(language));
         }
         visual_update(siv);
@@ -802,7 +802,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
     let blocked_words_list_button = {
         Button::new("", move |siv| {
             let appdata = get_appdata(siv);
-            let language = appdata.language;
+            let language = appdata.persistent_data.language;
 
             let wordslist_id = utils::new_id();
             let wordslist_id_clone = wordslist_id.clone();
@@ -810,7 +810,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
             let mut wordslist_view =
                 SelectView::<String>::new().on_submit(move |siv, word: &str| {
                     siv.with_user_data(|appdata: &mut Appdata| {
-                        appdata.blocked_phrases.retain(|x| x != word);
+                        appdata.persistent_data.blocked_phrases.retain(|x| x != word);
                     });
 
                     siv.call_on_name(&wordslist_id_clone, |view: &mut NamedView<SelectView>| {
@@ -824,7 +824,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                     save_appdata(siv);
                     visual_update(siv);
                 });
-            wordslist_view.add_all_str(&appdata.blocked_phrases);
+            wordslist_view.add_all_str(&appdata.persistent_data.blocked_phrases);
 
             let typingarea_id = utils::new_id();
             let typing_area = EditView::new().with_name(&typingarea_id);
@@ -838,12 +838,12 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                     .map(|x| x.to_string())
                     .unwrap_or("".to_string());
 
-                if get_appdata(siv).blocked_phrases.contains(&text) || text.is_empty() {
+                if get_appdata(siv).persistent_data.blocked_phrases.contains(&text) || text.is_empty() {
                     return;
                 }
 
                 siv.with_user_data(|appdata: &mut Appdata| {
-                    appdata.blocked_phrases.push(text.clone());
+                    appdata.persistent_data.blocked_phrases.push(text.clone());
                 });
 
                 siv.call_on_name(
@@ -882,7 +882,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
     // Server settings
     let server_settings_button = Button::new("", |siv| {
         let appdata = get_appdata(siv);
-        let language = appdata.language;
+        let language = appdata.persistent_data.language;
 
         keybind_setup_close_once(siv);
 
@@ -900,7 +900,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                                 .child(DummyView.fixed_width(1))
                                 .child(
                                     EditView::new()
-                                        .content(appdata.api_endpoint)
+                                        .content(appdata.persistent_data.api_endpoint)
                                         .with_name(SERVER_SETTINGS_ADDRESS_FIELD_ID)
                                         .min_width(SERVER_SETTINGS_FIELD_SIZE.0)
                                         .max_height(SERVER_SETTINGS_FIELD_SIZE.1),
@@ -915,7 +915,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                                 .child(DummyView.fixed_width(1))
                                 .child(
                                     EditView::new()
-                                        .content(appdata.api_refresh_rate.to_string())
+                                        .content(appdata.persistent_data.api_refresh_rate.to_string())
                                         .with_name(SERVER_SETTINGS_REFRESH_FIELD_ID)
                                         .min_width(SERVER_SETTINGS_FIELD_SIZE.0)
                                         .max_height(SERVER_SETTINGS_FIELD_SIZE.1),
@@ -930,7 +930,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                                 .child(DummyView.fixed_width(1))
                                 .child(
                                     EditView::new()
-                                        .content(appdata.api_password.to_string())
+                                        .content(appdata.persistent_data.api_password.to_string())
                                         .with_name(SERVER_SETTINGS_PASSWORD_FIELD_ID)
                                         .min_width(SERVER_SETTINGS_FIELD_SIZE.0)
                                         .max_height(SERVER_SETTINGS_FIELD_SIZE.1),
@@ -957,16 +957,16 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
                         .expect("Failed to retrieve server settings password input.");
 
                     siv.with_user_data(|appdata: &mut Appdata| {
-                        appdata.api_endpoint = input_addr.to_string();
+                        appdata.persistent_data.api_endpoint = input_addr.to_string();
 
                         let mut password = input_password.to_string();
                         if password.is_empty() {
                             password = DEFAULT_PASSWORD.to_string();
                         }
-                        appdata.api_password = password;
+                        appdata.persistent_data.api_password = password;
 
                         if let Ok(rate) = input_refresh.parse() {
-                            appdata.api_refresh_rate = rate;
+                            appdata.persistent_data.api_refresh_rate = rate;
                         }
                     });
 
@@ -984,7 +984,7 @@ pub fn setup_ui(siv: &mut Cursive) -> LinearLayout {
 
     let info_button = Button::new("", move |siv| {
         let appdata = get_appdata(siv);
-        let language = appdata.language;
+        let language = appdata.persistent_data.language;
 
         alert(siv, Labels::Information.localize(language), "Rei <rain@skuld.network>".to_string());
     })