|  |  | @ -2,19 +2,19 @@ use std::collections::HashSet; | 
			
		
	
		
		
			
				
					
					|  |  |  | use std::sync::Arc; |  |  |  | use std::sync::Arc; | 
			
		
	
		
		
			
				
					
					|  |  |  | use std::time::{Duration, Instant}; |  |  |  | use std::time::{Duration, Instant}; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | use elefren::{FediClient, StatusBuilder}; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | use elefren::debug::EventDisplay; |  |  |  | use elefren::debug::EventDisplay; | 
			
		
	
		
		
			
				
					
					|  |  |  | use elefren::debug::NotificationDisplay; |  |  |  | use elefren::debug::NotificationDisplay; | 
			
		
	
		
		
			
				
					
					|  |  |  | use elefren::entities::event::Event; |  |  |  | use elefren::entities::event::Event; | 
			
		
	
		
		
			
				
					
					|  |  |  | use elefren::entities::notification::{Notification, NotificationType}; |  |  |  | use elefren::entities::notification::{Notification, NotificationType}; | 
			
		
	
		
		
			
				
					
					|  |  |  | use elefren::status_builder::Visibility; |  |  |  | use elefren::status_builder::Visibility; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use elefren::{FediClient, StatusBuilder}; | 
			
		
	
		
		
			
				
					
					|  |  |  | use futures::StreamExt; |  |  |  | use futures::StreamExt; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::command::StatusCommand; |  |  |  | use crate::command::StatusCommand; | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::error::GroupError; |  |  |  | use crate::error::GroupError; | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::store::ConfigStore; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::store::data::GroupConfig; |  |  |  | use crate::store::data::GroupConfig; | 
			
		
	
		
		
			
				
					
					|  |  |  | use crate::utils::{LogError, normalize_acct}; |  |  |  | use crate::store::ConfigStore; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | use crate::utils::{normalize_acct, LogError}; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | /// This is one group's config store capable of persistence
 |  |  |  | /// This is one group's config store capable of persistence
 | 
			
		
	
		
		
			
				
					
					|  |  |  | #[derive(Debug)] |  |  |  | #[derive(Debug)] | 
			
		
	
	
		
		
			
				
					|  |  | @ -91,22 +91,29 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |             loop { |  |  |  |             loop { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if next_save < Instant::now() { |  |  |  |                 if next_save < Instant::now() { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     self.save_if_needed().await |  |  |  |                     self.save_if_needed() | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         .await | 
			
		
	
		
		
			
				
					
					|  |  |  |                         .log_error("Failed to save group"); |  |  |  |                         .log_error("Failed to save group"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     next_save = Instant::now() + PERIODIC_SAVE; |  |  |  |                     next_save = Instant::now() + PERIODIC_SAVE; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } |  |  |  |                 } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 let timeout = next_save.saturating_duration_since(Instant::now()) |  |  |  |                 let timeout = next_save | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     .saturating_duration_since(Instant::now()) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     .min(PING_INTERVAL) |  |  |  |                     .min(PING_INTERVAL) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     .max(Duration::from_secs(1)); |  |  |  |                     .max(Duration::from_secs(1)); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 match tokio::time::timeout(timeout, events.next()).await { |  |  |  |                 match tokio::time::timeout(timeout, events.next()).await { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     Ok(Some(event)) => { |  |  |  |                     Ok(Some(event)) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         debug!("(@{}) Event: {}", self.config.get_acct(), EventDisplay(&event)); |  |  |  |                         debug!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             "(@{}) Event: {}", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             self.config.get_acct(), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             EventDisplay(&event) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         ); | 
			
		
	
		
		
			
				
					
					|  |  |  |                         match event { |  |  |  |                         match event { | 
			
		
	
		
		
			
				
					
					|  |  |  |                             Event::Update(_status) => {} |  |  |  |                             Event::Update(_status) => {} | 
			
		
	
		
		
			
				
					
					|  |  |  |                             Event::Notification(n) => { |  |  |  |                             Event::Notification(n) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 self.handle_notification(n).await |  |  |  |                                 self.handle_notification(n) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     .await | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     .log_error("Error handling a notification"); |  |  |  |                                     .log_error("Error handling a notification"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                             } |  |  |  |                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                             Event::Delete(_id) => {} |  |  |  |                             Event::Delete(_id) => {} | 
			
		
	
	
		
		
			
				
					|  |  | @ -114,7 +121,10 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         } |  |  |  |                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     Ok(None) => { |  |  |  |                     Ok(None) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         warn!("Group @{} socket closed, restarting...", self.config.get_acct()); |  |  |  |                         warn!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             "Group @{} socket closed, restarting...", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             self.config.get_acct() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         ); | 
			
		
	
		
		
			
				
					
					|  |  |  |                         break; |  |  |  |                         break; | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                     Err(_) => { |  |  |  |                     Err(_) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -176,10 +186,13 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 // Someone tagged the group in OP, boost it.
 |  |  |  |                                 // Someone tagged the group in OP, boost it.
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 info!("Boosting OP mention"); |  |  |  |                                 info!("Boosting OP mention"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 tokio::time::sleep(DELAY_BEFORE_ACTION).await; |  |  |  |                                 tokio::time::sleep(DELAY_BEFORE_ACTION).await; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 self.client.reblog(&status.id).await |  |  |  |                                 self.client | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     .reblog(&status.id) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     .await | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     .log_error("Failed to boost"); |  |  |  |                                     .log_error("Failed to boost"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                             } else { |  |  |  |                             } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 replies.push(format!("You are not allowed to post to this group")); |  |  |  |                                 replies | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     .push("You are not allowed to post to this group".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                             } |  |  |  |                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                         } else { |  |  |  |                         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                             debug!("Not OP, ignore mention"); |  |  |  |                             debug!("Not OP, ignore mention"); | 
			
		
	
	
		
		
			
				
					|  |  | @ -200,7 +213,10 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     if can_write { |  |  |  |                                     if can_write { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         do_boost_prev_post = status.in_reply_to_id.is_some(); |  |  |  |                                         do_boost_prev_post = status.in_reply_to_id.is_some(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("You are not allowed to share to this group")); |  |  |  |                                         replies.push( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             "You are not allowed to share to this group" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                 .to_string(), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                         ); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::BanUser(u) => { |  |  |  |                                 StatusCommand::BanUser(u) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -210,17 +226,24 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             match self.config.ban_user(&u, true) { |  |  |  |                                             match self.config.ban_user(&u, true) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Ok(_) => { |  |  |  |                                                 Ok(_) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     any_admin_cmd = true; |  |  |  |                                                     any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("User {} banned from group!", u)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "User {} banned from group!", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     // no announcement here
 |  |  |  |                                                     // no announcement here
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Err(e) => { |  |  |  |                                                 Err(e) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("Failed to ban user {}: {}", u, e)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "Failed to ban user {}: {}", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u, e | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can manage user bans")); |  |  |  |                                         replies | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             .push("Only admins can manage user bans".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::UnbanUser(u) => { |  |  |  |                                 StatusCommand::UnbanUser(u) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -234,13 +257,14 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     // no announcement here
 |  |  |  |                                                     // no announcement here
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Err(e) => { |  |  |  |                                                 Err(_) => { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                                     unreachable!() |  |  |  |                                                     unreachable!() | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can manage user bans")); |  |  |  |                                         replies | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             .push("Only admins can manage user bans".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::BanServer(s) => { |  |  |  |                                 StatusCommand::BanServer(s) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -249,16 +273,26 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             match self.config.ban_server(&s, true) { |  |  |  |                                             match self.config.ban_server(&s, true) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Ok(_) => { |  |  |  |                                                 Ok(_) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     any_admin_cmd = true; |  |  |  |                                                     any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     announcements.push(format!("Server \"{}\" has been banned.", s)); |  |  |  |                                                     announcements.push(format!( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("Server {} banned from group!", s)); |  |  |  |                                                         "Server \"{}\" has been banned.", | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         s | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     replies.push(format!( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "Server {} banned from group!", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         s | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Err(e) => { |  |  |  |                                                 Err(e) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("Failed to ban server {}: {}", s, e)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "Failed to ban server {}: {}", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         s, e | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can manage server bans")); |  |  |  |                                         replies | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             .push("Only admins can manage server bans".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::UnbanServer(s) => { |  |  |  |                                 StatusCommand::UnbanServer(s) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -267,16 +301,21 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             match self.config.ban_server(&s, false) { |  |  |  |                                             match self.config.ban_server(&s, false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Ok(_) => { |  |  |  |                                                 Ok(_) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     any_admin_cmd = true; |  |  |  |                                                     any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     announcements.push(format!("Server \"{}\" has been un-banned.", s)); |  |  |  |                                                     announcements.push(format!( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("Server {} un-banned!", s)); |  |  |  |                                                         "Server \"{}\" has been un-banned.", | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         s | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     replies | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         .push(format!("Server {} un-banned!", s)); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Err(e) => { |  |  |  |                                                 Err(_) => { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                                     unreachable!() |  |  |  |                                                     unreachable!() | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can manage server bans")); |  |  |  |                                         replies | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             .push("Only admins can manage server bans".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::AddMember(u) => { |  |  |  |                                 StatusCommand::AddMember(u) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -286,19 +325,28 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             match self.config.set_member(&u, true) { |  |  |  |                                             match self.config.set_member(&u, true) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Ok(_) => { |  |  |  |                                                 Ok(_) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     any_admin_cmd = true; |  |  |  |                                                     any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("User {} added to the group!", u)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "User {} added to the group!", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     if self.config.is_member_only() { |  |  |  |                                                     if self.config.is_member_only() { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                         announcements.push(format!("Welcome new member @{} to the group!", u)); |  |  |  |                                                         announcements.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                             "Welcome new member @{} to the group!", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                             u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     } |  |  |  |                                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Err(e) => { |  |  |  |                                                 Err(e) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("Failed to add user {} to group: {}", u, e)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "Failed to add user {} to group: {}", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u, e | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can manage members")); |  |  |  |                                         replies.push("Only admins can manage members".to_string()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::RemoveMember(u) => { |  |  |  |                                 StatusCommand::RemoveMember(u) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -308,15 +356,18 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             match self.config.set_member(&u, false) { |  |  |  |                                             match self.config.set_member(&u, false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Ok(_) => { |  |  |  |                                                 Ok(_) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     any_admin_cmd = true; |  |  |  |                                                     any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("User {} removed from the group.", u)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "User {} removed from the group.", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Err(e) => { |  |  |  |                                                 Err(_) => { | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                                     unreachable!() |  |  |  |                                                     unreachable!() | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can manage members")); |  |  |  |                                         replies.push("Only admins can manage members".to_string()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::GrantAdmin(u) => { |  |  |  |                                 StatusCommand::GrantAdmin(u) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -326,16 +377,25 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             match self.config.set_admin(&u, true) { |  |  |  |                                             match self.config.set_admin(&u, true) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Ok(_) => { |  |  |  |                                                 Ok(_) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     any_admin_cmd = true; |  |  |  |                                                     any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("User {} is now a group admin!", u)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                                                     announcements.push(format!("User @{} can now manage this group!", u)); |  |  |  |                                                         "User {} is now a group admin!", | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     announcements.push(format!( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "User @{} can now manage this group!", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Err(e) => { |  |  |  |                                                 Err(e) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("Failed to make user {} a group admin: {}", u, e)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "Failed to make user {} a group admin: {}", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u, e | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can manage admins")); |  |  |  |                                         replies.push("Only admins can manage admins".to_string()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::RemoveAdmin(u) => { |  |  |  |                                 StatusCommand::RemoveAdmin(u) => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -345,16 +405,25 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             match self.config.set_admin(&u, false) { |  |  |  |                                             match self.config.set_admin(&u, false) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Ok(_) => { |  |  |  |                                                 Ok(_) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     any_admin_cmd = true; |  |  |  |                                                     any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("User {} is no longer a group admin!", u)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                                                     announcements.push(format!("User @{} no longer manages this group.", u)); |  |  |  |                                                         "User {} is no longer a group admin!", | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     announcements.push(format!( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "User @{} no longer manages this group.", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 Err(e) => { |  |  |  |                                                 Err(e) => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("Failed to revoke {}'s group admin: {}", u, e)); |  |  |  |                                                     replies.push(format!( | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         "Failed to revoke {}'s group admin: {}", | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                         u, e | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                     )); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can manage admins")); |  |  |  |                                         replies.push("Only admins can manage admins".to_string()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::OpenGroup => { |  |  |  |                                 StatusCommand::OpenGroup => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -362,11 +431,14 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         if self.config.is_member_only() { |  |  |  |                                         if self.config.is_member_only() { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             any_admin_cmd = true; |  |  |  |                                             any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             self.config.set_member_only(false); |  |  |  |                                             self.config.set_member_only(false); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             replies.push(format!("Group changed to open-access")); |  |  |  |                                             replies | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                                             announcements.push(format!("This group is now open-access!")); |  |  |  |                                                 .push("Group changed to open-access".to_string()); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             announcements | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                 .push("This group is now open-access!".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can set group options")); |  |  |  |                                         replies | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             .push("Only admins can set group options".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::CloseGroup => { |  |  |  |                                 StatusCommand::CloseGroup => { | 
			
		
	
	
		
		
			
				
					|  |  | @ -374,24 +446,27 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         if !self.config.is_member_only() { |  |  |  |                                         if !self.config.is_member_only() { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             any_admin_cmd = true; |  |  |  |                                             any_admin_cmd = true; | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             self.config.set_member_only(true); |  |  |  |                                             self.config.set_member_only(true); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             replies.push(format!("Group changed to member-only")); |  |  |  |                                             replies | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                                             announcements.push(format!("This group is now member-only!")); |  |  |  |                                                 .push("Group changed to member-only".to_string()); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             announcements | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                 .push("This group is now member-only!".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(format!("Only admins can set group options")); |  |  |  |                                         replies | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             .push("Only admins can set group options".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 StatusCommand::Help => { |  |  |  |                                 StatusCommand::Help => { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     if self.config.is_member_only() { |  |  |  |                                     if self.config.is_member_only() { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         let mut s = "This is a member-only group. ".to_string(); |  |  |  |                                         let mut s = "This is a member-only group. ".to_string(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         if self.config.can_write(¬if_acct) { |  |  |  |                                         if self.config.can_write(¬if_acct) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             s.push_str("*You are not a member, ask one of the admins to add you.*"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } else { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             if is_admin { |  |  |  |                                             if is_admin { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 s.push_str("*You are an admin.*"); |  |  |  |                                                 s.push_str("*You are an admin.*"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } else { |  |  |  |                                             } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 s.push_str("*You are a member.*"); |  |  |  |                                                 s.push_str("*You are a member.*"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                         } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             s.push_str("*You are not a member, ask one of the admins to add you.*"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push(s); |  |  |  |                                         replies.push(s); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } else { |  |  |  |                                     } else { | 
			
		
	
	
		
		
			
				
					|  |  | @ -409,7 +484,9 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         **Supported commands:**\n\ |  |  |  |                                         **Supported commands:**\n\ | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         `/ignore, /i` - make the group completely ignore the post\n\ |  |  |  |                                         `/ignore, /i` - make the group completely ignore the post\n\ | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         `/members, /who` - show group members / admins\n\ |  |  |  |                                         `/members, /who` - show group members / admins\n\ | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         `/boost, /b` - boost the replied-to post into the group".to_string()); |  |  |  |                                         `/boost, /b` - boost the replied-to post into the group" | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             .to_string(), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                     ); | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     if self.config.is_member_only() { |  |  |  |                                     if self.config.is_member_only() { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push("`/leave` - leave the group".to_string()); |  |  |  |                                         replies.push("`/leave` - leave the group".to_string()); | 
			
		
	
	
		
		
			
				
					|  |  | @ -433,8 +510,10 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     if is_admin { |  |  |  |                                     if is_admin { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         if self.config.is_member_only() { |  |  |  |                                         if self.config.is_member_only() { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             replies.push("Group members:".to_string()); |  |  |  |                                             replies.push("Group members:".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             let admins = self.config.get_admins().collect::<HashSet<_>>(); |  |  |  |                                             let admins = | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                                             let mut members = self.config.get_members().collect::<Vec<_>>(); |  |  |  |                                                 self.config.get_admins().collect::<HashSet<_>>(); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             let mut members = | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                                 self.config.get_members().collect::<Vec<_>>(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             members.extend(admins.iter()); |  |  |  |                                             members.extend(admins.iter()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             members.sort(); |  |  |  |                                             members.sort(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             members.dedup(); |  |  |  |                                             members.dedup(); | 
			
		
	
	
		
		
			
				
					|  |  | @ -442,7 +521,7 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 if admins.contains(&m) { |  |  |  |                                                 if admins.contains(&m) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("{} [admin]", m)); |  |  |  |                                                     replies.push(format!("{} [admin]", m)); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                 } else { |  |  |  |                                                 } else { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                                     replies.push(format!("{}", m)); |  |  |  |                                                     replies.push(m.to_string()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                                 } |  |  |  |                                                 } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             } |  |  |  |                                             } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         } else { |  |  |  |                                         } else { | 
			
		
	
	
		
		
			
				
					|  |  | @ -454,10 +533,11 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     if show_admins { |  |  |  |                                     if show_admins { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         replies.push("Group admins:".to_string()); |  |  |  |                                         replies.push("Group admins:".to_string()); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         let mut admins = self.config.get_admins().collect::<Vec<_>>(); |  |  |  |                                         let mut admins = | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                                             self.config.get_admins().collect::<Vec<_>>(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         admins.sort(); |  |  |  |                                         admins.sort(); | 
			
		
	
		
		
			
				
					
					|  |  |  |                                         for a in admins { |  |  |  |                                         for a in admins { | 
			
		
	
		
		
			
				
					
					|  |  |  |                                             replies.push(format!("{}", a)); |  |  |  |                                             replies.push(a.to_string()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |                                         } |  |  |  |                                         } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                     } |  |  |  |                                     } | 
			
		
	
		
		
			
				
					
					|  |  |  |                                 } |  |  |  |                                 } | 
			
		
	
	
		
		
			
				
					|  |  | @ -475,7 +555,9 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if do_boost_prev_post { |  |  |  |                     if do_boost_prev_post { | 
			
		
	
		
		
			
				
					
					|  |  |  |                         self.client.reblog(&status.in_reply_to_id.as_ref().unwrap()).await |  |  |  |                         self.client | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .reblog(&status.in_reply_to_id.as_ref().unwrap()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .await | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .log_error("Failed to boost"); |  |  |  |                             .log_error("Failed to boost"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -486,9 +568,14 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .status(format!("@{user}\n{msg}", user = notif_acct, msg = r)) |  |  |  |                             .status(format!("@{user}\n{msg}", user = notif_acct, msg = r)) | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .content_type("text/markdown") |  |  |  |                             .content_type("text/markdown") | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .visibility(Visibility::Direct) |  |  |  |                             .visibility(Visibility::Direct) | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .build().expect("error build status"); |  |  |  |                             .build() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                             .expect("error build status"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         let _ = self.client.new_status(post).await.log_error("Failed to post"); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         let _ = self | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .client | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .new_status(post) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .await | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .log_error("Failed to post"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if !announcements.is_empty() { |  |  |  |                     if !announcements.is_empty() { | 
			
		
	
	
		
		
			
				
					|  |  | @ -497,9 +584,14 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .status(format!("**📢 Group announcement**\n{msg}", msg = msg)) |  |  |  |                             .status(format!("**📢 Group announcement**\n{msg}", msg = msg)) | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .content_type("text/markdown") |  |  |  |                             .content_type("text/markdown") | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .visibility(Visibility::Unlisted) |  |  |  |                             .visibility(Visibility::Unlisted) | 
			
		
	
		
		
			
				
					
					|  |  |  |                             .build().expect("error build status"); |  |  |  |                             .build() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                             .expect("error build status"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         let _ = self.client.new_status(post).await.log_error("Failed to post"); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         let _ = self | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .client | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .new_status(post) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .await | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                             .log_error("Failed to post"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     } |  |  |  |                     } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                     if any_admin_cmd { |  |  |  |                     if any_admin_cmd { | 
			
		
	
	
		
		
			
				
					|  |  | @ -511,28 +603,36 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 info!("New follower!"); |  |  |  |                 info!("New follower!"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 tokio::time::sleep(Duration::from_millis(500)).await; |  |  |  |                 tokio::time::sleep(Duration::from_millis(500)).await; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 let text = if self.config.is_member_only() { |  |  |  |                 let text = | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     // Admins are listed without @, so they won't become handles here.
 |  |  |  |                     if self.config.is_member_only() { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     // Tagging all admins would be annoying.
 |  |  |  |                         // Admins are listed without @, so they won't become handles here.
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     let mut admins = self.config.get_admins().cloned().collect::<Vec<_>>(); |  |  |  |                         // Tagging all admins would be annoying.
 | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     admins.sort(); |  |  |  |                         let mut admins = self.config.get_admins().cloned().collect::<Vec<_>>(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     format!( |  |  |  |                         admins.sort(); | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         format!( | 
			
		
	
		
		
			
				
					
					|  |  |  |                         "@{user} welcome to the group! This is a member-only group, you won't be \ |  |  |  |                         "@{user} welcome to the group! This is a member-only group, you won't be \ | 
			
		
	
		
		
			
				
					
					|  |  |  |                          able to post. Ask the group admins if you wish to join!\n\n\ |  |  |  |                          able to post. Ask the group admins if you wish to join!\n\n\ | 
			
		
	
		
		
			
				
					
					|  |  |  |                          Admins: {admins}", user = notif_acct, admins = admins.join(", ")) |  |  |  |                          Admins: {admins}", user = notif_acct, admins = admins.join(", ")) | 
			
		
	
		
		
			
				
					
					|  |  |  |                 } else { |  |  |  |                     } else { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                     format!( |  |  |  |                         format!( | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                         "@{user} welcome to the group! \ |  |  |  |                             "@{user} welcome to the group! \ | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                          To share a post, tag the group user. Use /help for more info.", user = notif_acct) |  |  |  |                          To share a post, tag the group user. Use /help for more info.", | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 }; |  |  |  |                             user = notif_acct | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                         ) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     }; | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |                 let post = StatusBuilder::new() |  |  |  |                 let post = StatusBuilder::new() | 
			
		
	
		
		
			
				
					
					|  |  |  |                     .status(text) |  |  |  |                     .status(text) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     .content_type("text/markdown") |  |  |  |                     .content_type("text/markdown") | 
			
		
	
		
		
			
				
					
					|  |  |  |                     .visibility(Visibility::Direct) |  |  |  |                     .visibility(Visibility::Direct) | 
			
		
	
		
		
			
				
					
					|  |  |  |                     .build().expect("error build status"); |  |  |  |                     .build() | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |                     .expect("error build status"); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |                 let _ = self.client.new_status(post).await.log_error("Failed to post"); |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 let _ = self | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     .client | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     .new_status(post) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     .await | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     .log_error("Failed to post"); | 
			
		
	
		
		
			
				
					
					|  |  |  |             } |  |  |  |             } | 
			
		
	
		
		
			
				
					
					|  |  |  |             _ => {} |  |  |  |             _ => {} | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
	
		
		
			
				
					|  |  | @ -575,10 +675,11 @@ impl GroupHandle { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         for n in notifs_to_handle { |  |  |  |         for n in notifs_to_handle { | 
			
		
	
		
		
			
				
					
					|  |  |  |             debug!("Handling missed notification: {}", NotificationDisplay(&n)); |  |  |  |             debug!("Handling missed notification: {}", NotificationDisplay(&n)); | 
			
		
	
		
		
			
				
					
					|  |  |  |             self.handle_notification(n).await |  |  |  |             self.handle_notification(n) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 .await | 
			
		
	
		
		
			
				
					
					|  |  |  |                 .log_error("Error handling a notification"); |  |  |  |                 .log_error("Error handling a notification"); | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |         return Ok(true); |  |  |  |         Ok(true) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
	
		
		
			
				
					|  |  | 
 |