asdf98 commited on
Commit
3745156
·
verified ·
1 Parent(s): 396e732

fix: muse-action board emits fallback image event even if Rust download fails

Browse files
Files changed (1) hide show
  1. src-tauri/src/lib.rs +39 -10
src-tauri/src/lib.rs CHANGED
@@ -34,9 +34,44 @@ pub fn run() {
34
  let query = uri.split('?').nth(1).unwrap_or("");
35
  let params: std::collections::HashMap<String, String> = query.split('&').filter_map(|pair| { let (k, v) = pair.split_once('=')?; Some((percent_decode(k), percent_decode(v))) }).collect();
36
  match action.as_str() {
37
- "library" => { let url = params.get("url").cloned().unwrap_or_default(); if !url.is_empty() { let source = params.get("source").cloned(); let title = params.get("title").cloned(); tauri::async_runtime::spawn(async move { let _ = crate::library::library_add_item(app, url, source, title).await; }); } }
38
- "board" => { let url = params.get("url").cloned().unwrap_or_default(); if !url.is_empty() { let source = params.get("source").cloned(); let title = params.get("title").cloned(); tauri::async_runtime::spawn(async move { match crate::library::library_add_item(app.clone(), url.clone(), source.clone(), title.clone()).await { Ok(item) => { let _ = crate::board::board_add_image(app.clone(), Some(item.id.clone()), item.data_url.clone(), 120.0, 120.0, 300.0, 200.0); let _ = app.emit("board://image_added", serde_json::json!({"libraryId": item.id, "dataUrl": item.data_url, "url": item.url, "sourceUrl": item.source_url, "title": item.title, "width": item.width, "height": item.height, "colors": item.colors})); } Err(e) => { let _ = app.emit("board://image_add_failed", serde_json::json!({"url": url, "error": e})); } } }); } }
39
- "vault" => { let va = params.get("action").cloned().unwrap_or_default(); match va.as_str() { "save-prompt" => { let _ = app.emit("vault://save-prompt", serde_json::json!({"origin": params.get("origin").cloned().unwrap_or_default(), "username": params.get("username").cloned().unwrap_or_default(), "password": params.get("password").cloned().unwrap_or_default()})); } "has-login-form" => { let _ = app.emit("vault://login-detected", serde_json::json!({"origin": params.get("origin").cloned().unwrap_or_default(), "fields": params.get("fields").cloned().unwrap_or_default()})); } _ => {} } }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  _ => {}
41
  }
42
  tauri::http::Response::builder().status(200).header("Access-Control-Allow-Origin", "*").body(Vec::new()).unwrap()
@@ -76,11 +111,5 @@ pub fn run() {
76
  .expect("error while running Refstudio");
77
  }
78
 
79
- fn migrations() -> Vec<Migration> {
80
- vec![
81
- Migration { version: 1, description: "phase0_init", sql: include_str!("../migrations/001_phase0_init.sql"), kind: MigrationKind::Up },
82
- Migration { version: 2, description: "phase3_tables", sql: include_str!("../migrations/002_phase3_tables.sql"), kind: MigrationKind::Up },
83
- ]
84
- }
85
-
86
  fn percent_decode(s: &str) -> String { let bytes = s.as_bytes(); let mut out = Vec::with_capacity(bytes.len()); let mut i = 0; while i < bytes.len() { if bytes[i] == b'%' && i + 2 < bytes.len() { if let Ok(hex) = std::str::from_utf8(&bytes[i+1..i+3]) { if let Ok(v) = u8::from_str_radix(hex, 16) { out.push(v); i += 3; continue; } } } out.push(if bytes[i] == b'+' { b' ' } else { bytes[i] }); i += 1; } String::from_utf8_lossy(&out).to_string() }
 
34
  let query = uri.split('?').nth(1).unwrap_or("");
35
  let params: std::collections::HashMap<String, String> = query.split('&').filter_map(|pair| { let (k, v) = pair.split_once('=')?; Some((percent_decode(k), percent_decode(v))) }).collect();
36
  match action.as_str() {
37
+ "library" => {
38
+ let url = params.get("url").cloned().unwrap_or_default();
39
+ if !url.is_empty() {
40
+ let source = params.get("source").cloned();
41
+ let title = params.get("title").cloned();
42
+ tauri::async_runtime::spawn(async move { let _ = crate::library::library_add_item(app, url, source, title).await; });
43
+ }
44
+ }
45
+ "board" => {
46
+ let url = params.get("url").cloned().unwrap_or_default();
47
+ if !url.is_empty() {
48
+ let source = params.get("source").cloned().unwrap_or_default();
49
+ let title = params.get("title").cloned().unwrap_or_else(|| "Web Reference".to_string());
50
+ let w = params.get("w").and_then(|s| s.parse::<u32>().ok()).unwrap_or(300);
51
+ let h = params.get("h").and_then(|s| s.parse::<u32>().ok()).unwrap_or(200);
52
+ tauri::async_runtime::spawn(async move {
53
+ match crate::library::library_add_item(app.clone(), url.clone(), Some(source.clone()), Some(title.clone())).await {
54
+ Ok(item) => {
55
+ let _ = crate::board::board_add_image(app.clone(), Some(item.id.clone()), item.data_url.clone(), 120.0, 120.0, 300.0, 200.0);
56
+ let _ = app.emit("board://image_added", serde_json::json!({"libraryId": item.id, "dataUrl": item.data_url, "url": item.url, "sourceUrl": item.source_url, "title": item.title, "width": item.width, "height": item.height, "colors": item.colors}));
57
+ }
58
+ Err(e) => {
59
+ // Fallback: still add visible remote image to the canvas.
60
+ // This mirrors snip/webclip behavior: user action must produce a board item.
61
+ let _ = app.emit("board://image_added", serde_json::json!({"url": url, "dataUrl": url, "sourceUrl": source, "title": title, "width": w, "height": h, "colors": [], "downloadError": e}));
62
+ }
63
+ }
64
+ });
65
+ }
66
+ }
67
+ "vault" => {
68
+ let va = params.get("action").cloned().unwrap_or_default();
69
+ match va.as_str() {
70
+ "save-prompt" => { let _ = app.emit("vault://save-prompt", serde_json::json!({"origin": params.get("origin").cloned().unwrap_or_default(), "username": params.get("username").cloned().unwrap_or_default(), "password": params.get("password").cloned().unwrap_or_default()})); }
71
+ "has-login-form" => { let _ = app.emit("vault://login-detected", serde_json::json!({"origin": params.get("origin").cloned().unwrap_or_default(), "fields": params.get("fields").cloned().unwrap_or_default()})); }
72
+ _ => {}
73
+ }
74
+ }
75
  _ => {}
76
  }
77
  tauri::http::Response::builder().status(200).header("Access-Control-Allow-Origin", "*").body(Vec::new()).unwrap()
 
111
  .expect("error while running Refstudio");
112
  }
113
 
114
+ fn migrations() -> Vec<Migration> { vec![ Migration { version: 1, description: "phase0_init", sql: include_str!("../migrations/001_phase0_init.sql"), kind: MigrationKind::Up }, Migration { version: 2, description: "phase3_tables", sql: include_str!("../migrations/002_phase3_tables.sql"), kind: MigrationKind::Up } ] }
 
 
 
 
 
 
115
  fn percent_decode(s: &str) -> String { let bytes = s.as_bytes(); let mut out = Vec::with_capacity(bytes.len()); let mut i = 0; while i < bytes.len() { if bytes[i] == b'%' && i + 2 < bytes.len() { if let Ok(hex) = std::str::from_utf8(&bytes[i+1..i+3]) { if let Ok(v) = u8::from_str_radix(hex, 16) { out.push(v); i += 3; continue; } } } out.push(if bytes[i] == b'+' { b' ' } else { bytes[i] }); i += 1; } String::from_utf8_lossy(&out).to_string() }