mirror of
https://github.com/purrgrammer/grimoire.git
synced 2026-04-12 00:17:02 +02:00
refactor: Make thread comments more compact
- Create ThreadCommentRenderer for compact comment display - Remove reply preview from comments - Remove footer from comments - Remove reply count display when collapsed - Reduce padding in comments section - Tighter spacing between comments (space-y-0) - Use compact renderer for both kind 1 and 1111 in thread view
This commit is contained in:
49
src/components/ThreadCommentRenderer.tsx
Normal file
49
src/components/ThreadCommentRenderer.tsx
Normal file
@@ -0,0 +1,49 @@
|
||||
import { NostrEvent } from "@/types/nostr";
|
||||
import { UserName } from "./nostr/UserName";
|
||||
import { EventMenu } from "./nostr/kinds/BaseEventRenderer";
|
||||
import { RichText } from "./nostr/RichText";
|
||||
import { formatTimestamp } from "@/hooks/useLocale";
|
||||
import { useGrimoire } from "@/core/state";
|
||||
|
||||
/**
|
||||
* Compact renderer for comments in thread view
|
||||
* - No reply preview
|
||||
* - No footer
|
||||
* - Minimal padding
|
||||
* - Used for both kind 1 and kind 1111 in thread context
|
||||
*/
|
||||
export function ThreadCommentRenderer({ event }: { event: NostrEvent }) {
|
||||
const { locale } = useGrimoire();
|
||||
|
||||
// Format relative time for display
|
||||
const relativeTime = formatTimestamp(
|
||||
event.created_at,
|
||||
"relative",
|
||||
locale.locale,
|
||||
);
|
||||
|
||||
// Format absolute timestamp for hover
|
||||
const absoluteTime = formatTimestamp(
|
||||
event.created_at,
|
||||
"absolute",
|
||||
locale.locale,
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1.5 p-2 border-b border-border/50 last:border-0">
|
||||
<div className="flex flex-row justify-between items-center">
|
||||
<div className="flex flex-row gap-2 items-baseline">
|
||||
<UserName pubkey={event.pubkey} className="text-sm" />
|
||||
<span
|
||||
className="text-xs text-muted-foreground cursor-help"
|
||||
title={absoluteTime}
|
||||
>
|
||||
{relativeTime}
|
||||
</span>
|
||||
</div>
|
||||
<EventMenu event={event} />
|
||||
</div>
|
||||
<RichText event={event} className="text-sm" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -2,8 +2,8 @@ import { useState, useMemo } from "react";
|
||||
import { ChevronDown, ChevronRight } from "lucide-react";
|
||||
import { getNip10References } from "applesauce-common/helpers/threading";
|
||||
import { getCommentReplyPointer } from "applesauce-common/helpers/comment";
|
||||
import { KindRenderer } from "./nostr/kinds";
|
||||
import { EventErrorBoundary } from "./EventErrorBoundary";
|
||||
import { ThreadCommentRenderer } from "./ThreadCommentRenderer";
|
||||
import type { NostrEvent } from "@/types/nostr";
|
||||
|
||||
export interface ThreadConversationProps {
|
||||
@@ -140,7 +140,7 @@ export function ThreadConversation({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-0">
|
||||
{initialTree.map((node) => {
|
||||
const isCollapsed = collapsedIds.has(node.event.id);
|
||||
const hasChildren = node.children.length > 0;
|
||||
@@ -167,24 +167,16 @@ export function ThreadConversation({
|
||||
)}
|
||||
|
||||
<EventErrorBoundary event={node.event}>
|
||||
<KindRenderer event={node.event} />
|
||||
<ThreadCommentRenderer event={node.event} />
|
||||
</EventErrorBoundary>
|
||||
|
||||
{/* Reply count badge (when collapsed) */}
|
||||
{hasChildren && isCollapsed && (
|
||||
<div className="mt-2 ml-4 text-xs text-muted-foreground italic">
|
||||
{node.children.length}{" "}
|
||||
{node.children.length === 1 ? "reply" : "replies"}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
{/* Second-level replies (nested, indented) */}
|
||||
{hasChildren && !isCollapsed && (
|
||||
<div className="ml-8 mt-3 space-y-3 border-l-2 border-border pl-4">
|
||||
<div className="ml-8 mt-2 space-y-0 border-l-2 border-border pl-4">
|
||||
{node.children.map((child) => (
|
||||
<EventErrorBoundary key={child.id} event={child}>
|
||||
<KindRenderer event={child} />
|
||||
<ThreadCommentRenderer event={child} />
|
||||
</EventErrorBoundary>
|
||||
))}
|
||||
</div>
|
||||
|
||||
@@ -344,12 +344,7 @@ export function ThreadViewer({ pointer }: ThreadViewerProps) {
|
||||
</div>
|
||||
|
||||
{/* Replies Section */}
|
||||
<div className="p-4">
|
||||
<div className="text-sm font-semibold text-muted-foreground mb-3 flex items-center gap-2">
|
||||
<MessageSquare className="size-4" />
|
||||
{replies?.length || 0} {replies?.length === 1 ? "reply" : "replies"}
|
||||
</div>
|
||||
|
||||
<div className="px-3 py-2">
|
||||
{replies && replies.length > 0 ? (
|
||||
<ThreadConversation
|
||||
rootEventId={rootEvent.id}
|
||||
@@ -357,7 +352,7 @@ export function ThreadViewer({ pointer }: ThreadViewerProps) {
|
||||
threadKind={rootEvent.kind === 1 ? "nip10" : "nip22"}
|
||||
/>
|
||||
) : (
|
||||
<div className="text-sm text-muted-foreground italic">
|
||||
<div className="text-sm text-muted-foreground italic p-2">
|
||||
No replies yet
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user