1- use std:: { io, time:: Duration } ;
2-
31use crossterm:: event:: { self , Event , KeyCode , KeyEvent , KeyEventKind , KeyModifiers } ;
42use ratatui:: {
53 prelude:: * ,
64 widgets:: { block:: * , * } ,
75} ;
6+ use std:: { io, process, thread, time:: Duration } ;
87use tokio:: sync:: mpsc:: UnboundedReceiver ;
98
109use crate :: { extract:: get_currently_playing, tui} ;
1110
12- #[ derive( Debug , Default , Clone ) ]
11+ #[ derive( Debug , Default ) ]
1312pub struct State {
1413 pub name : String ,
1514 pub now_playing : String ,
@@ -20,14 +19,24 @@ pub struct State {
2019
2120#[ derive( Debug , Default ) ]
2221pub struct App {
23- pub state : State ,
22+ name : String ,
23+ now_playing : String ,
24+ genre : String ,
25+ description : String ,
26+ br : String ,
2427 exit : bool ,
2528}
2629
2730impl App {
2831 pub fn new ( ) -> Self {
29- let state = State :: default ( ) ;
30- Self { state, exit : false }
32+ Self {
33+ name : "" . to_string ( ) ,
34+ now_playing : "" . to_string ( ) ,
35+ genre : "" . to_string ( ) ,
36+ description : "" . to_string ( ) ,
37+ br : "" . to_string ( ) ,
38+ exit : false ,
39+ }
3140 }
3241}
3342
@@ -38,25 +47,51 @@ impl App {
3847 terminal : & mut tui:: Tui ,
3948 mut cmd_rx : UnboundedReceiver < State > ,
4049 id : & str ,
41- ) -> anyhow :: Result < ( ) > {
50+ ) {
4251 let new_state = cmd_rx. recv ( ) . await . unwrap ( ) ;
43-
44- while !self . exit {
45- self . state = new_state. clone ( ) ;
46-
52+ self . name = new_state. name ;
53+ self . genre = new_state. genre ;
54+ self . description = new_state. description ;
55+ self . br = new_state. br ;
56+
57+ thread:: spawn ( || loop {
58+ match event:: read ( ) . unwrap ( ) {
59+ // it's important to check that the event is a key press event as
60+ // crossterm also emits key release and repeat events on Windows.
61+ Event :: Key ( key_event) if key_event. kind == KeyEventKind :: Press => {
62+ match key_event. code {
63+ KeyCode :: Char ( 'q' ) => {
64+ let _ = tui:: restore ( ) ;
65+ process:: exit ( 0 ) ;
66+ } ,
67+ KeyCode :: Char ( 'd' )
68+ if key_event. modifiers . contains ( KeyModifiers :: CONTROL ) =>
69+ {
70+ let _ = tui:: restore ( ) ;
71+ process:: exit ( 0 ) ;
72+ }
73+ KeyCode :: Char ( 'c' )
74+ if key_event. modifiers . contains ( KeyModifiers :: CONTROL ) =>
75+ {
76+ let _ = tui:: restore ( ) ;
77+ process:: exit ( 0 ) ;
78+ }
79+ _ => { }
80+ }
81+ }
82+ _ => { }
83+ } ;
84+ } ) ;
85+
86+ loop {
4787 // Get current playing if available, otherwise use state's value
48- let now_playing = get_currently_playing ( id)
49- . await
50- . unwrap_or_else ( |_| self . state . now_playing . clone ( ) ) ;
88+ let now_playing = get_currently_playing ( id) . await . unwrap_or_default ( ) ;
5189
5290 // Update state with current playing
53- self . state . now_playing = now_playing;
54-
55- terminal. draw ( |frame| self . render_frame ( frame) ) ?;
56- self . handle_events ( ) ?;
91+ self . now_playing = now_playing;
92+ terminal. draw ( |frame| self . render_frame ( frame) ) . unwrap ( ) ;
5793 std:: thread:: sleep ( Duration :: from_millis ( 500 ) ) ;
5894 }
59- Ok ( ( ) )
6095 }
6196
6297 fn render_frame ( & self , frame : & mut Frame ) {
@@ -81,16 +116,11 @@ impl App {
81116 areas[ 0 ] ,
82117 ) ;
83118
84- self . render_line ( "Station " , & self . state . name , areas[ 1 ] , frame) ;
85- self . render_line ( "Now Playing " , & self . state . now_playing , areas[ 2 ] , frame) ;
86- self . render_line ( "Genre " , & self . state . genre , areas[ 3 ] , frame) ;
87- self . render_line ( "Description " , & self . state . description , areas[ 4 ] , frame) ;
88- self . render_line (
89- "Bitrate " ,
90- & format ! ( "{} kbps" , & self . state. br) ,
91- areas[ 5 ] ,
92- frame,
93- ) ;
119+ self . render_line ( "Station " , & self . name , areas[ 1 ] , frame) ;
120+ self . render_line ( "Now Playing " , & self . now_playing , areas[ 2 ] , frame) ;
121+ self . render_line ( "Genre " , & self . genre , areas[ 3 ] , frame) ;
122+ self . render_line ( "Description " , & self . description , areas[ 4 ] , frame) ;
123+ self . render_line ( "Bitrate " , & format ! ( "{} kbps" , & self . br) , areas[ 5 ] , frame) ;
94124 }
95125
96126 fn render_line ( & self , label : & str , value : & str , area : Rect , frame : & mut Frame ) {
0 commit comments