Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 7 additions & 1 deletion apps/desktop/src-tauri/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,14 @@
"description": "Hyprnote",
"args": [],
"subcommands": {
"hello": {
"bug": {
"description": "Open GitHub issues page to report a bug"
},
"web": {
"description": "Open https://hyprnote.com"
},
"changelog": {
"description": "Open the changelog page"
}
}
},
Expand Down
17 changes: 11 additions & 6 deletions plugins/cli2/src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
use crate::CliPluginExt;

#[tauri::command]
#[specta::specta]
pub(crate) async fn install_cli<R: tauri::Runtime>(app: tauri::AppHandle<R>) -> Result<(), String> {
use crate::CliPluginExt;
app.install_cli_to_path().map_err(|e| e.to_string())
app.plugin_cli()
.install_cli_to_path()
.map_err(|e| e.to_string())
}

#[tauri::command]
#[specta::specta]
pub(crate) async fn uninstall_cli<R: tauri::Runtime>(
app: tauri::AppHandle<R>,
) -> Result<(), String> {
use crate::CliPluginExt;
app.uninstall_cli_from_path().map_err(|e| e.to_string())
app.plugin_cli()
.uninstall_cli_from_path()
.map_err(|e| e.to_string())
}

#[tauri::command]
#[specta::specta]
pub(crate) async fn check_cli_status<R: tauri::Runtime>(
app: tauri::AppHandle<R>,
) -> Result<crate::CliStatus, String> {
use crate::CliPluginExt;
app.check_cli_status().map_err(|e| e.to_string())
app.plugin_cli()
.check_cli_status()
.map_err(|e| e.to_string())
}
37 changes: 22 additions & 15 deletions plugins/cli2/src/ext.rs
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
use std::path::PathBuf;

