use reqwest::Url;
-use std::collections::{HashMap, VecDeque};
+use std::collections::{HashMap, HashSet, VecDeque};
use std::io::Read;
use super::auth::{AuthConfig,AuthError};
Ok(())
}
- pub fn process_stream_update(&mut self, _up: StreamUpdate) {
+ pub fn process_stream_update(&mut self, up: StreamUpdate) ->
+ Result<HashSet<FeedId>, 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)
}
}
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;
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();
_ => LogicalAction::Nothing,
}
}
+
+ fn handle_feed_updates(&mut self, feeds_updated: &HashSet<FeedId>,
+ 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) ->
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::*;
}
},
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
+ _ => (),
+ }
}
}
}
(Vec<ColouredString>, CursorPosition);
fn handle_keypress(&mut self, key: OurKey, client: &mut Client) ->
LogicalAction;
+ fn handle_feed_updates(&mut self, _feeds_updated: &HashSet<FeedId>,
+ _client: &mut Client) {}
}
struct TuiLogicalState {
}
}
+ fn handle_feed_updates(&mut self, feeds_updated: HashSet<FeedId>,
+ 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);