Skip to repository content

tenant.openagents/omega

No repository description is available.

OpenAgents Git authority 2026-07-28T04:08:05.264Z Public web read
NIP-34 coordinate30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omega
MaintainersHidden in public view
References2 branches · 1 tag
Read-only clonegit clone https://openagents.com/git/tenant.openagents/omega.git
Browse files

update_version.rs

178 lines · 6.7 KB · rust
1use std::sync::Arc;
2
3use anyhow::anyhow;
4use auto_update::{AutoUpdateStatus, AutoUpdater, UpdateCheckType};
5use gpui::{Empty, Render};
6use semver::Version;
7use ui::{Tooltip, UpdateButton, prelude::*};
8
9pub struct UpdateVersion {
10    status: AutoUpdateStatus,
11    update_check_type: UpdateCheckType,
12    dismissed_status: Option<AutoUpdateStatus>,
13}
14
15impl UpdateVersion {
16    pub fn new(cx: &mut Context<Self>) -> Self {
17        if let Some(auto_updater) = AutoUpdater::get(cx) {
18            cx.observe(&auto_updater, |this, auto_update, cx| {
19                let auto_update = auto_update.read(cx);
20                this.status = auto_update.status();
21                this.update_check_type = auto_update.update_check_type();
22                this.dismissed_status = auto_update.dismissed_status();
23                cx.notify();
24            })
25            .detach();
26            Self {
27                status: auto_updater.read(cx).status(),
28                update_check_type: UpdateCheckType::Automatic,
29                dismissed_status: auto_updater.read(cx).dismissed_status(),
30            }
31        } else {
32            Self {
33                status: AutoUpdateStatus::Idle,
34                update_check_type: UpdateCheckType::Automatic,
35                dismissed_status: None,
36            }
37        }
38    }
39
40    pub fn update_simulation(&mut self, cx: &mut Context<Self>) {
41        let next_state = match self.status {
42            AutoUpdateStatus::Idle => AutoUpdateStatus::Checking,
43            AutoUpdateStatus::Checking => AutoUpdateStatus::Downloading {
44                version: Version::new(1, 99, 0),
45                progress: Some(0.5),
46            },
47            AutoUpdateStatus::Downloading { .. } => AutoUpdateStatus::Installing {
48                version: Version::new(1, 99, 0),
49            },
50            AutoUpdateStatus::Installing { .. } => AutoUpdateStatus::Updated {
51                version: Version::new(1, 99, 0),
52            },
53            AutoUpdateStatus::Updated { .. } => AutoUpdateStatus::Errored {
54                error: Arc::new(anyhow!("Network timeout")),
55            },
56            AutoUpdateStatus::Errored { .. } => AutoUpdateStatus::Idle,
57        };
58
59        self.status = next_state;
60        self.update_check_type = UpdateCheckType::Manual;
61        self.dismissed_status = None;
62        cx.notify()
63    }
64
65    pub fn show_update_in_menu_bar(&self) -> bool {
66        self.is_dismissed() && self.status.is_updated()
67    }
68
69    fn is_dismissed(&self) -> bool {
70        self.dismissed_status.as_ref() == Some(&self.status)
71    }
72
73    fn dismiss(&mut self, cx: &mut Context<Self>) {
74        self.dismissed_status = Some(self.status.clone());
75        if let Some(auto_updater) = AutoUpdater::get(cx) {
76            let status = self.status.clone();
77            auto_updater.update(cx, |auto_updater, cx| {
78                auto_updater.dismiss_status(status, cx)
79            });
80        }
81        cx.notify()
82    }
83
84    fn version_tooltip_message(version: &Version) -> String {
85        UpdateButton::version_tooltip_message(version)
86    }
87}
88
89impl Render for UpdateVersion {
90    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
91        if self.is_dismissed() {
92            return Empty.into_any_element();
93        }
94        match &self.status {
95            AutoUpdateStatus::Checking if self.update_check_type.is_manual() => {
96                UpdateButton::checking().into_any_element()
97            }
98            AutoUpdateStatus::Downloading { version, progress } => {
99                let rendered_version = version.clone();
100                let tooltip = Tooltip::element(move |_, cx| {
101                    let status = AutoUpdater::get(cx).map(|updater| updater.read(cx).status());
102                    let message = match &status {
103                        Some(AutoUpdateStatus::Downloading { version, progress }) => {
104                            UpdateButton::downloading_tooltip_message(version, *progress)
105                        }
106                        _ => Self::version_tooltip_message(&rendered_version),
107                    };
108                    Label::new(message).into_any_element()
109                });
110                UpdateButton::downloading(*progress)
111                    .tooltip_fn(tooltip)
112                    .into_any_element()
113            }
114            AutoUpdateStatus::Installing { version } => {
115                let version = Self::version_tooltip_message(version);
116                UpdateButton::installing(version).into_any_element()
117            }
118            AutoUpdateStatus::Updated { version } => {
119                let version = Self::version_tooltip_message(version);
120                UpdateButton::updated(version)
121                    .on_click(|_, _, cx| {
122                        workspace::reload(cx);
123                    })
124                    .on_dismiss(cx.listener(|this, _, _window, cx| this.dismiss(cx)))
125                    .into_any_element()
126            }
127            AutoUpdateStatus::Errored { error } => {
128                let error_str = error.to_string();
129                UpdateButton::errored(error_str)
130                    .on_click(|_, window, cx| {
131                        window.dispatch_action(Box::new(workspace::OpenLog), cx);
132                    })
133                    .on_dismiss(cx.listener(|this, _, _window, cx| this.dismiss(cx)))
134                    .into_any_element()
135            }
136            AutoUpdateStatus::Idle | AutoUpdateStatus::Checking { .. } => Empty.into_any_element(),
137        }
138    }
139}
140#[cfg(test)]
141mod tests {
142    use semver::Version;
143
144    use super::*;
145
146    #[test]
147    fn test_version_tooltip_message() {
148        let message = UpdateVersion::version_tooltip_message(&Version::new(1, 0, 0));
149
150        assert_eq!(message, "Update to Version: 1.0.0");
151
152        let message = UpdateVersion::version_tooltip_message(
153            &"1.0.0+nightly.14d9a4189f058d8736339b06ff2340101eaea5af"
154                .parse()
155                .unwrap(),
156        );
157
158        assert_eq!(
159            message,
160            "Update to Version: 1.0.0+nightly.14d9a4189f058d8736339b06ff2340101eaea5af"
161        );
162    }
163
164    #[test]
165    fn test_downloading_tooltip_message() {
166        let version = Version::new(1, 0, 0);
167
168        let message = UpdateButton::downloading_tooltip_message(&version, None);
169        assert_eq!(message, "Update to Version: 1.0.0");
170
171        let message = UpdateButton::downloading_tooltip_message(&version, Some(0.454));
172        assert_eq!(message, "Update to Version: 1.0.0 (45% downloaded)");
173
174        let message = UpdateButton::downloading_tooltip_message(&version, Some(1.5));
175        assert_eq!(message, "Update to Version: 1.0.0 (100% downloaded)");
176    }
177}
178
Served at tenant.openagents/omega Member data and write actions are omitted.