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 work | 1 | //! Where the window may go: the launcher, the server's pages, and the |
| 2 | //! pages that sign someone in there. Any other address opens in the | |
| The desktop app has settings of its own and a menu, and it is for using g1t, not browsing it. | 3 | //! browser the system uses, and the window stays where it is. So do the |
| 4 | //! server's pages for reading about g1t rather than using it (`OUTSIDE`): | |
| 5 | //! the window is for working in, the browser for browsing. bridge.js | |
| 6 | //! sends the same pages out when a link inside the site goes to one. | |
| preparing for cloud work | 7 | |
| 8 | use tauri::AppHandle; | |
| 9 | use tauri_plugin_opener::OpenerExt; | |
| 10 | use url::Url; | |
| 11 | ||
| 12 | use crate::config; | |
| 13 | ||
| 14 | /// Signing in with GitHub goes there and comes back. | |
| 15 | const SIGN_IN_HOSTS: &[&str] = &["github.com", "www.github.com"]; | |
| 16 | ||
| The desktop app has settings of its own and a menu, and it is for using g1t, not browsing it. | 17 | /// The server's pages that open in the browser: pricing, policies, |
| 18 | /// security, support, the desktop app's own downloads, and status. An | |
| 19 | /// entry ending in `/` is every page under it. | |
| 20 | pub const OUTSIDE: &[&str] = &["/pricing", "/policies", "/policies/", "/security", "/support", "/download", "/downloads/", "/status"]; | |
| 21 | ||
| 22 | /// Whether a path on the server is one for the browser. | |
| 23 | pub fn outside(path: &str) -> bool { | |
| 24 | let path = if path.len() > 1 { path.trim_end_matches('/') } else { path }; | |
| 25 | OUTSIDE.iter().any(|page| if page.ends_with('/') { path.starts_with(page) } else { path == *page }) | |
| 26 | } | |
| 27 | ||
| The desktop app draws its own title bar, as Slack and Discord do, and the site can call the app again. | 28 | /// Whether a page is one of signing in with GitHub's. |
| 29 | pub fn signing_in(url: &Url) -> bool { | |
| 30 | url.scheme() == "https" && url.host_str().is_some_and(|host| SIGN_IN_HOSTS.contains(&host)) | |
| 31 | } | |
| 32 | ||
| preparing for cloud work | 33 | /// Whether the window may load `url`. |
| 34 | pub fn allowed(app: &AppHandle, url: &Url) -> bool { | |
| 35 | match url.scheme() { | |
| 36 | "about" | "blob" | "data" => return true, | |
| 37 | "http" | "https" | "tauri" => {} | |
| 38 | _ => return false, | |
| 39 | } | |
| The desktop app has settings of its own and a menu, and it is for using g1t, not browsing it. | 40 | if config::is_launcher(url) || (config::is_server(app, url) && !outside(url.path())) { |
| preparing for cloud work | 41 | return true; |
| 42 | } | |
| The desktop app draws its own title bar, as Slack and Discord do, and the site can call the app again. | 43 | if signing_in(url) { |
| preparing for cloud work | 44 | return true; |
| 45 | } | |
| 46 | let _ = app.opener().open_url(url.as_str(), None::<&str>); | |
| 47 | false | |
| 48 | } | |
| The desktop app has settings of its own and a menu, and it is for using g1t, not browsing it. | 49 | |
| 50 | #[cfg(test)] | |
| 51 | mod tests { | |
| 52 | use super::outside; | |
| 53 | ||
| 54 | #[test] | |
| 55 | fn reading_about_g1t_is_for_the_browser() { | |
| 56 | assert!(outside("/pricing")); | |
| 57 | assert!(outside("/pricing/")); | |
| 58 | assert!(outside("/policies/terms")); | |
| 59 | assert!(outside("/downloads/desktop/latest.json")); | |
| 60 | assert!(!outside("/")); | |
| 61 | assert!(!outside("/login")); | |
| 62 | assert!(!outside("/acme/-/chat")); | |
| 63 | assert!(!outside("/pricingx")); | |
| 64 | assert!(!outside("/acme/security")); | |
| 65 | } | |
| 66 | } |