Skip to content

Commit

Permalink
feat(term): handle terminal focus event
Browse files Browse the repository at this point in the history
  • Loading branch information
ymgyt committed Jun 23, 2024
1 parent 36212b4 commit 27f02a3
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 39 deletions.
9 changes: 0 additions & 9 deletions crates/synd_term/src/application/flags.rs

This file was deleted.

50 changes: 26 additions & 24 deletions crates/synd_term/src/application/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ pub use auth::authenticator::{Authenticator, DeviceFlows, JwtService};
mod clock;
pub(crate) use clock::{Clock, SystemClock};

mod flags;
use flags::Should;

mod cache;
pub use cache::Cache;

Expand All @@ -64,10 +61,9 @@ pub use app_config::Config;

pub(crate) mod event;

enum Screen {
Login,
Browse,
}
mod state;
pub(crate) use state::TerminalFocus;
use state::{Should, State};

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Populate {
Expand All @@ -92,8 +88,7 @@ pub struct Application {
categories: Categories,
latest_release: Option<Version>,

screen: Screen,
flags: Should,
state: State,
}

impl Application {
Expand Down Expand Up @@ -128,6 +123,10 @@ impl Application {
key_handlers.push(event::KeyHandler::Keymaps(keymaps));
key_handlers
};
let mut state = State::new();
if dry_run {
state.flags = Should::Quit;
}

Self {
clock: Box::new(SystemClock),
Expand All @@ -141,16 +140,11 @@ impl Application {
cache,
theme,
idle_timer: Box::pin(tokio::time::sleep(config.idle_timer_interval)),
screen: Screen::Login,
config,
key_handlers,
categories,
latest_release: None,
flags: if dry_run {
Should::Quit
} else {
Should::empty()
},
state,
}
}

Expand Down Expand Up @@ -185,7 +179,7 @@ impl Application {
match self.terminal.init() {
Ok(()) => Ok(()),
Err(err) => {
if self.flags.contains(Should::Quit) {
if self.state.flags.contains(Should::Quit) {
tracing::warn!("Failed to init terminal: {err}");
Ok(())
} else {
Expand Down Expand Up @@ -220,7 +214,6 @@ impl Application {
self.keymaps().enable(KeymapId::Tabs);
self.keymaps().enable(KeymapId::Entries);
self.keymaps().enable(KeymapId::Filter);
self.screen = Screen::Browse;
self.reset_idle_timer();
self.should_render();
}
Expand Down Expand Up @@ -292,14 +285,14 @@ impl Application {
self.apply(command);
}

if self.flags.contains(Should::Render) {
if self.state.flags.contains(Should::Render) {
self.render();
self.flags.remove(Should::Render);
self.state.flags.remove(Should::Render);
self.components.prompt.clear_error_message();
}

if self.flags.contains(Should::Quit) {
self.flags.remove(Should::Quit); // for testing
if self.state.flags.contains(Should::Quit) {
self.state.flags.remove(Should::Quit); // for testing
break ControlFlow::Break(());
}
}
Expand All @@ -313,7 +306,7 @@ impl Application {
while let Some(command) = next.take() {
match command {
Command::Nop => {}
Command::Quit => self.flags.insert(Should::Quit),
Command::Quit => self.state.flags.insert(Should::Quit),
Command::ResizeTerminal { .. } => {
self.should_render();
}
Expand Down Expand Up @@ -632,14 +625,15 @@ impl Application {

#[inline]
fn should_render(&mut self) {
self.flags.insert(Should::Render);
self.state.flags.insert(Should::Render);
}

fn render(&mut self) {
let cx = ui::Context {
theme: &self.theme,
in_flight: &self.in_flight,
categories: &self.categories,
focus: self.state.focus(),
};
let root = Root::new(&self.components, cx);

Expand All @@ -654,6 +648,14 @@ impl Application {
_columns: columns,
_rows: rows,
}),
CrosstermEvent::FocusGained => {
self.should_render();
self.state.focus_gained()
}
CrosstermEvent::FocusLost => {
self.should_render();
self.state.focus_lost()
}
CrosstermEvent::Key(KeyEvent {
kind: KeyEventKind::Release,
..
Expand Down Expand Up @@ -1001,7 +1003,7 @@ impl Application {
#[cfg(feature = "integration")]
{
tracing::debug!("Quit for idle");
self.flags.insert(Should::Quit);
self.state.flags.insert(Should::Quit);
}
}

Expand Down
45 changes: 45 additions & 0 deletions crates/synd_term/src/application/state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
use crate::command::Command;

use bitflags::bitflags;

bitflags! {
pub(super) struct Should: u64 {
const Render = 1 << 0;
const Quit = 1 << 1;

}
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub(crate) enum TerminalFocus {
Gained,
Lost,
}

pub(super) struct State {
pub(super) flags: Should,
focus: TerminalFocus,
}

impl State {
pub(super) fn new() -> Self {
Self {
flags: Should::empty(),
focus: TerminalFocus::Gained,
}
}

pub(super) fn focus(&self) -> TerminalFocus {
self.focus
}

pub(super) fn focus_gained(&mut self) -> Option<Command> {
self.focus = TerminalFocus::Gained;
None
}

pub(super) fn focus_lost(&mut self) -> Option<Command> {
self.focus = TerminalFocus::Lost;
None
}
}
4 changes: 2 additions & 2 deletions crates/synd_term/src/terminal/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crossterm::{
event::EventStream,
event::{EnableFocusChange, EventStream},
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
ExecutableCommand,
};
Expand Down Expand Up @@ -36,7 +36,7 @@ impl Terminal {
/// Initialize terminal
pub fn init(&mut self) -> io::Result<()> {
terminal::enable_raw_mode()?;
crossterm::execute!(io::stdout(), EnterAlternateScreen)?;
crossterm::execute!(io::stdout(), EnterAlternateScreen, EnableFocusChange)?;

let panic_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |panic| {
Expand Down
7 changes: 6 additions & 1 deletion crates/synd_term/src/ui/components/entries.rs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,12 @@ impl Entries {
.header(header.style(cx.theme.entries.header))
.column_spacing(2)
.highlight_symbol(ui::TABLE_HIGHLIGHT_SYMBOL)
.highlight_style(cx.theme.entries.selected_entry)
.highlight_style(
cx.theme
.entries
.selected_entry
.add_modifier(cx.table_highlight_modifier()),
)
.highlight_spacing(ratatui::widgets::HighlightSpacing::WhenSelected);

StatefulWidget::render(entries, entries_area, buf, &mut entries_state);
Expand Down
7 changes: 6 additions & 1 deletion crates/synd_term/src/ui/components/subscription.rs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,12 @@ impl Subscription {
.column_spacing(2)
.style(cx.theme.subscription.background)
.highlight_symbol(ui::TABLE_HIGHLIGHT_SYMBOL)
.highlight_style(cx.theme.subscription.selected_feed)
.highlight_style(
cx.theme
.subscription
.selected_feed
.add_modifier(cx.table_highlight_modifier()),
)
.highlight_spacing(HighlightSpacing::WhenSelected);

StatefulWidget::render(feeds, feeds_area, buf, &mut feeds_state);
Expand Down
14 changes: 12 additions & 2 deletions crates/synd_term/src/ui/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use std::{str::FromStr, sync::OnceLock};

use ratatui::style::Color;
use ratatui::style::{Color, Modifier};
use synd_feed::types::{Category, Requirement};

use crate::{
application::InFlight,
application::{InFlight, TerminalFocus},
config::{Categories, Icon, IconColor},
ui::theme::Theme,
};
Expand Down Expand Up @@ -39,6 +39,16 @@ pub struct Context<'a> {
pub theme: &'a Theme,
pub in_flight: &'a InFlight,
pub categories: &'a Categories,
pub(crate) focus: TerminalFocus,
}

impl<'a> Context<'a> {
fn table_highlight_modifier(&self) -> Modifier {
match self.focus {
TerminalFocus::Gained => Modifier::empty(),
TerminalFocus::Lost => Modifier::DIM,
}
}
}

#[cfg(test)]
Expand Down

0 comments on commit 27f02a3

Please sign in to comment.