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;
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,
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(())
+ }
}