Files
lume/src/components/eventCollector.tsx
2023-04-15 09:06:29 +07:00

142 lines
4.2 KiB
TypeScript

'use client';
import { NetworkStatusIndicator } from '@components/networkStatusIndicator';
import { RelayContext } from '@components/relaysProvider';
import { hasNewerNoteAtom } from '@stores/note';
import { dateToUnix } from '@utils/getDate';
import { fetchMetadata } from '@utils/metadata';
import { getParentID, pubkeyArray } from '@utils/transform';
import useLocalStorage, { writeStorage } from '@rehooks/local-storage';
import { window } from '@tauri-apps/api';
import { TauriEvent } from '@tauri-apps/api/event';
import { useSetAtom } from 'jotai';
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 setHasNewerNote = useSetAtom(hasNewerNoteAtom);
const now = useRef(new Date());
const unsubscribe = useRef(null);
const unlisten = useRef(null);
const createFollowingPlebs = useCallback(
async (tags) => {
const { createPleb } = await import('@utils/bindings');
for (const tag of tags) {
const pubkey = tag[1];
const metadata: any = await fetchMetadata(pubkey);
createPleb({
pleb_id: pubkey + '-lume' + activeAccount.id.toString(),
pubkey: pubkey,
kind: 0,
metadata: metadata.content,
account_id: activeAccount.id,
}).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],
authors: pubkeyArray(follows),
since: dateToUnix(now.current),
},
{
kinds: [3],
authors: [activeAccount.pubkey],
},
{
kinds: [4],
'#p': [activeAccount.pubkey],
since: dateToUnix(now.current),
},
{
kinds: [40],
since: dateToUnix(now.current),
},
],
relays,
(event) => {
if (event.kind === 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: activeAccount.id,
})
.then(() =>
// notify user reload to get newer note
setHasNewerNote(true)
)
.catch(console.error);
} else if (event.kind === 3) {
createFollowingPlebs(event.tags);
} else if (event.kind === 4) {
if (event.pubkey !== activeAccount.pubkey) {
createChat({ pubkey: event.pubkey, created_at: event.created_at, account_id: activeAccount.id }).catch(
console.error
);
}
} else if (event.kind === 40) {
createChannel({ event_id: event.id, content: event.content, account_id: activeAccount.id }).catch(
console.error
);
} else {
console.error;
}
}
);
}, [pool, relays, activeAccount.id, activeAccount.pubkey, follows, setHasNewerNote, createFollowingPlebs]);
const listenWindowClose = useCallback(async () => {
unlisten.current = window.getCurrent().listen(TauriEvent.WINDOW_CLOSE_REQUESTED, () => {
writeStorage('lastLogin', now.current);
window.getCurrent().close();
});
}, []);
useEffect(() => {
subscribe();
listenWindowClose();
return () => {
if (unsubscribe.current) {
unsubscribe.current();
}
if (unlisten.current) {
unlisten.current;
}
};
}, [setHasNewerNote, subscribe, listenWindowClose]);
return (
<>
<NetworkStatusIndicator />
</>
);
}