Skip to repository content178 lines · 6.7 KB · rust
tenant.openagents/omega
No repository description is available.
OpenAgents Git authority 2026-07-28T02:58:35.427Z Public web read
NIP-34 coordinate
30617:7649603503856e5148d571eac2766b288a8ff1e9e35d380337a1d2b0015b4f92:omegaMaintainersHidden in public view
References2 branches · 1 tag
Read-only clone
git clone https://openagents.com/git/tenant.openagents/omega.gitBrowse files
update_version.rs
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