click-to-select for multi-reply + /new command + layout fix
- Click any message to select it for reply (click again to deselect) - Multiple messages can be selected — compose shows all - Selected messages get orange left border + tinted bg - Floating pill shows ✓ when selected - /new <name> slash command creates channels from compose box - Proper multi-reply context in compose with count 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 [messages, setMessages] = useState<Message[]>([]);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [replyTo, setReplyTo] = useState<{ id: string; username: string; content: string } | null>(null);
|
||||
const [selectedMessages, setSelectedMessages] = useState<{ id: string; username: string; content: string }[]>([]);
|
||||
const [sheetOpen, setSheetOpen] = useState(false);
|
||||
const [showScrollDown, setShowScrollDown] = useState(false);
|
||||
const scrollRef = useRef<HTMLDivElement>(null);
|
||||
@@ -93,7 +93,7 @@ export default function App() {
|
||||
|
||||
useEffect(() => {
|
||||
setMessages([]);
|
||||
setReplyTo(null);
|
||||
setSelectedMessages([]);
|
||||
prevMsgCountRef.current = 0;
|
||||
loadMessages();
|
||||
}, [activeChannelId, loadMessages]);
|
||||
@@ -212,11 +212,15 @@ export default function App() {
|
||||
message={msg}
|
||||
replyTarget={msg.reply_to ? messagesById.get(msg.reply_to) : undefined}
|
||||
currentUsername={getCurrentUsername()}
|
||||
onReply={(id) => {
|
||||
const target = messagesById.get(id);
|
||||
if (target) {
|
||||
setReplyTo({ id, username: target.user.display_name, content: target.content });
|
||||
}
|
||||
selected={selectedMessages.some((s) => s.id === msg.id)}
|
||||
onSelect={(id) => {
|
||||
setSelectedMessages((prev) => {
|
||||
const exists = prev.find((s) => s.id === id);
|
||||
if (exists) return prev.filter((s) => s.id !== id);
|
||||
const target = messagesById.get(id);
|
||||
if (!target) return prev;
|
||||
return [...prev, { id, username: target.user.display_name, content: target.content }];
|
||||
});
|
||||
}}
|
||||
onDelete={async (chId, msgId) => {
|
||||
try {
|
||||
@@ -248,9 +252,11 @@ export default function App() {
|
||||
<ComposeBox
|
||||
key={activeChannelId}
|
||||
channelId={activeChannelId}
|
||||
replyTo={replyTo}
|
||||
onClearReply={() => setReplyTo(null)}
|
||||
replyTo={selectedMessages.length > 0 ? selectedMessages[0] : null}
|
||||
selectedMessages={selectedMessages}
|
||||
onClearReply={() => setSelectedMessages([])}
|
||||
onMessageSent={() => {
|
||||
setSelectedMessages([]);
|
||||
loadMessages();
|
||||
setTimeout(() => scrollToBottom(), 100);
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user