}
pub struct Feed {
- ids: VecDeque<String>, // ids, whether of statuses, accounts or what
- origin: isize,
+ pub ids: VecDeque<String>, // ids, whether of statuses, accounts or what
+ pub origin: isize,
}
pub struct Client {
let body = req.send()?.text()?;
let st: Status = match serde_json::from_str(&body) {
Ok(st) => Ok(st),
- Err(e) => Err(ClientError::UrlError(url.clone(), e.to_string())),
+ Err(e) => {
+ Err(ClientError::UrlError(url.clone(), e.to_string()))
+ },
}?;
if st.id != id {
return Err(ClientError::UrlError(
let body = req.send()?.text()?;
let sts: Vec<Status> = match serde_json::from_str(&body) {
Ok(sts) => Ok(sts),
- Err(e) => Err(ClientError::UrlError(url.clone(), e.to_string())),
+ Err(e) => {
+ dbg!(&body);
+ Err(ClientError::UrlError(url.clone(), e.to_string()))
+ },
}?;
for st in &sts {
self.cache_status(st);
Ok(())
}
- pub fn borrow_feed(&self, id: FeedId) -> &Feed {
- self.feeds.get(&id).expect(
+ pub fn borrow_feed(&self, id: &FeedId) -> &Feed {
+ self.feeds.get(id).expect(
"should only ever borrow feeds that have been fetched")
}
}
use super::client::{Client, ClientError, FeedId, FeedExtend};
use super::coloured_string::ColouredString;
+use super::text::*;
use super::tui::{
ActivityState, CursorPosition, LogicalAction,
OurKey,
struct FeedFile {
id: FeedId,
+ items: Vec<Box<dyn TextFragment>>,
}
impl FeedFile {
fn new(id: FeedId, client: &mut Client) -> Result<Self, ClientError> {
client.fetch_feed(&id, FeedExtend::Initial)?;
- Ok(FeedFile {
+ let mut ff = FeedFile {
id: id,
- })
+ items: Vec::new(),
+ };
+
+ ff.update_items(client);
+
+ Ok(ff)
+ }
+
+ fn update_items(&mut self, client: &mut Client) {
+ let ids: Vec<_> = client.borrow_feed(&self.id).ids
+ .iter().map(|x| x.clone()).collect();
+ self.items.clear();
+ for id in ids {
+ let st = client.status_by_id(&id)
+ .expect("Any id stored in a Feed should also be cached")
+ .clone();
+ self.items.push(Box::new(StatusDisplay::new(st)));
+ }
}
}
impl ActivityState for FeedFile {
- fn draw(&self, _w: usize, _h: usize)
+ fn draw(&self, w: usize, h: usize)
-> (Vec<ColouredString>, CursorPosition) {
- (Vec::new(), CursorPosition::None) // FIXME
+ let mut lines = Vec::new();
+
+ for item in &self.items {
+ lines.extend(item.render(w).iter().map(|line| line.to_owned()));
+ if lines.len() + 1 >= h {
+ break;
+ }
+ }
+
+ (lines, CursorPosition::None) // FIXME
}
fn handle_keypress(&mut self, _key: OurKey) -> LogicalAction {
use unicode_width::UnicodeWidthStr;
use super::html;
+use super::types::*;
use super::tui::OurKey;
use super::coloured_string::{ColouredString, ColouredStringSlice};
" k K "),
});
}
+
+pub struct StatusDisplay {
+ st: Status,
+ via: Option<Account>,
+}
+
+impl StatusDisplay {
+ pub fn new(st: Status) -> Self {
+ let (st, via) = match st.reblog {
+ Some(b) => (*b, Some(st.account)),
+ None => (st, None),
+ };
+
+ StatusDisplay {
+ st: st,
+ via: via,
+ }
+ }
+}
+
+impl TextFragment for StatusDisplay {
+ fn render(&self, width: usize) -> Vec<ColouredString> {
+ let mut lines = Vec::new();
+
+ let sep = SeparatorLine::new(
+ Some(self.st.created_at),
+ self.st.favourited == Some(true),
+ self.st.reblogged == Some(true));
+ lines.extend(sep.render(width).iter().map(|line| line.to_owned()));
+
+ lines
+ }
+}