fix(desktop): rewrite upload with blocking reqwest, remove tokio dependency

This commit is contained in:
OpenCode Bot
2026-05-24 21:37:13 +08:00
parent a50824e831
commit 2255ce9c65
2 changed files with 33 additions and 53 deletions

View File

@@ -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"

View File

@@ -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<String>,
#[allow(dead_code)]
filename: Option<String>,
share_url: Option<String>,
error: Option<String>,
}
@@ -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::<UploadResponse>(&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;
}