feat(messages): support forwarding to multiple chats
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { deleteMessage, forwardMessage, listMessageReactions, pinMessage, toggleMessageReaction } from "../api/chats";
|
||||
import { deleteMessage, forwardMessageBulk, listMessageReactions, pinMessage, toggleMessageReaction } from "../api/chats";
|
||||
import type { Message, MessageReaction } from "../chat/types";
|
||||
import { useAuthStore } from "../store/authStore";
|
||||
import { useChatStore } from "../store/chatStore";
|
||||
@@ -40,6 +40,7 @@ export function MessageList() {
|
||||
const [forwardQuery, setForwardQuery] = useState("");
|
||||
const [forwardError, setForwardError] = useState<string | null>(null);
|
||||
const [isForwarding, setIsForwarding] = useState(false);
|
||||
const [forwardSelectedChatIds, setForwardSelectedChatIds] = useState<Set<number>>(new Set());
|
||||
const [deleteMessageId, setDeleteMessageId] = useState<number | null>(null);
|
||||
const [deleteError, setDeleteError] = useState<string | null>(null);
|
||||
const [selectedIds, setSelectedIds] = useState<Set<number>>(new Set());
|
||||
@@ -86,6 +87,7 @@ export function MessageList() {
|
||||
}
|
||||
setCtx(null);
|
||||
setForwardMessageId(null);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setDeleteMessageId(null);
|
||||
setSelectedIds(new Set());
|
||||
};
|
||||
@@ -98,6 +100,7 @@ export function MessageList() {
|
||||
setCtx(null);
|
||||
setDeleteMessageId(null);
|
||||
setForwardMessageId(null);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setReactionsByMessage({});
|
||||
}, [activeChatId]);
|
||||
|
||||
@@ -127,13 +130,19 @@ export function MessageList() {
|
||||
}
|
||||
const chatId = activeChatId;
|
||||
|
||||
async function handleForward(targetChatId: number) {
|
||||
async function handleForwardSubmit() {
|
||||
if (!forwardMessageId) return;
|
||||
const targetChatIds = [...forwardSelectedChatIds];
|
||||
if (!targetChatIds.length) {
|
||||
setForwardError("Select at least one chat");
|
||||
return;
|
||||
}
|
||||
setIsForwarding(true);
|
||||
setForwardError(null);
|
||||
try {
|
||||
await forwardMessage(forwardMessageId, targetChatId);
|
||||
await forwardMessageBulk(forwardMessageId, targetChatIds);
|
||||
setForwardMessageId(null);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setForwardQuery("");
|
||||
} catch {
|
||||
setForwardError("Failed to forward message");
|
||||
@@ -414,6 +423,7 @@ export function MessageList() {
|
||||
setForwardMessageId(ctx.messageId);
|
||||
setForwardQuery("");
|
||||
setForwardError(null);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setCtx(null);
|
||||
}}
|
||||
>
|
||||
@@ -459,10 +469,20 @@ export function MessageList() {
|
||||
<div className="tg-scrollbar max-h-56 space-y-1 overflow-auto">
|
||||
{forwardTargets.map((chat) => (
|
||||
<button
|
||||
className="block w-full rounded-lg bg-slate-800 px-3 py-2 text-left text-sm hover:bg-slate-700 disabled:opacity-60"
|
||||
className={`block w-full rounded-lg px-3 py-2 text-left text-sm disabled:opacity-60 ${forwardSelectedChatIds.has(chat.id) ? "bg-sky-500/30" : "bg-slate-800 hover:bg-slate-700"}`}
|
||||
disabled={isForwarding}
|
||||
key={chat.id}
|
||||
onClick={() => void handleForward(chat.id)}
|
||||
onClick={() => {
|
||||
setForwardSelectedChatIds((prev) => {
|
||||
const next = new Set(prev);
|
||||
if (next.has(chat.id)) {
|
||||
next.delete(chat.id);
|
||||
} else {
|
||||
next.add(chat.id);
|
||||
}
|
||||
return next;
|
||||
});
|
||||
}}
|
||||
>
|
||||
<p className="truncate font-semibold">{chatLabel(chat)}</p>
|
||||
<p className="truncate text-xs text-slate-400">{chat.handle ? `@${chat.handle}` : chat.type}</p>
|
||||
@@ -471,9 +491,14 @@ export function MessageList() {
|
||||
{forwardTargets.length === 0 ? <p className="px-1 py-2 text-xs text-slate-400">No chats found</p> : null}
|
||||
</div>
|
||||
{forwardError ? <p className="mt-2 text-xs text-red-400">{forwardError}</p> : null}
|
||||
<button className="mt-3 w-full rounded bg-slate-700 px-3 py-2 text-sm" onClick={() => setForwardMessageId(null)}>
|
||||
Cancel
|
||||
</button>
|
||||
<div className="mt-3 flex gap-2">
|
||||
<button className="w-full rounded bg-sky-500 px-3 py-2 text-sm font-semibold text-slate-950" onClick={() => void handleForwardSubmit()}>
|
||||
Forward ({forwardSelectedChatIds.size})
|
||||
</button>
|
||||
<button className="w-full rounded bg-slate-700 px-3 py-2 text-sm" onClick={() => setForwardMessageId(null)}>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
Reference in New Issue
Block a user