From 7c7b082b3a075dea4fd498b112b46c0dab16e0ec Mon Sep 17 00:00:00 2001 From: reya <123083837+reyamir@users.noreply.github.com> Date: Mon, 3 Jun 2024 07:32:34 +0700 Subject: [PATCH] fix: memory leak in image component --- apps/desktop2/public/404.jpg | Bin 0 -> 26738 bytes apps/desktop2/src/components/note/content.tsx | 2 +- .../src/components/note/contentLarge.tsx | 4 +- .../src/components/note/mentions/note.tsx | 2 +- .../src/components/note/preview/image.tsx | 63 +- .../src/components/note/preview/images.tsx | 8 + apps/desktop2/src/routes/index.tsx | 5 +- packages/system/src/commands.ts | 958 +++++++++++------- src-tauri/Cargo.lock | 8 +- src-tauri/Cargo.toml | 6 +- 10 files changed, 622 insertions(+), 434 deletions(-) create mode 100644 apps/desktop2/public/404.jpg diff --git a/apps/desktop2/public/404.jpg b/apps/desktop2/public/404.jpg new file mode 100644 index 0000000000000000000000000000000000000000..7485a5e8bc0eb0f3f21cd685fbf3f0392dfccfdf GIT binary patch literal 26738 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

^24dFkO?dxadw&gS4Y%Vq~n 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 literal 0 HcmV?d00001 diff --git a/apps/desktop2/src/components/note/content.tsx b/apps/desktop2/src/components/note/content.tsx index 2b9564a9..d0cecc67 100644 --- a/apps/desktop2/src/components/note/content.tsx +++ b/apps/desktop2/src/components/note/content.tsx @@ -102,7 +102,7 @@ export function NoteContent({

500 ? "max-h-[300px] gradient-mask-b-0" : "", className, )} diff --git a/apps/desktop2/src/components/note/contentLarge.tsx b/apps/desktop2/src/components/note/contentLarge.tsx index 03ee1625..c8614470 100644 --- a/apps/desktop2/src/components/note/contentLarge.tsx +++ b/apps/desktop2/src/components/note/contentLarge.tsx @@ -145,7 +145,9 @@ export function NoteContentLarge({ return (
-
{content}
+
+ {content} +
); } diff --git a/apps/desktop2/src/components/note/mentions/note.tsx b/apps/desktop2/src/components/note/mentions/note.tsx index 74dc23a2..d341fcca 100644 --- a/apps/desktop2/src/components/note/mentions/note.tsx +++ b/apps/desktop2/src/components/note/mentions/note.tsx @@ -48,7 +48,7 @@ export function MentionNote({
100 ? "max-h-[150px] gradient-mask-b-0" : "", )} > diff --git a/apps/desktop2/src/components/note/preview/image.tsx b/apps/desktop2/src/components/note/preview/image.tsx index ae1b0678..730b25fb 100644 --- a/apps/desktop2/src/components/note/preview/image.tsx +++ b/apps/desktop2/src/components/note/preview/image.tsx @@ -1,61 +1,44 @@ -import { CheckCircleIcon, DownloadIcon } from "@lume/icons"; -import { downloadDir } from "@tauri-apps/api/path"; import { WebviewWindow } from "@tauri-apps/api/webviewWindow"; -import { download } from "@tauri-apps/plugin-upload"; -import { type SyntheticEvent, useState } from "react"; export function ImagePreview({ url }: { url: string }) { - const [downloaded, setDownloaded] = useState(false); + const open = async (url: string) => { + const name = new URL(url).pathname + .split("/") + .pop() + .replace(/[^a-zA-Z ]/g, ""); + const label = `viewer-${name}`; + const window = WebviewWindow.getByLabel(label); - const downloadImage = async (e: { stopPropagation: () => void }) => { - try { - e.stopPropagation(); + if (!window) { + const newWindow = new WebviewWindow(label, { + url, + title: "Image Viewer", + width: 800, + height: 800, + titleBarStyle: "overlay", + }); - const downloadDirPath = await downloadDir(); - const filename = url.substring(url.lastIndexOf("/") + 1); - await download(url, `${downloadDirPath}/${filename}`); - - setDownloaded(true); - } catch (e) { - console.error(e); + return newWindow; } - }; - const open = async () => { - const name = new URL(url).pathname.split("/").pop(); - return new WebviewWindow("image-viewer", { - url, - title: name, - }); - }; - - const fallback = (event: SyntheticEvent) => { - event.currentTarget.src = "/fallback-image.jpg"; + return await window.setFocus(); }; return ( - // biome-ignore lint/a11y/useKeyWithClickEvents: -
open()} className="group relative my-1"> +
{url} open(url)} + onError={({ currentTarget }) => { + currentTarget.onerror = null; + currentTarget.src = "/404.jpg"; + }} /> -
); } diff --git a/apps/desktop2/src/components/note/preview/images.tsx b/apps/desktop2/src/components/note/preview/images.tsx index feecbe79..a92c8541 100644 --- a/apps/desktop2/src/components/note/preview/images.tsx +++ b/apps/desktop2/src/components/note/preview/images.tsx @@ -36,6 +36,10 @@ export function Images({ urls }: { urls: string[] }) { style={{ contentVisibility: "auto" }} className="max-h-[400px] w-auto object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15" onClick={() => open(urls[0])} + onError={({ currentTarget }) => { + currentTarget.onerror = null; + currentTarget.src = "/404.jpg"; + }} />
); @@ -54,6 +58,10 @@ export function Images({ urls }: { urls: string[] }) { style={{ contentVisibility: "auto" }} className="w-full h-full object-cover rounded-lg outline outline-1 -outline-offset-1 outline-black/15" onClick={() => open(item)} + onError={({ currentTarget }) => { + currentTarget.onerror = null; + currentTarget.src = "/404.jpg"; + }} /> )} diff --git a/apps/desktop2/src/routes/index.tsx b/apps/desktop2/src/routes/index.tsx index 7e11d38b..d7f8ef0a 100644 --- a/apps/desktop2/src/routes/index.tsx +++ b/apps/desktop2/src/routes/index.tsx @@ -57,7 +57,10 @@ function Screen() { }); return ( -
+

diff --git a/packages/system/src/commands.ts b/packages/system/src/commands.ts index 1a2dd3bd..244cacf6 100644 --- a/packages/system/src/commands.ts +++ b/packages/system/src/commands.ts @@ -1,404 +1,596 @@ - // This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually. +// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually. - export const commands = { -async getRelays() : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_relays") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async connectRelay(relay: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("connect_relay", { relay }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async removeRelay(relay: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("remove_relay", { relay }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getAccounts() : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_accounts") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async createAccount() : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("create_account") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async saveAccount(nsec: string, password: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("save_account", { nsec, password }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getEncryptedKey(npub: string, password: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_encrypted_key", { npub, password }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async connectRemoteAccount(uri: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("connect_remote_account", { uri }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async loadAccount(npub: string, bunker: string | null) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("load_account", { npub, bunker }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async eventToBech32(id: string, relays: string[]) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("event_to_bech32", { id, relays }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async userToBech32(key: string, relays: string[]) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("user_to_bech32", { key, relays }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async verifyNip05(key: string, nip05: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("verify_nip05", { key, nip05 }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getActivities(account: string, kind: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_activities", { account, kind }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getCurrentUserProfile() : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_current_user_profile") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getProfile(id: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_profile", { id }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getContactList() : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_contact_list") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async setContactList(pubkeys: string[]) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("set_contact_list", { pubkeys }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async createProfile(name: string, displayName: string, about: string, picture: string, banner: string, nip05: string, lud16: string, website: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("create_profile", { name, displayName, about, picture, banner, nip05, lud16, website }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async follow(id: string, alias: string | null) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("follow", { id, alias }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async unfollow(id: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("unfollow", { id }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getNstore(key: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_nstore", { key }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async setNstore(key: string, content: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("set_nstore", { key, content }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async setNwc(uri: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("set_nwc", { uri }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async loadNwc() : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("load_nwc") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getBalance() : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_balance") }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async zapProfile(id: string, amount: string, message: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("zap_profile", { id, amount, message }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async zapEvent(id: string, amount: string, message: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("zap_event", { id, amount, message }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async friendToFriend(npub: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("friend_to_friend", { npub }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getEvent(id: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_event", { id }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getReplies(id: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_replies", { id }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getEventsBy(publicKey: string, asOf: string | null) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_events_by", { publicKey, asOf }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getLocalEvents(pubkeys: string[], until: string | null) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_local_events", { pubkeys, until }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getGlobalEvents(until: string | null) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_global_events", { until }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async getHashtagEvents(hashtags: string[], until: string | null) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("get_hashtag_events", { hashtags, until }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async publish(content: string, tags: string[][]) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("publish", { content, tags }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async repost(raw: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("repost", { raw }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async showInFolder(path: string) : Promise { -await TAURI_INVOKE("show_in_folder", { path }); -}, -async createColumn(label: string, x: number, y: number, width: number, height: number, url: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("create_column", { label, x, y, width, height, url }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async closeColumn(label: string) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("close_column", { label }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async repositionColumn(label: string, x: number, y: number) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("reposition_column", { label, x, y }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async resizeColumn(label: string, width: number, height: number) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("resize_column", { label, width, height }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async openWindow(label: string, title: string, url: string, width: number, height: number) : Promise> { -try { - return { status: "ok", data: await TAURI_INVOKE("open_window", { label, title, url, width, height }) }; -} catch (e) { - if(e instanceof Error) throw e; - else return { status: "error", error: e as any }; -} -}, -async setBadge(count: number) : Promise { -await TAURI_INVOKE("set_badge", { count }); -} -} +/** user-defined commands **/ +export const commands = { + async getRelays(): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_relays") }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async connectRelay(relay: string): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("connect_relay", { relay }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async removeRelay(relay: string): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("remove_relay", { relay }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getAccounts(): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_accounts") }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async createAccount(): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("create_account") }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async saveAccount( + nsec: string, + password: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("save_account", { nsec, password }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getEncryptedKey( + npub: string, + password: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("get_encrypted_key", { npub, password }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async connectRemoteAccount(uri: string): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("connect_remote_account", { uri }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async loadAccount( + npub: string, + bunker: string | null, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("load_account", { npub, bunker }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async eventToBech32( + id: string, + relays: string[], + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("event_to_bech32", { id, relays }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async userToBech32( + key: string, + relays: string[], + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("user_to_bech32", { key, relays }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async verifyNip05( + key: string, + nip05: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("verify_nip05", { key, nip05 }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getActivities( + account: string, + kind: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("get_activities", { account, kind }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getCurrentUserProfile(): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("get_current_user_profile"), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getProfile(id: string): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_profile", { id }) }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getContactList(): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_contact_list") }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async setContactList(pubkeys: string[]): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("set_contact_list", { pubkeys }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async createProfile( + name: string, + displayName: string, + about: string, + picture: string, + banner: string, + nip05: string, + lud16: string, + website: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("create_profile", { + name, + displayName, + about, + picture, + banner, + nip05, + lud16, + website, + }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async follow( + id: string, + alias: string | null, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("follow", { id, alias }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async unfollow(id: string): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("unfollow", { id }) }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getNstore(key: string): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_nstore", { key }) }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async setNstore( + key: string, + content: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("set_nstore", { key, content }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async setNwc(uri: string): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("set_nwc", { uri }) }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async loadNwc(): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("load_nwc") }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getBalance(): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_balance") }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async zapProfile( + id: string, + amount: string, + message: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("zap_profile", { id, amount, message }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async zapEvent( + id: string, + amount: string, + message: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("zap_event", { id, amount, message }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async friendToFriend(npub: string): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("friend_to_friend", { npub }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getEvent(id: string): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_event", { id }) }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getReplies(id: string): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("get_replies", { id }) }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getEventsBy( + publicKey: string, + asOf: string | null, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("get_events_by", { publicKey, asOf }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getLocalEvents( + pubkeys: string[], + until: string | null, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("get_local_events", { pubkeys, until }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getGlobalEvents( + until: string | null, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("get_global_events", { until }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async getHashtagEvents( + hashtags: string[], + until: string | null, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("get_hashtag_events", { hashtags, until }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async publish( + content: string, + tags: string[][], + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("publish", { content, tags }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async repost(raw: string): Promise> { + try { + return { status: "ok", data: await TAURI_INVOKE("repost", { raw }) }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async showInFolder(path: string): Promise { + await TAURI_INVOKE("show_in_folder", { path }); + }, + async createColumn( + label: string, + x: number, + y: number, + width: number, + height: number, + url: string, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("create_column", { + label, + x, + y, + width, + height, + url, + }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async closeColumn(label: string): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("close_column", { label }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async repositionColumn( + label: string, + x: number, + y: number, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("reposition_column", { label, x, y }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async resizeColumn( + label: string, + width: number, + height: number, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("resize_column", { label, width, height }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async openWindow( + label: string, + title: string, + url: string, + width: number, + height: number, + ): Promise> { + try { + return { + status: "ok", + data: await TAURI_INVOKE("open_window", { + label, + title, + url, + width, + height, + }), + }; + } catch (e) { + if (e instanceof Error) throw e; + else return { status: "error", error: e as any }; + } + }, + async setBadge(count: number): Promise { + await TAURI_INVOKE("set_badge", { count }); + }, +}; +/** user-defined events **/ + +/** user-defined statics **/ /** user-defined types **/ -export type Account = { npub: string; nsec: string } -export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null } +export type Account = { npub: string; nsec: string }; +export type Relays = { + connected: string[]; + read: string[] | null; + write: string[] | null; + both: string[] | null; +}; /** tauri-specta globals **/ - import { invoke as TAURI_INVOKE } from "@tauri-apps/api/core"; +import { invoke as TAURI_INVOKE } from "@tauri-apps/api/core"; import * as TAURI_API_EVENT from "@tauri-apps/api/event"; import { type WebviewWindow as __WebviewWindow__ } from "@tauri-apps/api/webviewWindow"; type __EventObj__ = { - listen: ( - cb: TAURI_API_EVENT.EventCallback - ) => ReturnType>; - once: ( - cb: TAURI_API_EVENT.EventCallback - ) => ReturnType>; - emit: T extends null - ? (payload?: T) => ReturnType - : (payload: T) => ReturnType; + listen: ( + cb: TAURI_API_EVENT.EventCallback, + ) => ReturnType>; + once: ( + cb: TAURI_API_EVENT.EventCallback, + ) => ReturnType>; + emit: T extends null + ? (payload?: T) => ReturnType + : (payload: T) => ReturnType; }; export type Result = - | { status: "ok"; data: T } - | { status: "error"; error: E }; + | { status: "ok"; data: T } + | { status: "error"; error: E }; function __makeEvents__>( - mappings: Record + mappings: Record, ) { - return new Proxy( - {} as unknown as { - [K in keyof T]: __EventObj__ & { - (handle: __WebviewWindow__): __EventObj__; - }; - }, - { - get: (_, event) => { - const name = mappings[event as keyof T]; + return new Proxy( + {} as unknown as { + [K in keyof T]: __EventObj__ & { + (handle: __WebviewWindow__): __EventObj__; + }; + }, + { + get: (_, event) => { + const name = mappings[event as keyof T]; - return new Proxy((() => {}) as any, { - apply: (_, __, [window]: [__WebviewWindow__]) => ({ - listen: (arg: any) => window.listen(name, arg), - once: (arg: any) => window.once(name, arg), - emit: (arg: any) => window.emit(name, arg), - }), - get: (_, command: keyof __EventObj__) => { - switch (command) { - case "listen": - return (arg: any) => TAURI_API_EVENT.listen(name, arg); - case "once": - return (arg: any) => TAURI_API_EVENT.once(name, arg); - case "emit": - return (arg: any) => TAURI_API_EVENT.emit(name, arg); - } - }, - }); - }, - } - ); + return new Proxy((() => {}) as any, { + apply: (_, __, [window]: [__WebviewWindow__]) => ({ + listen: (arg: any) => window.listen(name, arg), + once: (arg: any) => window.once(name, arg), + emit: (arg: any) => window.emit(name, arg), + }), + get: (_, command: keyof __EventObj__) => { + switch (command) { + case "listen": + return (arg: any) => TAURI_API_EVENT.listen(name, arg); + case "once": + return (arg: any) => TAURI_API_EVENT.once(name, arg); + case "emit": + return (arg: any) => TAURI_API_EVENT.emit(name, arg); + } + }, + }); + }, + }, + ); } - - \ No newline at end of file diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index 73fbba25..b71b62cb 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -5841,8 +5841,9 @@ dependencies = [ [[package]] name = "tauri-specta" -version = "2.0.0-rc.10" -source = "git+https://github.com/cloudcad/tauri-specta?branch=main#806eb18e50d7015a5ff27f800b5fc5a74a4d41a6" +version = "2.0.0-rc.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85f26e4ded13fbeab2216dcb5a59b5cf8b475740afea932918888402bcc62a02" dependencies = [ "heck 0.5.0", "indoc", @@ -5857,7 +5858,8 @@ dependencies = [ [[package]] name = "tauri-specta-macros" version = "2.0.0-rc.5" -source = "git+https://github.com/cloudcad/tauri-specta?branch=main#806eb18e50d7015a5ff27f800b5fc5a74a4d41a6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6f9e90bf2012877e2c4029a1bf756277183e9c7c77b850ef965711553998012" dependencies = [ "heck 0.5.0", "proc-macro2", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 71a30f4c..fd5f2604 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -37,10 +37,8 @@ tauri-plugin-decorum = "0.1.0" webpage = { version = "2.0", features = ["serde"] } keyring = "2" keyring-search = "0.2.0" -specta = "=2.0.0-rc.12" -tauri-specta = { git = "https://github.com/cloudcad/tauri-specta", branch = "main", features = [ - "typescript", -] } +specta = "^2.0.0-rc.12" +tauri-specta = { version = "^2.0.0-rc.11", features = ["typescript"] } tauri-plugin-theme = "0.4.1" [target.'cfg(target_family = "unix")'.dependencies]