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:
@@ -51,7 +51,7 @@ function createSessionStore() {
|
||||
return {
|
||||
subscribe,
|
||||
async load() {
|
||||
const s = await tauriCall<Session | null>("current_session", undefined, null);
|
||||
const s = await tauriCall<Session | null>("current_session", null);
|
||||
set(s);
|
||||
},
|
||||
async login(handle: string, password: string) {
|
||||
@@ -355,18 +355,43 @@ export async function showNotification(
|
||||
/// The handler receives the event payload (empty object for these
|
||||
/// cases). Returns an unsubscribe function.
|
||||
export async function listenTrayEvents(
|
||||
handler: (event: "show" | "compose") => void,
|
||||
handler: (event: "show" | "home" | "compose" | "profile" | "search") => void,
|
||||
): Promise<() => void> {
|
||||
const { listen } = await import("@tauri-apps/api/event");
|
||||
const unlisteners: Array<() => void> = [];
|
||||
const u1 = await listen("app://show", () => handler("show"));
|
||||
const u2 = await listen("app://compose", () => handler("compose"));
|
||||
unlisteners.push(u1, u2);
|
||||
const u2 = await listen("app://navigate", (e) => {
|
||||
handler(e.payload as "home" | "profile" | "search");
|
||||
});
|
||||
const u3 = await listen("app://compose", () => handler("compose"));
|
||||
unlisteners.push(u1, u2, u3);
|
||||
return () => {
|
||||
for (const u of unlisteners) u();
|
||||
};
|
||||
}
|
||||
|
||||
/// Open an external URL in the user's default browser. The Rust
|
||||
/// `open_external_url` command enforces http(s) only; in the
|
||||
/// browser preview where no Tauri runtime is present, fall back
|
||||
/// to `window.open` and treat a popup-blocker denial as
|
||||
/// "fine, user can copy the URL themselves".
|
||||
export async function openExternalUrl(url: string): Promise<void> {
|
||||
try {
|
||||
if (isTauri()) {
|
||||
await safeInvoke("open_external_url", { url });
|
||||
return;
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("open_external_url failed", e);
|
||||
}
|
||||
// Browser fallback (vite dev preview).
|
||||
try {
|
||||
window.open(url, "_blank", "noopener,noreferrer");
|
||||
} catch (e) {
|
||||
console.warn("window.open failed (popup blocker?)", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Subscribe to `app://notification` events emitted by the Rust
|
||||
/// `show_notification` command. Used to focus the window and
|
||||
/// navigate when the user clicks the notification.
|
||||
|
||||
Reference in New Issue
Block a user