11use crate :: Result ;
22use crate :: game:: { SessionSummary , ascii_digits:: get_digit_patterns} ;
3+ use crate :: sharing:: { SharingService , SharingPlatform } ;
34use crossterm:: {
45 cursor:: MoveTo ,
5- event:: { self , Event } ,
6+ event:: { self , Event , KeyCode , KeyModifiers } ,
67 execute,
78 style:: { Attribute , Color , Print , ResetColor , SetAttribute , SetForegroundColor } ,
89 terminal:: { self , ClearType } ,
@@ -12,11 +13,32 @@ use std::io::{stdout, Write};
1213#[ derive( Debug ) ]
1314pub enum ExitAction {
1415 Exit ,
16+ Share ,
1517}
1618
1719pub struct ExitSummaryScreen ;
1820
1921impl ExitSummaryScreen {
22+ fn session_summary_to_typing_metrics ( session_summary : & SessionSummary ) -> crate :: scoring:: TypingMetrics {
23+ use crate :: scoring:: { TypingMetrics , ScoringEngine } ;
24+
25+ // Create a TypingMetrics from SessionSummary data
26+ let ranking_title = ScoringEngine :: get_ranking_title_for_score ( session_summary. session_score ) . name ( ) . to_string ( ) ;
27+
28+ TypingMetrics {
29+ cpm : session_summary. overall_cpm ,
30+ wpm : session_summary. overall_wpm ,
31+ accuracy : session_summary. overall_accuracy ,
32+ mistakes : session_summary. total_mistakes ,
33+ consistency_streaks : vec ! [ ] , // Not available in session summary
34+ completion_time : session_summary. total_session_time ,
35+ challenge_score : session_summary. session_score ,
36+ ranking_title,
37+ was_skipped : false ,
38+ was_failed : false ,
39+ }
40+ }
41+
2042 fn create_ascii_numbers ( score : & str ) -> Vec < String > {
2143 let digit_patterns = get_digit_patterns ( ) ;
2244 let max_height = 4 ;
@@ -145,7 +167,8 @@ impl ExitSummaryScreen {
145167 execute ! ( stdout, ResetColor ) ?;
146168
147169 let options = vec ! [
148- "Press any key to exit" ,
170+ "[S] Share Result" ,
171+ "[ESC] Exit" ,
149172 ] ;
150173
151174 for ( i, option) in options. iter ( ) . enumerate ( ) {
@@ -158,13 +181,113 @@ impl ExitSummaryScreen {
158181
159182 stdout. flush ( ) ?;
160183
161- // Wait for any key press
184+ // Wait for user input
185+ loop {
186+ if event:: poll ( std:: time:: Duration :: from_millis ( 100 ) ) ? {
187+ if let Event :: Key ( key_event) = event:: read ( ) ? {
188+ match key_event. code {
189+ KeyCode :: Char ( 's' ) | KeyCode :: Char ( 'S' ) => {
190+ return Ok ( ExitAction :: Share ) ;
191+ } ,
192+ KeyCode :: Esc => {
193+ return Ok ( ExitAction :: Exit ) ;
194+ } ,
195+ KeyCode :: Char ( 'c' ) if key_event. modifiers . contains ( KeyModifiers :: CONTROL ) => {
196+ std:: process:: exit ( 0 ) ;
197+ } ,
198+ _ => continue ,
199+ }
200+ }
201+ }
202+ }
203+ }
204+
205+ pub fn show_sharing_menu ( session_summary : & SessionSummary ) -> Result < ( ) > {
206+ let metrics = Self :: session_summary_to_typing_metrics ( session_summary) ;
207+
208+ let mut stdout = stdout ( ) ;
209+ execute ! ( stdout, terminal:: Clear ( ClearType :: All ) ) ?;
210+
211+ let ( terminal_width, terminal_height) = terminal:: size ( ) ?;
212+ let center_row = terminal_height / 2 ;
213+ let center_col = terminal_width / 2 ;
214+
215+ // Title
216+ let title = "📤 Share Your Session Result" ;
217+ let title_col = center_col. saturating_sub ( title. len ( ) as u16 / 2 ) ;
218+ execute ! ( stdout, MoveTo ( title_col, center_row. saturating_sub( 8 ) ) ) ?;
219+ execute ! ( stdout, SetAttribute ( Attribute :: Bold ) , SetForegroundColor ( Color :: Yellow ) ) ?;
220+ execute ! ( stdout, Print ( title) ) ?;
221+ execute ! ( stdout, ResetColor ) ?;
222+
223+ // Show preview of what will be shared
224+ let preview_text = format ! (
225+ "\" {}\" - Score: {:.0}, CPM: {:.0}, Session Time: {:.1}min" ,
226+ metrics. ranking_title,
227+ metrics. challenge_score,
228+ metrics. cpm,
229+ metrics. completion_time. as_secs_f64( ) / 60.0
230+ ) ;
231+ let preview_col = center_col. saturating_sub ( preview_text. len ( ) as u16 / 2 ) ;
232+ execute ! ( stdout, MoveTo ( preview_col, center_row. saturating_sub( 5 ) ) ) ?;
233+ execute ! ( stdout, SetForegroundColor ( Color :: Cyan ) ) ?;
234+ execute ! ( stdout, Print ( & preview_text) ) ?;
235+ execute ! ( stdout, ResetColor ) ?;
236+
237+ // Platform options
238+ let platforms = SharingPlatform :: all ( ) ;
239+ let start_row = center_row. saturating_sub ( 2 ) ;
240+
241+ for ( i, platform) in platforms. iter ( ) . enumerate ( ) {
242+ let option_text = format ! ( "[{}] {}" , i + 1 , platform. name( ) ) ;
243+ let option_col = center_col. saturating_sub ( option_text. len ( ) as u16 / 2 ) ;
244+ execute ! ( stdout, MoveTo ( option_col, start_row + i as u16 ) ) ?;
245+ execute ! ( stdout, SetForegroundColor ( Color :: White ) ) ?;
246+ execute ! ( stdout, Print ( & option_text) ) ?;
247+ execute ! ( stdout, ResetColor ) ?;
248+ }
249+
250+ // Back option
251+ let back_text = "[ESC] Back to Exit Screen" ;
252+ let back_col = center_col. saturating_sub ( back_text. len ( ) as u16 / 2 ) ;
253+ execute ! ( stdout, MoveTo ( back_col, start_row + platforms. len( ) as u16 + 2 ) ) ?;
254+ execute ! ( stdout, SetForegroundColor ( Color :: Grey ) ) ?;
255+ execute ! ( stdout, Print ( back_text) ) ?;
256+ execute ! ( stdout, ResetColor ) ?;
257+
258+ stdout. flush ( ) ?;
259+
260+ // Handle input
162261 loop {
163262 if event:: poll ( std:: time:: Duration :: from_millis ( 100 ) ) ? {
164- if let Event :: Key ( _) = event:: read ( ) ? {
165- return Ok ( ExitAction :: Exit ) ;
263+ if let Event :: Key ( key_event) = event:: read ( ) ? {
264+ match key_event. code {
265+ KeyCode :: Char ( '1' ) => {
266+ let _ = SharingService :: share_result ( & metrics, SharingPlatform :: Twitter ) ;
267+ break ;
268+ } ,
269+ KeyCode :: Char ( '2' ) => {
270+ let _ = SharingService :: share_result ( & metrics, SharingPlatform :: Reddit ) ;
271+ break ;
272+ } ,
273+ KeyCode :: Char ( '3' ) => {
274+ let _ = SharingService :: share_result ( & metrics, SharingPlatform :: LinkedIn ) ;
275+ break ;
276+ } ,
277+ KeyCode :: Char ( '4' ) => {
278+ let _ = SharingService :: share_result ( & metrics, SharingPlatform :: Facebook ) ;
279+ break ;
280+ } ,
281+ KeyCode :: Esc => break ,
282+ KeyCode :: Char ( 'c' ) if key_event. modifiers . contains ( KeyModifiers :: CONTROL ) => {
283+ std:: process:: exit ( 0 ) ;
284+ } ,
285+ _ => continue ,
286+ }
166287 }
167288 }
168289 }
290+
291+ Ok ( ( ) )
169292 }
170293}
0 commit comments