use std::cmp::{min, max};
use std::collections::{HashMap, HashSet};
-use super::activity_stack::{UtilityActivity, OverlayActivity};
-use super::client::{Client, ClientError, FeedId, FeedExtend};
+use super::activity_stack::{
+ NonUtilityActivity, UtilityActivity, OverlayActivity,
+};
+use super::client::{Client, ClientError, FeedId, FeedExtend, Boosts, Replies};
use super::coloured_string::ColouredString;
use super::text::*;
use super::tui::{
fn extendable(&self) -> bool;
fn single_id(&self) -> String {
- panic!("Should only call this if the FileType sets CAN_LIST");
+ panic!("Should only call this if the FileType sets CAN_LIST or CAN_GET_POSTS");
}
}
trait FileType {
type Item: TextFragment + Sized;
const CAN_LIST: CanList = CanList::Nothing;
+ const CAN_GET_POSTS: bool = false;
fn get_from_client(id: &str, client: &mut Client) ->
Result<Self::Item, ClientError>;
enum UIMode {
Normal,
ListSubmenu,
+ PostsSubmenu,
Select(HighlightType, SelectionPurpose),
}
let mut lines = Vec::new();
let highlight = match self.ui_mode {
- UIMode::Normal | UIMode::ListSubmenu => None,
UIMode::Select(htype, _purpose) => match self.selection {
None => None,
Some((item, sub)) => if item == index {
None
}
}
+ _ => None,
};
for line in self.contents.get(index)
} else {
fs
};
+ let fs = if Type::CAN_GET_POSTS {
+ fs.add(Pr('p'), "Show Posts", 41)
+ } else {
+ fs
+ };
let fs = if Type::CAN_LIST != CanList::Nothing {
fs.add(Pr('l'), "List", 40)
} else {
};
let fs = fs
.add(Pr('/'), "Search Down", 20)
- .add(Pr('\\'), "Search Up", 19)
+ .add(Pr('\\'), "Search Up", 20)
.add(Pr('q'), "Exit", 100);
// We calculate the percentage through the file in a
};
fs.add(Pr('Q'), "Quit", 100)
}
+ UIMode::PostsSubmenu => {
+ assert_eq!(Type::CAN_GET_POSTS, true,
+ "How did we get here if !CAN_GET_POSTS?");
+ fs.add(Pr('A'), "All", 99)
+ .add(Pr('O'), "Original", 97)
+ .add(Pr('T'), "Top-level", 98)
+ .add(Pr('Q'), "Quit", 100)
+ }
UIMode::Select(_htype, purpose) => {
let fs = match purpose {
SelectionPurpose::ExamineUser =>
self.search()
}
+ Pr('p') | Pr('P') => {
+ if Type::CAN_GET_POSTS {
+ self.ui_mode = UIMode::PostsSubmenu;
+ }
+ LogicalAction::Nothing
+ }
+
_ => LogicalAction::Nothing,
}
UIMode::ListSubmenu => match key {
}
_ => LogicalAction::Nothing,
}
+ UIMode::PostsSubmenu => match key {
+ Pr('a') | Pr('A') => LogicalAction::Goto(
+ NonUtilityActivity::UserPosts(
+ self.contents.source.single_id(),
+ Boosts::Show, Replies::Show).into()),
+ Pr('o') | Pr('O') => LogicalAction::Goto(
+ NonUtilityActivity::UserPosts(
+ self.contents.source.single_id(),
+ Boosts::Hide, Replies::Show).into()),
+ Pr('t') | Pr('T') => LogicalAction::Goto(
+ NonUtilityActivity::UserPosts(
+ self.contents.source.single_id(),
+ Boosts::Hide, Replies::Hide).into()),
+ Pr('q') | Pr('Q') => {
+ self.ui_mode = UIMode::Normal;
+ LogicalAction::Nothing
+ }
+ _ => LogicalAction::Nothing,
+ }
UIMode::Select(_, purpose) => match key {
Space => self.complete_selection(client, false),
Pr('d') | Pr('D') => match purpose {
Ok(Box::new(file))
}
+pub fn user_posts(
+ file_positions: &HashMap<FeedId, FilePosition>, client: &mut Client,
+ user: &str, boosts: Boosts, replies: Replies)
+ -> Result<Box<dyn ActivityState>, ClientError>
+{
+ let feed = FeedId::User(user.to_owned(), boosts, replies);
+ let pos = file_positions.get(&feed).cloned();
+ let desc = StatusFeedType::with_feed(feed.clone());
+ let file = File::new(
+ client, FeedSource::new(feed), ColouredString::general(
+ "Public timeline <P>",
+ "HHHHHHHHHHHHHHHHHHHKH"), desc, pos)?;
+ Ok(Box::new(file))
+}
+
pub fn list_status_favouriters(client: &mut Client, id: &str) ->
Result<Box<dyn ActivityState>, ClientError>
{
impl FileType for ExamineUserFileType {
type Item = ExamineUserDisplay;
const CAN_LIST: CanList = CanList::ForUser;
+ const CAN_GET_POSTS: bool = true;
fn get_from_client(id: &str, client: &mut Client) ->
Result<Self::Item, ClientError>