useSubscribe

This commit is contained in:
Martti Malmi 2023-08-23 22:46:04 +03:00
parent 644c266299
commit 541347d3e2

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useCallback, useEffect, useRef, useState } from 'react';
import throttle from 'lodash/throttle'; import throttle from 'lodash/throttle';
import { Event } from 'nostr-tools'; import { Event } from 'nostr-tools';
@ -15,37 +15,28 @@ interface SubscribeOptions {
} }
const useSubscribe = (ops: SubscribeOptions) => { const useSubscribe = (ops: SubscribeOptions) => {
const defaultOps = useMemo(
() => ({
enabled: true,
sinceLastOpened: false,
mergeSubscriptions: true,
}),
[],
);
const { const {
filter, filter,
filterFn, filterFn,
enabled = defaultOps.enabled, enabled = true,
sinceLastOpened = defaultOps.sinceLastOpened, sinceLastOpened = false,
mergeSubscriptions = defaultOps.mergeSubscriptions, mergeSubscriptions = true,
} = ops; } = ops;
const shouldReturnEarly = !enabled || filter.limit === 0; const shouldReturnEarly = !enabled || filter.limit === 0;
const getEvents = useCallback(() => { const getEvents = useCallback(() => {
if (shouldReturnEarly) return []; if (shouldReturnEarly) return [];
// maybe we should still add filter by displaycount?
let e = EventDB.findArray({ ...filter, limit: undefined }); let e = EventDB.findArray({ ...filter, limit: undefined });
if (filterFn) { if (filterFn) {
e = e.filter(filterFn); e = e.filter(filterFn);
} }
return e; return e;
}, [filter, filterFn]); }, [filter, filterFn, shouldReturnEarly]);
const [events, setEvents] = useState<Event[]>(getEvents()); const [events, setEvents] = useState<Event[]>(getEvents());
const lastUntilRef = useRef<number | null>(null); const lastUntilRef = useRef<number | null>(null);
const loadMoreCleanupRef = useRef<null | (() => void)>(null);
const updateEvents = useCallback(() => { const updateEvents = useCallback(() => {
setEvents(getEvents()); setEvents(getEvents());
@ -53,14 +44,14 @@ const useSubscribe = (ops: SubscribeOptions) => {
useEffect(() => { useEffect(() => {
setEvents([]); setEvents([]);
if (!enabled || !filter) return; if (shouldReturnEarly) return;
return PubSub.subscribe(filter, updateEvents, sinceLastOpened, mergeSubscriptions); return PubSub.subscribe(filter, updateEvents, sinceLastOpened, mergeSubscriptions);
}, [filter, filterFn, enabled, sinceLastOpened, mergeSubscriptions]); }, [filter, filterFn, shouldReturnEarly, sinceLastOpened, mergeSubscriptions]);
const loadMoreCleanupRef = useRef<null | (() => void)>(null);
const loadMore = useCallback( const loadMore = useCallback(
throttle(() => { throttle(() => {
if (shouldReturnEarly) return;
const until = events.length ? events[events.length - 1].created_at : undefined; const until = events.length ? events[events.length - 1].created_at : undefined;
if (!until || lastUntilRef.current === until) return; if (!until || lastUntilRef.current === until) return;
@ -74,10 +65,10 @@ const useSubscribe = (ops: SubscribeOptions) => {
loadMoreCleanupRef.current = cleanup; loadMoreCleanupRef.current = cleanup;
}, 500), }, 500),
[filter, filterFn, enabled, sinceLastOpened, mergeSubscriptions], [filter, filterFn, shouldReturnEarly, sinceLastOpened, mergeSubscriptions],
); );
// New effect for cleaning up the loadMore subscription // Clean up the loadMore subscription
useEffect(() => { useEffect(() => {
return () => { return () => {
if (loadMoreCleanupRef.current) { if (loadMoreCleanupRef.current) {
@ -86,10 +77,6 @@ const useSubscribe = (ops: SubscribeOptions) => {
}; };
}, [loadMore]); }, [loadMore]);
if (shouldReturnEarly) {
return { events: [], loadMore: () => {} };
}
return { events, loadMore }; return { events, loadMore };
}; };