reply UX: show username + content preview instead of hash
- ComposeBox takes ReplyContext {id, username, content} instead of string
- Reply chip shows "^ benji message preview..." with truncation
- App passes full reply context from messagesById
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -43,7 +43,7 @@ export default function App() {
|
|||||||
const [activeChannelId, setActiveChannelId] = useState<string | null>(null);
|
const [activeChannelId, setActiveChannelId] = useState<string | null>(null);
|
||||||
const [messages, setMessages] = useState<Message[]>([]);
|
const [messages, setMessages] = useState<Message[]>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [replyTo, setReplyTo] = useState<string | null>(null);
|
const [replyTo, setReplyTo] = useState<{ id: string; username: string; content: string } | null>(null);
|
||||||
const [sheetOpen, setSheetOpen] = useState(false);
|
const [sheetOpen, setSheetOpen] = useState(false);
|
||||||
const scrollRef = useRef<HTMLDivElement>(null);
|
const scrollRef = useRef<HTMLDivElement>(null);
|
||||||
const prevMsgCountRef = useRef(0);
|
const prevMsgCountRef = useRef(0);
|
||||||
@@ -178,7 +178,12 @@ export default function App() {
|
|||||||
key={msg.id}
|
key={msg.id}
|
||||||
message={msg}
|
message={msg}
|
||||||
replyTarget={msg.reply_to ? messagesById.get(msg.reply_to) : undefined}
|
replyTarget={msg.reply_to ? messagesById.get(msg.reply_to) : undefined}
|
||||||
onReply={setReplyTo}
|
onReply={(id) => {
|
||||||
|
const target = messagesById.get(id);
|
||||||
|
if (target) {
|
||||||
|
setReplyTo({ id, username: target.user.display_name, content: target.content });
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,9 +4,15 @@ import type { User } from "@/types/User";
|
|||||||
import { postMessage, getUsers, getCurrentUsername } from "@/api";
|
import { postMessage, getUsers, getCurrentUsername } from "@/api";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
|
|
||||||
|
interface ReplyContext {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
channelId: string;
|
channelId: string;
|
||||||
replyTo: string | null;
|
replyTo: ReplyContext | null;
|
||||||
onClearReply: () => void;
|
onClearReply: () => void;
|
||||||
onMessageSent: () => void;
|
onMessageSent: () => void;
|
||||||
}
|
}
|
||||||
@@ -95,7 +101,7 @@ export function ComposeBox({
|
|||||||
await postMessage(channelId, {
|
await postMessage(channelId, {
|
||||||
content: content.trim(),
|
content: content.trim(),
|
||||||
type: msgType,
|
type: msgType,
|
||||||
reply_to: replyTo ?? undefined,
|
reply_to: replyTo?.id ?? undefined,
|
||||||
});
|
});
|
||||||
setContent("");
|
setContent("");
|
||||||
setMsgType("text");
|
setMsgType("text");
|
||||||
@@ -122,11 +128,12 @@ export function ComposeBox({
|
|||||||
{replyTo && (
|
{replyTo && (
|
||||||
<div className="flex items-center gap-1.5 mb-1.5 text-[10px] font-mono">
|
<div className="flex items-center gap-1.5 mb-1.5 text-[10px] font-mono">
|
||||||
<span className="text-primary">^</span>
|
<span className="text-primary">^</span>
|
||||||
<span className="text-muted-foreground">#{replyTo.slice(0, 8)}</span>
|
<span className="text-foreground font-bold">{replyTo.username}</span>
|
||||||
|
<span className="text-muted-foreground truncate max-w-48 md:max-w-96">{replyTo.content}</span>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onClearReply}
|
onClick={onClearReply}
|
||||||
className="text-muted-foreground hover:text-primary ml-1"
|
className="text-muted-foreground hover:text-primary ml-auto flex-shrink-0"
|
||||||
>
|
>
|
||||||
x
|
x
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user