Skip to content

Commit d128af1

Browse files
committed
chore: clean up
1 parent f6eb5ee commit d128af1

File tree

27 files changed

+313
-743
lines changed

27 files changed

+313
-743
lines changed

src-tauri/src/commands/metadata.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{str::FromStr, time::Duration};
66
use tauri::State;
77
use tauri_specta::Event;
88

9-
use crate::{NewSettings, Nostr, Settings};
9+
use crate::{common::get_latest_event, NewSettings, Nostr, Settings};
1010

1111
#[derive(Clone, Serialize, Deserialize, Type)]
1212
pub struct Profile {
@@ -229,14 +229,14 @@ pub async fn get_lume_store(key: String, state: State<'_, Nostr>) -> Result<Stri
229229
.author(public_key)
230230
.kind(Kind::ApplicationSpecificData)
231231
.identifier(key)
232-
.limit(1);
232+
.limit(10);
233233

234234
match client
235235
.get_events_of(vec![filter], EventSource::Database)
236236
.await
237237
{
238238
Ok(events) => {
239-
if let Some(event) = events.first() {
239+
if let Some(event) = get_latest_event(&events) {
240240
match signer.nip44_decrypt(public_key, event.content()).await {
241241
Ok(decrypted) => Ok(decrypted),
242242
Err(_) => Err(event.content.to_string()),

src/commons.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import type {
44
PersistedQuery,
55
} from "@tanstack/query-persist-client-core";
66
import { Store } from "@tanstack/store";
7-
import { ask, message } from "@tauri-apps/plugin-dialog";
7+
import { ask, message, open } from "@tauri-apps/plugin-dialog";
8+
import { readFile } from "@tauri-apps/plugin-fs";
89
import { relaunch } from "@tauri-apps/plugin-process";
910
import type { Store as TauriStore } from "@tauri-apps/plugin-store";
1011
import { check } from "@tauri-apps/plugin-updater";
@@ -241,6 +242,61 @@ export async function checkForAppUpdates(silent: boolean) {
241242
}
242243
}
243244

245+
export async function upload(filePath?: string) {
246+
const allowExts = [
247+
"png",
248+
"jpeg",
249+
"jpg",
250+
"gif",
251+
"mp4",
252+
"mp3",
253+
"webm",
254+
"mkv",
255+
"avi",
256+
"mov",
257+
];
258+
259+
const selected =
260+
filePath ||
261+
(
262+
await open({
263+
multiple: false,
264+
filters: [
265+
{
266+
name: "Media",
267+
extensions: allowExts,
268+
},
269+
],
270+
})
271+
).path;
272+
273+
// User cancelled action
274+
if (!selected) return null;
275+
276+
try {
277+
const file = await readFile(selected);
278+
const blob = new Blob([file]);
279+
280+
const data = new FormData();
281+
data.append("fileToUpload", blob);
282+
data.append("submit", "Upload Image");
283+
284+
const res = await fetch("https://nostr.build/api/v2/upload/files", {
285+
method: "POST",
286+
body: data,
287+
});
288+
289+
if (!res.ok) return null;
290+
291+
const json = await res.json();
292+
const content = json.data[0];
293+
294+
return content.url as string;
295+
} catch (e) {
296+
throw new Error(String(e));
297+
}
298+
}
299+
244300
export function toLumeEvents(richEvents: RichEvent[]) {
245301
const events = richEvents.map((item) => {
246302
const nostrEvent: NostrEvent = JSON.parse(item.raw);

src/components/note/buttons/zap.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { appSettings, cn } from "@/commons";
22
import { LumeWindow } from "@/system";
33
import { Lightning } from "@phosphor-icons/react";
4+
import { useSearch } from "@tanstack/react-router";
45
import { useStore } from "@tanstack/react-store";
56
import { useNoteContext } from "../provider";
67

78
export function NoteZap({ large = false }: { large?: boolean }) {
9+
const search = useSearch({ strict: false });
810
const visible = useStore(appSettings, (state) => state.display_zap_button);
911
const event = useNoteContext();
1012

@@ -13,7 +15,7 @@ export function NoteZap({ large = false }: { large?: boolean }) {
1315
return (
1416
<button
1517
type="button"
16-
onClick={() => LumeWindow.openZap(event.id)}
18+
onClick={() => LumeWindow.openZap(event.id, search.account)}
1719
className={cn(
1820
"inline-flex items-center justify-center text-neutral-800 dark:text-neutral-200",
1921
large

src/components/repost.tsx

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@ import { cn } from "@/commons";
22
import { Spinner } from "@/components";
33
import { Note } from "@/components/note";
44
import { User } from "@/components/user";
5-
import { type LumeEvent, NostrQuery } from "@/system";
6-
import { useQuery } from "@tanstack/react-query";
5+
import { type LumeEvent, useEvent } from "@/system";
76
import { memo } from "react";
87

98
export const RepostNote = memo(function RepostNote({
@@ -13,22 +12,7 @@ export const RepostNote = memo(function RepostNote({
1312
event: LumeEvent;
1413
className?: string;
1514
}) {
16-
const { isLoading, isError, data } = useQuery({
17-
queryKey: ["event", event.repostId],
18-
queryFn: async () => {
19-
try {
20-
const data = await NostrQuery.getRepostEvent(event);
21-
return data;
22-
} catch (e) {
23-
throw new Error(e);
24-
}
25-
},
26-
refetchOnWindowFocus: false,
27-
refetchOnMount: false,
28-
refetchOnReconnect: false,
29-
staleTime: Number.POSITIVE_INFINITY,
30-
retry: 2,
31-
});
15+
const { isLoading, isError, data } = useEvent(event.repostId);
3216

3317
return (
3418
<Note.Root

src/components/user/followButton.tsx

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,69 @@
11
import { commands } from "@/commands.gen";
22
import { cn } from "@/commons";
33
import { Spinner } from "@/components";
4-
import { NostrAccount } from "@/system";
4+
import { useQuery } from "@tanstack/react-query";
5+
import { useRouteContext } from "@tanstack/react-router";
56
import { message } from "@tauri-apps/plugin-dialog";
6-
import { useEffect, useState, useTransition } from "react";
7+
import { useTransition } from "react";
78
import { useUserContext } from "./provider";
89

9-
export function UserFollowButton({
10-
simple = false,
11-
className,
12-
}: {
13-
simple?: boolean;
14-
className?: string;
15-
}) {
10+
export function UserFollowButton({ className }: { className?: string }) {
1611
const user = useUserContext();
1712

18-
const [followed, setFollowed] = useState(false);
13+
const { queryClient } = useRouteContext({ strict: false });
14+
const {
15+
isLoading,
16+
isError,
17+
data: isFollow,
18+
} = useQuery({
19+
queryKey: ["status", user.pubkey],
20+
queryFn: async () => {
21+
const res = await commands.checkContact(user.pubkey);
22+
23+
if (res.status === "ok") {
24+
return res.data;
25+
} else {
26+
throw new Error(res.error);
27+
}
28+
},
29+
refetchOnWindowFocus: false,
30+
});
31+
1932
const [isPending, startTransition] = useTransition();
2033

2134
const toggleFollow = () => {
2235
startTransition(async () => {
2336
const res = await commands.toggleContact(user.pubkey, null);
2437

2538
if (res.status === "ok") {
26-
setFollowed((prev) => !prev);
39+
queryClient.setQueryData(
40+
["status", user.pubkey],
41+
(prev: boolean) => !prev,
42+
);
43+
44+
// invalidate cache
45+
await queryClient.invalidateQueries({
46+
queryKey: ["status", user.pubkey],
47+
});
48+
49+
return;
2750
} else {
2851
await message(res.error, { kind: "error" });
2952
return;
3053
}
3154
});
3255
};
3356

34-
useEffect(() => {
35-
let mounted = true;
36-
37-
NostrAccount.checkContact(user.pubkey).then((status) => {
38-
if (mounted) setFollowed(status);
39-
});
40-
41-
return () => {
42-
mounted = false;
43-
};
44-
}, []);
45-
4657
return (
4758
<button
4859
type="button"
4960
disabled={isPending}
5061
onClick={() => toggleFollow()}
5162
className={cn("w-max", className)}
5263
>
53-
{isPending ? (
54-
<Spinner className="size-4" />
55-
) : followed ? (
56-
!simple ? (
57-
"Unfollow"
58-
) : null
59-
) : (
60-
"Follow"
61-
)}
64+
{isError ? "Error" : null}
65+
{isPending || isLoading ? <Spinner className="size-4" /> : null}
66+
{isFollow ? "Unfollow" : "Follow"}
6267
</button>
6368
);
6469
}

src/components/user/nip05.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import { commands } from "@/commands.gen";
12
import { displayLongHandle, displayNpub } from "@/commons";
2-
import { NostrQuery } from "@/system";
33
import { SealCheck } from "@phosphor-icons/react";
44
import * as Tooltip from "@radix-ui/react-tooltip";
55
import { useQuery } from "@tanstack/react-query";
@@ -10,14 +10,13 @@ export function UserNip05() {
1010
const { isLoading, data: verified } = useQuery({
1111
queryKey: ["nip05", user?.pubkey],
1212
queryFn: async () => {
13-
if (!user.profile?.nip05?.length) return false;
13+
const res = await commands.verifyNip05(user.pubkey, user.profile?.nip05);
1414

15-
const verify = await NostrQuery.verifyNip05(
16-
user.pubkey,
17-
user.profile?.nip05,
18-
);
19-
20-
return verify;
15+
if (res.status === "ok") {
16+
return res.data;
17+
} else {
18+
throw new Error(res.error);
19+
}
2120
},
2221
enabled: !!user.profile?.nip05?.length,
2322
refetchOnMount: false,

src/routes/$account/_app/home.lazy.tsx

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
import { commands } from "@/commands.gen";
12
import { Spinner } from "@/components";
23
import { Column } from "@/components/column";
3-
import { LumeWindow, NostrQuery } from "@/system";
4+
import { LumeWindow } from "@/system";
45
import type { ColumnEvent, LumeColumn } from "@/types";
56
import { ArrowLeft, ArrowRight, Plus, StackPlus } from "@phosphor-icons/react";
67
import { createLazyFileRoute } from "@tanstack/react-router";
@@ -24,7 +25,7 @@ export const Route = createLazyFileRoute("/$account/_app/home")({
2425
});
2526

2627
function Screen() {
27-
const initialColumnList = Route.useLoaderData();
28+
const { initialColumns } = Route.useRouteContext();
2829

2930
const [columns, setColumns] = useState<LumeColumn[]>([]);
3031
const [emblaRef, emblaApi] = useEmblaCarousel({
@@ -105,6 +106,18 @@ function Screen() {
105106
event.preventDefault();
106107
}, 150);
107108

109+
const saveAllColumns = useDebouncedCallback(async () => {
110+
const key = "lume_v4:columns";
111+
const content = JSON.stringify(columns);
112+
const res = await commands.setLumeStore(key, content);
113+
114+
if (res.status === "ok") {
115+
return res.data;
116+
} else {
117+
console.log(res.error);
118+
}
119+
}, 200);
120+
108121
useEffect(() => {
109122
if (emblaApi) {
110123
emblaApi.on("scroll", emitScrollEvent);
@@ -120,14 +133,12 @@ function Screen() {
120133
}, [emblaApi, emitScrollEvent, emitResizeEvent]);
121134

122135
useEffect(() => {
123-
if (columns) {
124-
NostrQuery.setColumns(columns).then(() => console.log("saved"));
125-
}
136+
if (columns) saveAllColumns();
126137
}, [columns]);
127138

128139
useEffect(() => {
129-
setColumns(initialColumnList);
130-
}, [initialColumnList]);
140+
setColumns(initialColumns);
141+
}, [initialColumns]);
131142

132143
// Listen for keyboard event
133144
useEffect(() => {

src/routes/$account/_app/home.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,18 @@ import type { LumeColumn } from "@/types";
33
import { createFileRoute } from "@tanstack/react-router";
44

55
export const Route = createFileRoute("/$account/_app/home")({
6-
loader: async ({ context }) => {
6+
beforeLoad: async ({ context }) => {
77
const key = "lume_v4:columns";
88
const defaultColumns = context.systemColumns.filter((col) => col.default);
99
const query = await commands.getLumeStore(key);
1010

11+
let initialColumns: LumeColumn[] = defaultColumns;
12+
1113
if (query.status === "ok") {
12-
const columns: LumeColumn[] = JSON.parse(query.data);
13-
return columns;
14-
} else {
15-
return defaultColumns;
14+
initialColumns = JSON.parse(query.data);
15+
return { initialColumns };
1616
}
17+
18+
return { initialColumns };
1719
},
1820
});

src/routes/$account/_settings/bitcoin-connect.lazy.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { commands } from "@/commands.gen";
12
import { NostrAccount } from "@/system";
23
import { Button } from "@getalby/bitcoin-connect-react";
34
import { createLazyFileRoute } from "@tanstack/react-router";
@@ -11,8 +12,13 @@ export const Route = createLazyFileRoute("/$account/_settings/bitcoin-connect")(
1112

1213
function Screen() {
1314
const setNwcUri = async (uri: string) => {
14-
const cmd = await NostrAccount.setWallet(uri);
15-
if (cmd) getCurrentWebviewWindow().close();
15+
const res = await commands.setWallet(uri);
16+
17+
if (res.status === "ok") {
18+
await getCurrentWebviewWindow().close();
19+
} else {
20+
throw new Error(res.error);
21+
}
1622
};
1723

1824
return (

0 commit comments

Comments
 (0)