diff --git a/client/src/components/Board.tsx b/client/src/components/Board.tsx index d534862..1485f6b 100644 --- a/client/src/components/Board.tsx +++ b/client/src/components/Board.tsx @@ -11,25 +11,14 @@ import { useParams } from "react-router-dom"; const DEFAULT_DIFFICULTY = 20; - -const Board = () => { - const { id } = useParams(); - const filterDifficulty = localStorage.getItem("filterDifficulty") || DEFAULT_DIFFICULTY; - const age = Number(localStorage.getItem("age")) || 24; - const [sortByTime, setSortByTime] = useState(localStorage.getItem('sortBy') !== 'false'); - const [setAnon, setSetAnon] = useState(localStorage.getItem('anonMode') !== 'false'); - - let decodeResult = nip19.decode(id as string); - let pubkey = decodeResult.data as string; - - const [delayedSort, setDelayedSort] = useState(false) +const useUniqEvents = (pubkey: string) => { const [events, setEvents] = useState([]); + const age = Number(localStorage.getItem("age")) || 24; useEffect(() => { const onEvent = (event: Event) => setEvents((prevEvents) => [...prevEvents, event]); console.log(events) const unsubscribe = subBoardFeed(pubkey, onEvent, age); - subProfile(pubkey, onEvent) return unsubscribe; }, [pubkey]); @@ -38,6 +27,22 @@ const Board = () => { const noteEvents = uniqEvents.filter(event => event.kind === 1 || event.kind === 6); const metadataEvents = uniqEvents.filter(event => event.kind === 0); + const pinnedEvents = uniqEvents.filter(event => event.pubkey === pubkey && !event.tags.some((tag) => tag[0] === "e")); + + return { pinnedEvents, noteEvents, metadataEvents }; +}; + +const Board = () => { + const { id } = useParams(); + const filterDifficulty = localStorage.getItem("filterDifficulty") || DEFAULT_DIFFICULTY; + const [sortByTime, setSortByTime] = useState(localStorage.getItem('sortBy') !== 'false'); + const [setAnon, setSetAnon] = useState(localStorage.getItem('anonMode') !== 'false'); + + let decodeResult = nip19.decode(id as string); + let pubkey = decodeResult.data as string; + const {pinnedEvents, noteEvents, metadataEvents } = useUniqEvents(pubkey); + + const [delayedSort, setDelayedSort] = useState(false) const postEvents: Event[] = noteEvents .filter((event) => @@ -60,8 +65,6 @@ const Board = () => { sortByTime ? b.created_at - a.created_at : verifyPow(b) - verifyPow(a) ) - const pinnedEvents = uniqEvents.filter(event => event.pubkey === pubkey && !event.tags.some((tag) => tag[0] === "e")); - if (delayedSort) { sortedEvents = sortedEvents.filter( !setAnon ? (e) => !metadataEvents.some((metadataEvent) => metadataEvent.pubkey === e.pubkey) : () => true diff --git a/client/src/utils/subscriptions.ts b/client/src/utils/subscriptions.ts index 1ad3d29..055d2ff 100644 --- a/client/src/utils/subscriptions.ts +++ b/client/src/utils/subscriptions.ts @@ -268,46 +268,90 @@ export const subBoardFeed = ( onEvent: SubCallback, age: number ) => { - console.info('subscribe to board'); - unsubAll(); - const now = Math.floor(Date.now() * 0.001); - const pubkeys = new Set(); - const notes = new Set(); - const prefix = Math.floor(16 / 4); // 4 bits in each '0' character - sub({ // get past events - cb: (evt, relay) => { - pubkeys.add(evt.pubkey); - notes.add(evt.id); - onEvent(evt, relay); - }, - filter: { - ...(prefix && { ids: ['0'.repeat(prefix)] }), - "#d": [board], - kinds: [1, 6], - since: Math.floor((Date.now() * 0.001) - (age * 60 * 60)), - limit: 500, - }, - unsub: true - }); - - // subscribe to future notes, reactions and profile updates - sub({ - cb: (evt, relay) => { - onEvent(evt, relay); - if ( - evt.kind !== 1 - || pubkeys.has(evt.pubkey) - ) { - return; - } - }, - filter: { - ...(prefix && { ids: ['0'.repeat(prefix)] }), - "#d": [board], - kinds: [1], - since: now, - }, - }); + console.info('subscribe to board feed'); + unsubAll(); + const now = Math.floor(Date.now() * 0.001); + const pubkeys = new Set(); + const notes = new Set(); + const prefix = Math.floor(16 / 4); // 4 bits in each '0' character + sub({ // get past events + cb: (evt, relay) => { + pubkeys.add(evt.pubkey); + notes.add(evt.id); + onEvent(evt, relay); + }, + filter: { + ...(prefix && { ids: ['0'.repeat(prefix)] }), + "#d": [board], + kinds: [1, 6], + since: Math.floor((Date.now() * 0.001) - (age * 60 * 60)), + limit: 500, + }, + unsub: true + }); + sub({ + cb: (evt, relay) => { + onEvent(evt, relay); + }, + filter: { + authors: [board], + kinds: [1, 7], + limit: 25, + }, + unsub: true, + }); + + setTimeout(() => { + // get profile info + sub({ + cb: onEvent, + filter: { + authors: Array.from(pubkeys), + kinds: [0], + limit: pubkeys.size, + }, + unsub: true, + }); + pubkeys.clear(); + + sub({ + cb: onEvent, + filter: { + '#e': Array.from(notes), + kinds: [1], + }, + unsub: true, + }); + + notes.clear(); + }, 2000); + + // subscribe to future notes, reactions and profile updates + sub({ + cb: (evt, relay) => { + onEvent(evt, relay); + if ( + evt.kind !== 1 + || pubkeys.has(evt.pubkey) + ) { + return; + } + subOnce({ // get profile data + relay, + cb: onEvent, + filter: { + authors: [evt.pubkey], + kinds: [0], + limit: 1, + } + }); + }, + filter: { + ...(prefix && { ids: ['0'.repeat(prefix)] }), + kinds: [1], + since: now, + }, + }); }; export const subProfile = (