chiark / gitweb /
Change my mind again about composing.
authorSimon Tatham <anakin@pobox.com>
Sun, 21 Jan 2024 15:36:35 +0000 (15:36 +0000)
committerSimon Tatham <anakin@pobox.com>
Sun, 21 Jan 2024 15:36:35 +0000 (15:36 +0000)
Composition activities should stack above reading files, but below
things to which you might pop out to get more information (such as
checking the username of someone to @mention). So I've given them an
Activity category of their own, which has at most one occupant (like
UtilityActivity) but is separate and just below Utility.

I'm still not sure this is right, but I think it's better than before.
I'll try using it for a while and see.

src/activity_stack.rs
src/file.rs
src/menu.rs
src/tui.rs

index 04785282e425d4a27f8814d31ba454f493e5b589..1f20a9d3a50d390dad79c06cd393663e8fc1cb48 100644 (file)
@@ -13,6 +13,14 @@ pub enum NonUtilityActivity {
     LoginMenu,
 }
 
+#[derive(PartialEq, Eq, Debug, Clone, Hash)]
+pub enum ComposeActivity {
+    ComposeToplevel,
+    PostComposeMenu,
+    ComposeReply(String),
+    PostReplyMenu(String),
+}
+
 #[derive(PartialEq, Eq, Debug, Clone, Hash)]
 pub enum UtilityActivity {
     UtilsMenu,
@@ -27,10 +35,6 @@ pub enum UtilityActivity {
     InfoStatus(String),
     ListStatusFavouriters(String),
     ListStatusBoosters(String),
-    ComposeToplevel,
-    PostComposeMenu,
-    ComposeReply(String),
-    PostReplyMenu(String),
     UserOptions(String),
     InstanceRules,
 }
@@ -46,6 +50,7 @@ pub enum OverlayActivity {
 #[derive(PartialEq, Eq, Debug, Clone, Hash)]
 pub enum Activity {
     NonUtil(NonUtilityActivity),
+    Compose(ComposeActivity),
     Util(UtilityActivity),
     Overlay(OverlayActivity),
 }
@@ -55,6 +60,11 @@ impl From<NonUtilityActivity> for Activity {
         Activity::NonUtil(value)
     }
 }
+impl From<ComposeActivity> for Activity {
+    fn from(value: ComposeActivity) -> Self {
+        Activity::Compose(value)
+    }
+}
 impl From<UtilityActivity> for Activity {
     fn from(value: UtilityActivity) -> Self {
         Activity::Util(value)
@@ -69,6 +79,8 @@ impl From<OverlayActivity> for Activity {
 #[derive(PartialEq, Eq, Debug)]
 pub struct ActivityStack {
     nonutil: Vec<NonUtilityActivity>,
+    compose: Option<ComposeActivity>,
+    initial_compose: Option<ComposeActivity>,
     util: Option<UtilityActivity>,
     initial_util: Option<UtilityActivity>,
     overlay: Option<OverlayActivity>,
@@ -83,10 +95,7 @@ impl Activity {
         // gets reinitialised, because that's the simplest way to jump
         // you down to the new message.
         match self {
-            Activity::Util(UtilityActivity::ComposeToplevel)
-            | Activity::Util(UtilityActivity::PostComposeMenu)
-            | Activity::Util(UtilityActivity::ComposeReply(..))
-            | Activity::Util(UtilityActivity::PostReplyMenu(..)) => false,
+            Activity::Compose(_) => false,
             _ => true,
         }
     }
@@ -98,6 +107,8 @@ impl ActivityStack {
             nonutil: vec![top],
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     }
@@ -105,6 +116,8 @@ impl ActivityStack {
     pub fn pop(&mut self) {
         if self.util.is_some() {
             self.util = None;
+        } else if self.compose.is_some() {
+            self.compose = None;
         } else if self.nonutil.len() > 1 {
             // never pop the topmost activity
             self.nonutil.pop();
@@ -131,6 +144,11 @@ impl ActivityStack {
                 self.overlay = None;
                 self.util = Some(x);
             }
+            Activity::Compose(x) => {
+                self.overlay = None;
+                self.util = None;
+                self.compose = Some(x);
+            }
             Activity::NonUtil(NonUtilityActivity::MainMenu) => {
                 // Special case: going to the Main Menu replaces the
                 // topmost activity on the stack _even_ if it was not
@@ -162,9 +180,12 @@ impl ActivityStack {
     pub fn top(&self) -> Activity {
         match &self.util {
             Some(x) => Activity::Util(x.clone()),
-            _ => match self.nonutil.last() {
-                Some(y) => Activity::NonUtil(y.clone()),
-                _ => Activity::NonUtil(NonUtilityActivity::MainMenu),
+            _ => match &self.compose {
+                Some(x) => Activity::Compose(x.clone()),
+                _ => match self.nonutil.last() {
+                    Some(y) => Activity::NonUtil(y.clone()),
+                    _ => Activity::NonUtil(NonUtilityActivity::MainMenu),
+                },
             },
         }
     }
@@ -187,6 +208,8 @@ impl ActivityStack {
             .iter()
             .cloned()
             .map(Activity::NonUtil)
+            .chain(self.compose.iter().cloned().map(Activity::Compose))
+            .chain(self.initial_compose.iter().cloned().map(Activity::Compose))
             .chain(self.util.iter().cloned().map(Activity::Util))
             .chain(self.initial_util.iter().cloned().map(Activity::Util))
             .chain(self.overlay.iter().cloned().map(Activity::Overlay))
@@ -203,6 +226,8 @@ fn test() {
             nonutil: vec! {NonUtilityActivity::MainMenu},
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -218,6 +243,8 @@ fn test() {
             },
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -233,6 +260,8 @@ fn test() {
             },
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -245,6 +274,8 @@ fn test() {
             nonutil: vec! {NonUtilityActivity::MainMenu},
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -260,6 +291,8 @@ fn test() {
             },
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -275,6 +308,8 @@ fn test() {
             },
             util: Some(UtilityActivity::UtilsMenu),
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -290,6 +325,8 @@ fn test() {
             },
             util: Some(UtilityActivity::ReadMentions),
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -305,6 +342,8 @@ fn test() {
             },
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -320,6 +359,8 @@ fn test() {
             },
             util: Some(UtilityActivity::ReadMentions),
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -335,6 +376,8 @@ fn test() {
             },
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -347,6 +390,8 @@ fn test() {
             nonutil: vec! {NonUtilityActivity::MainMenu},
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
@@ -359,6 +404,8 @@ fn test() {
             nonutil: vec! {NonUtilityActivity::MainMenu},
             util: None,
             initial_util: None,
+            compose: None,
+            initial_compose: None,
             overlay: None,
         }
     );
index b30eb1428a9bc6d6c923f3129d50d3b37cf87bd9..46b5700241acb497cd77f67573140bcbfff0ccb5 100644 (file)
@@ -6,7 +6,7 @@ use std::collections::{hash_map, HashMap, HashSet};
 use std::rc::Rc;
 
 use super::activity_stack::{
-    NonUtilityActivity, OverlayActivity, UtilityActivity,
+    NonUtilityActivity, OverlayActivity, UtilityActivity, ComposeActivity,
 };
 use super::client::{
     Boosts, Client, ClientError, FeedExtend, FeedId, Replies,
@@ -1040,7 +1040,7 @@ impl<Type: FileType, Source: FileDataSource> File<Type, Source> {
                     LogicalAction::Nothing
                 }
                 SelectionPurpose::Reply => LogicalAction::Goto(
-                    UtilityActivity::ComposeReply(id).into(),
+                    ComposeActivity::ComposeReply(id).into(),
                 ),
                 SelectionPurpose::Thread => LogicalAction::Goto(
                     NonUtilityActivity::ThreadFile(id, alt).into(),
index ceb24535520a5b8fa043485cb9c2b1ffda7c7999..409e3649ed340a83ee4c7f25d7280de1153c8a91 100644 (file)
@@ -2,7 +2,7 @@ use itertools::Itertools;
 use std::collections::HashMap;
 
 use super::activity_stack::{
-    NonUtilityActivity, OverlayActivity, UtilityActivity,
+    NonUtilityActivity, OverlayActivity, UtilityActivity, ComposeActivity,
 };
 use super::client::Client;
 use super::coloured_string::ColouredString;
@@ -247,7 +247,7 @@ pub fn main_menu(client: &Client) -> Box<dyn ActivityState> {
     menu.add_action(
         Pr('C'),
         "Compose a post",
-        LogicalAction::Goto(UtilityActivity::ComposeToplevel.into()),
+        LogicalAction::Goto(ComposeActivity::ComposeToplevel.into()),
     );
     menu.add_blank_line();
 
index f302a3fd12b651d18b2407437328048c25f93d25..467a8d98ca7ddca5a7a42414f780ed6dccc0050f 100644 (file)
@@ -778,11 +778,11 @@ impl TuiLogicalState {
                 LogicalAction::Error(_) => break PhysicalAction::Beep, // FIXME: Error Log
                 LogicalAction::PostComposed(post) => {
                     let newact = match self.activity_stack.top() {
-                        Activity::Util(UtilityActivity::ComposeToplevel) => {
-                            UtilityActivity::PostComposeMenu.into()
+                        Activity::Compose(ComposeActivity::ComposeToplevel) => {
+                            ComposeActivity::PostComposeMenu.into()
                         }
-                        Activity::Util(UtilityActivity::ComposeReply(id)) => {
-                            UtilityActivity::PostReplyMenu(id).into()
+                        Activity::Compose(ComposeActivity::ComposeReply(id)) => {
+                            ComposeActivity::PostReplyMenu(id).into()
                         }
                         act => panic!("can't postcompose {act:?}"),
                     };
@@ -792,11 +792,11 @@ impl TuiLogicalState {
                 }
                 LogicalAction::PostReEdit(post) => {
                     let newact = match self.activity_stack.top() {
-                        Activity::Util(UtilityActivity::PostComposeMenu) => {
-                            UtilityActivity::ComposeToplevel.into()
+                        Activity::Compose(ComposeActivity::PostComposeMenu) => {
+                            ComposeActivity::ComposeToplevel.into()
                         }
-                        Activity::Util(UtilityActivity::PostReplyMenu(id)) => {
-                            UtilityActivity::ComposeReply(id).into()
+                        Activity::Compose(ComposeActivity::PostReplyMenu(id)) => {
+                            ComposeActivity::ComposeReply(id).into()
                         }
                         act => panic!("can't reedit {act:?}"),
                     };
@@ -1004,7 +1004,7 @@ impl TuiLogicalState {
             Activity::Util(UtilityActivity::InfoStatus(ref id)) => {
                 view_single_post(self.unfolded_posts.clone(), client, id)
             }
-            Activity::Util(UtilityActivity::ComposeToplevel) => (|| {
+            Activity::Compose(ComposeActivity::ComposeToplevel) => (|| {
                 let post = match post {
                     Some(post) => post,
                     None => Post::new(client)?,
@@ -1012,10 +1012,10 @@ impl TuiLogicalState {
                 compose_post(client, post)
             })(
             ),
-            Activity::Util(UtilityActivity::PostComposeMenu) => Ok(post_menu(
+            Activity::Compose(ComposeActivity::PostComposeMenu) => Ok(post_menu(
                 post.expect("how did we get here without a Post?"),
             )),
-            Activity::Util(UtilityActivity::ComposeReply(ref id)) => {
+            Activity::Compose(ComposeActivity::ComposeReply(ref id)) => {
                 let post = match post {
                     Some(post) => Ok(post),
                     None => Post::reply_to(id, client),
@@ -1025,7 +1025,7 @@ impl TuiLogicalState {
                     Err(e) => Err(e),
                 }
             }
-            Activity::Util(UtilityActivity::PostReplyMenu(_)) => Ok(
+            Activity::Compose(ComposeActivity::PostReplyMenu(_)) => Ok(
                 post_menu(post.expect("how did we get here without a Post?")),
             ),
             Activity::NonUtil(NonUtilityActivity::ThreadFile(