1- use std:: { collections:: HashMap , sync:: Arc , thread:: sleep, time:: Duration } ;
1+ use std:: {
2+ collections:: HashMap ,
3+ sync:: {
4+ atomic:: { AtomicBool , Ordering } ,
5+ Arc ,
6+ } ,
7+ thread:: sleep,
8+ time:: Duration ,
9+ } ;
210
311use futures_util:: { SinkExt , StreamExt } ;
412use lazy_static:: lazy_static;
@@ -8,6 +16,7 @@ use serde::Serialize;
816use tauri:: {
917 async_runtime:: { self , Mutex } ,
1018 ipc:: Channel ,
19+ AppHandle , Listener ,
1120} ;
1221use tokio_tungstenite:: tungstenite:: Message ;
1322
@@ -59,7 +68,11 @@ pub enum ChatEvent {
5968}
6069
6170#[ tauri:: command]
62- pub async fn join_chat ( username : & str , reader : Channel < ChatEvent > ) -> Result < ( ) , String > {
71+ pub async fn join_chat (
72+ app_handle : AppHandle ,
73+ username : & str ,
74+ reader : Channel < ChatEvent > ,
75+ ) -> Result < ( ) , String > {
6376 let user_emotes = emote:: query_user_emotes ( username) . await . unwrap_or_default ( ) ;
6477
6578 let mut ws_stream = match tokio_tungstenite:: connect_async ( WS_CHAT_URL ) . await {
@@ -94,7 +107,19 @@ pub async fn join_chat(username: &str, reader: Channel<ChatEvent>) -> Result<(),
94107
95108 let ws_sink = Arc :: new ( Mutex :: new ( ws_sink) ) ;
96109
110+ let is_cancelled = Arc :: new ( AtomicBool :: new ( false ) ) ;
111+ let cancel_flag = Arc :: clone ( & is_cancelled) ;
112+
113+ let listener = app_handle. listen ( "leave_chat" , move |_event| {
114+ cancel_flag. store ( true , Ordering :: SeqCst ) ;
115+ } ) ;
116+
97117 while let Some ( Ok ( Message :: Text ( text) ) ) = ws_stream. next ( ) . await {
118+ if is_cancelled. load ( Ordering :: Relaxed ) {
119+ break ;
120+ }
121+
122+ // Handle PING/PONG messages
98123 if text. starts_with ( PING ) {
99124 let ws_sink = Arc :: clone ( & ws_sink) ;
100125
@@ -103,9 +128,8 @@ pub async fn join_chat(username: &str, reader: Channel<ChatEvent>) -> Result<(),
103128 continue ;
104129 }
105130
106- // Ping the server after 60 seconds
131+ // Schedule a PING after 60 seconds
107132 let ws_sink = Arc :: clone ( & ws_sink) ;
108-
109133 async_runtime:: spawn ( async move {
110134 sleep ( Duration :: from_secs ( 60 ) ) ;
111135
@@ -164,6 +188,8 @@ pub async fn join_chat(username: &str, reader: Channel<ChatEvent>) -> Result<(),
164188 }
165189 }
166190
191+ app_handle. unlisten ( listener) ;
192+
167193 Ok ( ( ) )
168194}
169195
0 commit comments