From c72798507e1f8fe34d0791eeb8f65855693719f4 Mon Sep 17 00:00:00 2001 From: Ren Amamiya <123083837+reyamir@users.noreply.github.com> Date: Tue, 18 Apr 2023 19:15:04 +0700 Subject: [PATCH] completed migrate to tauri-sql --- .../20230418080146_create_chats.sql | 10 ++ src-tauri/src/main.rs | 20 ++- src/app/nostr/channels/[id]/page.tsx | 2 +- src/app/nostr/channels/page.tsx | 9 +- src/app/nostr/chats/[pubkey]/page.tsx | 2 +- src/app/nostr/newsfeed/following/page.tsx | 28 +--- src/app/onboarding/create/[...slug]/page.tsx | 6 +- src/app/onboarding/login/[privkey]/page.tsx | 11 +- src/app/onboarding/login/page.tsx | 23 ++-- src/app/page.tsx | 121 ++++++++---------- src/components/channels/browseChannelItem.tsx | 17 +-- src/components/channels/channelList.tsx | 15 +-- src/components/channels/channelListItem.tsx | 4 +- .../channels/createChannelModal.tsx | 12 +- .../channels/messages/hideMessageButton.tsx | 2 +- .../channels/messages/muteButton.tsx | 2 +- src/components/chats/chatList.tsx | 11 +- src/components/chats/chatModal.tsx | 15 +-- src/components/chats/messageList.tsx | 2 +- src/components/eventCollector.tsx | 108 +++++----------- src/components/form/base.tsx | 2 +- src/components/form/channelMessage.tsx | 2 +- src/components/form/chat.tsx | 2 +- src/components/form/comment.tsx | 2 +- src/components/multiAccounts/index.tsx | 17 +-- src/components/note/base.tsx | 8 +- src/components/note/comment.tsx | 6 +- src/components/note/extend.tsx | 6 +- src/components/note/meta/comment.tsx | 2 +- src/components/note/meta/reaction.tsx | 2 +- src/components/note/metadata.tsx | 2 +- src/components/note/parent.tsx | 34 +++-- src/components/note/quote.tsx | 32 ++--- src/components/note/quoteRepost.tsx | 2 +- src/components/relaysProvider.tsx | 2 +- src/utils/bindings.ts | 110 ---------------- src/utils/commands.tsx | 13 -- src/utils/hooks/useProfileMetadata.tsx | 22 +--- src/utils/storage.tsx | 80 +++++++++++- src/utils/transform.tsx | 31 ++--- 40 files changed, 321 insertions(+), 476 deletions(-) create mode 100644 src-tauri/migrations/20230418080146_create_chats.sql delete mode 100644 src/utils/bindings.ts delete mode 100644 src/utils/commands.tsx diff --git a/src-tauri/migrations/20230418080146_create_chats.sql b/src-tauri/migrations/20230418080146_create_chats.sql new file mode 100644 index 00000000..0e0ceb3b --- /dev/null +++ b/src-tauri/migrations/20230418080146_create_chats.sql @@ -0,0 +1,10 @@ +-- Add migration script here +-- create chats table +CREATE TABLE + chats ( + id INTEGER NOT NULL PRIMARY KEY, + account_id INTEGER NOT NULL, + pubkey TEXT NOT NULL UNIQUE, + created_at INTEGER NOT NULL, + FOREIGN KEY (account_id) REFERENCES accounts (id) + ); \ No newline at end of file diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 817c0de4..54cd3367 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -50,12 +50,20 @@ fn main() { tauri_plugin_sql::Builder::default() .add_migrations( "sqlite:lume.db", - vec![Migration { - version: 20230418013219, - description: "initial data", - sql: include_str!("../migrations/20230418013219_initial_data.sql"), - kind: MigrationKind::Up, - }], + vec![ + Migration { + version: 20230418013219, + description: "initial data", + sql: include_str!("../migrations/20230418013219_initial_data.sql"), + kind: MigrationKind::Up, + }, + Migration { + version: 20230418080146, + description: "create chats", + sql: include_str!("../migrations/20230418080146_create_chats.sql"), + kind: MigrationKind::Up, + }, + ], ) .build(), ) diff --git a/src/app/nostr/channels/[id]/page.tsx b/src/app/nostr/channels/[id]/page.tsx index 6fa2a4e7..0e078998 100644 --- a/src/app/nostr/channels/[id]/page.tsx +++ b/src/app/nostr/channels/[id]/page.tsx @@ -13,7 +13,7 @@ import { Suspense, useContext, useEffect, useRef } from 'react'; export default function Page({ params }: { params: { id: string } }) { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const setChannelMessages = useSetAtom(channelMessagesAtom); const resetChannelMessages = useResetAtom(channelMessagesAtom); diff --git a/src/app/nostr/channels/page.tsx b/src/app/nostr/channels/page.tsx index be4ff78b..5dc58d62 100644 --- a/src/app/nostr/channels/page.tsx +++ b/src/app/nostr/channels/page.tsx @@ -2,18 +2,15 @@ import { BrowseChannelItem } from '@components/channels/browseChannelItem'; +import { getChannels } from '@utils/storage'; + import { useEffect, useState } from 'react'; export default function Page() { const [list, setList] = useState([]); useEffect(() => { - const fetchChannels = async () => { - const { getChannels } = await import('@utils/bindings'); - return await getChannels({ limit: 100, offset: 0 }); - }; - - fetchChannels() + getChannels(100, 0) .then((res) => setList(res)) .catch(console.error); }, []); diff --git a/src/app/nostr/chats/[pubkey]/page.tsx b/src/app/nostr/chats/[pubkey]/page.tsx index 22d8d5a2..2fbebde6 100644 --- a/src/app/nostr/chats/[pubkey]/page.tsx +++ b/src/app/nostr/chats/[pubkey]/page.tsx @@ -13,7 +13,7 @@ import { Suspense, useCallback, useContext, useEffect, useRef } from 'react'; export default function Page({ params }: { params: { pubkey: string } }) { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const setChatMessages = useSetAtom(chatMessagesAtom); const resetChatMessages = useResetAtom(chatMessagesAtom); diff --git a/src/app/nostr/newsfeed/following/page.tsx b/src/app/nostr/newsfeed/following/page.tsx index 9be40707..6b28d294 100644 --- a/src/app/nostr/newsfeed/following/page.tsx +++ b/src/app/nostr/newsfeed/following/page.tsx @@ -8,6 +8,7 @@ import { NoteQuoteRepost } from '@components/note/quoteRepost'; import { filteredNotesAtom, hasNewerNoteAtom, notesAtom } from '@stores/note'; import { dateToUnix } from '@utils/getDate'; +import { getLatestNotes, getNotes } from '@utils/storage'; import { ArrowUp } from 'iconoir-react'; import { useAtom, useAtomValue, useSetAtom } from 'jotai'; @@ -40,43 +41,28 @@ export default function Page() { const computeItemKey = useCallback( (index: string | number) => { - return data[index].eventId; + return data[index].event_id; }, [data] ); const initialData = useCallback(async () => { - const { getNotes } = await import('@utils/bindings'); - const result: any = await getNotes({ - date: dateToUnix(now.current), - limit: limit.current, - offset: offset.current, - }); + const result = await getNotes(dateToUnix(now.current), limit.current, offset.current); setData((data) => [...data, ...result]); }, [setData]); const loadMore = useCallback(async () => { - const { getNotes } = await import('@utils/bindings'); offset.current += limit.current; - // next query - const result: any = await getNotes({ - date: dateToUnix(now.current), - limit: limit.current, - offset: offset.current, - }); + // query next page + const result = await getNotes(dateToUnix(now.current), limit.current, offset.current); setData((data) => [...data, ...result]); }, [setData]); const loadLatest = useCallback(async () => { - const { getLatestNotes } = await import('@utils/bindings'); // next query - const result: any = await getLatestNotes({ date: dateToUnix(now.current) }); + const result = await getLatestNotes(dateToUnix(now.current)); // update data - if (Array.isArray(result)) { - setData((data) => [...result, ...data]); - } else { - setData((data) => [result, ...data]); - } + setData((data) => [...result, ...data]); // hide newer trigger setHasNewerNote(false); // scroll to top diff --git a/src/app/onboarding/create/[...slug]/page.tsx b/src/app/onboarding/create/[...slug]/page.tsx index dede8f66..0ec392c0 100644 --- a/src/app/onboarding/create/[...slug]/page.tsx +++ b/src/app/onboarding/create/[...slug]/page.tsx @@ -73,10 +73,11 @@ export default function Page({ params }: { params: { slug: string } }) { // save follows to database then broadcast const submit = useCallback(async () => { setLoading(true); + const nip02 = arrayToNIP02(follows); - // update account's folllows with nip03 tag list - updateAccount('follows', nip02, pubkey); + // update account's folllows with NIP-02 tag list + updateAccount('follows', follows, pubkey); // create pleb for (const tag of follows) { @@ -93,7 +94,6 @@ export default function Page({ params }: { params: { slug: string } }) { pubkey: pubkey, tags: nip02, }; - console.log(event); event.id = getEventHash(event); event.sig = signEvent(event, privkey); // broadcast diff --git a/src/app/onboarding/login/[privkey]/page.tsx b/src/app/onboarding/login/[privkey]/page.tsx index 0f1f113d..c5bcfb24 100644 --- a/src/app/onboarding/login/[privkey]/page.tsx +++ b/src/app/onboarding/login/[privkey]/page.tsx @@ -6,7 +6,8 @@ import { DEFAULT_AVATAR } from '@stores/constants'; import { fetchProfileMetadata } from '@utils/hooks/useProfileMetadata'; import { shortenKey } from '@utils/shortenKey'; -import { createAccount, createPleb } from '@utils/storage'; +import { createAccount, createPleb, updateAccount } from '@utils/storage'; +import { nip02ToArray } from '@utils/transform'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; @@ -26,7 +27,7 @@ export default function Page({ params }: { params: { privkey: string } }) { const createPlebs = useCallback(async (tags: string[]) => { for (const tag of tags) { fetchProfileMetadata(tag[1]) - .then((res: any) => createPleb(tag[1], res)) + .then((res: any) => createPleb(tag[1], res.content)) .catch(console.error); } }, []); @@ -37,6 +38,7 @@ export default function Page({ params }: { params: { privkey: string } }) { { authors: [pubkey], kinds: [0, 3], + since: 0, }, ], relays, @@ -46,11 +48,14 @@ export default function Page({ params }: { params: { privkey: string } }) { createAccount(pubkey, params.privkey, event.content); // update state setProfile({ - metadata: JSON.parse(event.metadata), + metadata: JSON.parse(event.content), }); } else { if (event.tags.length > 0) { createPlebs(event.tags); + const arr = nip02ToArray(event.tags); + // update account's folllows with NIP-02 tag list + updateAccount('follows', arr, pubkey); } } }, diff --git a/src/app/onboarding/login/page.tsx b/src/app/onboarding/login/page.tsx index 44fbb03c..dc2adca1 100644 --- a/src/app/onboarding/login/page.tsx +++ b/src/app/onboarding/login/page.tsx @@ -2,7 +2,7 @@ import { CableTag } from 'iconoir-react'; import { useRouter } from 'next/navigation'; -import { nip19 } from 'nostr-tools'; +import { getPublicKey, nip19 } from 'nostr-tools'; import { Resolver, useForm } from 'react-hook-form'; type FormValues = { @@ -33,14 +33,15 @@ export default function Page() { } = useForm({ resolver }); const onSubmit = async (data: any) => { - let privkey = data['key']; - - if (privkey.substring(0, 4) === 'nsec') { - privkey = nip19.decode(privkey).data; - } - try { - router.push(`/onboarding/login/${privkey}`); + let privkey = data['key']; + + if (privkey.substring(0, 4) === 'nsec') { + privkey = nip19.decode(privkey).data; + } + if (typeof getPublicKey(privkey) === 'string') { + router.push(`/onboarding/login/${privkey}`); + } } catch (error) { setError('key', { type: 'custom', @@ -75,7 +76,7 @@ export default function Page() { or -
+
- {errors.key &&

{errors.key.message}

}
+ {errors.key &&

{errors.key.message}

}
-
+
{isSubmitting ? ( { - const { getPlebs } = await import('@utils/bindings'); - return await getPlebs({ account_id: id, kind: kind }); - }, []); - - const totalNotes = useCallback(async () => { - const { countTotalNotes } = await import('@utils/commands'); - return countTotalNotes(); - }, []); - - const totalChannels = useCallback(async () => { - const { countTotalChannels } = await import('@utils/commands'); - return countTotalChannels(); - }, []); - - const totalChats = useCallback(async () => { - const { countTotalChats } = await import('@utils/commands'); - return countTotalChats(); - }, []); - const fetchData = useCallback( - async (account) => { - const { createNote } = await import('@utils/bindings'); - const { createChat } = await import('@utils/bindings'); - const { createChannel } = await import('@utils/bindings'); - - const notes = await totalNotes(); - const channels = await totalChannels(); - const chats = await totalChats(); + async (account: { id: number; pubkey: string; chats: string[] }, follows: any) => { + const notes = await countTotalNotes(); + const channels = await countTotalChannels(); + const chats = account.chats?.length || 0; const query = []; let since: number; // kind 1 (notes) query - if (notes === 0) { + if (notes.total === 0) { since = dateToUnix(hoursAgo(24, now.current)); } else { since = dateToUnix(new Date(lastLogin)); } query.push({ kinds: [1, 6], - authors: account.follows, + authors: JSON.parse(follows), since: since, until: dateToUnix(now.current), }); @@ -77,7 +61,7 @@ export default function Page() { }); } // kind 40 (channels) query - if (channels === 0) { + if (channels.total === 0) { query.push({ kinds: [40], since: 0, @@ -88,51 +72,46 @@ export default function Page() { unsubscribe.current = pool.subscribe( query, relays, - (event) => { + (event: { kind: number; tags: string[]; id: string; pubkey: string; content: string; created_at: number }) => { switch (event.kind) { // short text note case 1: const parentID = getParentID(event.tags, event.id); // insert event to local database - createNote({ - event_id: event.id, - pubkey: event.pubkey, - kind: event.kind, - tags: JSON.stringify(event.tags), - content: event.content, - parent_id: parentID, - parent_comment_id: '', - created_at: event.created_at, - account_id: account.id, - }).catch(console.error); + createNote( + event.id, + account.id, + event.pubkey, + event.kind, + event.tags, + event.content, + event.created_at, + parentID + ); break; // chat case 4: if (event.pubkey !== account.pubkey) { - createChat({ - pubkey: event.pubkey, - created_at: event.created_at, - account_id: account.id, - }).catch(console.error); + createChat(account.id, event.pubkey, event.created_at); } + break; // repost case 6: - createNote({ - event_id: event.id, - pubkey: event.pubkey, - kind: event.kind, - tags: JSON.stringify(event.tags), - content: event.content, - parent_id: '', - parent_comment_id: '', - created_at: event.created_at, - account_id: account.id, - }).catch(console.error); + createNote( + event.id, + account.id, + event.pubkey, + event.kind, + event.tags, + event.content, + event.created_at, + '' + ); + break; // channel case 40: - createChannel({ event_id: event.id, content: event.content, account_id: account.id }).catch( - console.error - ); + createChannel(event.id, event.content, event.created_at); + break; default: break; } @@ -151,18 +130,26 @@ export default function Page() { } ); }, - [router, pool, relays, lastLogin, totalChannels, totalChats, totalNotes] + [router, pool, relays, lastLogin] ); useEffect(() => { + getPlebs() + .then((res) => { + if (res) { + writeStorage('plebs', res); + } + }) + .catch(console.error); + getActiveAccount() .then((res: any) => { if (res) { const account = res; // update local storage - writeStorage('activeAccount', account); + writeStorage('account', account); // fetch data - fetchData(account); + fetchData(account, account.follows); } else { router.replace('/onboarding'); } diff --git a/src/components/channels/browseChannelItem.tsx b/src/components/channels/browseChannelItem.tsx index 0bf33991..60b6e791 100644 --- a/src/components/channels/browseChannelItem.tsx +++ b/src/components/channels/browseChannelItem.tsx @@ -16,19 +16,9 @@ export const BrowseChannelItem = ({ data }: { data: any }) => { [router] ); - const joinChannel = useCallback( - async (id: string) => { - const { updateChannel } = await import('@utils/bindings'); - updateChannel({ event_id: id, active: true }) - .then(() => openChannel(id)) - .catch(console.error); - }, - [openChannel] - ); - return (
openChannel(data.eventId)} + onClick={() => openChannel(data.event_id)} className="group relative flex items-center gap-2 border-b border-zinc-800 px-3 py-2.5 hover:bg-black/20" >
@@ -44,10 +34,7 @@ export const BrowseChannelItem = ({ data }: { data: any }) => { {channel.about}
-
diff --git a/src/components/channels/channelList.tsx b/src/components/channels/channelList.tsx index d927c1c8..01e260c3 100644 --- a/src/components/channels/channelList.tsx +++ b/src/components/channels/channelList.tsx @@ -3,21 +3,10 @@ import { CreateChannelModal } from '@components/channels/createChannelModal'; import { Globe } from 'iconoir-react'; import Link from 'next/link'; -import { useEffect, useState } from 'react'; +import { useState } from 'react'; export default function ChannelList() { - const [list, setList] = useState([]); - - useEffect(() => { - const fetchChannels = async () => { - const { getActiveChannels } = await import('@utils/bindings'); - return await getActiveChannels({ active: true }); - }; - - fetchChannels() - .then((res) => setList(res)) - .catch(console.error); - }, []); + const [list] = useState([]); return (
diff --git a/src/components/channels/channelListItem.tsx b/src/components/channels/channelListItem.tsx index f0141fae..6384d521 100644 --- a/src/components/channels/channelListItem.tsx +++ b/src/components/channels/channelListItem.tsx @@ -8,14 +8,14 @@ export const ChannelListItem = ({ data }: { data: any }) => { return (
diff --git a/src/components/channels/createChannelModal.tsx b/src/components/channels/createChannelModal.tsx index 3c83fc6f..11cedf09 100644 --- a/src/components/channels/createChannelModal.tsx +++ b/src/components/channels/createChannelModal.tsx @@ -6,14 +6,13 @@ import * as Dialog from '@radix-ui/react-dialog'; import useLocalStorage from '@rehooks/local-storage'; import { Cancel, Plus } from 'iconoir-react'; import { getEventHash, signEvent } from 'nostr-tools'; -import { useCallback, useContext, useState } from 'react'; +import { useContext, useState } from 'react'; import { useForm } from 'react-hook-form'; export const CreateChannelModal = () => { const [pool, relays]: any = useContext(RelayContext); const [open, setOpen] = useState(false); - - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const { register, @@ -22,11 +21,6 @@ export const CreateChannelModal = () => { formState: { isDirty, isValid }, } = useForm(); - const insertChannelToDB = useCallback(async (id, data, account) => { - const { createChannel } = await import('@utils/bindings'); - return await createChannel({ event_id: id, content: data, account_id: account }); - }, []); - const onSubmit = (data) => { const event: any = { content: JSON.stringify(data), @@ -40,8 +34,6 @@ export const CreateChannelModal = () => { // publish channel pool.publish(event, relays); - // save to database - insertChannelToDB(event.id, data, activeAccount.id); // close modal setOpen(false); // reset form diff --git a/src/components/channels/messages/hideMessageButton.tsx b/src/components/channels/messages/hideMessageButton.tsx index f2a44d30..ff06e4aa 100644 --- a/src/components/channels/messages/hideMessageButton.tsx +++ b/src/components/channels/messages/hideMessageButton.tsx @@ -11,7 +11,7 @@ import { useCallback, useContext } from 'react'; export const HideMessageButton = ({ id }: { id: string }) => { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const hideMessage = useCallback(() => { const event: any = { diff --git a/src/components/channels/messages/muteButton.tsx b/src/components/channels/messages/muteButton.tsx index abc21a4b..6fbc0cc8 100644 --- a/src/components/channels/messages/muteButton.tsx +++ b/src/components/channels/messages/muteButton.tsx @@ -11,7 +11,7 @@ import { useCallback, useContext } from 'react'; export const MuteButton = ({ pubkey }: { pubkey: string }) => { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const muteUser = useCallback(() => { const event: any = { diff --git a/src/components/chats/chatList.tsx b/src/components/chats/chatList.tsx index 6a467fe6..7be274bf 100644 --- a/src/components/chats/chatList.tsx +++ b/src/components/chats/chatList.tsx @@ -4,6 +4,8 @@ import { ImageWithFallback } from '@components/imageWithFallback'; import { DEFAULT_AVATAR } from '@stores/constants'; +import { getChats } from '@utils/storage'; + import useLocalStorage from '@rehooks/local-storage'; import { useRouter } from 'next/navigation'; import { useEffect, useState } from 'react'; @@ -12,7 +14,7 @@ export default function ChatList() { const router = useRouter(); const [list, setList] = useState([]); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const profile = activeAccount.metadata ? JSON.parse(activeAccount.metadata) : null; const openSelfChat = () => { @@ -20,12 +22,7 @@ export default function ChatList() { }; useEffect(() => { - const fetchChats = async () => { - const { getChats } = await import('@utils/bindings'); - return await getChats({ account_id: activeAccount.id }); - }; - - fetchChats() + getChats(activeAccount.id) .then((res) => setList(res)) .catch(console.error); }, [activeAccount.id]); diff --git a/src/components/chats/chatModal.tsx b/src/components/chats/chatModal.tsx index f9bc0a28..d2458f77 100644 --- a/src/components/chats/chatModal.tsx +++ b/src/components/chats/chatModal.tsx @@ -1,24 +1,19 @@ import { ChatModalUser } from '@components/chats/chatModalUser'; +import { getPlebs } from '@utils/storage'; + import * as Dialog from '@radix-ui/react-dialog'; -import useLocalStorage from '@rehooks/local-storage'; import { Cancel, Plus } from 'iconoir-react'; -import { useCallback, useEffect, useState } from 'react'; +import { useEffect, useState } from 'react'; export const ChatModal = () => { const [plebs, setPlebs] = useState([]); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); - - const fetchPlebsByAccount = useCallback(async (id) => { - const { getPlebs } = await import('@utils/bindings'); - return await getPlebs({ account_id: id, kind: 0 }); - }, []); useEffect(() => { - fetchPlebsByAccount(activeAccount.id) + getPlebs() .then((res) => setPlebs(res)) .catch(console.error); - }, [activeAccount.id, fetchPlebsByAccount]); + }, []); return ( diff --git a/src/components/chats/messageList.tsx b/src/components/chats/messageList.tsx index af91b114..3cebf4e2 100644 --- a/src/components/chats/messageList.tsx +++ b/src/components/chats/messageList.tsx @@ -9,7 +9,7 @@ import { useCallback, useRef } from 'react'; import { Virtuoso } from 'react-virtuoso'; export const MessageList = () => { - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const virtuosoRef = useRef(null); const data = useAtomValue(sortedChatMessagesAtom); diff --git a/src/components/eventCollector.tsx b/src/components/eventCollector.tsx index 0e3eb026..4c480948 100644 --- a/src/components/eventCollector.tsx +++ b/src/components/eventCollector.tsx @@ -6,8 +6,8 @@ import { RelayContext } from '@components/relaysProvider'; import { hasNewerNoteAtom } from '@stores/note'; import { dateToUnix } from '@utils/getDate'; -import { fetchProfileMetadata } from '@utils/hooks/useProfileMetadata'; -import { getParentID, pubkeyArray } from '@utils/transform'; +import { createChannel, createChat, createNote, updateAccount } from '@utils/storage'; +import { getParentID, nip02ToArray } from '@utils/transform'; import useLocalStorage, { writeStorage } from '@rehooks/local-storage'; import { window } from '@tauri-apps/api'; @@ -17,46 +17,19 @@ import { useCallback, useContext, useEffect, useRef } from 'react'; export default function EventCollector() { const [pool, relays]: any = useContext(RelayContext); - - const [activeAccount]: any = useLocalStorage('activeAccount', {}); - const [follows] = useLocalStorage('activeAccountFollows', []); + const [activeAccount]: any = useLocalStorage('account', {}); const setHasNewerNote = useSetAtom(hasNewerNoteAtom); const now = useRef(new Date()); const unsubscribe = useRef(null); - const createFollowingPlebs = useCallback( - async (tags) => { - const { createPleb } = await import('@utils/bindings'); - for (const tag of tags) { - const pubkey = tag[1]; - fetchProfileMetadata(pubkey) - .then((res: { content: string }) => { - createPleb({ - pleb_id: pubkey + '-lume' + activeAccount.id.toString(), - pubkey: pubkey, - kind: 0, - metadata: res.content, - account_id: activeAccount.id, - }).catch(console.error); - }) - .catch(console.error); - } - }, - [activeAccount.id] - ); - const subscribe = useCallback(async () => { - const { createNote } = await import('@utils/bindings'); - const { createChat } = await import('@utils/bindings'); - const { createChannel } = await import('@utils/bindings'); - unsubscribe.current = pool.subscribe( [ { kinds: [1, 6], - authors: pubkeyArray(follows), + authors: activeAccount.follows, since: dateToUnix(now.current), }, { @@ -79,65 +52,54 @@ export default function EventCollector() { // short text note case 1: const parentID = getParentID(event.tags, event.id); - createNote({ - event_id: event.id, - pubkey: event.pubkey, - kind: event.kind, - tags: JSON.stringify(event.tags), - content: event.content, - parent_id: parentID, - parent_comment_id: '', - created_at: event.created_at, - account_id: activeAccount.id, - }) - .then(() => - // notify user reload to get newer note - setHasNewerNote(true) - ) - .catch(console.error); + createNote( + event.id, + activeAccount.id, + event.pubkey, + event.kind, + event.tags, + event.content, + event.created_at, + parentID + ); + // notify user reload to get newer note + setHasNewerNote(true); break; // contacts case 3: - createFollowingPlebs(event.tags); + const arr = nip02ToArray(event.tags); + // update account's folllows with NIP-02 tag list + updateAccount('follows', arr, event.pubkey); break; // chat case 4: if (event.pubkey !== activeAccount.pubkey) { - createChat({ - pubkey: event.pubkey, - created_at: event.created_at, - account_id: activeAccount.id, - }).catch(console.error); + createChat(activeAccount.id, event.pubkey, event.created_at); } + break; // repost case 6: - createNote({ - event_id: event.id, - pubkey: event.pubkey, - kind: event.kind, - tags: JSON.stringify(event.tags), - content: event.content, - parent_id: '', - parent_comment_id: '', - created_at: event.created_at, - account_id: activeAccount.id, - }) - .then(() => - // notify user reload to get newer note - setHasNewerNote(true) - ) - .catch(console.error); + createNote( + event.id, + activeAccount.id, + event.pubkey, + event.kind, + event.tags, + event.content, + event.created_at, + '' + ); + break; // channel case 40: - createChannel({ event_id: event.id, content: event.content, account_id: activeAccount.id }).catch( - console.error - ); + createChannel(event.id, event.content, event.created_at); + break; default: break; } } ); - }, [pool, relays, activeAccount.id, activeAccount.pubkey, follows, setHasNewerNote, createFollowingPlebs]); + }, [activeAccount.follows, activeAccount.pubkey, activeAccount.id, pool, relays, setHasNewerNote]); const listenWindowClose = useCallback(async () => { window.getCurrent().listen(TauriEvent.WINDOW_CLOSE_REQUESTED, () => { diff --git a/src/components/form/base.tsx b/src/components/form/base.tsx index 7d91ffd9..4421647b 100644 --- a/src/components/form/base.tsx +++ b/src/components/form/base.tsx @@ -18,7 +18,7 @@ export default function FormBase() { const [value, setValue] = useAtom(noteContentAtom); const resetValue = useResetAtom(noteContentAtom); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const submitEvent = () => { const event: any = { diff --git a/src/components/form/channelMessage.tsx b/src/components/form/channelMessage.tsx index 2467bc80..f765fdf3 100644 --- a/src/components/form/channelMessage.tsx +++ b/src/components/form/channelMessage.tsx @@ -17,7 +17,7 @@ export default function FormChannelMessage({ eventId }: { eventId: string | stri const [pool, relays]: any = useContext(RelayContext); const [value, setValue] = useState(''); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const channelReply = useAtomValue(channelReplyAtom); const resetChannelReply = useResetAtom(channelReplyAtom); diff --git a/src/components/form/chat.tsx b/src/components/form/chat.tsx index 11d03810..939e0f3f 100644 --- a/src/components/form/chat.tsx +++ b/src/components/form/chat.tsx @@ -11,7 +11,7 @@ export default function FormChat({ receiverPubkey }: { receiverPubkey: string }) const [pool, relays]: any = useContext(RelayContext); const [value, setValue] = useState(''); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const encryptMessage = useCallback( async (privkey: string) => { diff --git a/src/components/form/comment.tsx b/src/components/form/comment.tsx index 1ece4979..fff0d71e 100644 --- a/src/components/form/comment.tsx +++ b/src/components/form/comment.tsx @@ -10,7 +10,7 @@ import { useContext, useState } from 'react'; export default function FormComment({ eventID }: { eventID: any }) { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const [value, setValue] = useState(''); const profile = JSON.parse(activeAccount.metadata); diff --git a/src/components/multiAccounts/index.tsx b/src/components/multiAccounts/index.tsx index 37bdabc1..3fbec1eb 100644 --- a/src/components/multiAccounts/index.tsx +++ b/src/components/multiAccounts/index.tsx @@ -5,6 +5,8 @@ import { InactiveAccount } from '@components/multiAccounts/inactiveAccount'; import { APP_VERSION } from '@stores/constants'; +import { getAccounts } from '@utils/storage'; + import LumeSymbol from '@assets/icons/Lume'; import useLocalStorage from '@rehooks/local-storage'; @@ -14,7 +16,7 @@ import { useCallback, useEffect, useState } from 'react'; export default function MultiAccounts() { const [users, setUsers] = useState([]); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const renderAccount = useCallback( (user: { pubkey: string }) => { @@ -27,16 +29,11 @@ export default function MultiAccounts() { [activeAccount.pubkey] ); - const fetchAccounts = useCallback(async () => { - const { getAccounts } = await import('@utils/bindings'); - const accounts = await getAccounts(); - // update state - setUsers(accounts); - }, []); - useEffect(() => { - fetchAccounts().catch(console.error); - }, [fetchAccounts]); + getAccounts() + .then((res) => setUsers(res)) + .catch(console.error); + }, []); return (
diff --git a/src/components/note/base.tsx b/src/components/note/base.tsx index 78cd3d77..e7103609 100644 --- a/src/components/note/base.tsx +++ b/src/components/note/base.tsx @@ -13,7 +13,7 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) { const parentNote = () => { if (event.parent_id) { - if (event.parent_id !== event.eventId && !event.content.includes('#[0]')) { + if (event.parent_id !== event.event_id && !event.content.includes('#[0]')) { return ; } } @@ -42,17 +42,17 @@ export const NoteBase = memo(function NoteBase({ event }: { event: any }) { {parentNote()}
openUserPage(e)}> - +
{content}
e.stopPropagation()} className="mt-5 pl-[52px]">
diff --git a/src/components/note/comment.tsx b/src/components/note/comment.tsx index 62af7b3f..d7b442e1 100644 --- a/src/components/note/comment.tsx +++ b/src/components/note/comment.tsx @@ -60,7 +60,7 @@ export const NoteComment = memo(function NoteComment({ event }: { event: any }) return (
- +
@@ -70,10 +70,10 @@ export const NoteComment = memo(function NoteComment({ event }: { event: any })
e.stopPropagation()} className="mt-5 pl-[52px]">
diff --git a/src/components/note/extend.tsx b/src/components/note/extend.tsx index 92d28508..65bc3550 100644 --- a/src/components/note/extend.tsx +++ b/src/components/note/extend.tsx @@ -60,7 +60,7 @@ export const NoteExtend = memo(function NoteExtend({ event }: { event: any }) { return (
- +
@@ -70,10 +70,10 @@ export const NoteExtend = memo(function NoteExtend({ event }: { event: any }) {
diff --git a/src/components/note/meta/comment.tsx b/src/components/note/meta/comment.tsx index 505f5977..00102710 100644 --- a/src/components/note/meta/comment.tsx +++ b/src/components/note/meta/comment.tsx @@ -30,7 +30,7 @@ export const NoteComment = ({ const [open, setOpen] = useState(false); const [value, setValue] = useState(''); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const profile = activeAccount.metadata ? JSON.parse(activeAccount.metadata) : null; const openThread = () => { diff --git a/src/components/note/meta/reaction.tsx b/src/components/note/meta/reaction.tsx index 22fb4d9c..82324635 100644 --- a/src/components/note/meta/reaction.tsx +++ b/src/components/note/meta/reaction.tsx @@ -19,7 +19,7 @@ export const NoteReaction = ({ eventPubkey: string; }) => { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const [isReact, setIsReact] = useState(false); const [like, setLike] = useState(0); diff --git a/src/components/note/metadata.tsx b/src/components/note/metadata.tsx index fbf6f67f..c2db47d3 100644 --- a/src/components/note/metadata.tsx +++ b/src/components/note/metadata.tsx @@ -17,7 +17,7 @@ export const NoteMetadata = memo(function NoteMetadata({ eventContent: any; }) { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const [liked, setLiked] = useState(false); const [likeCount, setLikeCount] = useState(0); diff --git a/src/components/note/parent.tsx b/src/components/note/parent.tsx index 48c8055b..311dfc48 100644 --- a/src/components/note/parent.tsx +++ b/src/components/note/parent.tsx @@ -3,6 +3,7 @@ import { RelayContext } from '@components/relaysProvider'; import { UserExtend } from '@components/user/extend'; import { contentParser } from '@utils/parser'; +import { createNote, getNoteByID } from '@utils/storage'; import { getParentID } from '@utils/transform'; import useLocalStorage from '@rehooks/local-storage'; @@ -11,14 +12,13 @@ import { memo, useCallback, useContext, useEffect, useRef, useState } from 'reac export const NoteParent = memo(function NoteParent({ id }: { id: string }) { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const [event, setEvent] = useState(null); const unsubscribe = useRef(null); const content = event ? contentParser(event.content, event.tags) : ''; const fetchEvent = useCallback(async () => { - const { createNote } = await import('@utils/bindings'); unsubscribe.current = pool.subscribe( [ { @@ -33,17 +33,16 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { // insert to database const parentID = getParentID(event.tags, event.id); // insert event to local database - createNote({ - event_id: event.id, - pubkey: event.pubkey, - kind: event.kind, - tags: JSON.stringify(event.tags), - content: event.content, - parent_id: parentID, - parent_comment_id: '', - created_at: event.created_at, - account_id: activeAccount.id, - }).catch(console.error); + createNote( + event.id, + activeAccount.id, + event.pubkey, + event.kind, + event.tags, + event.content, + event.created_at, + parentID + ); }, undefined, undefined, @@ -54,8 +53,7 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) { }, [activeAccount.id, id, pool, relays]); const checkNoteExist = useCallback(async () => { - const { getNoteById } = await import('@utils/bindings'); - getNoteById({ event_id: id }) + getNoteByID(id) .then((res) => { if (res) { setEvent(res); @@ -81,16 +79,16 @@ export const NoteParent = memo(function NoteParent({ id }: { id: string }) {
- +
{content}
e.stopPropagation()} className="mt-5 pl-[52px]">
diff --git a/src/components/note/quote.tsx b/src/components/note/quote.tsx index 9550b566..10a07514 100644 --- a/src/components/note/quote.tsx +++ b/src/components/note/quote.tsx @@ -2,6 +2,7 @@ import { RelayContext } from '@components/relaysProvider'; import { UserExtend } from '@components/user/extend'; import { contentParser } from '@utils/parser'; +import { createNote, getNoteByID } from '@utils/storage'; import { getParentID } from '@utils/transform'; import useLocalStorage from '@rehooks/local-storage'; @@ -10,15 +11,13 @@ import { memo, useCallback, useContext, useEffect, useRef, useState } from 'reac export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) { const [pool, relays]: any = useContext(RelayContext); - const [activeAccount]: any = useLocalStorage('activeAccount', {}); + const [activeAccount]: any = useLocalStorage('account', {}); const [event, setEvent] = useState(null); const unsubscribe = useRef(null); const content = event ? contentParser(event.content, event.tags) : ''; const fetchEvent = useCallback(async () => { - const { createNote } = await import('@utils/bindings'); - unsubscribe.current = pool.subscribe( [ { @@ -32,18 +31,16 @@ export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) { setEvent(event); // insert to database const parentID = getParentID(event.tags, event.id); - // insert event to local database - createNote({ - event_id: event.id, - pubkey: event.pubkey, - kind: event.kind, - tags: JSON.stringify(event.tags), - content: event.content, - parent_id: parentID, - parent_comment_id: '', - created_at: event.created_at, - account_id: activeAccount.id, - }).catch(console.error); + createNote( + event.id, + activeAccount.id, + event.pubkey, + event.kind, + event.tags, + event.content, + event.created_at, + parentID + ); }, undefined, undefined, @@ -54,8 +51,7 @@ export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) { }, [activeAccount.id, id, pool, relays]); const checkNoteExist = useCallback(async () => { - const { getNoteById } = await import('@utils/bindings'); - getNoteById({ event_id: id }) + getNoteByID(id) .then((res) => { if (res) { setEvent(res); @@ -80,7 +76,7 @@ export const NoteQuote = memo(function NoteQuote({ id }: { id: string }) { return (
- +
{content}
diff --git a/src/components/note/quoteRepost.tsx b/src/components/note/quoteRepost.tsx index d9ac2016..9d73533d 100644 --- a/src/components/note/quoteRepost.tsx +++ b/src/components/note/quoteRepost.tsx @@ -20,7 +20,7 @@ export const NoteQuoteRepost = memo(function NoteQuoteRepost({ event }: { event:
- +
{rootNote()}
diff --git a/src/components/relaysProvider.tsx b/src/components/relaysProvider.tsx index 5797a4df..7724c729 100644 --- a/src/components/relaysProvider.tsx +++ b/src/components/relaysProvider.tsx @@ -16,7 +16,7 @@ const relays = [ 'wss://relay.current.fyi', 'wss://nostr.bitcoiner.social', //'wss://relay.nostr.info', - 'wss://nostr-01.dorafactory.org', + //'wss://nostr-01.dorafactory.org', 'wss://nostr.zhongwen.world', 'wss://nostro.cc', 'wss://relay.nostr.net.in', diff --git a/src/utils/bindings.ts b/src/utils/bindings.ts deleted file mode 100644 index 86f21e3c..00000000 --- a/src/utils/bindings.ts +++ /dev/null @@ -1,110 +0,0 @@ -// This file was generated by [tauri-specta](https://github.com/oscartbeaumont/tauri-specta). Do not edit this file manually. - -declare global { - interface Window { - __TAURI_INVOKE__(cmd: string, args?: Record): Promise; - } -} - -const invoke = window.__TAURI_INVOKE__; - -export function getAccounts() { - return invoke('get_accounts'); -} - -export function createAccount(data: CreateAccountData) { - return invoke('create_account', { data }); -} - -export function getPlebs(data: GetPlebData) { - return invoke('get_plebs', { data }); -} - -export function getPlebByPubkey(data: GetPlebPubkeyData) { - return invoke('get_pleb_by_pubkey', { data }); -} - -export function createPleb(data: CreatePlebData) { - return invoke('create_pleb', { data }); -} - -export function createNote(data: CreateNoteData) { - return invoke('create_note', { data }); -} - -export function getNotes(data: GetNoteData) { - return invoke('get_notes', { data }); -} - -export function getLatestNotes(data: GetLatestNoteData) { - return invoke('get_latest_notes', { data }); -} - -export function getNoteById(data: GetNoteByIdData) { - return invoke('get_note_by_id', { data }); -} - -export function createChannel(data: CreateChannelData) { - return invoke('create_channel', { data }); -} - -export function updateChannel(data: UpdateChannelData) { - return invoke('update_channel', { data }); -} - -export function getChannels(data: GetChannelData) { - return invoke('get_channels', { data }); -} - -export function getActiveChannels(data: GetActiveChannelData) { - return invoke('get_active_channels', { data }); -} - -export function createChat(data: CreateChatData) { - return invoke('create_chat', { data }); -} - -export function getChats(data: GetChatData) { - return invoke('get_chats', { data }); -} - -export type GetLatestNoteData = { date: number }; -export type Note = { - id: number; - eventId: string; - pubkey: string; - kind: number; - tags: string; - content: string; - parent_id: string; - parent_comment_id: string; - createdAt: number; - accountId: number; -}; -export type GetActiveChannelData = { active: boolean }; -export type CreateChannelData = { event_id: string; content: string; account_id: number }; -export type CreateNoteData = { - event_id: string; - pubkey: string; - kind: number; - tags: string; - content: string; - parent_id: string; - parent_comment_id: string; - created_at: number; - account_id: number; -}; -export type GetPlebData = { account_id: number; kind: number }; -export type CreatePlebData = { pleb_id: string; pubkey: string; kind: number; metadata: string; account_id: number }; -export type Chat = { id: number; pubkey: string; createdAt: number; accountId: number }; -export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; -export type GetNoteByIdData = { event_id: string }; -export type GetPlebPubkeyData = { pubkey: string }; -export type GetChatData = { account_id: number }; -export type GetNoteData = { date: number; limit: number; offset: number }; -export type Channel = { id: number; eventId: string; content: string; active: boolean; accountId: number }; -export type UpdateChannelData = { event_id: string; active: boolean }; -export type CreateChatData = { pubkey: string; created_at: number; account_id: number }; -export type CreateAccountData = { pubkey: string; privkey: string; metadata: string }; -export type GetChannelData = { limit: number; offset: number }; -export type Pleb = { id: number; plebId: string; pubkey: string; kind: number; metadata: string; accountId: number }; diff --git a/src/utils/commands.tsx b/src/utils/commands.tsx deleted file mode 100644 index 4fa858db..00000000 --- a/src/utils/commands.tsx +++ /dev/null @@ -1,13 +0,0 @@ -import { invoke } from '@tauri-apps/api'; - -export function countTotalNotes() { - return invoke('count_total_notes'); -} - -export function countTotalChannels() { - return invoke('count_total_channels'); -} - -export function countTotalChats() { - return invoke('count_total_chats'); -} diff --git a/src/utils/hooks/useProfileMetadata.tsx b/src/utils/hooks/useProfileMetadata.tsx index 53b28c8d..443dcdb6 100644 --- a/src/utils/hooks/useProfileMetadata.tsx +++ b/src/utils/hooks/useProfileMetadata.tsx @@ -1,3 +1,5 @@ +import { createPleb } from '@utils/storage'; + import useLocalStorage from '@rehooks/local-storage'; import { fetch } from '@tauri-apps/api/http'; import { useCallback, useEffect, useMemo, useState } from 'react'; @@ -11,8 +13,8 @@ export const fetchProfileMetadata = async (pubkey: string) => { }; export const useProfileMetadata = (pubkey) => { - const [activeAccount]: any = useLocalStorage('activeAccount', {}); - const [plebs] = useLocalStorage('activeAccountFollows', []); + const [activeAccount]: any = useLocalStorage('account', {}); + const [plebs] = useLocalStorage('plebs', []); const [profile, setProfile] = useState(null); const cacheProfile = useMemo(() => { @@ -31,19 +33,9 @@ export const useProfileMetadata = (pubkey) => { return metadata; }, [plebs, pubkey, activeAccount.pubkey, activeAccount.metadata]); - const insertPlebToDB = useCallback( - async (pubkey: string, metadata: string) => { - const { createPleb } = await import('@utils/bindings'); - return await createPleb({ - pleb_id: pubkey + '-lume' + activeAccount.id, - pubkey: pubkey, - kind: 1, - metadata: metadata, - account_id: activeAccount.id, - }).catch(console.error); - }, - [activeAccount.id] - ); + const insertPlebToDB = useCallback(async (pubkey: string, metadata: string) => { + return createPleb(pubkey, metadata); + }, []); useEffect(() => { if (!cacheProfile) { diff --git a/src/utils/storage.tsx b/src/utils/storage.tsx index 47891e7e..e06c9d6d 100644 --- a/src/utils/storage.tsx +++ b/src/utils/storage.tsx @@ -20,6 +20,12 @@ export async function getActiveAccount() { return result[0]; } +// get all accounts +export async function getAccounts() { + const db = await connect(); + return await db.select(`SELECT * FROM accounts ORDER BY created_at DESC;`); +} + // create account export async function createAccount(pubkey: string, privkey: string, metadata: string) { const db = await connect(); @@ -36,12 +42,25 @@ export async function updateAccount(column: string, value: string | string[], pu return await db.execute(`UPDATE accounts SET ${column} = '${JSON.stringify(value)}' WHERE pubkey = "${pubkey}";`); } +// get all plebs +export async function getPlebs() { + const db = await connect(); + return await db.select(`SELECT * FROM plebs ORDER BY created_at DESC;`); +} + // create pleb export async function createPleb(pubkey: string, metadata: string) { const db = await connect(); return await db.execute('INSERT OR IGNORE INTO plebs (pubkey, metadata) VALUES (?, ?);', [pubkey, metadata]); } +// count total notes +export async function countTotalChannels() { + const db = await connect(); + const result = await db.select('SELECT COUNT(*) AS "total" FROM channels;'); + return result[0]; +} + // count total notes export async function countTotalNotes() { const db = await connect(); @@ -50,15 +69,72 @@ export async function countTotalNotes() { } // get all notes -export async function getNotes(time: string, limit: number, offset: number) { +export async function getNotes(time: number, limit: number, offset: number) { const db = await connect(); return await db.select( `SELECT * FROM notes WHERE created_at <= "${time}" ORDER BY created_at DESC LIMIT "${limit}" OFFSET "${offset}";` ); } +// get note by id +export async function getNoteByID(event_id) { + const db = await connect(); + const result = await db.select(`SELECT * FROM notes WHERE event_id = "${event_id}";`); + return result[0]; +} + // get all latest notes -export async function getLatestNotes(time) { +export async function getLatestNotes(time: number) { const db = await connect(); return await db.select(`SELECT * FROM cache_notes WHERE created_at > "${time}" ORDER BY created_at DESC;`); } + +// create note +export async function createNote( + event_id: string, + account_id: number, + pubkey: string, + kind: number, + tags: string[], + content: string, + created_at: number, + parent_id: string +) { + const db = await connect(); + return await db.execute( + 'INSERT OR IGNORE INTO notes (event_id, account_id, pubkey, kind, tags, content, created_at, parent_id) VALUES (?, ?, ?, ?, ?, ?, ?, ?);', + [event_id, account_id, pubkey, kind, tags, content, created_at, parent_id] + ); +} + +// get all channels +export async function getChannels(limit: number, offset: number) { + const db = await connect(); + return await db.select(`SELECT * FROM channels ORDER BY created_at DESC LIMIT "${limit}" OFFSET "${offset}";`); +} + +// create channel +export async function createChannel(event_id: string, metadata: string, created_at: number) { + const db = await connect(); + return await db.execute('INSERT OR IGNORE INTO channels (event_id, metadata, created_at) VALUES (?, ?, ?);', [ + event_id, + metadata, + created_at, + ]); +} + +// get all chats +export async function getChats(account_id: number) { + const db = await connect(); + return await db.select(`SELECT * FROM chats WHERE account_id <= "${account_id}" ORDER BY created_at DESC;`); +} + +// create chat +export async function createChat(account_id: number, pubkey: string, created_at: number) { + const db = await connect(); + return await db.execute('INSERT OR IGNORE INTO chats (account_id, pubkey, created_at) VALUES (?, ?, ?);', [ + account_id, + pubkey, + created_at, + ]); +} diff --git a/src/utils/transform.tsx b/src/utils/transform.tsx index 6c95bd4f..0c2d33e0 100644 --- a/src/utils/transform.tsx +++ b/src/utils/transform.tsx @@ -1,33 +1,26 @@ import destr from 'destr'; -export const tagsToArray = (arr) => { - const newarr = []; - // push item to newarr - arr.forEach((item) => { - newarr.push(item[1]); +// convert NIP-02 to array of pubkey +export const nip02ToArray = (tags: string[]) => { + const arr = []; + tags.forEach((item) => { + arr.push(item[1]); }); - return newarr; + return arr; }; // convert array to NIP-02 tag list export const arrayToNIP02 = (arr: string[]) => { - const nip03_array = []; + const nip02_arr = []; arr.forEach((item) => { - nip03_array.push(['p', item]); + nip02_arr.push(['p', item]); }); - return nip03_array; + + return nip02_arr; }; -export const pubkeyArray = (arr) => { - const newarr = []; - // push item to newarr - arr.forEach((item) => { - newarr.push(item.pubkey); - }); - return newarr; -}; - -export const getParentID = (arr, fallback) => { +// get parent id from event tags +export const getParentID = (arr: string[], fallback: string) => { const tags = destr(arr); let parentID = fallback;