From: Simon Tatham Date: Sun, 31 Dec 2023 07:31:19 +0000 (+0000) Subject: Use feed updates to lengthen the home timeline. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=c66b999548e0569a80b10fe7bb28c379a73da733;p=mastodonochrome.git Use feed updates to lengthen the home timeline. Untested as yet, but this _should_ replicate the behaviour from the Python version where you're reading your home timeline and a new post quietly appears below what you can currently see. --- diff --git a/src/client.rs b/src/client.rs index d0649a4..f9c3c50 100644 --- a/src/client.rs +++ b/src/client.rs @@ -1,5 +1,5 @@ use reqwest::Url; -use std::collections::{HashMap, VecDeque}; +use std::collections::{HashMap, HashSet, VecDeque}; use std::io::Read; use super::auth::{AuthConfig,AuthError}; @@ -414,6 +414,32 @@ impl Client { Ok(()) } - pub fn process_stream_update(&mut self, _up: StreamUpdate) { + pub fn process_stream_update(&mut self, up: StreamUpdate) -> + Result, ClientError> + { + let mut updates = HashSet::new(); + + match (up.id, up.response) { + (StreamId::User, StreamResponse::Line(_)) => { + self.fetch_feed(&FeedId::Home, FeedExtend::Future)?; + updates.insert(FeedId::Home); + }, + + // FIXME: we probably _should_ handle EOF from the + // subthread, though I'm not quite sure how yet. Stream + // connections seem to occasionally - as in, "on a + // minority of days" - spontaneously close from the server + // end, so just quietly restarting it is probably a good + // first step. But we wouldn't want to keep doing that in + // a way that became obnoxious, so at some point we have + // to switch to strategy #2, which is to notify the user + // of a problem and let them decide. So probably this + // function ends up returning a Result, and our owner + // responds to an error by putting it in the Error Log. + + _ => (), + } + + Ok(updates) } } diff --git a/src/file.rs b/src/file.rs index 42bf948..6675505 100644 --- a/src/file.rs +++ b/src/file.rs @@ -1,5 +1,5 @@ use std::cmp::{min, max}; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use super::client::{Client, ClientError, FeedId, FeedExtend}; use super::coloured_string::ColouredString; @@ -25,7 +25,8 @@ struct FeedFileContents { impl FeedFileContents { fn update_items(&mut self, client: &mut Client) { - // FIXME: deal with the feed having been extended + // FIXME: if the feed has been extended rather than created, + // we should be able to make less effort than this let feed = client.borrow_feed(&self.id); let ids: Vec<_> = feed.ids.iter().map(|x| x.clone()).collect(); @@ -414,6 +415,14 @@ impl ActivityState for FeedFile { _ => LogicalAction::Nothing, } } + + fn handle_feed_updates(&mut self, feeds_updated: &HashSet, + client: &mut Client) { + if feeds_updated.contains(&self.contents.id) { + self.contents.update_items(client); + self.ensure_enough_rendered(); + } + } } pub fn home_timeline(client: &mut Client) -> diff --git a/src/tui.rs b/src/tui.rs index cb550a1..331daec 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -10,11 +10,12 @@ use ratatui::{ prelude::{Buffer, CrosstermBackend, Rect, Terminal}, style::{Style, Color, Modifier}, }; +use std::collections::HashSet; use std::io::{Stdout, Write, stdout}; use unicode_width::UnicodeWidthStr; use super::activity_stack::*; -use super::client::{Client, ClientError, StreamId, StreamUpdate}; +use super::client::{Client, ClientError, FeedId, StreamId, StreamUpdate}; use super::coloured_string::{ColouredString, ColouredStringSlice}; use super::menu::*; use super::file::*; @@ -337,8 +338,14 @@ impl Tui { } }, Ok(SubthreadEvent::StreamEv(update)) => { - self.client.process_stream_update(update); - // FIXME: perhaps also notify state of a change + match self.client.process_stream_update(update) { + Ok(feeds_updated) => + state.handle_feed_updates(feeds_updated, + &mut self.client), + + // FIXME: errors here should go in the Error Log + _ => (), + } } } } @@ -374,6 +381,8 @@ pub trait ActivityState { (Vec, CursorPosition); fn handle_keypress(&mut self, key: OurKey, client: &mut Client) -> LogicalAction; + fn handle_feed_updates(&mut self, _feeds_updated: &HashSet, + _client: &mut Client) {} } struct TuiLogicalState { @@ -482,6 +491,15 @@ impl TuiLogicalState { } } + fn handle_feed_updates(&mut self, feeds_updated: HashSet, + client: &mut Client) { + // FIXME: if the mentions feed is updated, we may need to + // actually change the activity stack to throw the user into + // Read Messages. + + self.activity_state.handle_feed_updates(&feeds_updated, client); + } + fn changed_activity(&mut self, client: &mut Client) { self.activity_state = new_activity_state( self.activity_stack.top(), client);