update
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
#![cfg(not(target_arch = "wasm32"))]
|
||||
|
||||
use gpui::{App, AppContext, Context, Entity, Global, Subscription, Window};
|
||||
use gpui::{App, AppContext, Context, Entity, Global, SharedString, Subscription, Window};
|
||||
use gpui_updater::{EngineConfig, GitHubSource, UpdateStatus, Updater, Version};
|
||||
use instant::Duration;
|
||||
use instant::{Duration, Instant};
|
||||
|
||||
const COOP_UPDATE_EXPLANATION: &str = "COOP_UPDATE_EXPLANATION";
|
||||
|
||||
@@ -52,6 +52,8 @@ pub struct AutoUpdater {
|
||||
pub version: Version,
|
||||
/// Keeps the observer subscription alive.
|
||||
_subscription: Subscription,
|
||||
/// When the last error was recorded, so we can reset to idle after 5s.
|
||||
error_time: Option<Instant>,
|
||||
}
|
||||
|
||||
impl AutoUpdater {
|
||||
@@ -83,11 +85,24 @@ impl AutoUpdater {
|
||||
// When an update becomes available, automatically download and install it.
|
||||
let subscription = cx.observe(&updater, |this: &mut AutoUpdater, _updater, cx| {
|
||||
let status = this.updater.read(cx).status().clone();
|
||||
|
||||
if matches!(status, UpdateStatus::Available(_)) {
|
||||
this.updater.update(cx, |updater, cx| {
|
||||
updater.download_and_install(cx);
|
||||
});
|
||||
}
|
||||
|
||||
if matches!(status, UpdateStatus::Errored(_)) {
|
||||
this.error_time = Some(Instant::now());
|
||||
cx.spawn(async move |this, cx| {
|
||||
cx.background_executor().timer(Duration::from_secs(5)).await;
|
||||
this.update(cx, |_this, cx| cx.notify()).ok();
|
||||
})
|
||||
.detach();
|
||||
} else {
|
||||
this.error_time = None;
|
||||
}
|
||||
|
||||
cx.notify();
|
||||
});
|
||||
|
||||
@@ -111,6 +126,55 @@ impl AutoUpdater {
|
||||
updater,
|
||||
version,
|
||||
_subscription: subscription,
|
||||
error_time: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn idle(&self, cx: &App) -> bool {
|
||||
let status = self.updater.read(cx).status();
|
||||
if status == &UpdateStatus::Idle {
|
||||
return true;
|
||||
}
|
||||
if matches!(status, UpdateStatus::Errored(_))
|
||||
&& self
|
||||
.error_time
|
||||
.is_some_and(|t| t.elapsed() >= Duration::from_secs(5))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
pub fn status(&self, cx: &App) -> SharedString {
|
||||
let status = self.updater.read(cx).status();
|
||||
|
||||
match status {
|
||||
UpdateStatus::Idle => "Up to date".into(),
|
||||
UpdateStatus::Checking => "Checking for updates…".into(),
|
||||
UpdateStatus::UpToDate => "Up to date".into(),
|
||||
UpdateStatus::Available(version) => format!("Version {version} available").into(),
|
||||
UpdateStatus::Downloading { downloaded, total } => {
|
||||
let total_mb = total.map(|t| t as f64 / 1_048_576.0);
|
||||
let downloaded_mb = *downloaded as f64 / 1_048_576.0;
|
||||
match total_mb {
|
||||
Some(t) => format!("Downloading {downloaded_mb:.1} / {t:.1} MB").into(),
|
||||
None => format!("Downloading {downloaded_mb:.1} MB").into(),
|
||||
}
|
||||
}
|
||||
UpdateStatus::Installing => "Installing update…".into(),
|
||||
UpdateStatus::Staged(version) => {
|
||||
format!("Version {version} ready — restart to apply").into()
|
||||
}
|
||||
UpdateStatus::Errored(msg) => {
|
||||
if self
|
||||
.error_time
|
||||
.is_some_and(|t| t.elapsed() >= Duration::from_secs(5))
|
||||
{
|
||||
"Up to date".into()
|
||||
} else {
|
||||
format!("Update failed: {msg}").into()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user