mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-09 15:07:10 +02:00
refactor: use applesauce helpers for pointer parsing and filter comparison
Phase 2 & 3 of applesauce helpers refactoring plan. **Phase 2: Replace manual pointer parsing** - ReactionRenderer.tsx: replaced manual coordinate parsing with parseCoordinate helper - Benefits: more robust, handles edge cases, consistent with applesauce patterns **Phase 3: Improve filter comparison** - useStable.ts: replaced JSON.stringify with isFilterEqual for filter comparison - Benefits: handles undefined values correctly, supports NIP-ND AND operator - Implementation uses ref pattern to maintain stable reference when filters are equal All tests pass (607 tests).
This commit is contained in:
@@ -5,6 +5,7 @@ import { useMemo } from "react";
|
||||
import { NostrEvent } from "@/types/nostr";
|
||||
import { KindRenderer } from "./index";
|
||||
import { EventCardSkeleton } from "@/components/ui/skeleton";
|
||||
import { parseCoordinate } from "applesauce-core/helpers/pointers";
|
||||
|
||||
/**
|
||||
* Renderer for Kind 7 - Reactions
|
||||
@@ -54,16 +55,8 @@ export function Kind7Renderer({ event }: BaseEventProps) {
|
||||
const aTag = event.tags.find((tag) => tag[0] === "a");
|
||||
const reactedAddress = aTag?.[1]; // Format: kind:pubkey:d-tag
|
||||
|
||||
// Parse a tag into components
|
||||
const addressParts = useMemo(() => {
|
||||
if (!reactedAddress) return null;
|
||||
const parts = reactedAddress.split(":");
|
||||
return {
|
||||
kind: parseInt(parts[0], 10),
|
||||
pubkey: parts[1],
|
||||
dTag: parts[2],
|
||||
};
|
||||
}, [reactedAddress]);
|
||||
// Parse a tag coordinate using applesauce helper
|
||||
const addressPointer = reactedAddress ? parseCoordinate(reactedAddress) : null;
|
||||
|
||||
// Create event pointer for fetching
|
||||
const eventPointer = useMemo(() => {
|
||||
@@ -73,16 +66,16 @@ export function Kind7Renderer({ event }: BaseEventProps) {
|
||||
relays: reactedRelay ? [reactedRelay] : undefined,
|
||||
};
|
||||
}
|
||||
if (addressParts) {
|
||||
if (addressPointer) {
|
||||
return {
|
||||
kind: addressParts.kind,
|
||||
pubkey: addressParts.pubkey,
|
||||
identifier: addressParts.dTag || "",
|
||||
kind: addressPointer.kind,
|
||||
pubkey: addressPointer.pubkey,
|
||||
identifier: addressPointer.identifier || "",
|
||||
relays: [],
|
||||
};
|
||||
}
|
||||
return undefined;
|
||||
}, [reactedEventId, reactedRelay, addressParts]);
|
||||
}, [reactedEventId, reactedRelay, addressPointer]);
|
||||
|
||||
// Fetch the reacted event
|
||||
const reactedEvent = useNostrEvent(eventPointer);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { useMemo } from "react";
|
||||
import { useMemo, useRef } from "react";
|
||||
import { isFilterEqual } from "applesauce-core/helpers/filter";
|
||||
import type { Filter } from "nostr-tools";
|
||||
|
||||
/**
|
||||
* Stabilize a value for use in dependency arrays
|
||||
@@ -46,13 +48,23 @@ export function useStableArray<T extends string>(arr: T[]): T[] {
|
||||
/**
|
||||
* Stabilize a Nostr filter or array of filters
|
||||
*
|
||||
* Specialized stabilizer for Nostr filters which are commonly
|
||||
* recreated on each render.
|
||||
* Uses applesauce's isFilterEqual for robust filter comparison.
|
||||
* Better than JSON.stringify as it handles undefined values correctly
|
||||
* and supports NIP-ND AND operator.
|
||||
*
|
||||
* @param filters - Single filter or array of filters
|
||||
* @returns The memoized filter(s)
|
||||
*/
|
||||
export function useStableFilters<T>(filters: T): T {
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
return useMemo(() => filters, [JSON.stringify(filters)]);
|
||||
export function useStableFilters<T extends Filter | Filter[]>(filters: T): T {
|
||||
const prevFiltersRef = useRef<T>();
|
||||
|
||||
// Only update if filters actually changed (per isFilterEqual)
|
||||
if (
|
||||
!prevFiltersRef.current ||
|
||||
!isFilterEqual(prevFiltersRef.current as Filter | Filter[], filters as Filter | Filter[])
|
||||
) {
|
||||
prevFiltersRef.current = filters;
|
||||
}
|
||||
|
||||
return prevFiltersRef.current;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user