nav.rs (4645B)
1 use egui_nav::{NavAction, NavResponse}; 2 use enostr::Pubkey; 3 use nostrdb::Transaction; 4 use notedeck::{AppAction, AppContext, ReplacementType, Router}; 5 6 use crate::{ 7 cache::{ 8 ConversationCache, ConversationId, ConversationIdentifierUnowned, ParticipantSetUnowned, 9 }, 10 nip17::send_conversation_message, 11 }; 12 13 #[derive(Clone, Debug)] 14 pub enum Route { 15 ConvoList, 16 CreateConvo, 17 Conversation, 18 } 19 20 #[derive(Debug)] 21 pub enum MessagesAction { 22 SendMessage { 23 conversation_id: ConversationId, 24 content: String, 25 }, 26 Open(ConversationId), 27 Creating, 28 Back, 29 Create { 30 recipient: Pubkey, 31 }, 32 ToggleChrome, 33 } 34 35 pub struct MessagesUiResponse { 36 pub nav_response: Option<NavResponse<Option<MessagesAction>>>, 37 pub conversation_panel_response: Option<MessagesAction>, 38 } 39 40 pub fn process_messages_ui_response( 41 resp: MessagesUiResponse, 42 ctx: &mut AppContext, 43 cache: &mut ConversationCache, 44 router: &mut Router<Route>, 45 is_narrow: bool, 46 ) -> Option<AppAction> { 47 let mut action = None; 48 if let Some(convo_resp) = resp.conversation_panel_response { 49 action = handle_messages_action(convo_resp, ctx, cache, router, is_narrow); 50 } 51 52 let Some(nav) = resp.nav_response else { 53 return action; 54 }; 55 56 action.or(process_nav_resp(nav, ctx, cache, router, is_narrow)) 57 } 58 59 fn process_nav_resp( 60 nav: NavResponse<Option<MessagesAction>>, 61 ctx: &mut AppContext, 62 cache: &mut ConversationCache, 63 router: &mut Router<Route>, 64 is_narrow: bool, 65 ) -> Option<AppAction> { 66 let mut app_action = None; 67 if let Some(action) = nav.response.or(nav.title_response) { 68 app_action = handle_messages_action(action, ctx, cache, router, is_narrow); 69 } 70 71 let Some(action) = nav.action else { 72 return app_action; 73 }; 74 75 match action { 76 NavAction::Returning(_) => {} 77 NavAction::Resetting => {} 78 NavAction::Dragging => {} 79 NavAction::Returned(_) => { 80 router.pop(); 81 if is_narrow { 82 cache.active = None; 83 } 84 } 85 NavAction::Navigating => {} 86 NavAction::Navigated => { 87 router.navigating = false; 88 if router.is_replacing() { 89 router.complete_replacement(); 90 } 91 } 92 } 93 94 app_action 95 } 96 97 fn handle_messages_action( 98 action: MessagesAction, 99 ctx: &mut AppContext<'_>, 100 cache: &mut ConversationCache, 101 router: &mut Router<Route>, 102 is_narrow: bool, 103 ) -> Option<AppAction> { 104 let mut app_action = None; 105 match action { 106 MessagesAction::SendMessage { 107 conversation_id, 108 content, 109 } => send_conversation_message(conversation_id, content, cache, ctx), 110 MessagesAction::Open(conversation_id) => { 111 open_coversation_action(conversation_id, ctx, cache, router, is_narrow); 112 } 113 MessagesAction::Create { recipient } => { 114 let selected = ctx.accounts.selected_account_pubkey(); 115 let participants = vec![recipient.bytes(), selected.bytes()]; 116 let id = cache 117 .registry 118 .get_or_insert(ConversationIdentifierUnowned::Nip17( 119 ParticipantSetUnowned::new(participants), 120 )); 121 122 cache.initialize_conversation(id, vec![recipient, *selected]); 123 124 let txn = Transaction::new(ctx.ndb).expect("txn"); 125 cache.open_conversation( 126 ctx.ndb, 127 &txn, 128 id, 129 ctx.note_cache, 130 ctx.unknown_ids, 131 ctx.accounts.selected_account_pubkey(), 132 ); 133 134 if is_narrow { 135 router.route_to_replaced(Route::Conversation, ReplacementType::Single); 136 } else { 137 router.go_back(); 138 } 139 } 140 MessagesAction::Creating => { 141 router.route_to(Route::CreateConvo); 142 } 143 MessagesAction::Back => { 144 router.go_back(); 145 } 146 MessagesAction::ToggleChrome => app_action = Some(AppAction::ToggleChrome), 147 } 148 149 app_action 150 } 151 152 fn open_coversation_action( 153 id: ConversationId, 154 ctx: &mut AppContext<'_>, 155 cache: &mut ConversationCache, 156 router: &mut Router<Route>, 157 is_narrow: bool, 158 ) { 159 let txn = Transaction::new(ctx.ndb).expect("txn"); 160 cache.open_conversation( 161 ctx.ndb, 162 &txn, 163 id, 164 ctx.note_cache, 165 ctx.unknown_ids, 166 ctx.accounts.selected_account_pubkey(), 167 ); 168 169 if is_narrow { 170 router.route_to(Route::Conversation); 171 } 172 }