chiark / gitweb /
And reload the LDB on startup!
authorSimon Tatham <anakin@pobox.com>
Sat, 6 Jan 2024 13:29:19 +0000 (13:29 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 6 Jan 2024 14:06:13 +0000 (14:06 +0000)
Finally, you can restart the client and have it drop you at your
previous position.

src/tui.rs

index 16a7236b0eb6e20ec8fdf58521a8404be06b095d..86627857e33edfd0d797b895d708d95db87c65b2 100644 (file)
@@ -11,7 +11,7 @@ use ratatui::{
     style::{Style, Color, Modifier},
 };
 use std::cmp::min;
-use std::collections::{BTreeMap, HashMap, HashSet};
+use std::collections::{BTreeMap, HashMap, HashSet, hash_map};
 use std::io::{Stdout, Write, stdout};
 use std::fs::File;
 use unicode_width::UnicodeWidthStr;
@@ -234,13 +234,14 @@ impl Tui {
         client.set_writable(!readonly);
         client.set_logfile(logfile);
 
+        let mut state = TuiLogicalState::new(&client, cfgloc.clone());
+        state.load_ldb()?;
+
         stdout().execute(EnterAlternateScreen)?;
         enable_raw_mode()?;
         let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
         terminal.clear()?;
 
-        let state = TuiLogicalState::new(&client, cfgloc.clone());
-
         let mut tui = Tui {
             terminal,
             subthread_sender: sender,
@@ -779,4 +780,48 @@ impl TuiLogicalState {
         self.cfgloc.create_file("ldb", &json)?;
         Ok(())
     }
+
+    fn load_ldb(&mut self) -> Result<(), TuiError> {
+        let filename = self.cfgloc.get_path("ldb");
+        let load_result = std::fs::read_to_string(&filename);
+
+        if load_result.as_ref().is_err_and(
+            |e| e.kind() == std::io::ErrorKind::NotFound)
+        {
+            // Most errors are errors, but if the LDB file simply
+            // doesn't exist, that's fine (we may be being run for the
+            // first time!) and we just return without having loaded
+            // anything.
+            return Ok(());
+        }
+
+        let json = load_result?;
+        let ldb: BTreeMap<String, String> = serde_json::from_str(&json)?;
+
+        for (keystr, valstr) in &ldb {
+            let key = match keystr as &str {
+                "home" => FeedId::Home,
+                "mentions" => FeedId::Mentions,
+                "ego" => FeedId::Ego,
+
+                // Tolerate extra keys in ldb, in case they were
+                // written by a later version
+                _ => continue,
+            };
+
+            let val = Some(valstr.clone());
+
+            match self.file_positions.entry(key) {
+                hash_map::Entry::Vacant(e) => {
+                    e.insert(SavedFilePos {
+                        file_pos: None,
+                        latest_read_id: val,
+                    });
+                }
+                hash_map::Entry::Occupied(mut e) =>
+                    e.get_mut().latest_read_id = val,
+            }
+        }
+        Ok(())
+    }
 }