From 1e536318a21a165a471f7e726417b6aceeecdda7 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 17 Nov 2025 17:36:35 +0000 Subject: [PATCH] fix: Resolve WASM build errors for local development Fixed multiple compilation errors to enable local cargo and dx serve: 1. Added uuid "js" feature for WASM randomness support 2. Added gloo-timers dependency for async timer functionality 3. Added Navigator, Clipboard, and Location features to web-sys 4. Fixed clipboard API usage - clipboard() returns Clipboard directly, not Option 5. Fixed hostname() Result handling in video_player.rs 6. Fixed lifetime issues in login_modal.rs by cloning signal data The project now builds successfully for wasm32-unknown-unknown target. Build completes with only warnings (no errors). --- Cargo.lock | 1 + Cargo.toml | 6 +++++- src/components/login_modal.rs | 34 ++++++++++++++++------------------ src/components/video_player.rs | 6 +++++- 4 files changed, 27 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b8cfce..29df928 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3732,6 +3732,7 @@ dependencies = [ "futures-util", "gloo-file", "gloo-net 0.5.0", + "gloo-timers 0.3.0", "js-sys", "nostr", "nostr-sdk", diff --git a/Cargo.toml b/Cargo.toml index b8d49d1..4279259 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,9 @@ web-sys = { version = "0.3", features = [ "IdbIndex", "IdbKeyRange", "DomStringList", + "Navigator", + "Clipboard", + "Location", ] } # Serialization @@ -61,13 +64,14 @@ thiserror = "1" # Utilities chrono = { version = "0.4", features = ["serde", "wasmbind"] } -uuid = { version = "1", features = ["v4", "serde"] } +uuid = { version = "1", features = ["v4", "serde", "js"] } regex = "1" url = "2" base64 = "0.22" pulldown-cmark = "0.9" # Markdown rendering gloo-file = "0.3" # File upload in WASM gloo-net = "0.5" # HTTP requests in WASM +gloo-timers = "0.3" # Timers in WASM # Logging tracing = "0.1" diff --git a/src/components/login_modal.rs b/src/components/login_modal.rs index d6d53cd..cc1400e 100644 --- a/src/components/login_modal.rs +++ b/src/components/login_modal.rs @@ -381,7 +381,7 @@ fn GenerateKeysTab( } } - if let Some(keys) = generated_keys.read().as_ref() { + if let Some(keys) = generated_keys.read().clone() { div { class: "space-y-3", // Private Key div { @@ -403,14 +403,13 @@ fn GenerateKeysTab( { use wasm_bindgen::prelude::*; if let Some(window) = web_sys::window() { - if let Some(navigator) = window.navigator().clipboard() { - let nsec = keys.nsec.clone(); - spawn(async move { - let _ = wasm_bindgen_futures::JsFuture::from( - navigator.write_text(&nsec) - ).await; - }); - } + let clipboard = window.navigator().clipboard(); + let nsec = keys.nsec.clone(); + spawn(async move { + let _ = wasm_bindgen_futures::JsFuture::from( + clipboard.write_text(&nsec) + ).await; + }); } } }, @@ -420,7 +419,7 @@ fn GenerateKeysTab( } // Mnemonic if available - if let Some(mnemonic) = &keys.mnemonic { + if let Some(mnemonic) = keys.mnemonic.clone() { div { label { class: "block text-sm font-medium text-gray-700 mb-2", "Recovery Phrase (12 words)" @@ -440,14 +439,13 @@ fn GenerateKeysTab( { use wasm_bindgen::prelude::*; if let Some(window) = web_sys::window() { - if let Some(navigator) = window.navigator().clipboard() { - let mnem = mnemonic.clone(); - spawn(async move { - let _ = wasm_bindgen_futures::JsFuture::from( - navigator.write_text(&mnem) - ).await; - }); - } + let clipboard = window.navigator().clipboard(); + let mnem = mnemonic.clone(); + spawn(async move { + let _ = wasm_bindgen_futures::JsFuture::from( + clipboard.write_text(&mnem) + ).await; + }); } } }, diff --git a/src/components/video_player.rs b/src/components/video_player.rs index 84b0df1..c281b05 100644 --- a/src/components/video_player.rs +++ b/src/components/video_player.rs @@ -46,10 +46,14 @@ pub fn VideoEmbed(url: String) -> Element { } } else if url.contains("twitch.tv") { let channel = url.split('/').last().unwrap_or(""); + let hostname = window() + .location() + .hostname() + .unwrap_or_else(|_| String::from("localhost")); rsx! { div { class: "video-embed", iframe { - src: "https://player.twitch.tv/?channel={channel}&parent={window().location().hostname()}", + src: "https://player.twitch.tv/?channel={channel}&parent={hostname}", width: "100%", height: "450", allowfullscreen: true,