Skip to content

Commit a553ebd

Browse files
authored
feat: support Quicklink on Rust side (#760)
This commit implements the support for Quicklink on Rust side. We still need the frontend part to make this complete.
1 parent 232166e commit a553ebd

7 files changed

Lines changed: 852 additions & 21 deletions

File tree

src-tauri/Cargo.lock

Lines changed: 13 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ camino = "1.1.10"
105105
tokio-stream = { version = "0.1.17", features = ["io-util"] }
106106
cfg-if = "1.0.1"
107107
sysinfo = "0.35.2"
108+
indexmap = { version = "2.10.0", features = ["serde"] }
108109

109110
[target."cfg(target_os = \"macos\")".dependencies]
110111
tauri-nspanel = { git = "https://github.com/ahkohd/tauri-nspanel", branch = "v2" }

src-tauri/src/common/document.rs

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
use serde::{Deserialize, Serialize};
22
use std::collections::HashMap;
33
use tauri::AppHandle;
4-
use tauri::Runtime;
54

65
#[derive(Debug, Clone, Serialize, Deserialize)]
76
pub struct RichLabel {
@@ -42,6 +41,15 @@ pub(crate) enum OnOpened {
4241
Command {
4342
action: crate::extension::CommandAction,
4443
},
44+
// NOTE that this variant has the same definition as `struct Quicklink`, but we
45+
// cannot use it directly, its `link` field should be deserialized/serialized
46+
// from/to a string, but we need a JSON object here.
47+
//
48+
// See also the comments in `struct Quicklink`.
49+
Quicklink {
50+
link: crate::extension::QuicklinkLink,
51+
open_with: Option<String>,
52+
},
4553
}
4654

4755
impl OnOpened {
@@ -59,28 +67,37 @@ impl OnOpened {
5967

6068
ret
6169
}
70+
// Currently, our URL is static and does not support dynamic parameters.
71+
// The URL of a quicklink is nearly useless without such dynamic user
72+
// inputs, so until we have dynamic URL support, we just use "N/A".
73+
Self::Quicklink { .. } => String::from("N/A"),
6274
}
6375
}
6476
}
6577

6678
#[tauri::command]
67-
pub(crate) async fn open<R: Runtime>(
68-
tauri_app_handle: AppHandle<R>,
79+
pub(crate) async fn open(
80+
tauri_app_handle: AppHandle,
6981
on_opened: OnOpened,
82+
extra_args: Option<HashMap<String, String>>,
7083
) -> Result<(), String> {
71-
log::debug!("open({})", on_opened.url());
72-
7384
use crate::util::open as homemade_tauri_shell_open;
7485
use std::process::Command;
7586

7687
match on_opened {
7788
OnOpened::Application { app_path } => {
89+
log::debug!("open application [{}]", app_path);
90+
7891
homemade_tauri_shell_open(tauri_app_handle.clone(), app_path).await?
7992
}
8093
OnOpened::Document { url } => {
94+
log::debug!("open document [{}]", url);
95+
8196
homemade_tauri_shell_open(tauri_app_handle.clone(), url).await?
8297
}
8398
OnOpened::Command { action } => {
99+
log::debug!("open (execute) command [{:?}]", action);
100+
84101
let mut cmd = Command::new(action.exec);
85102
if let Some(args) = action.args {
86103
cmd.args(args);
@@ -107,6 +124,39 @@ pub(crate) async fn open<R: Runtime>(
107124
));
108125
}
109126
}
127+
OnOpened::Quicklink {
128+
link,
129+
open_with: opt_open_with,
130+
} => {
131+
let url = link.concatenate_url(&extra_args);
132+
133+
log::debug!("open quicklink [{}] with [{:?}]", url, opt_open_with);
134+
135+
cfg_if::cfg_if! {
136+
// The `open_with` functionality is only supported on macOS, provided
137+
// by the `open -a` command.
138+
if #[cfg(target_os = "macos")] {
139+
let mut cmd = Command::new("open");
140+
if let Some(ref open_with) = opt_open_with {
141+
cmd.arg("-a");
142+
cmd.arg(open_with.as_str());
143+
}
144+
cmd.arg(&url);
145+
146+
let output = cmd.output().map_err(|e| format!("failed to spawn [open] due to error [{}]", e))?;
147+
148+
if !output.status.success() {
149+
return Err(format!(
150+
"failed to open with app {:?}: {}",
151+
opt_open_with,
152+
String::from_utf8_lossy(&output.stderr)
153+
));
154+
}
155+
} else {
156+
homemade_tauri_shell_open(tauri_app_handle.clone(), url).await?
157+
}
158+
}
159+
}
110160
}
111161

112162
Ok(())

0 commit comments

Comments
 (0)