auto_update: Add title bar feedback when Zed is already up to date (#64106)
# Objective A manual "check for updates" that finds no newer version left the updater back at `Idle`, so the "Checking for Zed Updates…" indicator in the title bar simply vanished with no confirmation that the check had succeeded. ## Solution Track that transition in `UpdateVersion` and show an "Up to Date" button in its place for a few seconds. The timer is stored as a task on the view, so it is cancelled when the view is dropped or a new update state arrives. `restart_after_wake` passed through `Idle` before re-polling, which would read as a completed check; it now stays in `Checking`. ## Testing - Did you test these changes? If so, how? **Tested by running Zed in preview channel.** - Are there any parts that need more testing? **No** - How can other people (reviewers) test your changes? Is there anything specific they need to know? **Use `ZED_RELEASE_CHANNEL=preview cargo run` to open Zed. Then manually trigger a check within menu `Zed -> Check for Updates`.** - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? **Tested only on MacOS Tahoe** ## Self-Review Checklist: - [x] I've reviewed my own diff for quality, security, and reliability - [ ] Unsafe blocks (if any) have justifying comments - [x] The content adheres to Zed's UI standards ([UX/UI](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist) and [icon](https://github.com/zed-industries/zed/blob/main/crates/icons/README.md) guidelines) - [x] Tests cover the new/changed behavior - [x] Performance impact has been considered and is acceptable ## Showcase A visual demo of what happens in title_bar when a manual check for updates is triggered. https://github.com/user-attachments/assets/23b72bf2-6188-4eae-82b9-1c5b70782bb4 --- Release Notes: - Added confirmation in the title bar when a manual update check finds Zed is already up to date
This commit is contained in:
1 parent
b664a40042
commit
e57126dcd4
3 files changed
+62
-7
No files matched your search
@@ -3,8 +3,8 @@ use client::Client;
|
||||
use db::kvp::KeyValueStore;
|
||||
use futures_lite::StreamExt;
|
||||
use gpui::{
|
||||
App, AppContext as _, AsyncApp, BackgroundExecutor, Context, Entity, Global, Task, TaskExt,
|
||||
Window, actions,
|
||||
App, AppContext as _, AsyncApp, BackgroundExecutor, Context, Entity, EventEmitter, Global,
|
||||
Task, TaskExt, Window, actions,
|
||||
};
|
||||
use http_client::{HttpClient, HttpClientWithUrl};
|
||||
use paths::remote_servers_dir;
|
||||
@@ -173,6 +173,11 @@ impl AutoUpdateStatus {
|
||||
}
|
||||
}
|
||||
|
||||
pub enum AutoUpdateEvent {
|
||||
/// A manual check received a release response and found no newer version.
|
||||
UpToDate,
|
||||
}
|
||||
|
||||
pub struct AutoUpdater {
|
||||
status: AutoUpdateStatus,
|
||||
current_version: Version,
|
||||
@@ -419,6 +424,8 @@ impl UpdateCheckType {
|
||||
}
|
||||
}
|
||||
|
||||
impl EventEmitter<AutoUpdateEvent> for AutoUpdater {}
|
||||
|
||||
impl AutoUpdater {
|
||||
pub fn get(cx: &mut App) -> Option<Entity<Self>> {
|
||||
cx.default_global::<GlobalAutoUpdate>().0.clone()
|
||||
@@ -763,11 +770,15 @@ impl AutoUpdater {
|
||||
|
||||
let Some(newer_version) = newer_version else {
|
||||
this.update(cx, |this, cx| {
|
||||
let status = match previous_status {
|
||||
this.status = match previous_status {
|
||||
AutoUpdateStatus::Updated { .. } => previous_status,
|
||||
_ => AutoUpdateStatus::Idle,
|
||||
_ => {
|
||||
if this.update_check_type.is_manual() {
|
||||
cx.emit(AutoUpdateEvent::UpToDate);
|
||||
}
|
||||
AutoUpdateStatus::Idle
|
||||
}
|
||||
};
|
||||
this.status = status;
|
||||
cx.notify();
|
||||
});
|
||||
return Ok(());
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use auto_update::{AutoUpdateStatus, AutoUpdater, UpdateCheckType};
|
||||
use gpui::{Empty, Render};
|
||||
use auto_update::{AutoUpdateEvent, AutoUpdateStatus, AutoUpdater, UpdateCheckType};
|
||||
use gpui::{Empty, Render, Task};
|
||||
use semver::Version;
|
||||
use ui::{Tooltip, UpdateButton, prelude::*};
|
||||
|
||||
const UP_TO_DATE_DISPLAY_DURATION: Duration = Duration::from_secs(4);
|
||||
|
||||
pub struct UpdateVersion {
|
||||
status: AutoUpdateStatus,
|
||||
update_check_type: UpdateCheckType,
|
||||
dismissed_status: Option<AutoUpdateStatus>,
|
||||
showing_up_to_date: bool,
|
||||
_up_to_date_timer: Option<Task<()>>,
|
||||
}
|
||||
|
||||
impl UpdateVersion {
|
||||
@@ -20,23 +25,53 @@ impl UpdateVersion {
|
||||
this.status = auto_update.status();
|
||||
this.update_check_type = auto_update.update_check_type();
|
||||
this.dismissed_status = auto_update.dismissed_status();
|
||||
if !matches!(this.status, AutoUpdateStatus::Idle) {
|
||||
this.hide_up_to_date();
|
||||
}
|
||||
cx.notify();
|
||||
})
|
||||
.detach();
|
||||
cx.subscribe(&auto_updater, |this, _, event, cx| match event {
|
||||
AutoUpdateEvent::UpToDate => this.show_up_to_date(cx),
|
||||
})
|
||||
.detach();
|
||||
Self {
|
||||
status: auto_updater.read(cx).status(),
|
||||
update_check_type: UpdateCheckType::Automatic,
|
||||
dismissed_status: auto_updater.read(cx).dismissed_status(),
|
||||
showing_up_to_date: false,
|
||||
_up_to_date_timer: None,
|
||||
}
|
||||
} else {
|
||||
Self {
|
||||
status: AutoUpdateStatus::Idle,
|
||||
update_check_type: UpdateCheckType::Automatic,
|
||||
dismissed_status: None,
|
||||
showing_up_to_date: false,
|
||||
_up_to_date_timer: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn show_up_to_date(&mut self, cx: &mut Context<Self>) {
|
||||
self.showing_up_to_date = true;
|
||||
self._up_to_date_timer = Some(cx.spawn(async move |this, cx| {
|
||||
cx.background_executor()
|
||||
.timer(UP_TO_DATE_DISPLAY_DURATION)
|
||||
.await;
|
||||
this.update(cx, |this, cx| {
|
||||
this.hide_up_to_date();
|
||||
cx.notify();
|
||||
})
|
||||
.ok();
|
||||
}));
|
||||
}
|
||||
|
||||
fn hide_up_to_date(&mut self) {
|
||||
self.showing_up_to_date = false;
|
||||
self._up_to_date_timer = None;
|
||||
}
|
||||
|
||||
pub fn update_simulation(&mut self, cx: &mut Context<Self>) {
|
||||
let next_state = match self.status {
|
||||
AutoUpdateStatus::Idle => AutoUpdateStatus::Checking,
|
||||
@@ -59,6 +94,7 @@ impl UpdateVersion {
|
||||
self.status = next_state;
|
||||
self.update_check_type = UpdateCheckType::Manual;
|
||||
self.dismissed_status = None;
|
||||
self.hide_up_to_date();
|
||||
cx.notify()
|
||||
}
|
||||
|
||||
@@ -91,6 +127,9 @@ impl Render for UpdateVersion {
|
||||
if self.is_dismissed() {
|
||||
return Empty.into_any_element();
|
||||
}
|
||||
if self.showing_up_to_date {
|
||||
return UpdateButton::up_to_date().into_any_element();
|
||||
}
|
||||
match &self.status {
|
||||
AutoUpdateStatus::Checking if self.update_check_type.is_manual() => {
|
||||
UpdateButton::checking().into_any_element()
|
||||
|
||||
@@ -118,6 +118,10 @@ impl UpdateButton {
|
||||
.disabled(true)
|
||||
}
|
||||
|
||||
pub fn up_to_date() -> Self {
|
||||
Self::new(IconName::Check, "Up to Date").disabled(true)
|
||||
}
|
||||
|
||||
pub fn updated(version: impl Into<SharedString>) -> Self {
|
||||
Self::new(IconName::Download, "Restart to Update")
|
||||
.tooltip(version)
|
||||
@@ -254,6 +258,7 @@ impl Component for UpdateButton {
|
||||
"Installing",
|
||||
UpdateButton::installing(version).into_any_element(),
|
||||
),
|
||||
single_example("Up to Date", UpdateButton::up_to_date().into_any_element()),
|
||||
],
|
||||
),
|
||||
example_group_with_title(
|
||||
|
||||
Reference in new issue
Block a user