@@ -207,18 +207,27 @@ def on_item_selected(self, item: QListWidgetItem) -> None:
207207
208208 @QtCore .Slot ()
209209 def show_search_splash (self ) -> None :
210- """
211- Show splash screen for search operation.
212-
213- Creates and displays a splash screen with an animated loading GIF
214- to provide visual feedback during channel search operations.
215- """
216210 cwd = os .getcwd ()
217211 gif_path = os .path .join (cwd , "assets" , "gif" , "loading.gif" )
212+
213+ if self .splash :
214+ self .splash .close ()
215+
218216 self .splash = SplashScreen (parent = self .mainwindow , gif_path = gif_path )
219217 self .splash .set_title ("Searching Channels..." )
220218 self .splash .update_status ("Fetching channel information..." )
221- self .splash .show ()
219+ self .splash .set_progress (0 )
220+
221+ # Runtime overlay + cancel support
222+ self .splash .enable_runtime_mode (
223+ parent_window = self .mainwindow ,
224+ cancel_callback = self .cancel_search
225+ )
226+
227+ # THIS IS REQUIRED
228+ self .splash .show_with_animation ()
229+ self .splash .raise_ ()
230+ self .splash .activateWindow ()
222231
223232 @QtCore .Slot (int , str )
224233 def on_progress_update (self , progress : int , status : str ) -> None :
@@ -240,15 +249,20 @@ def on_progress_update(self, progress: int, status: str) -> None:
240249
241250 @QtCore .Slot ()
242251 def close_splash (self ) -> None :
243- """
244- Close splash screen.
245-
246- Closes and cleans up the splash screen instance if it exists.
247- """
248252 if self .splash :
249- self .splash .close ( )
253+ self .splash .fade_and_close ( 400 )
250254 self .splash = None
251255
256+ def cancel_search (self ):
257+ logger .warning ("User cancelled search operation." )
258+
259+ self .stop_event .set ()
260+
261+ if self .search_thread_instance and self .search_thread_instance .is_alive ():
262+ self .search_thread_instance .join (timeout = 0.5 )
263+
264+ self .close_splash_signal .emit ()
265+
252266 def update_results (self , channels : List [str ]) -> None :
253267 """
254268 Update dropdown list with search results.
@@ -382,27 +396,25 @@ def _run_search(self, query: str, final: bool) -> None:
382396
383397 # Check if thread should stop before starting work
384398 if self .stop_event .is_set ():
399+ self .close_splash_signal .emit ()
385400 logger .debug ("Search thread cancelled before execution" )
386401 return
387402
388403 try :
389- if final :
390- # Show splash screen for final search
391- self .show_splash_signal .emit ()
392-
404+ if final :
393405 # Define progress callback for the search
394- def progress_callback (progress : Any , status : Optional [str ] = None ) -> None :
395- """
396- Callback function for reporting search progress.
397-
398- Args:
399- progress: Progress value (int/float for percentage, str for status message)
400- status: Optional status message, defaults to None
401- """
406+ def progress_callback (progress : Any , status : Optional [str ] = None ):
407+ if self .stop_event .is_set ():
408+ return
409+
402410 if isinstance (progress , (int , float )):
403411 self .progress_update .emit (int (progress ), status or "" )
412+ if self .splash :
413+ self .splash .update_eta (int (progress ))
414+
404415 elif isinstance (progress , str ):
405- self .progress_update .emit (- 1 , progress ) # -1 means don't update progress bar
416+ self .progress_update .emit (- 1 , progress )
417+
406418
407419 # Perform search with progress tracking
408420 self .channels = self .search .search_channel (
@@ -444,26 +456,33 @@ def progress_callback(progress: Any, status: Optional[str] = None) -> None:
444456 # Signal that search is complete
445457 self .search_complete .emit ()
446458
459+ if self .stop_event .is_set ():
460+ self .close_splash_signal .emit ()
461+ return
462+
447463 def search_channel (self ) -> None :
448464 """
449465 Handle search button click event.
450-
451- Initiates a final comprehensive search for the query entered in the search bar.
452- Cancels any ongoing auto-search operations before starting the new search.
453- Clears previous incomplete results to ensure fresh data is retrieved.
454466 """
455467 query = self .searchbar .text ().strip ()
456468 if not query :
457469 return
458470
459- # --- Cancel any ongoing auto- search ---
471+ # CANCEL any running search
460472 if self .search_thread_instance and self .search_thread_instance .is_alive ():
461473 self .stop_event .set ()
462- self .search_thread_instance .join (timeout = 1.0 ) # Ensure it fully stops before continuing
474+ self .search_thread_instance .join (timeout = 0.5 )
463475
464- # Clear old incomplete results
465476 self .channels = None
466- self .search .search_channel (name = None ) # reset internal state if needed
467-
468- # --- Now run the final search with fresh data ---
469- self .search_keyword (query = query , final = True )
477+ self .stop_event .clear ()
478+
479+ # SHOW SPLASH IMMEDIATELY (MAIN THREAD)
480+ self .show_search_splash ()
481+
482+ # START WORKER THREAD AFTER SPLASH IS VISIBLE
483+ self .search_thread_instance = threading .Thread (
484+ target = self ._run_search ,
485+ daemon = True ,
486+ args = (query , True )
487+ )
488+ self .search_thread_instance .start ()
0 commit comments