use zellij_utils::async_std::task; use zellij_utils::errors::{prelude::*, BackgroundJobContext, ContextType}; use std::collections::HashMap; use std::time::{Duration, Instant}; use crate::panes::PaneId; use crate::screen::ScreenInstruction; use crate::thread_bus::Bus; #[derive(Debug, Clone, Eq, PartialEq, Hash)] pub enum BackgroundJob { DisplayPaneError(Vec, String), Exit, } impl From<&BackgroundJob> for BackgroundJobContext { fn from(background_job: &BackgroundJob) -> Self { match *background_job { BackgroundJob::DisplayPaneError(..) => BackgroundJobContext::DisplayPaneError, BackgroundJob::Exit => BackgroundJobContext::Exit, } } } static FLASH_DURATION_MS: u64 = 1000; pub(crate) fn background_jobs_main(bus: Bus) -> Result<()> { let err_context = || "failed to write to pty".to_string(); let mut running_jobs: HashMap = HashMap::new(); loop { let (event, mut err_ctx) = bus.recv().with_context(err_context)?; err_ctx.add_call(ContextType::BackgroundJob((&event).into())); let job = event.clone(); match event { BackgroundJob::DisplayPaneError(pane_ids, text) => { if job_already_running(job, &mut running_jobs) { continue; } task::spawn({ let senders = bus.senders.clone(); async move { let _ = senders.send_to_screen( ScreenInstruction::AddRedPaneFrameColorOverride( pane_ids.clone(), Some(text), ), ); task::sleep(std::time::Duration::from_millis(FLASH_DURATION_MS)).await; let _ = senders.send_to_screen( ScreenInstruction::ClearPaneFrameColorOverride(pane_ids), ); } }); }, BackgroundJob::Exit => { return Ok(()); }, } } } fn job_already_running( job: BackgroundJob, running_jobs: &mut HashMap, ) -> bool { match running_jobs.get_mut(&job) { Some(current_running_job_start_time) => { if current_running_job_start_time.elapsed() > Duration::from_millis(FLASH_DURATION_MS) { *current_running_job_start_time = Instant::now(); false } else { true } }, None => { running_jobs.insert(job.clone(), Instant::now()); false }, } }