pub trait CliPluginExt<R: tauri::Runtime> {
fn handle_cli_matches(&self) -> Result<(), crate::Error>;
fn get_cli_symlink_path(&self) -> PathBuf;
fn get_cli_executable_path(&self) -> Result<PathBuf, crate::Error>;
fn install_cli_to_path(&self) -> Result<(), crate::Error>;
fn uninstall_cli_from_path(&self) -> Result<(), crate::Error>;
fn check_cli_status(&self) -> Result<CliStatus, crate::Error>;
pub struct PluginCli<R: tauri::Runtime> {
app_handle: tauri::AppHandle<R>,
}

impl<R: tauri::Runtime, T: tauri::Manager<R>> crate::CliPluginExt<R> for T {
fn handle_cli_matches(&self) -> Result<(), crate::Error> {
impl<R: tauri::Runtime> PluginCli<R> {
pub fn handle_cli_matches(&self) -> Result<(), crate::Error> {
use tauri_plugin_cli::CliExt;

match self.cli().matches() {
match self.app_handle.cli().matches() {
Ok(matches) => {
if matches.args.contains_key("help") || matches.args.contains_key("version") {
std::process::exit(0);
Expand All @@ -28,7 +23,7 @@ impl<R: tauri::Runtime, T: tauri::Manager<R>> crate::CliPluginExt<R> for T {
Ok(())
}

fn get_cli_symlink_path(&self) -> PathBuf {
pub fn get_cli_symlink_path(&self) -> PathBuf {
#[cfg(unix)]
{
if let Some(home) = std::env::var_os("HOME") {
Expand All @@ -51,11 +46,11 @@ impl<R: tauri::Runtime, T: tauri::Manager<R>> crate::CliPluginExt<R> for T {
}
}

fn get_cli_executable_path(&self) -> Result<PathBuf, crate::Error> {
pub fn get_cli_executable_path(&self) -> Result<PathBuf, crate::Error> {
std::env::current_exe().map_err(|e| e.into())
}

fn install_cli_to_path(&self) -> Result<(), crate::Error> {
pub fn install_cli_to_path(&self) -> Result<(), crate::Error> {
let exe_path = self.get_cli_executable_path()?;
let symlink_path = self.get_cli_symlink_path();

Expand Down Expand Up @@ -91,7 +86,7 @@ impl<R: tauri::Runtime, T: tauri::Manager<R>> crate::CliPluginExt<R> for T {
Ok(())
}

fn uninstall_cli_from_path(&self) -> Result<(), crate::Error> {
pub fn uninstall_cli_from_path(&self) -> Result<(), crate::Error> {
#[cfg(not(any(unix, windows)))]
{
return Err(crate::Error::UnsupportedPlatform);
Expand All @@ -116,7 +111,7 @@ impl<R: tauri::Runtime, T: tauri::Manager<R>> crate::CliPluginExt<R> for T {
Ok(())
}

fn check_cli_status(&self) -> Result<CliStatus, crate::Error> {
pub fn check_cli_status(&self) -> Result<CliStatus, crate::Error> {
let symlink_path = self.get_cli_symlink_path();

if !symlink_path.exists() {
Expand All @@ -137,6 +132,18 @@ impl<R: tauri::Runtime, T: tauri::Manager<R>> crate::CliPluginExt<R> for T {
}
}

pub trait CliPluginExt<R: tauri::Runtime> {
fn plugin_cli(&self) -> PluginCli<R>;
}

impl<R: tauri::Runtime, T: tauri::Manager<R>> CliPluginExt<R> for T {
fn plugin_cli(&self) -> PluginCli<R> {
PluginCli {
app_handle: self.app_handle().clone(),
}
}
}

#[derive(serde::Serialize, serde::Deserialize, specta::Type)]
#[serde(rename_all = "camelCase")]
pub struct CliStatus {
Expand Down
20 changes: 9 additions & 11 deletions plugins/cli2/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,15 @@ use tauri::AppHandle;
use tauri_plugin_cli::Matches;

pub fn entrypoint<R: tauri::Runtime>(app: &AppHandle<R>, matches: Matches) {
if matches.args.contains_key("help") {
std::process::exit(0);
}

if matches.args.contains_key("version") {
std::process::exit(0);
}

let version = app.package_info().version.to_string();
if let Some(subcommand_matches) = matches.subcommand {
match subcommand_matches.name.as_str() {
"hello" => hello(app),
"bug" => url(
app,
format!("https://github.com/fastrepl/hyprnote/issues/new?labels=bug,v{version}"),
),
"web" => url(app, "https://hyprnote.com"),
"changelog" => url(app, "https://hyprnote.com/changelog"),
_ => {
tracing::warn!("unknown_subcommand: {}", subcommand_matches.name);
std::process::exit(1);
Expand All @@ -21,8 +19,8 @@ pub fn entrypoint<R: tauri::Runtime>(app: &AppHandle<R>, matches: Matches) {
}
}

fn hello<R: tauri::Runtime>(_app: &AppHandle<R>) {
match open::that("https://hyprnote.com") {
fn url<R: tauri::Runtime>(_app: &AppHandle<R>, url: impl Into<String>) {
match open::that(url.into()) {
Ok(_) => std::process::exit(0),
Err(e) => {
tracing::error!("open_url_error: {e}");
Expand Down
2 changes: 2 additions & 0 deletions plugins/cli2/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ mod handler;
pub use error::{Error, Result};
pub use ext::*;

pub use tauri_plugin_cli::CliExt;

const PLUGIN_NAME: &str = "cli2";

fn make_specta_builder<R: tauri::Runtime>() -> tauri_specta::Builder<R> {
Expand Down
1 change: 1 addition & 0 deletions plugins/tray/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ hypr-host = { workspace = true }
tauri = { workspace = true, features = ["tray-icon", "image-png"] }
tauri-specta = { workspace = true, features = ["derive", "typescript"] }

tauri-plugin-cli2 = { workspace = true }
tauri-plugin-clipboard-manager = { workspace = true }
tauri-plugin-dialog = { workspace = true }
tauri-plugin-local-stt = { workspace = true }
Expand Down
51 changes: 49 additions & 2 deletions plugins/tray/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ pub enum HyprMenuItem {
TrayStart,
TrayQuit,
AppInfo,
AppCliInstall,
AppCliUninstall,
AppNew,
}

Expand All @@ -27,6 +29,8 @@ impl From<HyprMenuItem> for MenuId {
HyprMenuItem::TrayStart => "hypr_tray_start",
HyprMenuItem::TrayQuit => "hypr_tray_quit",
HyprMenuItem::AppInfo => "hypr_app_info",
HyprMenuItem::AppCliInstall => "hypr_app_cli_install",
HyprMenuItem::AppCliUninstall => "hypr_app_cli_uninstall",
HyprMenuItem::AppNew => "hypr_app_new",
}
.into()
Expand All @@ -41,6 +45,8 @@ impl From<MenuId> for HyprMenuItem {
"hypr_tray_start" => HyprMenuItem::TrayStart,
"hypr_tray_quit" => HyprMenuItem::TrayQuit,
"hypr_app_info" => HyprMenuItem::AppInfo,
"hypr_app_cli_install" => HyprMenuItem::AppCliInstall,
"hypr_app_cli_uninstall" => HyprMenuItem::AppCliUninstall,
"hypr_app_new" => HyprMenuItem::AppNew,
_ => unreachable!(),
}
Expand All @@ -58,6 +64,7 @@ impl<T: tauri::Manager<tauri::Wry>> TrayPluginExt<tauri::Wry> for T {
let app = self.app_handle();

let info_item = app_info_menu(app)?;
let cli_item = app_cli_menu(app)?;
let new_item = app_new_menu(app)?;

if cfg!(target_os = "macos") {
Expand All @@ -67,15 +74,15 @@ impl<T: tauri::Manager<tauri::Wry>> TrayPluginExt<tauri::Wry> for T {
if items.len() > 0 {
if let MenuItemKind::Submenu(submenu) = &items[0] {
submenu.remove_at(0)?;
submenu.remove_at(0)?;
submenu.prepend(&cli_item)?;
submenu.prepend(&info_item)?;
return Ok(());
}
}

if items.len() > 1 {
if let MenuItemKind::Submenu(submenu) = &items[1] {
submenu.prepend(&new_item)?;
return Ok(());
}
}
}
Expand Down Expand Up @@ -163,6 +170,18 @@ impl<T: tauri::Manager<tauri::Wry>> TrayPluginExt<tauri::Wry> for T {
}
});
}
HyprMenuItem::AppCliInstall => {
use tauri_plugin_cli2::CliPluginExt;
if let Ok(_) = app.plugin_cli().install_cli_to_path() {
let _ = app.create_app_menu();
}
}
HyprMenuItem::AppCliUninstall => {
use tauri_plugin_cli2::CliPluginExt;
if let Ok(_) = app.plugin_cli().uninstall_cli_from_path() {
let _ = app.create_app_menu();
}
}
HyprMenuItem::AppNew => {
use tauri_plugin_windows::{AppWindow, Navigate, WindowsPluginExt};
if let Ok(_) = app.window_show(AppWindow::Main) {
Expand Down Expand Up @@ -213,6 +232,34 @@ fn app_info_menu<R: tauri::Runtime>(app: &AppHandle<R>) -> Result<MenuItem<R>> {
)
}

fn app_cli_menu<R: tauri::Runtime>(app: &AppHandle<R>) -> Result<MenuItem<R>> {
use tauri_plugin_cli2::CliPluginExt;

let is_installed = app
.plugin_cli()
.check_cli_status()
.map(|status| status.is_installed)
.unwrap_or(false);

if is_installed {
MenuItem::with_id(
app,
HyprMenuItem::AppCliUninstall,
"Uninstall CLI",
true,
None::<&str>,
)
} else {
MenuItem::with_id(
app,
HyprMenuItem::AppCliInstall,
"Install CLI",
true,
None::<&str>,
)
}
}

fn app_new_menu<R: tauri::Runtime>(app: &AppHandle<R>) -> Result<MenuItem<R>> {
MenuItem::with_id(
app,
Expand Down
Loading