chiark / gitweb /
Check for new messages on startup.
authorSimon Tatham <anakin@pobox.com>
Sun, 7 Jan 2024 08:38:08 +0000 (08:38 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 7 Jan 2024 08:43:41 +0000 (08:43 +0000)
And beep the user into their mentions feed if there are any, just like
Mono does when you log in.

src/tui.rs

index 7f24fbe172e044516b01803f6b14419f2ef6a902..b34aa73b7f3229ddbbf27d45a2ee2029f99f8585 100644 (file)
@@ -325,6 +325,13 @@ impl Tui {
         self.client.fetch_feed(&FeedId::Home, FeedExtend::Initial)?;
         self.client.fetch_feed(&FeedId::Mentions, FeedExtend::Initial)?;
 
+        // Now we've fetched the mentions feed, see if we need to beep
+        // and throw the user into the mentions activity immediately
+        // on startup.
+        if self.state.check_startup_mentions(&mut self.client) {
+            Self::beep()?;
+        }
+
         self.main_loop()
     }
 
@@ -468,7 +475,7 @@ pub enum LogicalAction {
     PostReEdit(Post),
 }
 
-#[derive(PartialEq, Eq, Debug, Clone)]
+#[derive(PartialEq, Eq, Debug, Clone, Default)]
 pub struct SavedFilePos {
     // The current position we're _looking at_ within the file, within
     // this run
@@ -683,6 +690,34 @@ impl TuiLogicalState {
         }
     }
 
+    fn check_startup_mentions(&mut self, client: &mut Client) -> bool {
+        let feedid = FeedId::Mentions;
+        let last_id = client.borrow_feed(&feedid).ids.back();
+        let last_read_mention = self.file_positions.get(&feedid)
+            .and_then(|sfp| sfp.latest_read_id.clone());
+
+        if let Some(read) = last_read_mention {
+            if !last_id.is_some_and(|latest| latest > &read) {
+                return false; // nothing new to see
+            }
+        } else {
+            // If this client is being started for the very first
+            // time, then we don't want to instantly beep the user
+            // into their mentions. But we do want to save the fact
+            // that _those_ mentions were the ones that existed before
+            // they started running this client. So here we _make_ an
+            // LDB entry.
+            if let Some(last_id) = last_id {
+                self.set_latest_read(feedid, last_id.to_owned());
+            }
+            return false;
+        }
+
+        self.activity_stack.goto(UtilityActivity::ReadMentions.into());
+        self.changed_activity(client, None, true);
+        true
+    }
+
     fn checkpoint_ldb(&mut self) {
         if let Some((feed_id, saved_pos)) =
             self.activity_state.save_file_position()
@@ -850,19 +885,21 @@ impl TuiLogicalState {
                 _ => continue,
             };
 
-            let val = Some(valstr.clone());
+            self.set_latest_read(key.clone(), valstr.clone());
+        }
+        Ok(())
+    }
 
-            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,
+    fn set_latest_read(&mut self, key: FeedId, val: String) {
+        match self.file_positions.entry(key) {
+            hash_map::Entry::Vacant(e) => {
+                e.insert(SavedFilePos {
+                    file_pos: None,
+                    latest_read_id: Some(val),
+                });
             }
+            hash_map::Entry::Occupied(mut e) =>
+                e.get_mut().latest_read_id = Some(val),
         }
-        Ok(())
     }
 }