1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
mod sm2; mod records; mod slide; mod events; mod cards; pub mod errors; use records::*; use slide::Slide; use std::io; use termion::raw::IntoRawMode; use termion::event::Key; use tui::Terminal; use tui::backend::TermionBackend; use tui::layout::{Constraint,Direction,Layout}; use events::Event; use errors::Res; const DEFAULT: usize = 20; pub fn start_tui(file : &str, num: Option<usize>) -> Res<()> { let stdout = io::stdout().into_raw_mode()?; let backend = TermionBackend::new(stdout); let mut terminal = Terminal::new(backend)?; let events = events::setup_events(); let records = Records::read_file(file)?.records(); let num = num.unwrap_or(DEFAULT); let mut cards = cards::Cards::from(records).select(num); terminal.clear()?; while let Some(_) = cards.next() { let record = cards.current_record(); let mut slide = Slide::default().record(record); let mut exit_called = false; let mut exit = || exit_called = true; while let Some(step) = slide.step() { let final_step = step == 2; let record = slide.clone(); terminal.draw(|f| { let h2 = 3u16; let h1 = f.size().height - h2; let section = Layout::default() .direction(Direction::Vertical) .constraints( [ Constraint::Length(h1), Constraint::Length(h2), ] ).split(f.size()); f.render_widget(record.clone(),section[0]); f.render_widget(cards.status(),section[1]); })?; match events.recv().unwrap() { Event::Refresh => (), Event::Key(key) => match key { Key::Char(' ') => if !final_step { slide.cont() }, Key::Char('\n') => if final_step { slide.cont() }, Key::Char('l') | Key::Right => if final_step {slide.next()}, Key::Char('h') | Key::Left => if final_step {slide.prev()}, Key::Char('q') | Key::Esc => { exit(); break }, Key::Ctrl('c') | Key::Ctrl('d') => { exit(); break }, _ => (), }, }; } if exit_called { break } let rating = slide.rating(); cards.review_current_card(rating); }; let records = cards.records(); let records = Records::from(records); records.write_to_file(file)?; terminal.clear()?; Ok(()) } pub fn generate_sample() -> Res<()> { let sample = r#" # Structure each new card in the format below. # Deckster will generate additional metadata for each # card and store it in this file. Avoid editing # the metadata. # # Uncomment the block below to begin. # # [[card]] # question = 'question 1' # answer = 'answer 1' "#; println!("{}",sample); Ok(()) }