/ apps / microtop / src / app / effects_native.rs
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  }