Compare commits

..
4 Commits
Author SHA1 Message Date
reya 6d42360549 chore: bump version 2024-05-29 14:47:22 +07:00
reya 70c5143445 feat: redirect to index after add account 2024-05-29 14:41:33 +07:00
reya 41b66b18f5 feat: lazy load onboarding videos 2024-05-29 14:11:30 +07:00
雨宮蓮andGitHub dda0720ed4 chore: update deps (#195) 2024-05-29 12:54:58 +07:00
21 changed files with 1315 additions and 1480 deletions
+16 -16
View File
@@ -9,8 +9,8 @@
"preview": "vite preview" "preview": "vite preview"
}, },
"dependencies": { "dependencies": {
"@lume/system": "workspace:^",
"@lume/icons": "workspace:^", "@lume/icons": "workspace:^",
"@lume/system": "workspace:^",
"@lume/ui": "workspace:^", "@lume/ui": "workspace:^",
"@lume/utils": "workspace:^", "@lume/utils": "workspace:^",
"@radix-ui/react-avatar": "^1.0.4", "@radix-ui/react-avatar": "^1.0.4",
@@ -22,42 +22,42 @@
"@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-popover": "^1.0.7",
"@radix-ui/react-switch": "^1.0.3", "@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-tooltip": "^1.0.7", "@radix-ui/react-tooltip": "^1.0.7",
"@tanstack/query-sync-storage-persister": "^5.36.0", "@tanstack/query-sync-storage-persister": "^5.40.0",
"@tanstack/react-query": "^5.36.0", "@tanstack/react-query": "^5.40.0",
"@tanstack/react-query-persist-client": "^5.36.0", "@tanstack/react-query-persist-client": "^5.40.0",
"@tanstack/react-router": "1.32.5", "@tanstack/react-router": "^1.34.5",
"i18next": "^23.11.4", "i18next": "^23.11.5",
"i18next-resources-to-backend": "^1.2.1", "i18next-resources-to-backend": "^1.2.1",
"minidenticons": "^4.2.1", "minidenticons": "^4.2.1",
"nanoid": "^5.0.7", "nanoid": "^5.0.7",
"nostr-tools": "^2.5.2", "nostr-tools": "^2.6.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-currency-input-field": "^3.8.0", "react-currency-input-field": "^3.8.0",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-hook-form": "^7.51.4", "react-hook-form": "^7.51.5",
"react-hotkeys-hook": "^4.5.0", "react-hotkeys-hook": "^4.5.0",
"react-i18next": "^14.1.1", "react-i18next": "^14.1.2",
"react-string-replace": "^1.1.1", "react-string-replace": "^1.1.1",
"slate": "^0.103.0", "slate": "^0.103.0",
"slate-react": "^0.102.0", "slate-react": "^0.104.0",
"sonner": "^1.4.41", "sonner": "^1.4.41",
"use-debounce": "^10.0.0", "use-debounce": "^10.0.1",
"virtua": "^0.31.0" "virtua": "^0.31.0"
}, },
"devDependencies": { "devDependencies": {
"@lume/tailwindcss": "workspace:^", "@lume/tailwindcss": "workspace:^",
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@tanstack/router-devtools": "^1.32.5", "@tanstack/router-devtools": "^1.34.5",
"@tanstack/router-vite-plugin": "^1.32.2", "@tanstack/router-vite-plugin": "^1.34.1",
"@types/react": "^18.3.2", "@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"@vitejs/plugin-react-swc": "^3.6.0", "@vitejs/plugin-react-swc": "^3.7.0",
"autoprefixer": "^10.4.19", "autoprefixer": "^10.4.19",
"postcss": "^8.4.38", "postcss": "^8.4.38",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"typescript": "^5.4.5", "typescript": "^5.4.5",
"vite": "^5.2.11", "vite": "^5.2.12",
"vite-plugin-top-level-await": "^1.4.1", "vite-plugin-top-level-await": "^1.4.1",
"vite-tsconfig-paths": "^4.3.2" "vite-tsconfig-paths": "^4.3.2"
} }
Binary file not shown.

After

Width:  |  Height:  |  Size: 171 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

