From d7f77ebfe1907f6993ba54bbd1b5c8544cdf7214 Mon Sep 17 00:00:00 2001 From: Ellie Huxtable Date: Thu, 6 Jun 2024 10:36:39 +0100 Subject: feat(ui): setup single-instance (#2093) --- ui/backend/src/main.rs | 19 ++++++++++++++++-- ui/backend/src/update.rs | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 2 deletions(-) create mode 100644 ui/backend/src/update.rs (limited to 'ui/backend/src') diff --git a/ui/backend/src/main.rs b/ui/backend/src/main.rs index 88c9ae87..f07e0c95 100644 --- a/ui/backend/src/main.rs +++ b/ui/backend/src/main.rs @@ -2,14 +2,15 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] use std::path::PathBuf; -use time::format_description::well_known::Rfc3339; -use atuin_client::settings::Settings; +use tauri::{AppHandle, Manager}; +use time::format_description::well_known::Rfc3339; mod db; mod dotfiles; mod store; +use atuin_client::settings::Settings; use atuin_client::{ encryption, history::HISTORY_TAG, record::sqlite_store::SqliteStore, record::store::Store, }; @@ -165,6 +166,17 @@ async fn home_info() -> Result { Ok(info) } +fn show_window(app: &AppHandle) { + let windows = app.webview_windows(); + + windows + .values() + .next() + .expect("Sorry, no window found") + .set_focus() + .expect("Can't Bring Window to Focus"); +} + fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![ @@ -186,6 +198,9 @@ fn main() { ]) .plugin(tauri_plugin_sql::Builder::default().build()) .plugin(tauri_plugin_http::init()) + .plugin(tauri_plugin_single_instance::init(|app, args, cwd| { + let _ = show_window(app); + })) .run(tauri::generate_context!()) .expect("error while running tauri application"); } diff --git a/ui/backend/src/update.rs b/ui/backend/src/update.rs new file mode 100644 index 00000000..d8cd2255 --- /dev/null +++ b/ui/backend/src/update.rs @@ -0,0 +1,51 @@ +// While technically using a "self update" crate, we can actually use the same method +// for managing a CLI install. Neat! +// This should still be locked to the same version as the UI. Drift there could lead to issues. +// In the future we can follow semver and allow for minor version drift. + +// If you'd like to follow the conventions of your OS, distro, etc, then I would suggest +// following the CLI install instructions. This is intended to streamline install UX +use eyre::{eyre, Result}; +use std::{ + ffi::{OsStr, OsString}, + path::Path, +}; + +pub fn install(version: &str, path: &str) -> Result<()> { + let dir = std::path::PathBuf::from(path); + std::fs::create_dir_all(path)?; + let bin = dir.join("atuin"); + + let releases = self_update::backends::github::ReleaseList::configure() + .repo_owner("atuinsh") + .repo_name("atuin") + .build()? + .fetch()?; + + let release = releases + .iter() + .find(|r| r.version == version) + .ok_or_else(|| eyre!("No release found for version: {}", version))?; + + let asset = release + .asset_for(&self_update::get_target(), None) + .ok_or_else(|| eyre!("No asset found for target"))?; + + let tmp_dir = tempfile::Builder::new().prefix("atuin").tempdir()?; + let tmp_tarball_path = tmp_dir.path().join(&asset.name); + let tmp_tarball = std::fs::File::create(&tmp_tarball_path)?; + println!("{:?}", tmp_tarball_path); + + self_update::Download::from_url(&asset.download_url).download_to(&tmp_tarball)?; + + let root = asset.name.replace(".tar.gz", ""); + let bin_name = std::path::PathBuf::from(format!("{}/atuin", root,)); + + self_update::Extract::from_source(&tmp_tarball_path) + .archive(self_update::ArchiveKind::Tar(Some( + self_update::Compression::Gz, + ))) + .extract_file(&bin, &bin_name)?; + + Ok(()) +} -- cgit v1.3.1