11use serde:: { Deserialize , Serialize } ;
22use std:: collections:: HashMap ;
33use tauri:: AppHandle ;
4- use tauri:: Runtime ;
54
65#[ derive( Debug , Clone , Serialize , Deserialize ) ]
76pub 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
4755impl 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