effects_native.rs
1 #[cfg(not(target_arch = "wasm32"))] 2 use { 3 super::{ 4 ApiEnvelope, App, FileSystemEntry, FileSystemLoadState, NativeBackgroundMessage, 5 NetworkScanLoadState, WirelessScanData, WirelessStatus, 6 }, 7 reqwest::blocking::Client, 8 serde::de::DeserializeOwned, 9 std::{ 10 sync::mpsc::{Sender, TryRecvError}, 11 thread, 12 }, 13 }; 14 15 #[cfg(not(target_arch = "wasm32"))] 16 impl App { 17 pub fn start_initial_load_native(&mut self) { 18 self.start_file_system_refresh_native(); 19 self.start_wireless_status_refresh_native(); 20 self.start_network_scan_native(); 21 } 22 23 pub fn poll_native_background_messages(&mut self) { 24 loop { 25 match self.native_background_receiver.try_recv() { 26 Ok(native_background_message) => match native_background_message { 27 NativeBackgroundMessage::FileSystem(fetch_result) => { 28 self.apply_file_system_result(fetch_result) 29 } 30 NativeBackgroundMessage::WirelessStatus(fetch_result) => { 31 self.apply_wireless_status_result(fetch_result) 32 } 33 NativeBackgroundMessage::WirelessScan(fetch_result) => { 34 self.apply_wireless_scan_result(fetch_result) 35 } 36 }, 37 Err(TryRecvError::Empty) | Err(TryRecvError::Disconnected) => break, 38 } 39 } 40 } 41 42 fn spawn_native_get_json<T>( 43 endpoint: String, 44 native_background_sender: Sender<NativeBackgroundMessage>, 45 error_context: &'static str, 46 map_message: fn(Result<T, String>) -> NativeBackgroundMessage, 47 ) where 48 T: DeserializeOwned + Send + 'static, 49 { 50 thread::spawn(move || { 51 let fetch_result = Client::new() 52 .get(endpoint) 53 .send() 54 .and_then(|response| response.error_for_status()) 55 .and_then(|response| response.json::<T>()) 56 .map_err(|error| format!("{error_context} request failed: {error}")); 57 let _ = native_background_sender.send(map_message(fetch_result)); 58 }); 59 } 60 61 fn spawn_native_post_json<T>( 62 endpoint: String, 63 native_background_sender: Sender<NativeBackgroundMessage>, 64 error_context: &'static str, 65 map_message: fn(Result<T, String>) -> NativeBackgroundMessage, 66 ) where 67 T: DeserializeOwned + Send + 'static, 68 { 69 thread::spawn(move || { 70 let fetch_result = Client::new() 71 .post(endpoint) 72 .send() 73 .and_then(|response| response.error_for_status()) 74 .and_then(|response| response.json::<T>()) 75 .map_err(|error| format!("{error_context} request failed: {error}")); 76 let _ = native_background_sender.send(map_message(fetch_result)); 77 }); 78 } 79 80 pub fn start_file_system_refresh_native(&mut self) { 81 if matches!(self.file_system_load_state, FileSystemLoadState::Loading) { 82 return; 83 } 84 self.file_system_load_state = FileSystemLoadState::Loading; 85 Self::spawn_native_get_json::<Vec<FileSystemEntry>>( 86 self.endpoint("/api/filesystem/list"), 87 self.native_background_sender.clone(), 88 "filesystem", 89 NativeBackgroundMessage::FileSystem, 90 ); 91 } 92 93 pub fn start_wireless_status_refresh_native(&mut self) { 94 Self::spawn_native_get_json::<ApiEnvelope<WirelessStatus>>( 95 self.endpoint("/api/wireless/status"), 96 self.native_background_sender.clone(), 97 "wireless status", 98 |fetch_result| { 99 NativeBackgroundMessage::WirelessStatus(fetch_result.map(|envelope| envelope.data)) 100 }, 101 ); 102 } 103 104 pub fn start_network_scan_native(&mut self) { 105 if matches!(self.network_scan_load_state, NetworkScanLoadState::Loading) { 106 return; 107 } 108 self.network_scan_load_state = NetworkScanLoadState::Loading; 109 Self::spawn_native_post_json::<ApiEnvelope<WirelessScanData>>( 110 self.endpoint("/api/wireless/actions/scan"), 111 self.native_background_sender.clone(), 112 "wireless scan", 113 |fetch_result| { 114 NativeBackgroundMessage::WirelessScan( 115 fetch_result.map(|envelope| envelope.data.networks), 116 ) 117 }, 118 ); 119 } 120 }