tui: Re-render only if message received

Signed-off-by: Erik Kundt <erik@zirkular.io>
This commit is contained in:
Erik Kundt 2023-04-18 16:02:09 +02:00 committed by Alexis Sellier
parent 1bde528a1b
commit 38c9f0a1c0
No known key found for this signature in database
2 changed files with 38 additions and 41 deletions

View File

@ -1,5 +1,3 @@
use std::time::Duration;
use anyhow::Result; use anyhow::Result;
use tui_realm_stdlib::Phantom; use tui_realm_stdlib::Phantom;
@ -69,6 +67,7 @@ pub enum Message {
Home(HomeMessage), Home(HomeMessage),
Patch(PatchMessage), Patch(PatchMessage),
NavigationChanged(u16), NavigationChanged(u16),
Tick,
Quit, Quit,
} }
@ -147,35 +146,33 @@ impl Tui<Cid, Message> for App {
self.active_page.as_mut().view(app, frame); self.active_page.as_mut().view(app, frame);
} }
fn update( fn update(&mut self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<bool> {
&mut self, match app.tick(PollStrategy::Once) {
app: &mut Application<Cid, Message, NoUserEvent>, Ok(messages) if !messages.is_empty() => {
interval: u64, let theme = theme::default_dark();
) -> Result<()> { for message in messages {
if let Ok(messages) = app.tick(PollStrategy::TryFor(Duration::from_millis(interval))) { match message {
let theme = theme::default_dark(); Message::Home(HomeMessage::Show) => {
for message in messages { self.mount_home_view(app, &theme)?;
match message { }
Message::Home(HomeMessage::Show) => { Message::Patch(PatchMessage::Show(index)) => {
self.mount_home_view(app, &theme)?; self.context.selected_patch = index;
} self.mount_patch_view(app, &theme)?;
Message::Patch(PatchMessage::Show(index)) => { }
self.context.selected_patch = index; Message::Patch(PatchMessage::Leave) => {
self.mount_patch_view(app, &theme)?; self.mount_home_view(app, &theme)?;
} }
Message::Patch(PatchMessage::Leave) => { Message::Quit => self.quit = true,
self.mount_home_view(app, &theme)?; _ => {
} self.active_page.update(message);
Message::Quit => self.quit = true, self.active_page.activate(app)?;
_ => { }
self.active_page.update(message);
self.active_page.activate(app)?;
} }
} }
Ok(true)
} }
_ => Ok(false),
} }
Ok(())
} }
fn quit(&self) -> bool { fn quit(&self) -> bool {
@ -230,7 +227,7 @@ impl ViewPage for Home {
let navigation = ui::home_navigation(theme).to_boxed(); let navigation = ui::home_navigation(theme).to_boxed();
let dashboard = ui::dashboard(theme, &context.id, &context.project).to_boxed(); let dashboard = ui::dashboard(theme, &context.id, &context.project).to_boxed();
let issue_browser = ui::issue_browser(&theme).to_boxed(); let issue_browser = ui::issue_browser(theme).to_boxed();
let patch_browser = ui::patch_browser(theme, &context.patches, &context.profile).to_boxed(); let patch_browser = ui::patch_browser(theme, &context.patches, &context.profile).to_boxed();
let shortcuts = ui::shortcuts( let shortcuts = ui::shortcuts(
@ -383,6 +380,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<GlobalListener> {
code: Key::Char('q'), code: Key::Char('q'),
.. ..
}) => Some(Message::Quit), }) => Some(Message::Quit),
Event::WindowResize(_, _) => Some(Message::Tick),
_ => None, _ => None,
} }
} }
@ -409,13 +407,13 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<Browser<(PatchId, Patc
match event { match event {
Event::Keyboard(KeyEvent { code: Key::Up, .. }) => { Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
self.perform(Cmd::Move(MoveDirection::Up)); self.perform(Cmd::Move(MoveDirection::Up));
None Some(Message::Tick)
} }
Event::Keyboard(KeyEvent { Event::Keyboard(KeyEvent {
code: Key::Down, .. code: Key::Down, ..
}) => { }) => {
self.perform(Cmd::Move(MoveDirection::Down)); self.perform(Cmd::Move(MoveDirection::Down));
None Some(Message::Tick)
} }
Event::Keyboard(KeyEvent { Event::Keyboard(KeyEvent {
code: Key::Enter, .. code: Key::Enter, ..

View File

@ -25,12 +25,9 @@ where
/// Should initialize an application by mounting and activating components. /// Should initialize an application by mounting and activating components.
fn init(&mut self, app: &mut Application<Id, Message, NoUserEvent>) -> Result<()>; fn init(&mut self, app: &mut Application<Id, Message, NoUserEvent>) -> Result<()>;
/// Should update the current state by handling a message from the view. /// Should update the current state by handling a message from the view. Returns true
fn update( /// if view should be updated (e.g. a message was received and the current state changed).
&mut self, fn update(&mut self, app: &mut Application<Id, Message, NoUserEvent>) -> Result<bool>;
app: &mut Application<Id, Message, NoUserEvent>,
interval: u64,
) -> Result<()>;
/// Should draw the application to a frame. /// Should draw the application to a frame.
fn view(&mut self, app: &mut Application<Id, Message, NoUserEvent>, frame: &mut Frame); fn view(&mut self, app: &mut Application<Id, Message, NoUserEvent>, frame: &mut Frame);
@ -76,17 +73,19 @@ impl Window {
Id: Eq + PartialEq + Clone + Hash, Id: Eq + PartialEq + Clone + Hash,
Message: Eq, Message: Eq,
{ {
let mut update = true;
let mut app = Application::init( let mut app = Application::init(
EventListenerCfg::default().default_input_listener(Duration::from_millis(interval)), EventListenerCfg::default().default_input_listener(Duration::from_millis(interval)),
); );
tui.init(&mut app)?; tui.init(&mut app)?;
while !tui.quit() { while !tui.quit() {
tui.update(&mut app, interval)?; if update {
self.terminal.raw_mut().draw(|frame| {
self.terminal.raw_mut().draw(|frame| { tui.view(&mut app, frame);
tui.view(&mut app, frame); })?;
})?; }
update = tui.update(&mut app)?;
} }
Ok(()) Ok(())