148 lines · 5.4 KB · Rust
RawDownload
use std::sync::Arc; use anyhow::anyhow;use auto_update::{AutoUpdateStatus, AutoUpdater, UpdateCheckType, VersionCheckType};use gpui::{Empty, Render};use semver::Version;use ui::{UpdateButton, prelude::*}; pub struct UpdateVersion {    status: AutoUpdateStatus,    update_check_type: UpdateCheckType,    dismissed: bool,} impl UpdateVersion {    pub fn new(cx: &mut Context<Self>) -> Self {        if let Some(auto_updater) = AutoUpdater::get(cx) {            cx.observe(&auto_updater, |this, auto_update, cx| {                this.status = auto_update.read(cx).status();                this.update_check_type = auto_update.read(cx).update_check_type();                if this.status.is_updated() {                    this.dismissed = false;                }            })            .detach();            Self {                status: auto_updater.read(cx).status(),                update_check_type: UpdateCheckType::Automatic,                dismissed: false,            }        } else {            Self {                status: AutoUpdateStatus::Idle,                update_check_type: UpdateCheckType::Automatic,                dismissed: false,            }        }    }     pub fn update_simulation(&mut self, cx: &mut Context<Self>) {        let next_state = match self.status {            AutoUpdateStatus::Idle => AutoUpdateStatus::Checking,            AutoUpdateStatus::Checking => AutoUpdateStatus::Downloading {                version: VersionCheckType::Semantic(Version::new(1, 99, 0)),            },            AutoUpdateStatus::Downloading { .. } => AutoUpdateStatus::Installing {                version: VersionCheckType::Semantic(Version::new(1, 99, 0)),            },            AutoUpdateStatus::Installing { .. } => AutoUpdateStatus::Updated {                version: VersionCheckType::Semantic(Version::new(1, 99, 0)),            },            AutoUpdateStatus::Updated { .. } => AutoUpdateStatus::Errored {                error: Arc::new(anyhow!("Network timeout")),            },            AutoUpdateStatus::Errored { .. } => AutoUpdateStatus::Idle,        };         self.status = next_state;        self.update_check_type = UpdateCheckType::Manual;        self.dismissed = false;        cx.notify()    }     pub fn show_update_in_menu_bar(&self) -> bool {        self.dismissed && self.status.is_updated()    }     fn version_tooltip_message(version: &VersionCheckType) -> String {        format!("Version: {}", {            match version {                VersionCheckType::Sha(sha) => format!("{}…", sha.short()),                VersionCheckType::Semantic(semantic_version) => semantic_version.to_string(),            }        })    }} impl Render for UpdateVersion {    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {        if self.dismissed {            return Empty.into_any_element();        }        match &self.status {            AutoUpdateStatus::Checking if self.update_check_type.is_manual() => {                UpdateButton::checking().into_any_element()            }            AutoUpdateStatus::Downloading { version } if self.update_check_type.is_manual() => {                let tooltip = Self::version_tooltip_message(&version);                UpdateButton::downloading(tooltip).into_any_element()            }            AutoUpdateStatus::Installing { version } if self.update_check_type.is_manual() => {                let tooltip = Self::version_tooltip_message(&version);                UpdateButton::installing(tooltip).into_any_element()            }            AutoUpdateStatus::Updated { version } => {                let tooltip = Self::version_tooltip_message(&version);                UpdateButton::updated(tooltip)                    .on_click(|_, _, cx| {                        workspace::reload(cx);                    })                    .on_dismiss(cx.listener(|this, _, _window, cx| {                        this.dismissed = true;                        cx.notify()                    }))                    .into_any_element()            }            AutoUpdateStatus::Errored { error } => {                let error_str = error.to_string();                UpdateButton::errored(error_str)                    .on_click(|_, window, cx| {                        window.dispatch_action(Box::new(workspace::OpenLog), cx);                    })                    .on_dismiss(cx.listener(|this, _, _window, cx| {                        this.dismissed = true;                        cx.notify()                    }))                    .into_any_element()            }            AutoUpdateStatus::Idle            | AutoUpdateStatus::Checking { .. }            | AutoUpdateStatus::Downloading { .. }            | AutoUpdateStatus::Installing { .. } => Empty.into_any_element(),        }    }}#[cfg(test)]mod tests {    use auto_update::VersionCheckType;    use release_channel::AppCommitSha;    use semver::Version;     use super::*;     #[test]    fn test_version_tooltip_message() {        let message = UpdateVersion::version_tooltip_message(&VersionCheckType::Semantic(            Version::new(1, 0, 0),        ));         assert_eq!(message, "Version: 1.0.0");         let message = UpdateVersion::version_tooltip_message(&VersionCheckType::Sha(            AppCommitSha::new("14d9a4189f058d8736339b06ff2340101eaea5af".to_string()),        ));         assert_eq!(message, "Version: 14d9a41…");    }}