mirror of
https://github.com/aljazceru/rabbit.git
synced 2025-12-17 22:14:26 +01:00
update
This commit is contained in:
@@ -1,3 +1,85 @@
|
||||
import { useReactions } from '@/nostr/useBatchedEvents';
|
||||
import { createMemo, observable } from 'solid-js';
|
||||
|
||||
import { createQuery, useQueryClient, type CreateQueryResult } from '@tanstack/solid-query';
|
||||
import { Event as NostrEvent } from 'nostr-tools';
|
||||
|
||||
import { exec } from '@/nostr/useBatchedEvents';
|
||||
import timeout from '@/utils/timeout';
|
||||
|
||||
export type UseReactionsProps = {
|
||||
eventId: string;
|
||||
};
|
||||
|
||||
export type UseReactions = {
|
||||
reactions: () => NostrEvent[];
|
||||
reactionsGroupedByContent: () => Map<string, NostrEvent[]>;
|
||||
isReactedBy: (pubkey: string) => boolean;
|
||||
isReactedByWithEmoji: (pubkey: string) => boolean;
|
||||
invalidateReactions: () => Promise<void>;
|
||||
query: CreateQueryResult<NostrEvent[]>;
|
||||
};
|
||||
|
||||
const EmojiRegex = /\p{Emoji_Presentation}/u;
|
||||
|
||||
const useReactions = (propsProvider: () => UseReactionsProps | null): UseReactions => {
|
||||
const queryClient = useQueryClient();
|
||||
const props = createMemo(propsProvider);
|
||||
const genQueryKey = createMemo(() => ['useReactions', props()] as const);
|
||||
|
||||
const query = createQuery(
|
||||
genQueryKey,
|
||||
({ queryKey, signal }) => {
|
||||
const [, currentProps] = queryKey;
|
||||
if (currentProps == null) return [];
|
||||
|
||||
const { eventId: mentionedEventId } = currentProps;
|
||||
const promise = exec({ type: 'Reactions', mentionedEventId }, signal).then(
|
||||
(batchedEvents) => {
|
||||
const events = () => batchedEvents().events;
|
||||
observable(batchedEvents).subscribe(() => {
|
||||
queryClient.setQueryData(queryKey, events());
|
||||
});
|
||||
return events();
|
||||
},
|
||||
);
|
||||
return timeout(15000, `useReactions: ${mentionedEventId}`)(promise);
|
||||
},
|
||||
{
|
||||
staleTime: 1 * 60 * 1000, // 1 min
|
||||
cacheTime: 4 * 60 * 60 * 1000, // 4 hour
|
||||
refetchInterval: 1 * 60 * 1000, // 1 min
|
||||
},
|
||||
);
|
||||
|
||||
const reactions = () => query.data ?? [];
|
||||
|
||||
const reactionsGroupedByContent = () => {
|
||||
const result = new Map<string, NostrEvent[]>();
|
||||
reactions().forEach((event) => {
|
||||
const events = result.get(event.content) ?? [];
|
||||
events.push(event);
|
||||
result.set(event.content, events);
|
||||
});
|
||||
return result;
|
||||
};
|
||||
|
||||
const isReactedBy = (pubkey: string): boolean =>
|
||||
reactions().findIndex((event) => event.pubkey === pubkey) !== -1;
|
||||
|
||||
const isReactedByWithEmoji = (pubkey: string): boolean =>
|
||||
reactions().findIndex((event) => event.pubkey === pubkey && EmojiRegex.test(event.content)) !==
|
||||
-1;
|
||||
|
||||
const invalidateReactions = (): Promise<void> => queryClient.invalidateQueries(genQueryKey());
|
||||
|
||||
return {
|
||||
reactions,
|
||||
reactionsGroupedByContent,
|
||||
isReactedBy,
|
||||
isReactedByWithEmoji,
|
||||
invalidateReactions,
|
||||
query,
|
||||
};
|
||||
};
|
||||
|
||||
export default useReactions;
|
||||
|
||||
Reference in New Issue
Block a user