From 1028ae62cce8cfabe7fe8c308254c4d6bb48c5ee Mon Sep 17 00:00:00 2001 From: Simon Tatham Date: Mon, 1 Jan 2024 10:11:07 +0000 Subject: [PATCH] UNFINISHED examine --- src/activity_stack.rs | 2 +- src/client.rs | 25 +++++++++++++++++++++++++ src/editor.rs | 25 +++++++++++++++++-------- src/file.rs | 33 +++++++++++++++++++++++++++++++++ src/tui.rs | 2 ++ 5 files changed, 78 insertions(+), 9 deletions(-) diff --git a/src/activity_stack.rs b/src/activity_stack.rs index 0d9b724..0a78da1 100644 --- a/src/activity_stack.rs +++ b/src/activity_stack.rs @@ -14,7 +14,7 @@ pub enum UtilityActivity { LogsMenu2, EgoLog, ExitMenu, - ExamineUser(String), + ExamineUser(String), // the account _id_, not its name ListUserFollowers(String), ListUserFollowees(String), InfoStatus(String), diff --git a/src/client.rs b/src/client.rs index a9b4e03..c80260e 100644 --- a/src/client.rs +++ b/src/client.rs @@ -595,4 +595,29 @@ impl Client { Ok(updates) } + + pub fn account_by_name(&mut self, name: &str) -> + Result + { + let (url, req) = self.api_request( + Req::get("accounts/lookup").param("acct", name))?; + let rsp = req.send()?; + let rspstatus = rsp.status(); + let ac: Account = if !rspstatus.is_success() { + Err(ClientError::UrlError(url.clone(), rspstatus.to_string())) + } else { + match serde_json::from_str(&rsp.text()?) { + Ok(ac) => Ok(ac), + Err(e) => Err(ClientError::UrlError( + url.clone(), e.to_string())), + } + }?; + if ac.acct != name && self.fq(&ac.acct) != name { + return Err(ClientError::UrlError( + url.clone(), format!("request returned wrong account name {}", + &ac.acct))); + } + self.cache_account(&ac); + Ok(ac) + } } diff --git a/src/editor.rs b/src/editor.rs index fbb7ae5..0e00ee6 100644 --- a/src/editor.rs +++ b/src/editor.rs @@ -527,12 +527,12 @@ struct BottomLineEditorOverlay { prompt: ColouredString, promptwidth: usize, ed: SingleLineEditor, - result: Box LogicalAction>, + result: Box LogicalAction>, } impl BottomLineEditorOverlay { - fn new(prompt: ColouredString, result: Box LogicalAction>) - -> Self + fn new(prompt: ColouredString, + result: Box LogicalAction>) -> Self { let promptwidth = prompt.width(); BottomLineEditorOverlay { @@ -563,11 +563,11 @@ impl ActivityState for BottomLineEditorOverlay { (vec! { &self.prompt + buffer }, cursorpos) } - fn handle_keypress(&mut self, key: OurKey, _client: &mut Client) -> + fn handle_keypress(&mut self, key: OurKey, client: &mut Client) -> LogicalAction { if self.ed.handle_keypress(key) { - (self.result)(&self.ed.core.text) + (self.result)(&self.ed.core.text, client) } else { LogicalAction::Nothing } @@ -577,12 +577,21 @@ impl ActivityState for BottomLineEditorOverlay { pub fn get_user_to_examine() -> Box { Box::new(BottomLineEditorOverlay::new( ColouredString::plain("Examine User: "), - Box::new(move |s| { + Box::new(move |s, client| { + let s = s.trim(); + let s = s.strip_prefix("@").unwrap_or(s); if s.is_empty() { LogicalAction::PopOverlaySilent } else { - LogicalAction::Goto( - UtilityActivity::ExamineUser(s.to_owned()).into()) + match dbg!(client.account_by_name(s)) { + Ok(account) => LogicalAction::Goto( + UtilityActivity::ExamineUser(account.id).into()), + + // FIXME: it would be nice to discriminate errors + // better here, and maybe return anything worse + // than 'user not found' to the Error Log + Err(_) => LogicalAction::PopOverlayBeep, + } } }) )) diff --git a/src/file.rs b/src/file.rs index a93aa9f..cf38202 100644 --- a/src/file.rs +++ b/src/file.rs @@ -63,6 +63,20 @@ impl FileDataSource for FeedSource { fn extendable(&self) -> bool { true } } +struct SingletonSource {} + +impl FileDataSource for SingletonSource { + fn get(&self, _client: &mut Client) -> (Vec, isize) { + (vec! { "".to_owned() }, 0) + } + fn init(&self, _client: &mut Client) -> Result<(), ClientError> { Ok(()) } + fn try_extend(&self, _client: &mut Client) -> Result { + Ok(false) + } + fn updated(&self, _feeds_updated: &HashSet) -> bool { false } + fn extendable(&self) -> bool { false } +} + trait FileType { type Item: TextFragment + Sized; @@ -108,6 +122,17 @@ impl FileType for EgoNotificationFeedType { } } +struct ExamineUserFileType {} +impl FileType for ExamineUserFileType { + type Item = EditorHeaderSeparator; // FIXME + + fn get_from_client(_id: &str, _client: &mut Client) -> + Result + { + Ok(EditorHeaderSeparator::new()) + } +} + struct FileContents { source: Source, header: FileHeader, @@ -602,3 +627,11 @@ pub fn ego_log(client: &mut Client) -> "HHHHHHHHHHHKKKHHKHHKHHKH"))?; Ok(Box::new(file)) } + +pub fn examine_user(client: &mut Client, account_id: &str) -> + Result, ClientError> +{ + let file = File::::new( + client, SingletonSource{}, ColouredString::uniform(account_id, '!'))?; + Ok(Box::new(file)) +} diff --git a/src/tui.rs b/src/tui.rs index eae9a5c..c63c5b1 100644 --- a/src/tui.rs +++ b/src/tui.rs @@ -443,6 +443,8 @@ fn new_activity_state(activity: Activity, client: &mut Client) -> ego_log(client), Activity::Overlay(OverlayActivity::GetUserToExamine) => Ok(get_user_to_examine()), + Activity::Util(UtilityActivity::ExamineUser(ref name)) => + examine_user(client, name), _ => todo!(), }; -- 2.30.2