experiments in a post-browser web
10
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(tauri): add net-fetch proxy and file dialog commands

+24 -23
+24 -23
backend/tauri/src-tauri/src/commands/file_dialog.rs
··· 2 2 //! 3 3 //! Mirrors the Electron `file-save-dialog` and `file-open-dialog` IPC handlers. 4 4 5 - use serde::{Deserialize, Serialize}; 5 + use serde::Serialize; 6 6 use std::path::Path; 7 7 use tauri_plugin_dialog::DialogExt; 8 - 9 - /// Filter for file dialogs (e.g., { name: "JSON", extensions: ["json"] }) 10 - #[derive(Debug, Deserialize)] 11 - pub struct DialogFilter { 12 - pub name: String, 13 - pub extensions: Vec<String>, 14 - } 15 8 16 9 // ── file-save-dialog ──────────────────────────────────────────────── 17 10 ··· 60 53 builder = builder.set_file_name(name); 61 54 } 62 55 63 - // Show dialog (blocking on async channel) 64 - let (tx, rx) = tokio::sync::oneshot::channel(); 56 + // Show dialog using std::sync channel (consistent with extensions.rs pattern) 57 + let (tx, rx) = std::sync::mpsc::channel(); 65 58 builder.save_file(move |path| { 66 59 let _ = tx.send(path); 67 60 }); 68 61 69 - let file_path = rx.await.map_err(|e| format!("Dialog channel error: {}", e))?; 70 - 71 - match file_path { 72 - Some(path) => { 73 - let path_str = path.to_string_lossy().to_string(); 62 + match rx.recv() { 63 + Ok(Some(file_path)) => { 64 + let path_str = file_path.to_string(); 74 65 // Write content to the selected path 75 66 if let Err(e) = std::fs::write(&path_str, &content) { 76 67 return Ok(FileSaveResponse { ··· 87 78 error: None, 88 79 }) 89 80 } 90 - None => Ok(FileSaveResponse { 81 + Ok(None) => Ok(FileSaveResponse { 91 82 success: false, 92 83 path: None, 93 84 canceled: Some(true), 94 85 error: None, 95 86 }), 87 + Err(_) => Ok(FileSaveResponse { 88 + success: false, 89 + path: None, 90 + canceled: None, 91 + error: Some("Dialog error".to_string()), 92 + }), 96 93 } 97 94 } 98 95 ··· 139 136 .add_filter("Documents", &["pdf", "doc", "docx", "rtf"]); 140 137 141 138 // Show dialog 142 - let (tx, rx) = tokio::sync::oneshot::channel(); 139 + let (tx, rx) = std::sync::mpsc::channel(); 143 140 builder.pick_file(move |path| { 144 141 let _ = tx.send(path); 145 142 }); 146 143 147 - let file_path = rx.await.map_err(|e| format!("Dialog channel error: {}", e))?; 148 - 149 - match file_path { 150 - Some(selected) => { 151 - let path_str = selected.to_string_lossy().to_string(); 144 + match rx.recv() { 145 + Ok(Some(selected)) => { 146 + let path_str = selected.to_string(); 152 147 let path = Path::new(&path_str); 153 148 154 149 let file_name = path ··· 191 186 error: None, 192 187 }) 193 188 } 194 - None => Ok(FileOpenResponse { 189 + Ok(None) => Ok(FileOpenResponse { 195 190 success: false, 196 191 data: None, 197 192 canceled: Some(true), 198 193 error: None, 194 + }), 195 + Err(_) => Ok(FileOpenResponse { 196 + success: false, 197 + data: None, 198 + canceled: None, 199 + error: Some("Dialog error".to_string()), 199 200 }), 200 201 } 201 202 }