chiark / gitweb /
Support listing your follow requesters.
authorSimon Tatham <anakin@pobox.com>
Sat, 3 Feb 2024 10:54:50 +0000 (10:54 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 3 Feb 2024 11:37:57 +0000 (11:37 +0000)
We don't yet have a method of approving or denying the request.

src/activity_stack.rs
src/client.rs
src/file.rs
src/tui.rs

index 01e5d4c1e7fd4846379032f10da0719db1ea9dd9..e040fd20f5df1f02fee23446a25379ce55920ff9 100644 (file)
@@ -28,6 +28,7 @@ pub enum UtilityActivity {
     LogsMenu1,
     LogsMenu2,
     EgoLog,
+    ListFollowRequesters,
     ExitMenu,
     ExamineUser(String), // the account _id_, not its name
     ListUserFollowers(String),
index a064416c2a73b3dde99a78c182fa0de392aed99a..29a181607dfcd5c7deb069ebf4bc8606e24f27b1 100644 (file)
@@ -30,6 +30,7 @@ pub enum FeedId {
     User(String, Boosts, Replies),
     Mentions,
     Ego,
+    YourFollowRequesters,
     Favouriters(String),
     Boosters(String),
     Followers(String),
@@ -989,6 +990,9 @@ impl Client {
             FeedId::Followees(id) => {
                 Req::get(&format!("api/v1/accounts/{id}/following"))
             }
+            FeedId::YourFollowRequesters => {
+                Req::get(&format!("api/v1/follow_requests"))
+            }
             FeedId::Errors => return Ok(false),
         };
 
@@ -1100,7 +1104,8 @@ impl Client {
             FeedId::Favouriters(..)
             | FeedId::Boosters(..)
             | FeedId::Followers(..)
-            | FeedId::Followees(..) => {
+            | FeedId::Followees(..)
+            | FeedId::YourFollowRequesters => {
                 let acs: Vec<Account> = match serde_json::from_str(&body) {
                     Ok(acs) => Ok(acs),
                     Err(e) => {
index 31412857d36202484110f14f99ea71a058aa0e1a..feb66a97c3e4f99306fe474a0e0bc2844aef5c62 100644 (file)
@@ -164,7 +164,10 @@ impl FileDataSource for StaticSource {
 enum CanList {
     Nothing,
     ForPost,
-    ForUser,
+
+    // true if the account is your own, and also locked, so that we
+    // also need a third option to list follow _requesters_
+    ForUser(bool),
 }
 
 trait FileType {
@@ -1312,17 +1315,25 @@ impl<Type: FileType, Source: FileDataSource> ActivityState
                 )
             }
             UIMode::ListSubmenu => {
-                let fs = match self.file_desc.can_list() {
-                    CanList::ForUser => fs
-                        .add(Pr('I'), "List Followers", 99)
-                        .add(Pr('O'), "List Followed", 99),
-                    CanList::ForPost => fs
-                        .add(Pr('F'), "List Favouriters", 99)
-                        .add(Pr('B'), "List Boosters", 99),
-                    CanList::Nothing => {
-                        panic!("Then we shouldn't be in this submenu")
-                    }
-                };
+                let fs =
+                    match self.file_desc.can_list() {
+                        CanList::ForUser(locked) => {
+                            let fs = fs
+                                .add(Pr('I'), "List Followers", 98)
+                                .add(Pr('O'), "List Followed", 98);
+                            if locked {
+                                fs.add(Pr('R'), "List Requesters", 99)
+                            } else {
+                                fs
+                            }
+                        }
+                        CanList::ForPost => fs
+                            .add(Pr('F'), "List Favouriters", 99)
+                            .add(Pr('B'), "List Boosters", 99),
+                        CanList::Nothing => {
+                            panic!("Then we shouldn't be in this submenu")
+                        }
+                    };
                 fs.add(Pr('Q'), "Quit", 100)
             }
             UIMode::PostsSubmenu => {
@@ -1660,7 +1671,7 @@ impl<Type: FileType, Source: FileDataSource> ActivityState
                 }
 
                 Pr('i') | Pr('I') => {
-                    if self.file_desc.can_list() == CanList::ForUser {
+                    if let CanList::ForUser(_) = self.file_desc.can_list() {
                         LogicalAction::Goto(
                             UtilityActivity::ListUserFollowers(
                                 self.contents.source.single_id(),
@@ -1673,7 +1684,7 @@ impl<Type: FileType, Source: FileDataSource> ActivityState
                 }
 
                 Pr('o') | Pr('O') => {
-                    if self.file_desc.can_list() == CanList::ForUser {
+                    if let CanList::ForUser(_) = self.file_desc.can_list() {
                         LogicalAction::Goto(
                             UtilityActivity::ListUserFollowees(
                                 self.contents.source.single_id(),
@@ -1685,6 +1696,16 @@ impl<Type: FileType, Source: FileDataSource> ActivityState
                     }
                 }
 
+                Pr('r') | Pr('R') => {
+                    if self.file_desc.can_list() == CanList::ForUser(true) {
+                        LogicalAction::Goto(
+                            UtilityActivity::ListFollowRequesters.into(),
+                        )
+                    } else {
+                        LogicalAction::Nothing
+                    }
+                }
+
                 Pr('q') | Pr('Q') => {
                     self.ui_mode = UIMode::Normal;
                     LogicalAction::Nothing
@@ -2039,6 +2060,26 @@ pub fn list_user_followees(
     Ok(Box::new(file))
 }
 
+pub fn list_follow_requesters(
+    client: &mut Client,
+) -> Result<Box<dyn ActivityState>, ClientError> {
+    let name = client.our_account_fq();
+
+    let file = File::new(
+        client,
+        FeedSource::new(FeedId::YourFollowRequesters),
+        ColouredString::uniform(
+            &format!("Users who have requested to follow {name}"),
+            'H',
+        ),
+        UserListFeedType {},
+        None,
+        None,
+        false,
+    )?;
+    Ok(Box::new(file))
+}
+
 pub fn hashtag_timeline(
     unfolded: Rc<RefCell<HashSet<String>>>,
     client: &mut Client,
@@ -2062,7 +2103,9 @@ pub fn hashtag_timeline(
     Ok(Box::new(file))
 }
 
-struct ExamineUserFileType {}
+struct ExamineUserFileType {
+    locked: bool,
+}
 impl FileType for ExamineUserFileType {
     type Item = ExamineUserDisplay;
     const CAN_GET_POSTS: bool = true;
@@ -2078,7 +2121,7 @@ impl FileType for ExamineUserFileType {
     }
 
     fn can_list(&self) -> CanList {
-        CanList::ForUser
+        CanList::ForUser(self.locked)
     }
 }
 
@@ -2087,6 +2130,7 @@ pub fn examine_user(
     account_id: &str,
 ) -> Result<Box<dyn ActivityState>, ClientError> {
     let ac = client.account_by_id(account_id)?;
+    let locked = ac.id == client.our_account_id() && ac.locked;
     let username = client.fq(&ac.acct);
     let title = ColouredString::uniform(
         &format!("Information about user {username}"),
@@ -2097,7 +2141,7 @@ pub fn examine_user(
         client,
         StaticSource::singleton(ac.id),
         title,
-        ExamineUserFileType {},
+        ExamineUserFileType { locked },
         Some(&FilePosition::item_top(isize::MIN).into()),
         None,
         false,
index fe1d615714f46015ee2a0b53e6ad40c97d83bef4..2ad2545e1bea10fd54e659bf229b26feaf36e44c 100644 (file)
@@ -1092,6 +1092,9 @@ impl TuiLogicalState {
             Activity::Util(UtilityActivity::ListUserFollowees(ref id)) => {
                 list_user_followees(client, id)
             }
+            Activity::Util(UtilityActivity::ListFollowRequesters) => {
+                list_follow_requesters(client)
+            }
             Activity::NonUtil(NonUtilityActivity::UserPosts(
                 ref user,
                 boosts,