aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.toml4
-rw-r--r--src/display/mod.rs186
-rw-r--r--src/tw/events.rs1
-rw-r--r--src/tw/mod.rs2
4 files changed, 125 insertions, 68 deletions
diff --git a/Cargo.toml b/Cargo.toml
index ecc2ffe..78a38c5 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,8 +12,8 @@ a nice twitter
[[bin]]
name = "twidder"
# path = "main.rs"
-# test = false
-# bench = false
+test = false
+bench = false
[dependencies]
"termios" = "0.2.2"
diff --git a/src/display/mod.rs b/src/display/mod.rs
index fdb8448..c011294 100644
--- a/src/display/mod.rs
+++ b/src/display/mod.rs
@@ -1,6 +1,10 @@
extern crate termion;
+use std::io::Write;
+use std::io::stdout;
+
use self::termion::color;
+use self::termion::{clear, cursor};
use ::tw;
@@ -8,6 +12,7 @@ use ::tw::TweetId;
use std;
+#[derive(Clone)]
pub enum Infos {
Tweet(TweetId),
Thread(Vec<TweetId>),
@@ -16,27 +21,73 @@ pub enum Infos {
}
pub fn paint(tweeter: &mut ::tw::TwitterCache) {
- println!("Painting, totally.");
- println!("Statuses:");
- {
- let to_show = tweeter.display_info.log.iter().rev().take(4).collect::<Vec<&String>>().into_iter().rev();
- for line in to_show {
- println!("{}", line);
- }
- }
+ match termion::terminal_size() {
+ Ok((width, height)) => {
+ // draw input prompt
+ println!("{}{}", cursor::Goto(1, height - 6), clear::CurrentLine);
+ println!("{}{}>", cursor::Goto(1, height - 5), clear::CurrentLine);
+ println!("{}{}", cursor::Goto(1, height - 4), clear::CurrentLine);
+ let mut i = 0;
+ let log_size = 4;
+ let last_elem = tweeter.display_info.log.len().saturating_sub(log_size);
+ {
+ let to_show = tweeter.display_info.log.drain(last_elem..);
+ for line in to_show {
+ println!("{}{}{}", cursor::Goto(1, height - i), clear::CurrentLine, line);
+ i = i + 1;
+ }
+ }
+ while i < log_size as u16 {
+ println!("{}{}", cursor::Goto(1, height - i), clear::CurrentLine);
+ i = i + 1;
+ }
+ // draw status lines
+ // draw tweets
+ let last_twevent = tweeter.display_info.infos.len().saturating_sub(height as usize - 4);
+ let last_few_twevent: Vec<Infos> = tweeter.display_info.infos[last_twevent..].iter().map(|x| x.clone()).rev().collect::<Vec<Infos>>();
- if let Some(elem) = tweeter.display_info.infos.pop() {
- match elem {
- Infos::Tweet(id) => render_twete(&id, tweeter),
- Infos::Thread(ids) => {
- println!("I'd show a thread if I knew how");
- },
- Infos::Event(e) => {
- e.render(tweeter);
- },
- Infos::DM(msg) => {
- println!("DM: {}", msg);
+ let mut h = 7;
+ for info in last_few_twevent {
+ let mut to_draw = match info {
+ Infos::Tweet(id) => {
+ render_twete(&id, tweeter).iter().map(|x| x.to_owned()).rev().collect()
+ }
+ Infos::Thread(ids) => {
+ vec![format!("{}{}I'd show a thread if I knew how", cursor::Goto(1, height - h), clear::CurrentLine)]
+ },
+ Infos::Event(e) => {
+ e.clone().render(tweeter).into_iter().rev().collect()
+ },
+ Infos::DM(msg) => {
+ vec![format!("{}{}DM: {}", cursor::Goto(1, height - h), clear::CurrentLine, msg)]
+ }
+ };
+ for line in to_draw {
+ println!("{}{}{}", cursor::Goto(1, height - h), clear::CurrentLine, line);
+ h = h + 1;
+ if h >= height {
+ print!("{}", cursor::Goto(2, height - 6));
+ stdout().flush();
+ return;
+ }
+ }
+ println!("{}{}", cursor::Goto(1, height - h), clear::CurrentLine);
+ h = h + 1;
+ if h >= height {
+ print!("{}", cursor::Goto(2, height - 6));
+ stdout().flush();
+ return;
+ }
}
+ while h < height {
+ println!("{}{}", cursor::Goto(1, height - h), clear::CurrentLine);
+ h = h + 1;
+ }
+ print!("{}", cursor::Goto(2, height - 6));
+ stdout().flush();
+ },
+ Err(e) => {
+ println!("Can't get term dimensions: {}", e);
}
}
}
@@ -63,14 +114,15 @@ fn color_for(handle: &String) -> termion::color::Fg<&color::Color> {
}
pub trait Render {
- fn render(self, tweeter: &mut ::tw::TwitterCache);
+ fn render(self, tweeter: &mut ::tw::TwitterCache) -> Vec<String>;
}
impl Render for tw::events::Event {
- fn render(self, tweeter: &mut ::tw::TwitterCache) {
+ fn render(self, tweeter: &mut ::tw::TwitterCache) -> Vec<String> {
+ let mut result = Vec::new();
match self {
tw::events::Event::Quoted { user_id, twete_id } => {
- println!("---------------------------------");
+ result.push("---------------------------------".to_string());
{
let user = tweeter.retrieve_user(&user_id).unwrap();
println!(" quoted_tweet : {} (@{})", user.name, user.handle);
@@ -80,75 +132,75 @@ impl Render for tw::events::Event {
tw::events::Event::Deleted { user_id, twete_id } => {
if let Some(handle) = tweeter.retrieve_user(&user_id).map(|x| &x.handle).map(|x| x.clone()) {
if let Some(_tweet) = tweeter.retrieve_tweet(&TweetId::Twitter(twete_id.to_owned())).map(|x| x.clone()) {
- println!("-------------DELETED------------------");
- render_twete(&TweetId::Twitter(twete_id), tweeter);
- println!("-------------DELETED------------------");
+ result.push(format!("-------------DELETED------------------"));
+ result.extend(render_twete(&TweetId::Twitter(twete_id), tweeter));
+ result.push(format!("-------------DELETED------------------"));
} else {
- println!("dunno what, but do know who: {} - {}", user_id, handle);
+ result.push(format!("dunno what, but do know who: {} - {}", user_id, handle));
}
} else {
- println!("delete...");
- println!("dunno who...");
+ result.push("delete... dunno who".to_string());
}
},
tw::events::Event::RT_RT { user_id, twete_id } => {
- println!("---------------------------------");
+ result.push("---------------------------------".to_string());
{
let user = tweeter.retrieve_user(&user_id).unwrap();
- println!(" +rt_rt : {} (@{})", user.name, user.handle);
+ result.push(format!(" +rt_rt : {} (@{})", user.name, user.handle));
}
- render_twete(&TweetId::Twitter(twete_id), tweeter);
+ result.extend(render_twete(&TweetId::Twitter(twete_id), tweeter));
},
tw::events::Event::Fav_RT { user_id, twete_id } => {
- println!("---------------------------------");
+ result.push("---------------------------------".to_string());
if let Some(user) = tweeter.retrieve_user(&user_id) {
- println!(" +rt_fav : {} (@{})", user.name, user.handle);
+ result.push(format!(" +rt_fav : {} (@{})", user.name, user.handle));
} else {
- println!(" +rt_fav but don't know who {} is", user_id);
+ result.push(format!(" +rt_fav but don't know who {} is", user_id));
}
- render_twete(&TweetId::Twitter(twete_id), tweeter);
+ result.extend(render_twete(&TweetId::Twitter(twete_id), tweeter));
},
tw::events::Event::Fav { user_id, twete_id } => {
- println!("---------------------------------");
+ result.push("---------------------------------".to_string());
{
let user = tweeter.retrieve_user(&user_id).unwrap();
- println!("{} +fav : {} (@{}){}", color::Fg(color::Yellow), user.name, user.handle, color::Fg(color::Reset));
+ result.push(format!("{} +fav : {} (@{}){}", color::Fg(color::Yellow), user.name, user.handle, color::Fg(color::Reset)));
}
- render_twete(&TweetId::Twitter(twete_id), tweeter);
+ result.extend(render_twete(&TweetId::Twitter(twete_id), tweeter));
},
tw::events::Event::Unfav { user_id, twete_id } => {
- println!("---------------------------------");
+ result.push("---------------------------------".to_string());
{
let user = tweeter.retrieve_user(&user_id).unwrap();
- println!("{} -fav : {} (@{}){}", color::Fg(color::Yellow), user.name, user.handle, color::Fg(color::Reset));
+ result.push(format!("{} -fav : {} (@{}){}", color::Fg(color::Yellow), user.name, user.handle, color::Fg(color::Reset)));
}
- render_twete(&TweetId::Twitter(twete_id), tweeter);
+ result.extend(render_twete(&TweetId::Twitter(twete_id), tweeter));
},
tw::events::Event::Followed { user_id } => {
- println!("---------------------------------");
+ result.push("---------------------------------".to_string());
let user = tweeter.retrieve_user(&user_id).unwrap();
- println!(" +fl : {} (@{})", user.name, user.handle);
+ result.push(format!(" +fl : {} (@{})", user.name, user.handle));
},
tw::events::Event::Unfollowed { user_id } => {
- println!("---------------------------------");
+ result.push("---------------------------------".to_string());
let user = tweeter.retrieve_user(&user_id).unwrap();
- println!(" -fl : {} (@{})", user.name, user.handle);
+ result.push(format!(" -fl : {} (@{})", user.name, user.handle));
}
/*
Blocked(user_id) => {
},
*/
}
- println!("");
+ result
}
}
-pub fn render_twete(twete_id: &TweetId, tweeter: &mut tw::TwitterCache) {
+pub fn render_twete(twete_id: &TweetId, tweeter: &mut tw::TwitterCache) -> Vec<String> {
+ let mut result = Vec::new();
let id_color = color::Fg(color::Rgb(180, 80, 40));
let maybe_twete = tweeter.retrieve_tweet(twete_id).map(|x| x.clone());
if maybe_twete.is_none() {
- println!("No such tweet: {:?}", twete_id);
- return;
+ result.push(format!("No such tweet: {:?}", twete_id));
+ return result;
}
let twete = maybe_twete.unwrap();
// if we got the tweet, the API gave us the user too
@@ -159,7 +211,7 @@ pub fn render_twete(twete_id: &TweetId, tweeter: &mut tw::TwitterCache) {
let rt = tweeter.retrieve_tweet(&TweetId::Twitter(rt_id.to_owned())).unwrap().clone();
// and its author
let rt_author = tweeter.retrieve_user(&rt.author_id).unwrap().clone();
- println!("{} id:{} (rt_id:{}){}{}",
+ result.push(format!("{} id:{} (rt_id:{}){}{}",
id_color, rt.internal_id, twete.internal_id,
rt.reply_to_tweet.clone()
.map(|id| tweeter.retrieve_tweet(&TweetId::Twitter(id.to_owned()))
@@ -168,16 +220,16 @@ pub fn render_twete(twete_id: &TweetId, tweeter: &mut tw::TwitterCache) {
)
.unwrap_or("".to_string()),
color::Fg(color::Reset)
- );
- println!(" {}{}{} ({}@{}{}) via {}{}{} ({}@{}{}) RT:",
+ ));
+ result.push(format!(" {}{}{} ({}@{}{}) via {}{}{} ({}@{}{}) RT:",
color_for(&rt_author.handle), rt_author.name, color::Fg(color::Reset),
color_for(&rt_author.handle), rt_author.handle, color::Fg(color::Reset),
color_for(&user.handle), user.name, color::Fg(color::Reset),
color_for(&user.handle), user.handle, color::Fg(color::Reset)
- );
+ ));
}
None => {
- println!("{} id:{}{}{}",
+ result.push(format!("{} id:{}{}{}",
id_color, twete.internal_id,
twete.reply_to_tweet.clone()
.map(|id| tweeter.retrieve_tweet(&TweetId::Twitter(id.to_owned()))
@@ -186,21 +238,23 @@ pub fn render_twete(twete_id: &TweetId, tweeter: &mut tw::TwitterCache) {
)
.unwrap_or("".to_string()),
color::Fg(color::Reset)
- );
- println!(" {}{}{} ({}@{}{})",
+ ));
+ result.push(format!(" {}{}{} ({}@{}{})",
color_for(&user.handle), user.name, color::Fg(color::Reset),
color_for(&user.handle), user.handle, color::Fg(color::Reset)
- );
+ ));
}
}
- println!(" {}", twete.text.replace("\r", "\\r").split("\n").collect::<Vec<&str>>().join("\n "));
+ result.extend(
+ format!(" {}", twete.text.replace("\r", "\\r").split("\n").collect::<Vec<&str>>().join("\n ")).split("\n").map(|x| x.to_owned())
+ );
if let Some(ref qt_id) = twete.quoted_tweet_id {
let maybe_qt = tweeter.retrieve_tweet(&TweetId::Twitter(qt_id.to_owned())).map(|x| x.to_owned());
if let Some(qt) = maybe_qt {
let qt_author = tweeter.retrieve_user(&qt.author_id).unwrap().clone();
- println!("{} id:{}{}{}",
+ result.push(format!("{} id:{}{}{}",
id_color, qt.internal_id,
qt.reply_to_tweet.clone()
.map(|id| tweeter.retrieve_tweet(&TweetId::Twitter(id.to_owned()))
@@ -209,18 +263,20 @@ pub fn render_twete(twete_id: &TweetId, tweeter: &mut tw::TwitterCache) {
)
.unwrap_or("".to_string()),
color::Fg(color::Reset)
- );
- println!(
+ ));
+ result.push(format!(
" {}{}{} ({}@{}{})",
color_for(&qt_author.handle), qt_author.name, color::Fg(color::Reset),
color_for(&qt_author.handle), qt_author.handle, color::Fg(color::Reset)
- );
- println!(
+ ));
+ result.push(format!(
" {}",
qt.text.replace("\r", "\\r").split("\n").collect::<Vec<&str>>().join("\n ")
- );
+ ));
} else {
- println!(" << don't have quoted tweet! >>");
+ result.push(format!(" << don't have quoted tweet! >>"));
}
}
+
+ result
}
diff --git a/src/tw/events.rs b/src/tw/events.rs
index c26a840..afc7fbb 100644
--- a/src/tw/events.rs
+++ b/src/tw/events.rs
@@ -1,5 +1,6 @@
extern crate serde_json;
+#[derive(Clone)]
pub enum Event {
Deleted { user_id: String, twete_id: String },
RT_RT { user_id: String, twete_id: String },
diff --git a/src/tw/mod.rs b/src/tw/mod.rs
index f2582cf..0341ec9 100644
--- a/src/tw/mod.rs
+++ b/src/tw/mod.rs
@@ -135,7 +135,7 @@ impl Default for IdConversions {
}
}
-#[derive(Debug, PartialEq)]
+#[derive(Debug, PartialEq, Clone)]
pub enum TweetId {
Today(u64), // just a number
Dated(String, u64), // 20171002:number