feat(tauri-app): expand tray menu + open_external_url + Profile/Search items
Tray menu now has:
Show maarcadetweet
Home
Compose
Profile
Search
----
Quit
The Home/Profile/Search items emit 'app://navigate' events
which the frontend's listenTrayEvents translates to view
switches. The compose and show events continue to be
separate event types ('app://compose', 'app://show').
open_external_url Tauri command takes a URL, validates it's
http(s), and uses tauri-plugin-shell to open it in the user's
default browser. The frontend's openExternalUrl falls back
to window.open in the browser preview (no Tauri runtime).
svelte-check error fix: tauriCall<T>(cmd, fallback, args?)
had the second call argument as 'undefined' instead of 'null'
on the call site for session.load(). The TypeScript compiler
correctly noted that the fallback type 'T' (here Session |
null) couldn't be undefined. Replaced with 'null' and
dropped the trailing null args argument (it's optional).
This commit is contained in:
@@ -444,6 +444,28 @@ async fn pick_and_upload_image(
|
||||
Ok(Some(resp))
|
||||
}
|
||||
|
||||
/// Open an external URL in the user's default browser. Returns
|
||||
/// silently on success. Only accepts `http://` and `https://` —
|
||||
/// any other scheme (e.g. `file://`, `mailto:`, `javascript:`)
|
||||
/// is rejected so the Rust side is the single source of truth for
|
||||
/// which schemes are allowed.
|
||||
#[tauri::command]
|
||||
async fn open_external_url(
|
||||
url: String,
|
||||
app: tauri::AppHandle,
|
||||
) -> Result<(), String> {
|
||||
use tauri_plugin_shell::ShellExt;
|
||||
let lower = url.to_ascii_lowercase();
|
||||
if !(lower.starts_with("http://") || lower.starts_with("https://")) {
|
||||
return Err(format!(
|
||||
"open_external_url: refusing non-http(s) scheme in {url:?}"
|
||||
));
|
||||
}
|
||||
app.shell()
|
||||
.open(url, None)
|
||||
.map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
/// Map a file extension to a MIME type. Returns
|
||||
/// `application/octet-stream` when the extension is unrecognised —
|
||||
/// the PDS's magic-byte sniffer will take over from there.
|
||||
@@ -529,6 +551,7 @@ pub fn run() {
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_notification::init())
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())
|
||||
.plugin(tauri_plugin_window_state::Builder::default().build())
|
||||
.manage(state)
|
||||
@@ -551,6 +574,14 @@ pub fn run() {
|
||||
None::<&str>,
|
||||
)
|
||||
.map_err(|e| format!("failed to build show menu item: {e}"))?;
|
||||
let home_item = tauri::menu::MenuItem::with_id(
|
||||
app,
|
||||
"tray_home",
|
||||
"Home",
|
||||
true,
|
||||
None::<&str>,
|
||||
)
|
||||
.map_err(|e| format!("failed to build home menu item: {e}"))?;
|
||||
let compose_item = tauri::menu::MenuItem::with_id(
|
||||
app,
|
||||
"tray_compose",
|
||||
@@ -559,6 +590,22 @@ pub fn run() {
|
||||
None::<&str>,
|
||||
)
|
||||
.map_err(|e| format!("failed to build compose menu item: {e}"))?;
|
||||
let profile_item = tauri::menu::MenuItem::with_id(
|
||||
app,
|
||||
"tray_profile",
|
||||
"Profile",
|
||||
true,
|
||||
None::<&str>,
|
||||
)
|
||||
.map_err(|e| format!("failed to build profile menu item: {e}"))?;
|
||||
let search_item = tauri::menu::MenuItem::with_id(
|
||||
app,
|
||||
"tray_search",
|
||||
"Search",
|
||||
true,
|
||||
None::<&str>,
|
||||
)
|
||||
.map_err(|e| format!("failed to build search menu item: {e}"))?;
|
||||
let quit_item = tauri::menu::MenuItem::with_id(
|
||||
app,
|
||||
"tray_quit",
|
||||
@@ -572,7 +619,15 @@ pub fn run() {
|
||||
|
||||
let tray_menu = tauri::menu::Menu::with_items(
|
||||
app,
|
||||
&[&show_item, &compose_item, &separator, &quit_item],
|
||||
&[
|
||||
&show_item,
|
||||
&home_item,
|
||||
&compose_item,
|
||||
&profile_item,
|
||||
&search_item,
|
||||
&separator,
|
||||
&quit_item,
|
||||
],
|
||||
)
|
||||
.map_err(|e| format!("failed to build tray menu: {e}"))?;
|
||||
|
||||
@@ -586,9 +641,18 @@ pub fn run() {
|
||||
"tray_show" => {
|
||||
let _ = tauri::Emitter::emit(app, "app://show", ());
|
||||
}
|
||||
"tray_home" => {
|
||||
let _ = tauri::Emitter::emit(app, "app://navigate", "home");
|
||||
}
|
||||
"tray_compose" => {
|
||||
let _ = tauri::Emitter::emit(app, "app://compose", ());
|
||||
}
|
||||
"tray_profile" => {
|
||||
let _ = tauri::Emitter::emit(app, "app://navigate", "profile");
|
||||
}
|
||||
"tray_search" => {
|
||||
let _ = tauri::Emitter::emit(app, "app://navigate", "search");
|
||||
}
|
||||
"tray_quit" => {
|
||||
app.exit(0);
|
||||
}
|
||||
@@ -634,6 +698,7 @@ pub fn run() {
|
||||
fetch_blob,
|
||||
pick_and_upload_image,
|
||||
show_notification,
|
||||
open_external_url,
|
||||
])
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running maarcadetweet");
|
||||
|
||||
Reference in New Issue
Block a user