@@ -9,7 +9,7 @@ import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { toast } from "sonner"; import { toast } from "sonner";
export const Route = createFileRoute("/auth/new/$account/backup")({ export const Route = createFileRoute("/auth/$account/backup")({
component: Screen, component: Screen,
}); });
@@ -33,8 +33,7 @@ function Screen() {
} }
return navigate({ return navigate({
to: "/auth/$account/settings", to: "/auth/settings",
params: { account },
}); });
} }
@@ -45,7 +45,7 @@ function Screen() {
if (eventId) { if (eventId) {
navigate({ navigate({
to: "/auth/new/$account/backup", to: "/auth/$account/backup",
params: { account: account.npub }, params: { account: account.npub },
replace: true, replace: true,
}); });
@@ -28,8 +28,7 @@ function Screen() {
if (npub) { if (npub) {
navigate({ navigate({
to: "/auth/$account/settings", to: "/auth/settings",
params: { account: npub },
replace: true, replace: true,
}); });
} }
@@ -27,8 +27,7 @@ function Screen() {
if (npub) { if (npub) {
navigate({ navigate({
to: "/auth/$account/settings", to: "/auth/settings",
params: { account: npub },
replace: true, replace: true,
}); });
} }
@@ -8,7 +8,7 @@ import { useState } from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { toast } from "sonner"; import { toast } from "sonner";
export const Route = createFileRoute("/auth/$account/settings")({ export const Route = createFileRoute("/auth/settings")({
beforeLoad: async () => { beforeLoad: async () => {
const settings = await NostrQuery.getSettings(); const settings = await NostrQuery.getSettings();
return { settings }; return { settings };
@@ -18,14 +18,14 @@ export const Route = createFileRoute("/auth/$account/settings")({
}); });
function Screen() { function Screen() {
const navigate = Route.useNavigate();
const { account } = Route.useParams();
const { settings } = Route.useRouteContext(); const { settings } = Route.useRouteContext();
const { t } = useTranslation(); const { t } = useTranslation();
const [newSettings, setNewSettings] = useState(settings); const [newSettings, setNewSettings] = useState(settings);
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const navigate = Route.useNavigate();
const toggleNofitication = async () => { const toggleNofitication = async () => {
await requestPermission(); await requestPermission();
setNewSettings((prev) => ({ setNewSettings((prev) => ({
@@ -72,8 +72,7 @@ function Screen() {
if (eventId) { if (eventId) {
return navigate({ return navigate({
to: "/$account/home", to: "/",
params: { account },
replace: true, replace: true,
}); });
} }
+8
View File
@@ -34,6 +34,8 @@ function Screen() {
className="h-auto w-full aspect-square rounded-lg shadow-md transform" className="h-auto w-full aspect-square rounded-lg shadow-md transform"
controls controls
muted muted
preload="none"
poster="/poster_1.jpeg"
> >
<source <source
src="https://video.nostr.build/692f71e2be47ecfc29edcbdaa198cc5979bfb9c900f05d78682895dd546d8d4f.mp4" src="https://video.nostr.build/692f71e2be47ecfc29edcbdaa198cc5979bfb9c900f05d78682895dd546d8d4f.mp4"
@@ -55,6 +57,8 @@ function Screen() {
className="h-auto w-full aspect-square rounded-lg shadow-md transform" className="h-auto w-full aspect-square rounded-lg shadow-md transform"
controls controls
muted muted
preload="none"
poster="/poster_2.jpeg"
> >
<source <source
src="https://video.nostr.build/d33962520506d86acfb4b55a7b265821e10ae637f5ec830a173b7e6092b16ec8.mp4" src="https://video.nostr.build/d33962520506d86acfb4b55a7b265821e10ae637f5ec830a173b7e6092b16ec8.mp4"
@@ -76,6 +80,8 @@ function Screen() {
className="h-auto w-full aspect-square rounded-lg shadow-md transform" className="h-auto w-full aspect-square rounded-lg shadow-md transform"
controls controls
muted muted
preload="none"
poster="/poster_3.jpeg"
> >
<source <source
src="https://video.nostr.build/927abbfde2097e470ac751181b1db456b7e4b9149550408efff1a966a7ffb9a8.mp4" src="https://video.nostr.build/927abbfde2097e470ac751181b1db456b7e4b9149550408efff1a966a7ffb9a8.mp4"
@@ -97,6 +103,8 @@ function Screen() {
className="h-auto w-full rounded-lg shadow-md transform" className="h-auto w-full rounded-lg shadow-md transform"
controls controls
muted muted
preload="none"
poster="/poster_4.jpeg"
> >
<source <source
src="https://video.nostr.build/513de4824b6abaf7e9698c1dad2f68096574356848c0c200bc8cb8074df29410.mp4" src="https://video.nostr.build/513de4824b6abaf7e9698c1dad2f68096574356848c0c200bc8cb8074df29410.mp4"
+1 -1
View File
@@ -13,7 +13,7 @@
"@astrojs/check": "^0.5.10", "@astrojs/check": "^0.5.10",
"@astrojs/tailwind": "^5.1.0", "@astrojs/tailwind": "^5.1.0",
"@fontsource/alice": "^5.0.13", "@fontsource/alice": "^5.0.13",
"astro": "^4.8.3", "astro": "^4.9.2",
"astro-seo-meta": "^4.1.1", "astro-seo-meta": "^4.1.1",
"astro-seo-schema": "^4.0.2", "astro-seo-schema": "^4.0.2",
"schema-dts": "^1.1.2", "schema-dts": "^1.1.2",
+1 -1
View File
@@ -20,7 +20,7 @@
"node": ">=18" "node": ">=18"
}, },
"dependencies": { "dependencies": {
"@tauri-apps/api": "^2.0.0-beta.7", "@tauri-apps/api": "2.0.0-beta.13",
"@tauri-apps/plugin-autostart": "2.0.0-beta.3", "@tauri-apps/plugin-autostart": "2.0.0-beta.3",
"@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.1", "@tauri-apps/plugin-clipboard-manager": "2.1.0-beta.1",
"@tauri-apps/plugin-dialog": "2.0.0-beta.3", "@tauri-apps/plugin-dialog": "2.0.0-beta.3",
+1 -1
View File
@@ -8,7 +8,7 @@
}, },
"devDependencies": { "devDependencies": {
"@lume/tsconfig": "workspace:*", "@lume/tsconfig": "workspace:*",
"@types/react": "^18.3.2", "@types/react": "^18.3.3",
"typescript": "^5.4.5" "typescript": "^5.4.5"
} }
} }
+2 -2
View File
@@ -5,13 +5,13 @@
"main": "./src/index.ts", "main": "./src/index.ts",
"dependencies": { "dependencies": {
"@lume/utils": "workspace:^", "@lume/utils": "workspace:^",
"@tanstack/react-query": "^5.36.0", "@tanstack/react-query": "^5.40.0",
"react": "^18.3.1" "react": "^18.3.1"
}, },
"devDependencies": { "devDependencies": {
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.3.2", "@types/react": "^18.3.3",
"typescript": "^5.4.5" "typescript": "^5.4.5"
} }
} }
+393 -579
View File
@@ -1,598 +1,412 @@
// 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<Result<Relays, null>> {
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<Result<boolean, null>> {
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<Result<boolean, null>> {
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<Result<string[], string>> {
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<Result<Account, null>> {
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<Result<string, string>> {
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<Result<string, string>> {
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 nostrConnect(npub: string, uri: string) : Promise<Result<string, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("nostr_connect", { npub, uri }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async loadAccount(npub: string) : Promise<Result<boolean, string>> {
try {
return { status: "ok", data: await TAURI_INVOKE("load_account", { npub }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async eventToBech32(id: string, relays: string[]) : Promise<Result<string, null>> {
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<Result<string, null>> {
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 toNpub(hex: string) : Promise<Result<string, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("to_npub", { hex }) };
} catch (e) {
if(e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async verifyNip05(key: string, nip05: string) : Promise<Result<boolean, string>> {
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<Result<string[], string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<string[], string>> {
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<Result<boolean, string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<boolean, string>> {
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<Result<boolean, string>> {
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<Result<string, string>> {
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<Result<boolean, string>> {
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<Result<boolean, string>> {
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<Result<boolean, string>> {
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<Result<string, string>> {
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<Result<string[], string>> {
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<Result<string[], string>> {
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<Result<string[], string>> {
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<Result<string[], string>> {
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<Result<string[], string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<void> {
await TAURI_INVOKE("show_in_folder", { path });
},
async createColumn(label: string, x: number, y: number, width: number, height: number, url: string) : Promise<Result<string, string>> {
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<Result<boolean, null>> {
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<Result<null, string>> {
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<Result<null, string>> {
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<Result<null, string>> {
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<void> {
await TAURI_INVOKE("set_badge", { count });
}
}
export const commands = {
async getRelays(): Promise<Result<Relays, null>> {
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<Result<boolean, null>> {
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<Result<boolean, null>> {
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<Result<string[], string>> {
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<Result<Account, null>> {
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<Result<string, string>> {
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<Result<string, string>> {
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 nostrConnect(
npub: string,
uri: string,
): Promise<Result<string, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("nostr_connect", { npub, uri }),
};
} catch (e) {
if (e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async loadAccount(npub: string): Promise<Result<boolean, string>> {
try {
return {
status: "ok",
data: await TAURI_INVOKE("load_account", { npub }),
};
} catch (e) {
if (e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async eventToBech32(
id: string,
relays: string[],
): Promise<Result<string, null>> {
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<Result<string, null>> {
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 toNpub(hex: string): Promise<Result<string, null>> {
try {
return { status: "ok", data: await TAURI_INVOKE("to_npub", { hex }) };
} catch (e) {
if (e instanceof Error) throw e;
else return { status: "error", error: e as any };
}
},
async verifyNip05(
key: string,
nip05: string,
): Promise<Result<boolean, string>> {
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<Result<string[], string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<string[], string>> {
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<Result<boolean, string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<Result<boolean, string>> {
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<Result<boolean, string>> {
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<Result<string, string>> {
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<Result<boolean, string>> {
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<Result<boolean, string>> {
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<Result<boolean, string>> {
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<Result<string, string>> {
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<Result<string[], string>> {
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<Result<string[], string>> {
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<Result<string[], string>> {
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<Result<string[], string>> {
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<Result<string[], string>> {
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<Result<string, string>> {
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<Result<string, string>> {
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<void> {
await TAURI_INVOKE("show_in_folder", { path });
},
async createColumn(
label: string,
x: number,
y: number,
width: number,
height: number,
url: string,
): Promise<Result<string, string>> {
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<Result<boolean, null>> {
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<Result<null, string>> {
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<Result<null, string>> {
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<Result<null, string>> {
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<void> {
await TAURI_INVOKE("set_badge", { count });
},
};
/** user-defined types **/ /** user-defined types **/
export type Account = { npub: string; nsec: string }; export type Account = { npub: string; nsec: string }
export type Relays = { export type Relays = { connected: string[]; read: string[] | null; write: string[] | null; both: string[] | null }
connected: string[];
read: string[] | null;
write: string[] | null;
both: string[] | null;
};
/** tauri-specta globals **/ /** 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 * as TAURI_API_EVENT from "@tauri-apps/api/event";
import { type WebviewWindow as __WebviewWindow__ } from "@tauri-apps/api/webviewWindow"; import { type WebviewWindow as __WebviewWindow__ } from "@tauri-apps/api/webviewWindow";
type __EventObj__<T> = { type __EventObj__<T> = {
listen: ( listen: (
cb: TAURI_API_EVENT.EventCallback<T>, cb: TAURI_API_EVENT.EventCallback<T>
) => ReturnType<typeof TAURI_API_EVENT.listen<T>>; ) => ReturnType<typeof TAURI_API_EVENT.listen<T>>;
once: ( once: (
cb: TAURI_API_EVENT.EventCallback<T>, cb: TAURI_API_EVENT.EventCallback<T>
) => ReturnType<typeof TAURI_API_EVENT.once<T>>; ) => ReturnType<typeof TAURI_API_EVENT.once<T>>;
emit: T extends null emit: T extends null
? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit> ? (payload?: T) => ReturnType<typeof TAURI_API_EVENT.emit>
: (payload: T) => ReturnType<typeof TAURI_API_EVENT.emit>; : (payload: T) => ReturnType<typeof TAURI_API_EVENT.emit>;
}; };
export type Result<T, E> = export type Result<T, E> =
| { status: "ok"; data: T } | { status: "ok"; data: T }
| { status: "error"; error: E }; | { status: "error"; error: E };
function __makeEvents__<T extends Record<string, any>>( function __makeEvents__<T extends Record<string, any>>(
mappings: Record<keyof T, string>, mappings: Record<keyof T, string>
) { ) {
return new Proxy( return new Proxy(
{} as unknown as { {} as unknown as {
[K in keyof T]: __EventObj__<T[K]> & { [K in keyof T]: __EventObj__<T[K]> & {
(handle: __WebviewWindow__): __EventObj__<T[K]>; (handle: __WebviewWindow__): __EventObj__<T[K]>;
}; };
}, },
{ {
get: (_, event) => { get: (_, event) => {
const name = mappings[event as keyof T]; const name = mappings[event as keyof T];
return new Proxy((() => {}) as any, { return new Proxy((() => {}) as any, {
apply: (_, __, [window]: [__WebviewWindow__]) => ({ apply: (_, __, [window]: [__WebviewWindow__]) => ({
listen: (arg: any) => window.listen(name, arg), listen: (arg: any) => window.listen(name, arg),
once: (arg: any) => window.once(name, arg), once: (arg: any) => window.once(name, arg),
emit: (arg: any) => window.emit(name, arg), emit: (arg: any) => window.emit(name, arg),
}), }),
get: (_, command: keyof __EventObj__<any>) => { get: (_, command: keyof __EventObj__<any>) => {
switch (command) { switch (command) {
case "listen": case "listen":
return (arg: any) => TAURI_API_EVENT.listen(name, arg); return (arg: any) => TAURI_API_EVENT.listen(name, arg);
case "once": case "once":
return (arg: any) => TAURI_API_EVENT.once(name, arg); return (arg: any) => TAURI_API_EVENT.once(name, arg);
case "emit": case "emit":
return (arg: any) => TAURI_API_EVENT.emit(name, arg); return (arg: any) => TAURI_API_EVENT.emit(name, arg);
} }
}, },
}); });
}, },
}, }
); );
} }
+7 -10
View File
@@ -236,31 +236,28 @@ export class NostrQuery {
} }
static async getColumns() { static async getColumns() {
const systemPath = "resources/system_columns.json";
const resourcePath = await resolveResource(systemPath);
const resourceFile = await readTextFile(resourcePath);
const systemColumns: LumeColumn[] = JSON.parse(resourceFile);
const query = await commands.getNstore(NSTORE_KEYS.columns); const query = await commands.getNstore(NSTORE_KEYS.columns);
if (query.status === "ok") { if (query.status === "ok") {
const columns: LumeColumn[] = query.data ? JSON.parse(query.data) : []; const columns: LumeColumn[] = query.data ? JSON.parse(query.data) : [];
if (columns.length < 1) { if (columns.length < 1) {
const systemPath = "resources/system_columns.json";
const resourcePath = await resolveResource(systemPath);
const resourceFile = await readTextFile(resourcePath);
const systemColumns: LumeColumn[] = JSON.parse(resourceFile);
return systemColumns; return systemColumns;
} }
return columns; return columns;
} else { } else {
return []; return systemColumns;
} }
} }
static async setColumns(columns: LumeColumn[]) { static async setColumns(columns: LumeColumn[]) {
const query = await commands.setNstore( const content = JSON.stringify(columns);
NSTORE_KEYS.columns, const query = await commands.setNstore(NSTORE_KEYS.columns, content);
JSON.stringify(columns),
);
if (query.status === "ok") { if (query.status === "ok") {
return query.data; return query.data;
+1 -1
View File
@@ -14,7 +14,7 @@
"@lume/tailwindcss": "workspace:^", "@lume/tailwindcss": "workspace:^",
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.3.2", "@types/react": "^18.3.3",
"tailwindcss": "^3.4.3", "tailwindcss": "^3.4.3",
"typescript": "^5.4.5" "typescript": "^5.4.5"
} }
+4 -4
View File
@@ -8,21 +8,21 @@
"access": "public" "access": "public"
}, },
"dependencies": { "dependencies": {
"@tanstack/react-query": "^5.36.0", "@tanstack/react-query": "^5.40.0",
"bitcoin-units": "^1.0.0", "bitcoin-units": "^1.0.0",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"dayjs": "^1.11.11", "dayjs": "^1.11.11",
"light-bolt11-decoder": "^3.1.1", "light-bolt11-decoder": "^3.1.1",
"nostr-tools": "^2.5.2", "nostr-tools": "^2.6.0",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"slate": "^0.103.0", "slate": "^0.103.0",
"slate-react": "^0.102.0" "slate-react": "^0.104.0"
}, },
"devDependencies": { "devDependencies": {
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.3.2", "@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0", "@types/react-dom": "^18.3.0",
"tailwind-merge": "^2.3.0", "tailwind-merge": "^2.3.0",
"typescript": "^5.4.5" "typescript": "^5.4.5"
+871 -851
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -1,7 +1,7 @@
{ {
"$schema": "../node_modules/@tauri-apps/cli/schema.json", "$schema": "../node_modules/@tauri-apps/cli/schema.json",
"productName": "Lume", "productName": "Lume",
"version": "4.0.6", "version": "4.0.7",
"identifier": "nu.lume.Lume", "identifier": "nu.lume.Lume",
"build": { "build": {
"beforeBuildCommand": "pnpm desktop:build", "beforeBuildCommand": "pnpm desktop:build",