Skip to content
106 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

preparing for cloud work1//! The tray icon and its menu, and showing and hiding the window. Closing
2//! the window hides it; g1t keeps running for notifications, and the
3//! tray's Open, or the icon, brings it back. Quit is here too.
4
5use std::sync::OnceLock;
6
7use tauri::menu::{Menu, MenuItem, PredefinedMenuItem};
8use tauri::tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent};
9use tauri::{AppHandle, Manager, Wry};
10
11use crate::{WINDOW, updates};
12
13pub const TRAY: &str = "g1t";
14
15/// The menu row that restarts into a downloaded update: off until one is.
16static RESTART: OnceLock<MenuItem<Wry>> = OnceLock::new();
17
18pub fn install(app: &AppHandle) -> tauri::Result<()> {
19 let open = MenuItem::with_id(app, "open", "Open g1t", true, None::<&str>)?;
20 let check = MenuItem::with_id(app, "check", "Check for updates…", true, None::<&str>)?;
21 let restart = MenuItem::with_id(app, "restart", "Restart to finish updating", false, None::<&str>)?;
22 let server = MenuItem::with_id(app, "server", "Use another g1t…", true, None::<&str>)?;
23 let quit = MenuItem::with_id(app, "quit", "Quit g1t", true, None::<&str>)?;
24 let menu = Menu::with_items(
25 app,
26 &[
27 &open,
28 &PredefinedMenuItem::separator(app)?,
29 &check,
30 &restart,
31 &PredefinedMenuItem::separator(app)?,
32 &server,
33 &PredefinedMenuItem::separator(app)?,
34 &quit,
35 ],
36 )?;
37 let _ = RESTART.set(restart);
38 let mut tray = TrayIconBuilder::with_id(TRAY)
39 .menu(&menu)
40 .show_menu_on_left_click(false)
41 .tooltip("g1t")
42 .on_menu_event(|app, event| match event.id().as_ref() {
43 "open" => show(app),
44 "check" => {
45 let app = app.clone();
46 tauri::async_runtime::spawn(async move {
47 let _ = updates::check(&app, true).await;
48 });
49 }
50 "restart" => updates::restart(app),
51 "server" => launcher(app, "change"),
52 "quit" => updates::quit(app),
53 _ => {}
54 })
55 .on_tray_icon_event(|tray, event| {
56 if let TrayIconEvent::Click { button: MouseButton::Left, button_state: MouseButtonState::Up, .. } = event {
57 show(tray.app_handle());
58 }
59 });
60 if let Some(icon) = app.default_window_icon() {
61 tray = tray.icon(icon.clone());
62 }
63 tray.build(app)?;
64 Ok(())
65}
66
67/// The update is downloaded: the menu says so, and offers the restart.
68pub fn update_ready(version: &str) {
69 if let Some(item) = RESTART.get() {
70 let _ = item.set_text(format!("Restart to update to {version}"));
71 let _ = item.set_enabled(true);
72 }
73}
74
75pub fn show(app: &AppHandle) {
76 if let Some(window) = app.get_webview_window(WINDOW) {
77 let _ = window.show();
78 let _ = window.unminimize();
79 let _ = window.set_focus();
80 }
81}
82
83pub fn hide(app: &AppHandle) {
84 if let Some(window) = app.get_webview_window(WINDOW) {
85 let _ = window.hide();
86 }
87}
88
89/// The address of the launcher page bundled with the app.
90pub fn launcher_url(query: &str) -> url::Url {
91 let base = if cfg!(windows) { "http://tauri.localhost/" } else { "tauri://localhost/" };
92 let mut url = url::Url::parse(base).expect("the launcher's address is a URL");
93 url.set_path("/index.html");
94 if !query.is_empty() {
95 url.set_query(Some(query));
96 }
97 url
98}
99
100/// Takes the window to the launcher: `change` to choose another server.
101pub fn launcher(app: &AppHandle, query: &str) {
102 if let Some(window) = app.get_webview_window(WINDOW) {
103 let _ = window.navigate(launcher_url(query));
104 show(app);
105 }
106}