mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-09 23:16:50 +02:00
refactor(nip56): use RichText for comment and applesauce helpers
- Render report comments using RichText like kind 1 notes - Use getTagValue/getTagValues helpers instead of direct tag access - Add explanatory comments where direct tag access is still required https://claude.ai/code/session_012ux81GyM8iZ1GLnKHC7esJ
This commit is contained in:
@@ -15,10 +15,14 @@ import {
|
||||
UserX,
|
||||
HelpCircle,
|
||||
} from "lucide-react";
|
||||
import { BaseEventProps, BaseEventContainer } from "./BaseEventRenderer";
|
||||
import {
|
||||
BaseEventProps,
|
||||
BaseEventContainer,
|
||||
ClickableEventTitle,
|
||||
} from "./BaseEventRenderer";
|
||||
import { QuotedEvent } from "@/components/nostr/QuotedEvent";
|
||||
import { UserName } from "@/components/nostr/UserName";
|
||||
import { useGrimoire } from "@/core/state";
|
||||
import { RichText } from "../RichText";
|
||||
import {
|
||||
getReportInfo,
|
||||
type ReportType,
|
||||
@@ -53,7 +57,6 @@ function getReportTypeIcon(reportType: ReportType) {
|
||||
* Renderer for Kind 1984 - Reports (NIP-56)
|
||||
*/
|
||||
export function ReportRenderer({ event }: BaseEventProps) {
|
||||
const { addWindow } = useGrimoire();
|
||||
// Parse report using cached helper (no useMemo needed - applesauce caches internally)
|
||||
const report = getReportInfo(event);
|
||||
|
||||
@@ -69,19 +72,14 @@ export function ReportRenderer({ event }: BaseEventProps) {
|
||||
|
||||
const reasonLabel = REPORT_TYPE_LABELS[report.reportType].toLowerCase();
|
||||
|
||||
// Open report detail view
|
||||
const openReportDetail = (e: React.MouseEvent) => {
|
||||
e.stopPropagation();
|
||||
addWindow("open", { pointer: { id: event.id } });
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseEventContainer event={event}>
|
||||
<div className="flex flex-col gap-2">
|
||||
{/* Report header: "Reported <username> for <reason>" - whole line clickable */}
|
||||
<button
|
||||
onClick={openReportDetail}
|
||||
className="flex items-center gap-1.5 flex-wrap text-sm text-left hover:underline decoration-dotted cursor-crosshair"
|
||||
{/* Report header: "Reported <username> for <reason>" */}
|
||||
<ClickableEventTitle
|
||||
event={event}
|
||||
as="div"
|
||||
className="flex items-center gap-1.5 flex-wrap text-sm"
|
||||
>
|
||||
<Flag className="size-4 text-muted-foreground flex-shrink-0" />
|
||||
<span className="text-muted-foreground">Reported</span>
|
||||
@@ -89,7 +87,7 @@ export function ReportRenderer({ event }: BaseEventProps) {
|
||||
<span className="inline-flex items-center gap-1 px-1.5 py-0.5 rounded text-xs font-medium bg-muted text-muted-foreground">
|
||||
for {getReportTypeIcon(report.reportType)} {reasonLabel}
|
||||
</span>
|
||||
</button>
|
||||
</ClickableEventTitle>
|
||||
|
||||
{/* Reported event - collapsed with hidden preview (depth=2, hidePreview) */}
|
||||
{report.targetType === "event" && report.reportedEventId && (
|
||||
@@ -118,12 +116,8 @@ export function ReportRenderer({ event }: BaseEventProps) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* Report comment */}
|
||||
{report.comment && (
|
||||
<div className="text-sm border-l-2 border-muted pl-3 text-muted-foreground italic">
|
||||
"{report.comment}"
|
||||
</div>
|
||||
)}
|
||||
{/* Report comment - rendered like a kind 1 note */}
|
||||
{event.content && <RichText event={event} className="text-sm" />}
|
||||
</div>
|
||||
</BaseEventContainer>
|
||||
);
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
|
||||
import { getTagValue, getOrComputeCachedValue } from "applesauce-core/helpers";
|
||||
import type { NostrEvent } from "@/types/nostr";
|
||||
import { getTagValues } from "@/lib/nostr-utils";
|
||||
|
||||
/**
|
||||
* Report types as defined in NIP-56
|
||||
@@ -88,33 +89,22 @@ export interface ParsedReport {
|
||||
* Get the reported pubkey from a report event
|
||||
*/
|
||||
export function getReportedPubkey(event: NostrEvent): string | undefined {
|
||||
const pTag = event.tags.find((t) => t[0] === "p");
|
||||
return pTag?.[1];
|
||||
return getTagValue(event, "p");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the report type from a report event
|
||||
* The report type is the 3rd element of the p, e, or x tag
|
||||
* The report type is the 3rd element (index 2) of the p, e, or x tag.
|
||||
* Direct tag access is required since getTagValue only returns tag[1].
|
||||
*/
|
||||
export function getReportType(event: NostrEvent): ReportType | undefined {
|
||||
// Check p tag for report type
|
||||
const pTag = event.tags.find((t) => t[0] === "p" && t[2]);
|
||||
if (pTag?.[2] && REPORT_TYPES.includes(pTag[2] as ReportType)) {
|
||||
return pTag[2] as ReportType;
|
||||
// Check p, e, x tags for report type in the 3rd element
|
||||
for (const tagName of ["p", "e", "x"]) {
|
||||
const tag = event.tags.find((t) => t[0] === tagName && t[2]);
|
||||
if (tag?.[2] && REPORT_TYPES.includes(tag[2] as ReportType)) {
|
||||
return tag[2] as ReportType;
|
||||
}
|
||||
}
|
||||
|
||||
// Check e tag for report type
|
||||
const eTag = event.tags.find((t) => t[0] === "e" && t[2]);
|
||||
if (eTag?.[2] && REPORT_TYPES.includes(eTag[2] as ReportType)) {
|
||||
return eTag[2] as ReportType;
|
||||
}
|
||||
|
||||
// Check x tag for report type
|
||||
const xTag = event.tags.find((t) => t[0] === "x" && t[2]);
|
||||
if (xTag?.[2] && REPORT_TYPES.includes(xTag[2] as ReportType)) {
|
||||
return xTag[2] as ReportType;
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
@@ -122,23 +112,21 @@ export function getReportType(event: NostrEvent): ReportType | undefined {
|
||||
* Get the reported event ID from a report event
|
||||
*/
|
||||
export function getReportedEventId(event: NostrEvent): string | undefined {
|
||||
const eTag = event.tags.find((t) => t[0] === "e");
|
||||
return eTag?.[1];
|
||||
return getTagValue(event, "e");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the reported blob hash from a report event
|
||||
*/
|
||||
export function getReportedBlobHash(event: NostrEvent): string | undefined {
|
||||
const xTag = event.tags.find((t) => t[0] === "x");
|
||||
return xTag?.[1];
|
||||
return getTagValue(event, "x");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get server URLs from a report event (for blob reports)
|
||||
*/
|
||||
export function getReportServerUrls(event: NostrEvent): string[] {
|
||||
return event.tags.filter((t) => t[0] === "server").map((t) => t[1]);
|
||||
return getTagValues(event, "server");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +181,8 @@ export function isValidReportType(type: string): type is ReportType {
|
||||
|
||||
/**
|
||||
* Get NIP-32 label tags from a report event (optional enhancement)
|
||||
* Uses applesauce caching - result is cached on the event object
|
||||
* Uses applesauce caching - result is cached on the event object.
|
||||
* Direct tag access for "l" tags is required to filter by namespace in tag[2].
|
||||
*/
|
||||
export function getReportLabels(
|
||||
event: NostrEvent,
|
||||
|
||||
Reference in New Issue
Block a user