chiark / gitweb /
Show what user you're logged in as.
authorSimon Tatham <anakin@pobox.com>
Thu, 4 Jan 2024 20:05:16 +0000 (20:05 +0000)
committerSimon Tatham <anakin@pobox.com>
Thu, 4 Jan 2024 20:05:16 +0000 (20:05 +0000)
Useful when testing two dummy accounts on a dev server, but might come
in useful for real people maintaining more than one config directory
as well.

src/menu.rs
src/text.rs
src/tui.rs

index f9b57eab1ea023eca74568323d73b1d588ee6259..f33c6dbf28a7211ed0ec2dde08b9ed7b58354b4e 100644 (file)
@@ -16,6 +16,7 @@ use super::tui::{
 enum MenuLine {
     Blank,
     Key(MenuKeypressLine),
+    Info(CentredInfoLine),
 }
 
 fn find_substring(haystack: &str, needle: &str)
@@ -45,6 +46,7 @@ struct Menu {
     title: FileHeader,
     status: FileStatusLineFinal,
     lines: Vec<MenuLine>,
+    bottom_lines: Vec<MenuLine>,
     actions: HashMap<OurKey, LogicalAction>,
 }
 
@@ -61,6 +63,7 @@ impl Menu {
             title: FileHeader::new(title),
             status: status.finalise(),
             lines: Vec::new(),
+            bottom_lines: Vec::new(),
             actions: HashMap::new(),
         };
 
@@ -121,6 +124,13 @@ impl Menu {
         self.lines.push(MenuLine::Blank);
     }
 
+    fn add_info_coloured(&mut self, desc: ColouredString) {
+        self.bottom_lines.push(MenuLine::Info(CentredInfoLine::new(desc)));
+    }
+    fn add_info(&mut self, desc: &str) {
+        self.add_info_coloured(ColouredString::uniform(desc, 'H'));
+    }
+
     fn finalise(mut self) -> Self {
         let mut lmaxwid = 0;
         let mut rmaxwid = 0;
@@ -154,6 +164,19 @@ impl ActivityState for Menu {
             lines.extend_from_slice(&match line {
                 MenuLine::Blank => BlankLine::render_static(),
                 MenuLine::Key(mk) => mk.render(w),
+                MenuLine::Info(cl) => cl.render(w),
+            });
+        }
+
+        while lines.len() + 2 + self.bottom_lines.len() < h {
+            lines.extend_from_slice(&BlankLine::render_static());
+        }
+
+        for line in &self.bottom_lines {
+            lines.extend_from_slice(&match line {
+                MenuLine::Blank => BlankLine::render_static(),
+                MenuLine::Key(mk) => mk.render(w),
+                MenuLine::Info(cl) => cl.render(w),
             });
         }
 
@@ -176,7 +199,7 @@ impl ActivityState for Menu {
     }
 }
 
-pub fn main_menu() -> Box<dyn ActivityState> {
+pub fn main_menu(client: &Client) -> Box<dyn ActivityState> {
     let mut menu = Menu::new(
         ColouredString::uniform("Mastodonochrome Main Menu", 'H'), true);
 
@@ -205,6 +228,8 @@ pub fn main_menu() -> Box<dyn ActivityState> {
     // anywhere.
     menu.add_action(Escape, "Utilities and Exit", LogicalAction::Nothing);
 
+    menu.add_info(&format!("Logged in as {}", &client.our_account_fq()));
+
     Box::new(menu.finalise())
 }
 
index 9a6e5c255267a6b58ccc4f2ee480112f63f487c9..150438615a922f4799265842cfe9d3cdd9d7888a 100644 (file)
@@ -1640,6 +1640,31 @@ fn test_menu_keypress() {
             });
 }
 
+pub struct CentredInfoLine {
+    text: ColouredString,
+}
+
+impl CentredInfoLine {
+    pub fn new(text: ColouredString) -> Self {
+        CentredInfoLine {
+            text,
+        }
+    }
+}
+
+impl TextFragment for CentredInfoLine {
+    fn render_highlighted(&self, width: usize, _highlight: Option<Highlight>)
+                          -> Vec<ColouredString>
+    {
+        let twidth = width.saturating_sub(1);
+        let title = self.text.truncate(twidth);
+        let tspace = twidth - title.width();
+        let tleft = tspace / 2;
+        let textpad = ColouredString::plain(" ").repeat(tleft) + &self.text;
+        vec! { textpad }
+    }
+}
+
 pub struct StatusDisplay {
     sep: SeparatorLine,
     from: UsernameHeader,
index 99829a57d9e1f80eaf4f68ed5d13e931421cc9b9..fd3b535f15dfdbb3c3e39d8d9e48c577b15ee081 100644 (file)
@@ -224,11 +224,13 @@ impl Tui {
         let mut terminal = Terminal::new(CrosstermBackend::new(stdout()))?;
         terminal.clear()?;
 
+        let state = TuiLogicalState::new(&client);
+
         let mut tui = Tui {
             terminal,
             subthread_sender: sender,
             subthread_receiver: receiver,
-            state: TuiLogicalState::new(),
+            state,
             client,
         };
 
@@ -445,12 +447,9 @@ struct TuiLogicalState {
 }
 
 impl TuiLogicalState {
-    fn new() -> Self {
+    fn new(client: &Client) -> Self {
         let activity_stack = ActivityStack::new();
-        // It would be nice to construct this by calling
-        // new_activity_state, but we don't have a &mut Client to give
-        // it, and in this case we know we don't need one.
-        let activity_state = main_menu();
+        let activity_state = main_menu(client);
 
         TuiLogicalState {
             activity_stack,
@@ -642,7 +641,7 @@ fn new_activity_state(&self, activity: Activity, client: &mut Client,
     {
         let result = match activity {
             Activity::NonUtil(NonUtilityActivity::MainMenu) =>
-                Ok(main_menu()),
+                Ok(main_menu(client)),
             Activity::Util(UtilityActivity::UtilsMenu) =>
                 Ok(utils_menu(client)),
             Activity::Util(UtilityActivity::ExitMenu) =>