From: Simon Tatham Date: Fri, 5 Jan 2024 06:25:53 +0000 (+0000) Subject: Add feature to show posts by the user you're examining. X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ian/git?a=commitdiff_plain;h=45bee8d6df352236343ad5e8c882c3c94f4a3e87;p=mastodonochrome.git Add feature to show posts by the user you're examining. --- diff --git a/src/activity_stack.rs b/src/activity_stack.rs index cc08f8c..917ce6b 100644 --- a/src/activity_stack.rs +++ b/src/activity_stack.rs @@ -1,3 +1,4 @@ +use super::client::{Boosts, Replies}; use super::file::SearchDirection; #[derive(PartialEq, Eq, Debug, Clone)] @@ -7,6 +8,7 @@ pub enum NonUtilityActivity { PublicTimelineFile, LocalTimelineFile, HashtagTimeline(String), + UserPosts(String, Boosts, Replies), ComposeToplevel, PostComposeMenu, } diff --git a/src/file.rs b/src/file.rs index 48f1514..d664605 100644 --- a/src/file.rs +++ b/src/file.rs @@ -3,8 +3,10 @@ use regex::Regex; 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::{ @@ -46,7 +48,7 @@ trait FileDataSource { 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"); } } @@ -115,6 +117,7 @@ enum CanList { 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; @@ -275,6 +278,7 @@ enum SelectionPurpose { enum UIMode { Normal, ListSubmenu, + PostsSubmenu, Select(HighlightType, SelectionPurpose), } @@ -346,7 +350,6 @@ impl File { 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 { @@ -355,6 +358,7 @@ impl File { None } } + _ => None, }; for line in self.contents.get(index) @@ -877,6 +881,11 @@ impl } 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 { @@ -902,7 +911,7 @@ impl }; 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 @@ -937,6 +946,14 @@ impl }; 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 => @@ -1111,6 +1128,13 @@ impl self.search() } + Pr('p') | Pr('P') => { + if Type::CAN_GET_POSTS { + self.ui_mode = UIMode::PostsSubmenu; + } + LogicalAction::Nothing + } + _ => LogicalAction::Nothing, } UIMode::ListSubmenu => match key { @@ -1148,6 +1172,25 @@ impl } _ => 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 { @@ -1272,6 +1315,21 @@ pub fn ego_log(file_positions: &HashMap, Ok(Box::new(file)) } +pub fn user_posts( + file_positions: &HashMap, client: &mut Client, + user: &str, boosts: Boosts, replies: Replies) + -> Result, 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

", + "HHHHHHHHHHHHHHHHHHHKH"), desc, pos)?; + Ok(Box::new(file)) +} + pub fn list_status_favouriters(client: &mut Client, id: &str) -> Result, ClientError> { @@ -1339,6 +1397,7 @@ struct ExamineUserFileType {} 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 diff --git a/src/tui.rs b/src/tui.rs index fd3b535..70e1288 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -702,6 +702,9 @@ fn new_activity_state(&self, activity: Activity, client: &mut Client, list_user_followers(client, id), Activity::Util(UtilityActivity::ListUserFollowees(ref id)) => list_user_followees(client, id), + Activity::NonUtil(NonUtilityActivity::UserPosts( + ref user, boosts, replies)) => + user_posts(&self.file_positions, client, user, boosts, replies), }; result.expect("FIXME: need to implement the Error Log here")