hooks.rs
1 use super::{bridge::*, state::*}; 2 use dioxus::prelude::*; 3 use ui::components::toast::use_toast; 4 5 #[derive(Clone, Copy, PartialEq)] 6 pub struct FlashController { 7 pub device: FlashDeviceState, 8 pub chip: FlashChipInfo, 9 pub firmware: FlashFirmwareState, 10 pub config: FlashConfig, 11 } 12 13 impl FlashController { 14 pub fn connect(&self) { 15 let mut device = self.device; 16 let chip = self.chip; 17 let mut firmware = self.firmware; 18 let baud_val = self.config.baud.read().clone(); 19 20 device.connecting.set(true); 21 22 spawn(async move { 23 document::eval(JS_INIT_TERMINAL); 24 eval_send_and_process(JS_CONNECT, baud_val, device, chip, firmware).await; 25 device.connecting.set(false); 26 27 if *device.is_connected.read() { 28 restart_monitor(device, chip, firmware).await; 29 } 30 }); 31 } 32 33 pub fn disconnect(&self) { 34 let mut device = self.device; 35 let mut chip = self.chip; 36 let mut firmware = self.firmware; 37 38 device.is_connected.set(false); 39 device.monitor_active.set(false); 40 firmware.clear(); 41 chip.clear(); 42 43 spawn(async move { 44 eval_and_process(JS_DISCONNECT, device, chip, firmware).await; 45 }); 46 } 47 48 pub fn flash(&self) { 49 let mut device = self.device; 50 let mut chip = self.chip; 51 let mut firmware = self.firmware; 52 let config = self.config; 53 54 firmware.flashing.set(true); 55 firmware.progress.set(0); 56 57 let flash_config = serde_json::json!({ 58 "baud": *config.baud.read(), 59 "mode": *config.mode.read(), 60 "freq": *config.freq.read(), 61 "size": *config.size.read(), 62 "addr": *config.address.read(), 63 "compress": *config.compress.read(), 64 "eraseAll": *config.erase_first.read(), 65 "wifiSsid": *config.wifi_ssid.read(), 66 "wifiPass": *config.wifi_pass.read(), 67 }); 68 69 spawn(async move { 70 eval_send_and_process(JS_FLASH, flash_config, device, chip, firmware).await; 71 firmware.flashing.set(false); 72 restart_monitor(device, chip, firmware).await; 73 }); 74 } 75 76 pub fn erase(&self) { 77 let mut device = self.device; 78 let mut chip = self.chip; 79 let mut firmware = self.firmware; 80 let baud_val = self.config.baud.read().clone(); 81 82 spawn(async move { 83 eval_send_and_process(JS_ERASE, baud_val, device, chip, firmware).await; 84 restart_monitor(device, chip, firmware).await; 85 }); 86 } 87 88 pub fn reset(&self) { 89 let device = self.device; 90 let chip = self.chip; 91 let firmware = self.firmware; 92 let baud_val = self.config.baud.read().clone(); 93 94 spawn(async move { 95 eval_send_and_process(JS_RESET, baud_val, device, chip, firmware).await; 96 restart_monitor(device, chip, firmware).await; 97 }); 98 } 99 100 pub fn select_firmware(&self) { 101 let device = self.device; 102 let chip = self.chip; 103 let firmware = self.firmware; 104 105 spawn(async move { 106 eval_and_process(JS_SELECT_FIRMWARE, device, chip, firmware).await; 107 }); 108 } 109 110 pub fn toggle_monitor(&self) { 111 if *self.device.monitor_active.read() { 112 document::eval(JS_MONITOR_STOP); 113 } else { 114 let device = self.device; 115 let chip = self.chip; 116 let firmware = self.firmware; 117 spawn(async move { 118 restart_monitor(device, chip, firmware).await; 119 }); 120 } 121 } 122 } 123 124 async fn restart_monitor( 125 device: FlashDeviceState, 126 chip: FlashChipInfo, 127 firmware: FlashFirmwareState, 128 ) { 129 eval_send_and_process(JS_MONITOR_START, "115200", device, chip, firmware).await; 130 } 131 132 pub fn use_flash_controller() -> FlashController { 133 let mut device = FlashDeviceState::new(); 134 let mut chip = FlashChipInfo::new(); 135 let mut firmware = FlashFirmwareState::new(); 136 let mut config = FlashConfig::new(); 137 let mut config_loaded = use_signal(|| false); 138 139 let toasts = use_toast(); 140 141 // Load config from localStorage on mount 142 use_effect(move || { 143 let mut config = config; 144 spawn(async move { 145 let eval = document::eval( 146 r#" 147 try { 148 const c = JSON.parse(localStorage.getItem('flash_options') || '{}'); 149 return JSON.stringify(c); 150 } catch(e) { return '{}'; } 151 "#, 152 ); 153 if let Ok(json) = eval.await { 154 if let Ok(map) = 155 serde_json::from_value::<serde_json::Map<String, serde_json::Value>>(json) 156 { 157 if let Some(v) = map.get("baud").and_then(|v| v.as_str()) { 158 config.baud.set(v.to_string()); 159 } 160 if let Some(v) = map.get("mode").and_then(|v| v.as_str()) { 161 config.mode.set(v.to_string()); 162 } 163 if let Some(v) = map.get("freq").and_then(|v| v.as_str()) { 164 config.freq.set(v.to_string()); 165 } 166 if let Some(v) = map.get("size").and_then(|v| v.as_str()) { 167 config.size.set(v.to_string()); 168 } 169 if let Some(v) = map.get("addr").and_then(|v| v.as_str()) { 170 config.address.set(v.to_string()); 171 } 172 if let Some(v) = map.get("compress").and_then(|v| v.as_bool()) { 173 config.compress.set(v); 174 } 175 if let Some(v) = map.get("eraseAll").and_then(|v| v.as_bool()) { 176 config.erase_first.set(v); 177 } 178 } 179 } 180 config_loaded.set(true); 181 }); 182 }); 183 184 use_effect(move || { 185 if !*config_loaded.read() { 186 return; 187 } 188 let baud = config.baud.read().clone(); 189 let mode = config.mode.read().clone(); 190 let freq = config.freq.read().clone(); 191 let size = config.size.read().clone(); 192 let addr = config.address.read().clone(); 193 let compress = *config.compress.read(); 194 let erase = *config.erase_first.read(); 195 let config_json = serde_json::json!({ 196 "baud": baud, 197 "mode": mode, 198 "freq": freq, 199 "size": size, 200 "addr": addr, 201 "compress": compress, 202 "eraseAll": erase, 203 }); 204 document::eval(&format!( 205 "localStorage.setItem('flash_options',{});", 206 serde_json::to_string(&config_json).unwrap_or_default() 207 )); 208 }); 209 210 use_effect(move || { 211 if *device.device_lost.read() { 212 toasts.error("Device disconnected unexpectedly".to_string(), None); 213 device.device_lost.set(false); 214 } 215 }); 216 217 use_drop(|| { 218 document::eval(JS_CLEANUP); 219 }); 220 221 FlashController { 222 device, 223 chip, 224 firmware, 225 config, 226 } 227 }