feat(desktop): add detailed error messages and SSL bypass checkbox

This commit is contained in:
OpenCode Bot
2026-05-24 21:41:26 +08:00
parent 2255ce9c65
commit d2c60b56c9

View File

@@ -21,6 +21,7 @@ struct App {
share_url: String,
upload_rx: Option<mpsc::Receiver<UploadResult>>,
uploading: bool,
skip_ssl: bool,
}
impl App {
@@ -31,16 +32,19 @@ impl App {
share_url: String::new(),
upload_rx: None,
uploading: false,
skip_ssl: false,
}
}
fn start_upload(&mut self, filepath: std::path::PathBuf, api_url: String) {
fn start_upload(&mut self, filepath: std::path::PathBuf) {
let (tx, rx) = mpsc::channel();
self.upload_rx = Some(rx);
self.uploading = true;
let api_url = self.api_url.clone();
let skip_ssl = self.skip_ssl;
std::thread::spawn(move || {
let result = do_upload(&api_url, &filepath);
let result = do_upload(&api_url, &filepath, skip_ssl);
let _ = tx.send(result);
});
}
@@ -65,7 +69,7 @@ impl App {
}
}
fn do_upload(api_url: &str, filepath: &std::path::Path) -> UploadResult {
fn do_upload(api_url: &str, filepath: &std::path::Path, skip_ssl: bool) -> UploadResult {
let filename = filepath
.file_name()
.map(|n| n.to_string_lossy().to_string())
@@ -81,18 +85,33 @@ fn do_upload(api_url: &str, filepath: &std::path::Path) -> UploadResult {
.part("file", part)
.text("expiry", "24h");
let client = match reqwest::blocking::Client::builder()
.user_agent("TempFileTransfer-Desktop/0.1")
.timeout(std::time::Duration::from_secs(300))
.build()
{
let mut builder = reqwest::blocking::Client::builder()
.user_agent("TempFileTransfer-Desktop/0.2")
.timeout(std::time::Duration::from_secs(300));
if skip_ssl {
builder = builder.danger_accept_invalid_certs(true);
}
let client = match builder.build() {
Ok(c) => c,
Err(e) => return UploadResult::Err(format!("创建客户端失败: {}", e)),
};
let resp = match client.post(api_url).multipart(form).send() {
Ok(r) => r,
Err(e) => return UploadResult::Err(format!("网络请求失败: {}", e)),
Err(e) => {
let detail = if e.is_connect() {
format!("连接失败(无法连接到服务器): {}", e)
} else if e.is_timeout() {
format!("连接超时: {}", e)
} else if e.is_body() {
format!("SSL/数据传输出错请尝试勾选「跳过SSL验证」: {}", e)
} else {
format!("{}", e)
};
return UploadResult::Err(detail);
}
};
let status = resp.status();
@@ -138,6 +157,11 @@ impl eframe::App for App {
);
});
ui.add_space(4.0);
ui.horizontal(|ui| {
ui.checkbox(&mut self.skip_ssl, "跳过 SSL 证书验证(仅当连接失败时尝试)");
});
ui.add_space(8.0);
let drop_frame = egui::Frame::dark_canvas(ui.style())
@@ -180,7 +204,7 @@ impl eframe::App for App {
if !self.uploading {
for f in files {
if let Some(ref path) = f.path {
self.start_upload(path.to_owned(), self.api_url.clone());
self.start_upload(path.to_owned());
break;
}
}
@@ -191,10 +215,14 @@ impl eframe::App for App {
ui.horizontal(|ui| {
ui.label("状态:");
ui.label(
egui::RichText::new(&self.status)
.color(egui::Color32::from_rgb(100, 180, 100)),
);
let color = if self.status.starts_with("上传失败") {
egui::Color32::from_rgb(220, 80, 80)
} else if self.status.starts_with("上传成功") {
egui::Color32::from_rgb(80, 200, 80)
} else {
egui::Color32::from_rgb(100, 180, 100)
};
ui.label(egui::RichText::new(&self.status).color(color));
});
ui.add_space(8.0);
@@ -253,7 +281,7 @@ fn load_chinese_font(ctx: &egui::Context) {
fn main() {
let options = eframe::NativeOptions {
viewport: egui::ViewportBuilder::default()
.with_inner_size([560.0, 480.0])
.with_inner_size([560.0, 500.0])
.with_resizable(false)
.with_title("临时文件传输"),
..Default::default()