use anyhow::Result;
use crossterm::event::{self, Event, KeyCode, KeyEvent, KeyModifiers};
use std::time::Duration;
use tracing::debug;
use super::app::{App, ViewMode};
pub async fn handle_events(app: &mut App) -> Result<bool> {
static mut LAST_UPDATE: Option<std::time::Instant> = None;
let now = std::time::Instant::now();
unsafe {
if LAST_UPDATE.is_none_or(|last| now.duration_since(last).as_secs() >= 2) {
if let Err(e) = app.update_daemon_status().await {
debug!("Failed to update daemon status: {}", e);
}
LAST_UPDATE = Some(now);
}
}
if event::poll(Duration::from_millis(100))? {
match event::read()? {
Event::Key(key_event) => {
return handle_key_event(app, key_event).await;
}
Event::Mouse(_) => {
}
Event::Resize(_, _) => {
debug!("Terminal resized");
}
_ => {}
}
}
Ok(false) }
async fn handle_key_event(app: &mut App, key: KeyEvent) -> Result<bool> {
if handle_global_keys(app, &key).await? {
return Ok(true); }
match app.view_mode {
ViewMode::Browse => handle_browse_keys(app, &key).await?,
ViewMode::Preview => handle_preview_keys(app, &key).await?,
ViewMode::Help => handle_help_keys(app, &key).await?,
}
Ok(false)
}
async fn handle_global_keys(app: &mut App, key: &KeyEvent) -> Result<bool> {
match (key.modifiers, key.code) {
(KeyModifiers::CONTROL, KeyCode::Char('c')) => {
app.quit();
return Ok(true);
}
(KeyModifiers::NONE, KeyCode::Char('q')) => {
if app.view_mode == ViewMode::Browse {
app.quit();
return Ok(true);
}
}
(KeyModifiers::NONE, KeyCode::Esc) => {
if app.view_mode != ViewMode::Browse {
app.set_view_mode(ViewMode::Browse);
}
}
(KeyModifiers::NONE, KeyCode::Char('?')) => {
app.set_view_mode(ViewMode::Help);
}
(KeyModifiers::NONE, KeyCode::Char('c')) => {
if app.view_mode == ViewMode::Browse {
app.clear_messages();
}
}
_ => {}
}
Ok(false)
}
async fn handle_browse_keys(app: &mut App, key: &KeyEvent) -> Result<()> {
match key.code {
KeyCode::Char('j') | KeyCode::Down => {
app.select_next();
debug!("Selected wallpaper: {}/{}", app.selected + 1, app.wallpapers.len());
}
KeyCode::Char('k') | KeyCode::Up => {
app.select_previous();
debug!("Selected wallpaper: {}/{}", app.selected + 1, app.wallpapers.len());
}
KeyCode::Char('J') => {
for _ in 0..10 {
app.select_next();
}
}
KeyCode::Char('K') => {
for _ in 0..10 {
app.select_previous();
}
}
KeyCode::Char('g') => {
app.selected = 0;
app.request_thumbnail();
debug!("Jumped to first wallpaper");
}
KeyCode::Char('G') => {
if !app.wallpapers.is_empty() {
app.selected = app.wallpapers.len() - 1;
app.request_thumbnail();
debug!("Jumped to last wallpaper");
}
}
KeyCode::Enter | KeyCode::Char(' ') => {
app.apply_selected_wallpaper().await?;
}
KeyCode::Char('p') => {
app.set_view_mode(ViewMode::Preview);
}
KeyCode::Char('e') => {
app.open_editor = true;
}
KeyCode::Char('r') => {
app.status_message = Some("Refreshing wallpapers...".to_string());
app.refresh_wallpapers().await?;
}
KeyCode::Char('q') => {
app.quit();
}
_ => {}
}
Ok(())
}
async fn handle_preview_keys(app: &mut App, key: &KeyEvent) -> Result<()> {
match key.code {
KeyCode::Char('j') | KeyCode::Down => {
app.select_next();
}
KeyCode::Char('k') | KeyCode::Up => {
app.select_previous();
}
KeyCode::Enter | KeyCode::Char(' ') => {
app.apply_selected_wallpaper().await?;
}
KeyCode::Char('b') | KeyCode::Esc => {
app.set_view_mode(ViewMode::Browse);
}
_ => {}
}
Ok(())
}
async fn handle_help_keys(_app: &mut App, key: &KeyEvent) -> Result<()> {
if key.code == KeyCode::Esc {
}
Ok(())
}