feat(web): bulk forward/favorite in multi-select mode
Rounds out the multi-select bottom bar (README §3.6) with 转发/收藏 alongside the existing 删除 -- reuses the single-message ForwardPickerModal/ favoriteMessages/forwardMessage machinery from the context-menu actions, just applied to the whole selected set. One "转发" button (not separate 逐条/合并 buttons) matching the old app's real dialog-internal mode toggle, which this app's simplified single-target picker doesn't model -- already noted as a scope cut in ForwardPickerModal's own docstring. Verified live: entering multi-select via a message's context menu shows 转发/收藏/删除, and bulk-favorite POSTs a real /v1/im/favorites/batch request. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
03b8098b3c
commit
d5440b962b
@@ -47,6 +47,7 @@ export function ConversationView() {
|
||||
const [selectedSeqs, setSelectedSeqs] = useState<Set<number>>(new Set());
|
||||
const [loadingOlder, setLoadingOlder] = useState(false);
|
||||
const [recording, setRecording] = useState(false);
|
||||
const [bulkForwardOpen, setBulkForwardOpen] = useState(false);
|
||||
const [replyTo, setReplyTo] = useState<StoredMessage | null>(null);
|
||||
const [forwardMsg, setForwardMsg] = useState<StoredMessage | null>(null);
|
||||
const [emojiOpen, setEmojiOpen] = useState(false);
|
||||
@@ -161,6 +162,22 @@ export function ConversationView() {
|
||||
exitSelectMode();
|
||||
};
|
||||
|
||||
const bulkFavorite = () => {
|
||||
if (selectedSeqs.size === 0) return;
|
||||
favoriteMessages([...selectedSeqs].map((seq) => ({ topic: topicId, seq }))).catch(() => {});
|
||||
exitSelectMode();
|
||||
};
|
||||
|
||||
const bulkForward = (targetTopic: string) => {
|
||||
const target = tinode.getTopic(targetTopic);
|
||||
for (const seq of selectedSeqs) {
|
||||
const msg = topic.findMessage(seq);
|
||||
if (msg) forwardMessage(topicId, msg, target);
|
||||
}
|
||||
setBulkForwardOpen(false);
|
||||
exitSelectMode();
|
||||
};
|
||||
|
||||
const handleAction = (action: MessageAction) => {
|
||||
const msg = menu?.msg;
|
||||
setMenu(null);
|
||||
@@ -275,6 +292,24 @@ export function ConversationView() {
|
||||
|
||||
{selectMode ? (
|
||||
<div className="flex h-18 flex-none items-center justify-around border-t border-border-panel bg-white">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => setBulkForwardOpen(true)}
|
||||
disabled={selectedSeqs.size === 0}
|
||||
className="flex flex-col items-center gap-1 text-text-secondary disabled:opacity-40"
|
||||
>
|
||||
<Icon name="reply" className="text-[22px]" />
|
||||
<span className="text-xs">转发</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
onClick={bulkFavorite}
|
||||
disabled={selectedSeqs.size === 0}
|
||||
className="flex flex-col items-center gap-1 text-text-secondary disabled:opacity-40"
|
||||
>
|
||||
<Icon name="inventory_2" className="text-[22px]" />
|
||||
<span className="text-xs">收藏</span>
|
||||
</button>
|
||||
<button type="button" onClick={bulkDelete} className="flex flex-col items-center gap-1 text-danger-text">
|
||||
<Icon name="delete_outline" className="text-[22px]" />
|
||||
<span className="text-xs">删除</span>
|
||||
@@ -379,6 +414,8 @@ export function ConversationView() {
|
||||
}}
|
||||
/>
|
||||
) : null}
|
||||
|
||||
{bulkForwardOpen ? <ForwardPickerModal onClose={() => setBulkForwardOpen(false)} onPick={bulkForward} /> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user