From 9b733010aba083b679ed16ea0c9bfb89d8a32d20 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Mon, 6 Apr 2026 11:53:31 +0400 Subject: [PATCH] fix: blocking_lock panic in status(), fingerprint copy-to-clipboard MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Change status() from blocking_lock to async lock().await — fixes "Cannot block the current thread from within a runtime" panic that froze the call timer and broke audio - Click fingerprint to copy to clipboard (both connect and settings screens) - Show "Copied!" feedback on click Co-Authored-By: Claude Opus 4.6 (1M context) --- desktop/src-tauri/src/engine.rs | 4 ++-- desktop/src-tauri/src/main.rs | 2 +- desktop/src/main.ts | 34 +++++++++++++++++++++++++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/desktop/src-tauri/src/engine.rs b/desktop/src-tauri/src/engine.rs index 8d4292d..a1ace5f 100644 --- a/desktop/src-tauri/src/engine.rs +++ b/desktop/src-tauri/src/engine.rs @@ -333,8 +333,8 @@ impl CallEngine { !was } - pub fn status(&self) -> EngineStatus { - let parts = self.participants.blocking_lock(); + pub async fn status(&self) -> EngineStatus { + let parts = self.participants.lock().await; EngineStatus { mic_muted: self.mic_muted.load(Ordering::Relaxed), spk_muted: self.spk_muted.load(Ordering::Relaxed), diff --git a/desktop/src-tauri/src/main.rs b/desktop/src-tauri/src/main.rs index 5c83082..32cf2b3 100644 --- a/desktop/src-tauri/src/main.rs +++ b/desktop/src-tauri/src/main.rs @@ -108,7 +108,7 @@ async fn toggle_speaker(state: tauri::State<'_, Arc>) -> Result>) -> Result { let engine_lock = state.engine.lock().await; if let Some(ref engine) = *engine_lock { - let status = engine.status(); + let status = engine.status().await; Ok(CallStatus { active: true, mic_muted: status.mic_muted, diff --git a/desktop/src/main.ts b/desktop/src/main.ts index c86f26e..b33ba91 100644 --- a/desktop/src/main.ts +++ b/desktop/src/main.ts @@ -108,6 +108,29 @@ function renderRecentRooms(rooms: string[]) { applySettings(); +// Click fingerprint to copy +myFingerprintEl.addEventListener("click", () => { + if (myFingerprint) { + navigator.clipboard.writeText(myFingerprint).then(() => { + const orig = myFingerprintEl.textContent; + myFingerprintEl.textContent = "Copied!"; + setTimeout(() => { myFingerprintEl.textContent = orig; }, 1000); + }); + } +}); +myFingerprintEl.style.cursor = "pointer"; + +sFingerprint.addEventListener("click", () => { + if (myFingerprint) { + navigator.clipboard.writeText(myFingerprint).then(() => { + const orig = sFingerprint.textContent; + sFingerprint.textContent = "Copied!"; + setTimeout(() => { sFingerprint.textContent = orig; }, 1000); + }); + } +}); +sFingerprint.style.cursor = "pointer"; + // ── Connect ── connectBtn.addEventListener("click", doConnect); // Enter key to connect @@ -277,6 +300,17 @@ listen("call-event", (event: any) => { }); // ── Settings panel ── +// Load fingerprint into settings when status is available +async function refreshFingerprint() { + try { + const st: CallStatus = await invoke("get_status"); + if (st.fingerprint) { + myFingerprint = st.fingerprint; + myFingerprintEl.textContent = `ID: ${st.fingerprint}`; + } + } catch {} +} + function openSettings() { const s = loadSettings(); sRelay.value = s.relay;