Restore TUI key hints after updates
This commit is contained in:
@@ -12,6 +12,7 @@ use gotcha_gitea::{
|
|||||||
use crate::editor::{Editor, EditorAction, EditorEvent};
|
use crate::editor::{Editor, EditorAction, EditorEvent};
|
||||||
|
|
||||||
const ALL_BRANCHES: &str = "All branches";
|
const ALL_BRANCHES: &str = "All branches";
|
||||||
|
const UPDATE_STATUS_DURATION: Duration = Duration::from_secs(2);
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||||
pub enum Tab {
|
pub enum Tab {
|
||||||
@@ -162,6 +163,7 @@ pub struct App {
|
|||||||
pub editor: Option<Editor>,
|
pub editor: Option<Editor>,
|
||||||
pub confirm: Option<(String, ConfirmAction)>,
|
pub confirm: Option<(String, ConfirmAction)>,
|
||||||
pub status: String,
|
pub status: String,
|
||||||
|
status_deadline: Option<Instant>,
|
||||||
pub should_quit: bool,
|
pub should_quit: bool,
|
||||||
pub last_input: Instant,
|
pub last_input: Instant,
|
||||||
pub last_reload: Instant,
|
pub last_reload: Instant,
|
||||||
@@ -218,6 +220,7 @@ impl App {
|
|||||||
editor: None,
|
editor: None,
|
||||||
confirm: None,
|
confirm: None,
|
||||||
status: "Loading…".into(),
|
status: "Loading…".into(),
|
||||||
|
status_deadline: None,
|
||||||
should_quit: false,
|
should_quit: false,
|
||||||
last_input: Instant::now(),
|
last_input: Instant::now(),
|
||||||
last_reload: Instant::now(),
|
last_reload: Instant::now(),
|
||||||
@@ -256,6 +259,7 @@ impl App {
|
|||||||
|
|
||||||
pub async fn handle_key(&mut self, key: KeyEvent) {
|
pub async fn handle_key(&mut self, key: KeyEvent) {
|
||||||
self.last_input = Instant::now();
|
self.last_input = Instant::now();
|
||||||
|
self.status_deadline = None;
|
||||||
if let Some(editor) = &mut self.editor {
|
if let Some(editor) = &mut self.editor {
|
||||||
match editor.handle_key(key) {
|
match editor.handle_key(key) {
|
||||||
EditorEvent::Submit => self.submit_editor().await,
|
EditorEvent::Submit => self.submit_editor().await,
|
||||||
@@ -328,6 +332,7 @@ impl App {
|
|||||||
|
|
||||||
pub async fn handle_mouse(&mut self, mouse: MouseEvent) {
|
pub async fn handle_mouse(&mut self, mouse: MouseEvent) {
|
||||||
self.last_input = Instant::now();
|
self.last_input = Instant::now();
|
||||||
|
self.status_deadline = None;
|
||||||
if self.editor.is_some() || self.confirm.is_some() {
|
if self.editor.is_some() || self.confirm.is_some() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -396,6 +401,7 @@ impl App {
|
|||||||
let page = self.screen.page;
|
let page = self.screen.page;
|
||||||
let selected_key = self.screen.selected_item().map(|item| item.key.clone());
|
let selected_key = self.screen.selected_item().map(|item| item.key.clone());
|
||||||
self.status = "Loading…".into();
|
self.status = "Loading…".into();
|
||||||
|
self.status_deadline = None;
|
||||||
match self.load_screen(kind, page).await {
|
match self.load_screen(kind, page).await {
|
||||||
Ok(mut screen) => {
|
Ok(mut screen) => {
|
||||||
if let Some(key) = selected_key
|
if let Some(key) = selected_key
|
||||||
@@ -405,12 +411,21 @@ impl App {
|
|||||||
}
|
}
|
||||||
self.screen = screen;
|
self.screen = screen;
|
||||||
self.status = format!("Updated {}", clock());
|
self.status = format!("Updated {}", clock());
|
||||||
|
self.status_deadline = Some(Instant::now() + UPDATE_STATUS_DURATION);
|
||||||
}
|
}
|
||||||
Err(error) => self.status = error,
|
Err(error) => self.status = error,
|
||||||
}
|
}
|
||||||
self.last_reload = Instant::now();
|
self.last_reload = Instant::now();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn visible_status(&self) -> Option<&str> {
|
||||||
|
(!self.status.is_empty()
|
||||||
|
&& self
|
||||||
|
.status_deadline
|
||||||
|
.is_none_or(|deadline| Instant::now() < deadline))
|
||||||
|
.then_some(self.status.as_str())
|
||||||
|
}
|
||||||
|
|
||||||
async fn switch_tab(&mut self, tab: Tab) {
|
async fn switch_tab(&mut self, tab: Tab) {
|
||||||
self.tab = tab;
|
self.tab = tab;
|
||||||
self.history.clear();
|
self.history.clear();
|
||||||
@@ -1898,6 +1913,13 @@ mod tests {
|
|||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn auto_reload_waits_for_idle_overview_without_an_editor() {
|
async fn auto_reload_waits_for_idle_overview_without_an_editor() {
|
||||||
let mut app = App::new(Config::default(), None).await.unwrap();
|
let mut app = App::new(Config::default(), None).await.unwrap();
|
||||||
|
assert!(app.visible_status().unwrap().starts_with("Updated "));
|
||||||
|
app.status_deadline = Some(Instant::now() - Duration::from_secs(1));
|
||||||
|
assert_eq!(app.visible_status(), None);
|
||||||
|
app.status = "Network unavailable".into();
|
||||||
|
app.status_deadline = None;
|
||||||
|
assert_eq!(app.visible_status(), Some("Network unavailable"));
|
||||||
|
|
||||||
app.last_reload = Instant::now() - Duration::from_secs(6);
|
app.last_reload = Instant::now() - Duration::from_secs(6);
|
||||||
app.last_input = Instant::now() - Duration::from_secs(6);
|
app.last_input = Instant::now() - Duration::from_secs(6);
|
||||||
assert!(app.should_auto_reload());
|
assert!(app.should_auto_reload());
|
||||||
|
|||||||
@@ -187,15 +187,15 @@ fn draw_detail(frame: &mut Frame<'_>, app: &App, area: Rect) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn draw_footer(frame: &mut Frame<'_>, app: &App, area: Rect) {
|
fn draw_footer(frame: &mut Frame<'_>, app: &App, area: Rect) {
|
||||||
let status = if app.status.is_empty() {
|
let status = if let Some(status) = app.visible_status() {
|
||||||
format!(
|
format!(
|
||||||
"Page {} · j/k move · Enter open · Backspace back · n/p pages · a/e/c/x/d actions · / filters · * favorite · r reload · q quit",
|
"{} · Page {} · j/k move · Enter open · Backspace back · n/p pages · q quit",
|
||||||
app.screen.page
|
status, app.screen.page
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
format!(
|
format!(
|
||||||
"{} · Page {} · j/k move · Enter open · Backspace back · n/p pages · q quit",
|
"Page {} · j/k move · Enter open · Backspace back · n/p pages · a/e/c/x/d actions · / filters · * favorite · r reload · q quit",
|
||||||
app.status, app.screen.page
|
app.screen.page
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
frame.render_widget(
|
frame.render_widget(
|
||||||
|
|||||||
Reference in New Issue
Block a user