Files
lume/src/shared/eventCollector.tsx
Ren Amamiya 5c7b18bf29 refactor
2023-05-26 09:28:49 +07:00

146 lines
3.2 KiB
TypeScript

import { RelayContext } from "@shared/relayProvider";
import HeartBeatIcon from "@icons/heartbeat";
import { READONLY_RELAYS } from "@stores/constants";
import { hasNewerNoteAtom } from "@stores/note";
import { dateToUnix } from "@utils/date";
import { useActiveAccount } from "@utils/hooks/useActiveAccount";
import { createChat, createNote, updateAccount } from "@utils/storage";
import { getParentID, nip02ToArray } from "@utils/transform";
import { useSetAtom } from "jotai";
import { useContext, useRef } from "react";
import useSWRSubscription from "swr/subscription";
function isJSON(str: string) {
try {
JSON.parse(str);
} catch (e) {
return false;
}
return true;
}
export default function EventCollector() {
const pool: any = useContext(RelayContext);
const setHasNewerNote = useSetAtom(hasNewerNoteAtom);
const now = useRef(new Date());
const { account, isLoading, isError } = useActiveAccount();
useSWRSubscription(
!isLoading && !isError && account ? ["eventCollector", account] : null,
([, key]) => {
const follows = JSON.parse(key.follows);
const followsAsArray = nip02ToArray(follows);
const unsubscribe = pool.subscribe(
[
{
kinds: [1, 6],
authors: followsAsArray,
since: dateToUnix(now.current),
},
{
kinds: [3],
authors: [key.pubkey],
},
{
kinds: [4],
"#p": [key.pubkey],
since: dateToUnix(now.current),
},
{
kinds: [30023],
since: dateToUnix(now.current),
},
],
READONLY_RELAYS,
(event: any) => {
switch (event.kind) {
// short text note
case 1: {
const parentID = getParentID(event.tags, event.id);
createNote(
event.id,
account.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: {
const follows = nip02ToArray(event.tags);
// update account's folllows with NIP-02 tag list
updateAccount("follows", follows, event.pubkey);
break;
}
// chat
case 4:
createChat(
event.id,
key.pubkey,
event.pubkey,
event.content,
event.created_at,
);
break;
// repost
case 6:
createNote(
event.id,
key.id,
event.pubkey,
event.kind,
event.tags,
event.content,
event.created_at,
event.id,
);
break;
// long post
case 30023: {
const verifyMetadata = isJSON(event.tags);
if (verifyMetadata) {
// insert event to local database
createNote(
event.id,
account.id,
event.pubkey,
event.kind,
event.tags,
event.content,
event.created_at,
"",
);
}
break;
}
default:
break;
}
},
);
return () => {
unsubscribe();
};
},
);
return (
<div className="inline-flex h-6 w-6 items-center justify-center rounded text-zinc-500 hover:bg-zinc-900 hover:text-green-500">
<HeartBeatIcon width={16} height={16} />
</div>
);
}