diff --git a/src-tauri/src/commands/audio.rs b/src-tauri/src/commands/audio.rs index 916ab3b..05f7ed1 100644 --- a/src-tauri/src/commands/audio.rs +++ b/src-tauri/src/commands/audio.rs @@ -46,6 +46,7 @@ pub struct VoiceState { #[derive(Default)] pub struct VoiceStateInner { pub session: Mutex>, + pub backend_config: Arc>, } pub struct VoiceSession { @@ -532,10 +533,7 @@ pub fn connect_to_vc( producer_in: Arc::clone(&shared_producer_in), consumer_out: Arc::clone(&shared_consumer_out), - backend_config: Arc::new(Mutex::new(BackendConfig { - is_muted: false, - is_deaf: false, - })), + backend_config: Arc::clone(&voice_state.inner.backend_config), }; session.setup_input(config.input_device_name.clone(), Arc::clone(&state_inner))?; @@ -641,6 +639,7 @@ pub fn connect_to_vc( let shutdown = shutdown.clone(); let cipher = cipher.clone(); let backend_config = session.backend_config.clone(); + let consumer_out = session.consumer_out.clone(); thread::spawn(move || { let mut packets: BTreeMap> = BTreeMap::new(); @@ -651,13 +650,28 @@ pub fn connect_to_vc( let mut next_frame_time = Instant::now(); while !shutdown.load(Ordering::Relaxed) { - let is_deaf = { backend_config.lock().unwrap().is_deaf }; + let is_deaf = { + let cfg = backend_config.lock().unwrap(); + cfg.is_deaf + }; if is_deaf { + // Keep draining the UDP socket while deafened/muted so stale + // packets don't accumulate in the OS buffer and get replayed + // when we undeafen/unmute. Decrypting and discarding here + // fully consumes the socket backlog. + if let Ok(len) = socket.recv(&mut udp_buffer) { + let _ = cipher.lock().unwrap().decrypt(&udp_buffer[..len]); + } + // Drop any audio already buffered for playback so that on + // unmute/undeafen we don't replay audio from the past. + if let Ok(mut cons) = consumer_out.lock() { + cons.clear(); + } packets.clear(); is_prebuffering = true; - std::thread::sleep(Duration::from_secs(1)); + thread::sleep(Duration::from_millis(1)); continue; } diff --git a/src-tauri/src/commands/config.rs b/src-tauri/src/commands/config.rs index c8d672f..5befd49 100644 --- a/src-tauri/src/commands/config.rs +++ b/src-tauri/src/commands/config.rs @@ -103,7 +103,7 @@ pub fn get_config(app: AppHandle, state: State) -> Result, config: BackendConfig, ) -> Result<(), String> { - if let Some(v) = &mut *voice_state.inner.session.lock().unwrap() { - *v.backend_config.lock().unwrap() = config - } + *voice_state.inner.backend_config.lock().unwrap() = config; Ok(()) } diff --git a/src/App.tsx b/src/App.tsx index 52d1655..542ba27 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -49,7 +49,7 @@ export default function App() { minSize="4rem" groupResizeBehavior="preserve-pixel-size" > -
+
diff --git a/src/components/sidebar/MainPageSidebar.tsx b/src/components/sidebar/MainPageSidebar.tsx index 0b72932..f46aaaa 100644 --- a/src/components/sidebar/MainPageSidebar.tsx +++ b/src/components/sidebar/MainPageSidebar.tsx @@ -5,6 +5,7 @@ import { openUrl } from "@tauri-apps/plugin-opener"; import { Button } from "@/components/ui/button"; import { RefreshCw, Rss } from "lucide-react"; import { cn } from "@/lib/utils"; +import StatusCard from "../view/StatusCard"; function formatTime(publishedAt: number): string { if (!publishedAt) return ""; @@ -73,7 +74,9 @@ function StaticFallback() { ); } -export default function MainPageSidebar(_props: { +export default function MainPageSidebar({ + appRef, +}: { appRef: React.RefObject; }) { const [items, setItems] = useState(null); @@ -98,58 +101,62 @@ export default function MainPageSidebar(_props: { }, [load]); return ( -
-
-

- - Security News -

- -
+
+
+
+

+ + Security News +

+ +
-
- {loading && items === null && ( -

- Loading news… -

- )} +
+ {loading && items === null && ( +

+ Loading news… +

+ )} - {error && !loading && } + {error && !loading && } - {items && ( -
- {items.map((item) => ( - - ))} -
- )} -
+ {items && ( +
+ {items.map((item) => ( + + ))} +
+ )} +
+
+ +
); } diff --git a/src/components/sidebar/ServerSidebar.tsx b/src/components/sidebar/ServerSidebar.tsx index 3b20c19..9b0bbbd 100644 --- a/src/components/sidebar/ServerSidebar.tsx +++ b/src/components/sidebar/ServerSidebar.tsx @@ -64,7 +64,7 @@ export function RenderFeatures({ return ( users && ( -
+
{(isCurrentVc ? users : users.slice(0, 15)).map((pubkey) => { const user = appRef.current?.server?.users[pubkey]; if (!user) return null; @@ -156,20 +156,20 @@ export default function ServerSidebar({ appRef: React.RefObject; }) { return ( -
+
{appRef.current?.server?.meta && ( - <> +

{appRef.current.server.meta.name}

-
+
- +
)}