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
105
106
107
108
109
110
111
112
113
114
115
116
use std::io::Stdout;

use super::common_keymap;
use crossterm::{
    event::{self, Event, KeyCode, KeyEventKind, KeyModifiers},
    execute,
};
use miette::{IntoDiagnostic, Result};
use ratatui::prelude::Backend;
use ratatui::Terminal;
use tui_textarea::{Input, Key};

use crate::{
    editor::edit_config,
    leetcode::IdSlug,
    mytui::{
        app::{App, InputMode},
        myevent::UserEvent,
        redraw,
    },
};

pub async fn tab0_keymap<B: Backend>(
    app: &mut App<'_>,
    terminal: &mut Terminal<B>,
    event: &Event,
    stdout: &mut Stdout,
) -> Result<()> {
    match app.tab0.input_line_mode {
        InputMode::Normal => {
            if let Event::Key(keyevent) = event {
                match keyevent.code {
                    KeyCode::Char('C') => {
                        // stop listen keyevent
                        *app.editor_flag.lock().unwrap() = false;
                        edit_config().await?;
                        // start listen keyevent
                        *app.editor_flag.lock().unwrap() = true;
                        app.editor_cond.notify_one();

                        // let res = USER_CONFIG
                        //     .set(read_config::get_user_conf().unwrap_or_default());

                        use crossterm::terminal::EnterAlternateScreen;
                        execute!(stdout, EnterAlternateScreen).into_diagnostic()?;

                        redraw(terminal, app)?;
                    }
                    KeyCode::Char('e') => {
                        app.tab0.input_line_mode = InputMode::Insert;
                    }
                    KeyCode::Char('S') => {
                        app.tab0.sync_state = true;
                        app.tx
                            .send(UserEvent::StartSync)
                            .into_diagnostic()?;
                    }
                    KeyCode::Char('g') => {
                        if let Event::Key(key) = event::read().into_diagnostic()? {
                            if key.kind == KeyEventKind::Press
                                && key.code == KeyCode::Char('g')
                            {
                                app.tab0.first_question();
                            }
                        }
                    }
                    KeyCode::Char('G') => app.tab0.last_question(),
                    KeyCode::Enter => app.goto_tab(1)?,
                    KeyCode::Down | KeyCode::Char('j') => app.tab0.next_question(),
                    KeyCode::Up | KeyCode::Char('k') => app.tab0.previous_question(),
                    KeyCode::Char('r') if keyevent.modifiers == KeyModifiers::CONTROL => {
                        app.tx
                            .send(UserEvent::GetQs((
                                IdSlug::Id(app.tab0.current_qs()),
                                true,
                            )))
                            .into_diagnostic()?;
                    }
                    KeyCode::Char('o') => {
                        // stop listen keyevent
                        *app.editor_flag.lock().unwrap() = false;
                        app.tab0.confirm_qs().await?;
                        // start listen keyevent
                        *app.editor_flag.lock().unwrap() = true;
                        app.editor_cond.notify_one();
                        app.get_code(&app.tab0.cur_qs.clone())
                            .await?;

                        use crossterm::terminal::EnterAlternateScreen;
                        execute!(stdout, EnterAlternateScreen).into_diagnostic()?;

                        redraw(terminal, app)?;
                    }
                    _ => {
                        common_keymap(app, terminal, event, stdout).await?;
                    }
                }
            }
        }
        InputMode::Insert => match event.clone().into() {
            Input { key: Key::Esc, .. } => app.tab0.input_line_mode = InputMode::Normal,
            Input {
                key: Key::Char('m'),
                ctrl: true,
                ..
            }
            | Input {
                key: Key::Enter, ..
            } => {}
            input => {
                app.tab0.text_line.input(input);
            }
        },
    };
    Ok(())
}