aboutsummaryrefslogtreecommitdiff
path: root/src/app
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-03-31 14:23:14 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-03-31 14:23:14 +0300
commit7c8f12e8f2656d239a029552bc042bf44efdcf41 (patch)
tree3c6ac99c9304de1f30876b4d0c5f1645e91c8430 /src/app
parentb2293687afa4ba268eac98bf885bf6e5a5133180 (diff)
feat: poll for updates and show toast notifications
Diffstat (limited to 'src/app')
-rw-r--r--src/app/actions.rs10
-rw-r--r--src/app/mod.rs29
-rw-r--r--src/app/state.rs1
3 files changed, 38 insertions, 2 deletions
diff --git a/src/app/actions.rs b/src/app/actions.rs
index 6c42b966..02c25d64 100644
--- a/src/app/actions.rs
+++ b/src/app/actions.rs
@@ -197,8 +197,13 @@ impl AppState {
match event {
AppEvent::PaneDied { pane_id } => self.handle_pane_died(pane_id),
AppEvent::UpdateReady { version } => {
- self.update_available = Some(version);
- self.update_dismissed = false;
+ self.update_available = Some(version.clone());
+ self.update_dismissed = true;
+ self.toast = Some(ToastNotification {
+ kind: ToastKind::UpdateInstalled,
+ title: format!("updated to v{version}"),
+ context: "restart to use it".to_string(),
+ });
}
AppEvent::StateChanged {
pane_id,
@@ -240,6 +245,7 @@ impl AppState {
let event_text = match kind {
ToastKind::NeedsAttention => "needs attention",
ToastKind::Finished => "finished",
+ ToastKind::UpdateInstalled => "updated",
};
self.toast = Some(ToastNotification {
kind,
diff --git a/src/app/mod.rs b/src/app/mod.rs
index 82c3777a..928ed2aa 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -18,6 +18,7 @@ const MIN_RENDER_INTERVAL: Duration = Duration::from_millis(16);
const ANIMATION_INTERVAL: Duration = Duration::from_millis(16);
const RESIZE_POLL_INTERVAL: Duration = Duration::from_millis(100);
const GIT_REMOTE_STATUS_REFRESH_INTERVAL: Duration = Duration::from_millis(1500);
+const AUTO_UPDATE_CHECK_INTERVAL: Duration = Duration::from_secs(30 * 60);
const SIDEBAR_DOUBLE_CLICK_WINDOW: Duration = Duration::from_millis(350);
use crossterm::terminal;
@@ -49,6 +50,7 @@ pub struct App {
last_sidebar_divider_click: Option<Instant>,
next_resize_poll: Instant,
next_animation_tick: Option<Instant>,
+ next_auto_update_check: Option<Instant>,
last_render_at: Option<Instant>,
render_notify: Arc<Notify>,
render_dirty: Arc<AtomicBool>,
@@ -226,6 +228,7 @@ impl App {
}
// Background auto-update (skipped in --no-session / test mode)
+ // Check once at startup, then periodically from the main loop.
if !no_session {
let update_tx = event_tx.clone();
std::thread::spawn(move || crate::update::auto_update(update_tx));
@@ -251,6 +254,8 @@ impl App {
last_sidebar_divider_click: None,
next_resize_poll: Instant::now() + RESIZE_POLL_INTERVAL,
next_animation_tick: None,
+ next_auto_update_check: (!no_session)
+ .then_some(Instant::now() + AUTO_UPDATE_CHECK_INTERVAL),
last_render_at: None,
api_rx,
event_hub,
@@ -487,6 +492,13 @@ impl App {
changed = true;
}
+ if self
+ .next_auto_update_check
+ .is_some_and(|deadline| now >= deadline)
+ {
+ self.run_auto_update_check();
+ }
+
self.sync_animation_timer(now);
changed
}
@@ -514,6 +526,21 @@ impl App {
}
}
+ fn run_auto_update_check(&mut self) {
+ self.next_auto_update_check = self
+ .state
+ .update_available
+ .is_none()
+ .then_some(Instant::now() + AUTO_UPDATE_CHECK_INTERVAL);
+
+ if self.state.update_available.is_some() {
+ return;
+ }
+
+ let update_tx = self.event_tx.clone();
+ std::thread::spawn(move || crate::update::auto_update(update_tx));
+ }
+
fn git_refresh_deadline(&self) -> Option<Instant> {
(!self.state.workspaces.is_empty())
.then_some(self.last_git_remote_status_refresh + GIT_REMOTE_STATUS_REFRESH_INTERVAL)
@@ -534,6 +561,7 @@ impl App {
self.toast_deadline,
self.next_animation_tick,
self.git_refresh_deadline(),
+ self.next_auto_update_check,
render_deadline,
]
.into_iter()
@@ -606,6 +634,7 @@ impl App {
let duration = match toast.kind {
ToastKind::NeedsAttention => Duration::from_secs(8),
ToastKind::Finished => Duration::from_secs(5),
+ ToastKind::UpdateInstalled => Duration::from_secs(3),
};
Instant::now() + duration
});
diff --git a/src/app/state.rs b/src/app/state.rs
index bee6c262..caedb419 100644
--- a/src/app/state.rs
+++ b/src/app/state.rs
@@ -438,6 +438,7 @@ impl ContextMenuState {
pub enum ToastKind {
NeedsAttention,
Finished,
+ UpdateInstalled,
}
#[derive(Debug, Clone, PartialEq, Eq)]