import { LumeIcon } from "@shared/icons"; import { RelayContext } from "@shared/relayProvider"; import { useActiveAccount } from "@stores/accounts"; import { READONLY_RELAYS } from "@stores/constants"; import { dateToUnix, getHourAgo } from "@utils/date"; import { addToBlacklist, countTotalNotes, createChat, createNote, } from "@utils/storage"; import { getParentID } from "@utils/transform"; import { useCallback, useContext, useRef } from "react"; import useSWRSubscription from "swr/subscription"; import { navigate } from "vite-plugin-ssr/client/router"; let totalNotes: number; if (typeof window !== "undefined") { totalNotes = await countTotalNotes(); } export function Page() { const pool: any = useContext(RelayContext); const [account, lastLogin] = useActiveAccount((state: any) => [ state.account, state.lastLogin, ]); const now = useRef(new Date()); const eose = useRef(0); const getQuery = useCallback(() => { const query = []; const follows = JSON.parse(account.follows); let queryNoteSince: number; if (totalNotes === 0) { queryNoteSince = dateToUnix(getHourAgo(48, now.current)); } else { if (lastLogin > 0) { queryNoteSince = lastLogin; } else { queryNoteSince = dateToUnix(getHourAgo(48, now.current)); } } // kind 1 (notes) query query.push({ kinds: [1, 6, 1063], authors: follows, since: queryNoteSince, }); // kind 4 (chats) query query.push({ kinds: [4], "#p": [account.pubkey], since: lastLogin, }); // kind 4 (chats) query query.push({ kinds: [4], authors: [account.pubkey], since: lastLogin, }); // kind 43, 43 (mute user, hide message) query query.push({ authors: [account.pubkey], kinds: [43, 44], since: lastLogin, }); return query; }, [account]); useSWRSubscription(account ? "prefetch" : null, () => { const query = getQuery(); const unsubscribe = pool.subscribe( query, READONLY_RELAYS, (event: any) => { switch (event.kind) { // short text note case 1: { const parentID = getParentID(event.tags, event.id); // insert event to local database 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) { const receiver = event.tags.find((t) => t[0] === "p")[1]; createChat( event.id, receiver, event.pubkey, event.content, event.tags, event.created_at, ); } else { createChat( event.id, account.pubkey, event.pubkey, event.content, event.tags, event.created_at, ); } break; } // repost case 6: createNote( event.id, account.id, event.pubkey, event.kind, event.tags, event.content, event.created_at, event.id, ); break; // hide message (channel only) case 43: if (event.tags[0][0] === "e") { addToBlacklist(account.id, event.tags[0][1], 43, 1); } break; // mute user (channel only) case 44: if (event.tags[0][0] === "p") { addToBlacklist(account.id, event.tags[0][1], 44, 1); } break; case 1063: createNote( event.id, account.id, event.pubkey, event.kind, event.tags, event.content, event.created_at, "", ); break; default: break; } }, undefined, () => { eose.current += 1; if (eose.current === READONLY_RELAYS.length) { navigate("/app/space", { overwriteLastHistoryEntry: true }); } }, ); return () => { unsubscribe(); }; }); return (
Bitcoin and Nostr can be used by anyone, and no one can stop you!