Radish alpha
r
Radicle terminal user interface
Radicle
Git (anonymous pull)
Log in to clone via SSH
tui: Re-render only if message received
Erik Kundt committed 3 years ago
commit 4de821e6c54aa0e921d17b2e944e0097e8825fe4
parent eea29b0d5d82a95373d04b196d7c66f4dc46fc4e
2 files changed +38 -41
modified radicle-tui/src/app.rs
@@ -1,5 +1,3 @@
-
use std::time::Duration;
-

use anyhow::Result;

use tui_realm_stdlib::Phantom;
@@ -69,6 +67,7 @@ pub enum Message {
    Home(HomeMessage),
    Patch(PatchMessage),
    NavigationChanged(u16),
+
    Tick,
    Quit,
}

@@ -147,35 +146,33 @@ impl Tui<Cid, Message> for App {
        self.active_page.as_mut().view(app, frame);
    }

-
    fn update(
-
        &mut self,
-
        app: &mut Application<Cid, Message, NoUserEvent>,
-
        interval: u64,
-
    ) -> Result<()> {
-
        if let Ok(messages) = app.tick(PollStrategy::TryFor(Duration::from_millis(interval))) {
-
            let theme = theme::default_dark();
-
            for message in messages {
-
                match message {
-
                    Message::Home(HomeMessage::Show) => {
-
                        self.mount_home_view(app, &theme)?;
-
                    }
-
                    Message::Patch(PatchMessage::Show(index)) => {
-
                        self.context.selected_patch = index;
-
                        self.mount_patch_view(app, &theme)?;
-
                    }
-
                    Message::Patch(PatchMessage::Leave) => {
-
                        self.mount_home_view(app, &theme)?;
-
                    }
-
                    Message::Quit => self.quit = true,
-
                    _ => {
-
                        self.active_page.update(message);
-
                        self.active_page.activate(app)?;
+
    fn update(&mut self, app: &mut Application<Cid, Message, NoUserEvent>) -> Result<bool> {
+
        match app.tick(PollStrategy::Once) {
+
            Ok(messages) if !messages.is_empty() => {
+
                let theme = theme::default_dark();
+
                for message in messages {
+
                    match message {
+
                        Message::Home(HomeMessage::Show) => {
+
                            self.mount_home_view(app, &theme)?;
+
                        }
+
                        Message::Patch(PatchMessage::Show(index)) => {
+
                            self.context.selected_patch = index;
+
                            self.mount_patch_view(app, &theme)?;
+
                        }
+
                        Message::Patch(PatchMessage::Leave) => {
+
                            self.mount_home_view(app, &theme)?;
+
                        }
+
                        Message::Quit => self.quit = true,
+
                        _ => {
+
                            self.active_page.update(message);
+
                            self.active_page.activate(app)?;
+
                        }
                    }
                }
+
                Ok(true)
            }
+
            _ => Ok(false),
        }
-

-
        Ok(())
    }

    fn quit(&self) -> bool {
@@ -230,7 +227,7 @@ impl ViewPage for Home {
        let navigation = ui::home_navigation(theme).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 shortcuts = ui::shortcuts(
@@ -383,6 +380,7 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<GlobalListener> {
                code: Key::Char('q'),
                ..
            }) => Some(Message::Quit),
+
            Event::WindowResize(_, _) => Some(Message::Tick),
            _ => None,
        }
    }
@@ -409,13 +407,13 @@ impl tuirealm::Component<Message, NoUserEvent> for Widget<Browser<(PatchId, Patc
        match event {
            Event::Keyboard(KeyEvent { code: Key::Up, .. }) => {
                self.perform(Cmd::Move(MoveDirection::Up));
-
                None
+
                Some(Message::Tick)
            }
            Event::Keyboard(KeyEvent {
                code: Key::Down, ..
            }) => {
                self.perform(Cmd::Move(MoveDirection::Down));
-
                None
+
                Some(Message::Tick)
            }
            Event::Keyboard(KeyEvent {
                code: Key::Enter, ..
modified radicle-tui/src/lib.rs
@@ -25,12 +25,9 @@ where
    /// Should initialize an application by mounting and activating components.
    fn init(&mut self, app: &mut Application<Id, Message, NoUserEvent>) -> Result<()>;

-
    /// Should update the current state by handling a message from the view.
-
    fn update(
-
        &mut self,
-
        app: &mut Application<Id, Message, NoUserEvent>,
-
        interval: u64,
-
    ) -> Result<()>;
+
    /// Should update the current state by handling a message from the view. Returns true
+
    /// if view should be updated (e.g. a message was received and the current state changed).
+
    fn update(&mut self, app: &mut Application<Id, Message, NoUserEvent>) -> Result<bool>;

    /// Should draw the application to a 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,
        Message: Eq,
    {
+
        let mut update = true;
        let mut app = Application::init(
            EventListenerCfg::default().default_input_listener(Duration::from_millis(interval)),
        );
        tui.init(&mut app)?;

        while !tui.quit() {
-
            tui.update(&mut app, interval)?;
-

-
            self.terminal.raw_mut().draw(|frame| {
-
                tui.view(&mut app, frame);
-
            })?;
+
            if update {
+
                self.terminal.raw_mut().draw(|frame| {
+
                    tui.view(&mut app, frame);
+
                })?;
+
            }
+
            update = tui.update(&mut app)?;
        }

        Ok(())