11# Copyright (c) 2025. All rights reserved.
22"""CLI interface using rich-click for beautiful output."""
33
4+ import contextlib
45import sys
56
67import rich_click as click
@@ -225,6 +226,25 @@ def volume(level: float | None) -> None:
225226 console .print ("[green]✓[/green] Volume saved!" )
226227
227228
229+ @cli .command ()
230+ @click .option ("--sequential" , is_flag = True , help = "Play sounds in alphabetical order instead of random." )
231+ def auto (sequential : bool ) -> None : # noqa: FBT001
232+ """Play all sounds randomly, one after another.
233+
234+ Each sound will play completely before the next one starts.
235+ Press Ctrl+C to stop playback.
236+ """
237+ soundboard , _ = get_soundboard ()
238+
239+ if not soundboard .sounds :
240+ console .print ("[red]✗[/red] No sounds found." )
241+ console .print (f"[dim]Add audio files to: { soundboard .sounds_dir } [/dim]" )
242+ sys .exit (1 )
243+
244+ with contextlib .suppress (KeyboardInterrupt ):
245+ soundboard .play_all_sounds (shuffle = not sequential )
246+
247+
228248def _handle_play_sound (soundboard : Soundboard ) -> None :
229249 """Handle playing a sound by name."""
230250 sound_name = click .prompt ("Enter sound name" )
@@ -284,11 +304,18 @@ def _show_menu() -> None:
284304 console .print ("6. List audio devices" )
285305 console .print ("7. Change output device" )
286306 console .print ("8. Adjust volume" )
307+ console .print ("9. Auto-play all sounds" )
287308 console .print ("0. Exit" )
288309
289310
311+ def _handle_auto_play (soundboard : Soundboard ) -> None :
312+ """Handle auto-play all sounds."""
313+ with contextlib .suppress (KeyboardInterrupt ):
314+ soundboard .play_all_sounds ()
315+
316+
290317@cli .command ()
291- def interactive () -> None : # noqa: C901
318+ def interactive () -> None :
292319 """Launch interactive menu mode.
293320
294321 Provides a text-based menu for exploring and using the soundboard.
@@ -302,29 +329,30 @@ def interactive() -> None: # noqa: C901
302329
303330 soundboard .setup_default_hotkeys ()
304331
332+ # Menu action dispatch table (lambdas needed for partial application)
333+ menu_actions = {
334+ "1" : soundboard .list_sounds ,
335+ "2" : lambda : _handle_play_sound (soundboard ),
336+ "3" : soundboard .list_hotkeys ,
337+ "4" : lambda : _handle_hotkey_listener (soundboard ),
338+ "5" : soundboard .stop_sound ,
339+ "6" : audio_manager .print_devices ,
340+ "7" : lambda : _handle_change_device (audio_manager ),
341+ "8" : lambda : _handle_volume (audio_manager ),
342+ "9" : lambda : _handle_auto_play (soundboard ),
343+ }
344+
305345 while True :
306346 _show_menu ()
307347 choice = click .prompt ("\n Enter your choice" , type = str ).strip ()
308348
309- if choice == "1" :
310- soundboard .list_sounds ()
311- elif choice == "2" :
312- _handle_play_sound (soundboard )
313- elif choice == "3" :
314- soundboard .list_hotkeys ()
315- elif choice == "4" :
316- _handle_hotkey_listener (soundboard )
317- elif choice == "5" :
318- soundboard .stop_sound ()
319- elif choice == "6" :
320- audio_manager .print_devices ()
321- elif choice == "7" :
322- _handle_change_device (audio_manager )
323- elif choice == "8" :
324- _handle_volume (audio_manager )
325- elif choice == "0" :
349+ if choice == "0" :
326350 console .print ("\n [cyan]Goodbye! 👋[/cyan]" )
327351 break
352+
353+ action = menu_actions .get (choice )
354+ if action :
355+ action ()
328356 else :
329357 console .print ("[red]Invalid choice.[/red]" )
330358
0 commit comments