From 2255ce9c65d2c87ee9d30afeb631cd99183e3ee6 Mon Sep 17 00:00:00 2001 From: OpenCode Bot Date: Sun, 24 May 2026 21:37:13 +0800 Subject: [PATCH] fix(desktop): rewrite upload with blocking reqwest, remove tokio dependency --- desktop/Cargo.toml | 3 +- desktop/src/main.rs | 83 +++++++++++++++++---------------------------- 2 files changed, 33 insertions(+), 53 deletions(-) diff --git a/desktop/Cargo.toml b/desktop/Cargo.toml index 5a072e8..76dd103 100644 --- a/desktop/Cargo.toml +++ b/desktop/Cargo.toml @@ -5,8 +5,7 @@ edition = "2021" [dependencies] eframe = "0.31" -reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "multipart"] } -tokio = { version = "1", features = ["rt", "macros"] } +reqwest = { version = "0.12", default-features = false, features = ["rustls-tls", "multipart", "blocking"] } serde = { version = "1", features = ["derive"] } serde_json = "1" diff --git a/desktop/src/main.rs b/desktop/src/main.rs index a9e3440..9548957 100644 --- a/desktop/src/main.rs +++ b/desktop/src/main.rs @@ -1,15 +1,11 @@ #![windows_subsystem = "windows"] use eframe::egui; -use reqwest::multipart; +use reqwest::blocking::multipart; use std::sync::mpsc; #[derive(serde::Deserialize)] struct UploadResponse { - #[allow(dead_code)] - id: Option, - #[allow(dead_code)] - filename: Option, share_url: Option, error: Option, } @@ -43,27 +39,9 @@ impl App { self.upload_rx = Some(rx); self.uploading = true; - let filename = filepath - .file_name() - .unwrap_or_default() - .to_string_lossy() - .to_string(); - std::thread::spawn(move || { - let rt = tokio::runtime::Builder::new_current_thread() - .enable_all() - .build(); - match rt { - Ok(rt) => { - let result = rt.block_on(async { - do_upload(&api_url, &filepath, &filename).await - }); - let _ = tx.send(result); - } - Err(e) => { - let _ = tx.send(UploadResult::Err(format!("启动运行时失败: {}", e))); - } - } + let result = do_upload(&api_url, &filepath); + let _ = tx.send(result); }); } @@ -87,55 +65,56 @@ impl App { } } -async fn do_upload(api_url: &str, filepath: &std::path::Path, filename: &str) -> UploadResult { +fn do_upload(api_url: &str, filepath: &std::path::Path) -> UploadResult { + let filename = filepath + .file_name() + .map(|n| n.to_string_lossy().to_string()) + .unwrap_or_else(|| "unknown".to_owned()); + let data = match std::fs::read(filepath) { Ok(d) => d, Err(e) => return UploadResult::Err(format!("读取文件失败: {}", e)), }; - let part = multipart::Part::bytes(data) - .file_name(filename.to_owned()) - .mime_str("application/octet-stream") - .unwrap_or_else(|_| multipart::Part::bytes(vec![]).file_name(filename.to_owned())); - + let part = multipart::Part::bytes(data).file_name(filename); let form = multipart::Form::new() .part("file", part) .text("expiry", "24h"); - let client = match reqwest::Client::builder().build() { + let client = match reqwest::blocking::Client::builder() + .user_agent("TempFileTransfer-Desktop/0.1") + .timeout(std::time::Duration::from_secs(300)) + .build() + { Ok(c) => c, Err(e) => return UploadResult::Err(format!("创建客户端失败: {}", e)), }; - let resp = match client.post(api_url).multipart(form).send().await { + let resp = match client.post(api_url).multipart(form).send() { Ok(r) => r, - Err(e) => return UploadResult::Err(format!("请求失败: {}", e)), + Err(e) => return UploadResult::Err(format!("网络请求失败: {}", e)), }; let status = resp.status(); - let body = match resp.text().await { + let body = match resp.text() { Ok(b) => b, Err(e) => return UploadResult::Err(format!("读取响应失败: {}", e)), }; if !status.is_success() { let err: UploadResponse = serde_json::from_str(&body).unwrap_or(UploadResponse { - id: None, - filename: None, share_url: None, error: Some(body), }); - return UploadResult::Err(err.error.unwrap_or_else(|| "未知错误".to_owned())); + return UploadResult::Err(err.error.unwrap_or_else(|| format!("HTTP {}", status))); } - let result: UploadResponse = match serde_json::from_str(&body) { - Ok(r) => r, - Err(e) => return UploadResult::Err(format!("解析响应失败: {}", e)), - }; - - match result.share_url { - Some(url) => UploadResult::Ok(url), - None => UploadResult::Err(result.error.unwrap_or_else(|| "未知服务器响应".to_owned())), + match serde_json::from_str::(&body) { + Ok(r) => match r.share_url { + Some(url) => UploadResult::Ok(url), + None => UploadResult::Err(r.error.unwrap_or_else(|| "未知服务器响应".to_owned())), + }, + Err(e) => UploadResult::Err(format!("解析响应失败: {} - body: {}", e, body)), } } @@ -236,13 +215,14 @@ impl eframe::App for App { }); }); - ctx.request_repaint_after(std::time::Duration::from_millis(100)); + ctx.request_repaint_after(std::time::Duration::from_millis(200)); } } fn load_chinese_font(ctx: &egui::Context) { let font_paths = [ "C:\\Windows\\Fonts\\msyh.ttc", + "C:\\Windows\\Fonts\\msyhbd.ttc", "C:\\Windows\\Fonts\\simhei.ttf", "C:\\Windows\\Fonts\\simsun.ttc", ]; @@ -250,9 +230,10 @@ fn load_chinese_font(ctx: &egui::Context) { for path in &font_paths { if let Ok(data) = std::fs::read(path) { let mut fonts = egui::FontDefinitions::default(); - fonts - .font_data - .insert("chinese".to_owned(), std::sync::Arc::new(egui::FontData::from_owned(data))); + fonts.font_data.insert( + "chinese".to_owned(), + std::sync::Arc::new(egui::FontData::from_owned(data)), + ); fonts .families .get_mut(&egui::FontFamily::Proportional) @@ -262,7 +243,7 @@ fn load_chinese_font(ctx: &egui::Context) { .families .get_mut(&egui::FontFamily::Monospace) .unwrap() - .push("chinese".to_owned()); + .insert(0, "chinese".to_owned()); ctx.set_fonts(fonts); return; }