web: add multi-message forward from selection
Some checks failed
CI / test (push) Has been cancelled
Some checks failed
CI / test (push) Has been cancelled
This commit is contained in:
@@ -63,7 +63,7 @@ export function MessageList() {
|
||||
const showToast = useUiStore((s) => s.showToast);
|
||||
|
||||
const [ctx, setCtx] = useState<ContextMenuState>(null);
|
||||
const [forwardMessageId, setForwardMessageId] = useState<number | null>(null);
|
||||
const [forwardMessageIds, setForwardMessageIds] = useState<number[]>([]);
|
||||
const [forwardQuery, setForwardQuery] = useState("");
|
||||
const [forwardError, setForwardError] = useState<string | null>(null);
|
||||
const [isForwarding, setIsForwarding] = useState(false);
|
||||
@@ -169,7 +169,7 @@ export function MessageList() {
|
||||
return;
|
||||
}
|
||||
setCtx(null);
|
||||
setForwardMessageId(null);
|
||||
setForwardMessageIds([]);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setDeleteMessageId(null);
|
||||
setSelectedIds(new Set());
|
||||
@@ -184,7 +184,7 @@ export function MessageList() {
|
||||
setSelectedIds(new Set());
|
||||
setCtx(null);
|
||||
setDeleteMessageId(null);
|
||||
setForwardMessageId(null);
|
||||
setForwardMessageIds([]);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setForwardIncludeAuthor(true);
|
||||
if (activeChatId) {
|
||||
@@ -337,7 +337,7 @@ export function MessageList() {
|
||||
}
|
||||
|
||||
async function handleForwardSubmit() {
|
||||
if (!forwardMessageId) return;
|
||||
if (!forwardMessageIds.length) return;
|
||||
const targetChatIds = [...forwardSelectedChatIds];
|
||||
if (!targetChatIds.length) {
|
||||
setForwardError("Select at least one chat");
|
||||
@@ -346,11 +346,14 @@ export function MessageList() {
|
||||
setIsForwarding(true);
|
||||
setForwardError(null);
|
||||
try {
|
||||
await forwardMessageBulk(forwardMessageId, targetChatIds, forwardIncludeAuthor);
|
||||
setForwardMessageId(null);
|
||||
await Promise.all(
|
||||
forwardMessageIds.map((messageId) => forwardMessageBulk(messageId, targetChatIds, forwardIncludeAuthor))
|
||||
);
|
||||
setForwardMessageIds([]);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setForwardIncludeAuthor(true);
|
||||
setForwardQuery("");
|
||||
setSelectedIds(new Set());
|
||||
} catch {
|
||||
setForwardError("Failed to forward message");
|
||||
} finally {
|
||||
@@ -359,6 +362,17 @@ export function MessageList() {
|
||||
setCtx(null);
|
||||
}
|
||||
|
||||
function openForwardDialog(messageIds: number[]) {
|
||||
if (!messageIds.length) {
|
||||
return;
|
||||
}
|
||||
setForwardMessageIds([...new Set(messageIds)]);
|
||||
setForwardQuery("");
|
||||
setForwardError(null);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setForwardIncludeAuthor(true);
|
||||
}
|
||||
|
||||
async function handlePin(messageId: number) {
|
||||
const nextPinned = activeChat?.pinned_message_id === messageId ? null : messageId;
|
||||
const chat = await pinMessage(chatId, nextPinned);
|
||||
@@ -493,6 +507,12 @@ export function MessageList() {
|
||||
<div className="flex items-center justify-between border-b border-slate-700/50 bg-slate-900/80 px-3 py-2 text-xs">
|
||||
<span className="font-semibold text-slate-200">{selectedIds.size} selected</span>
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
className="rounded bg-sky-500 px-2 py-1 font-semibold text-slate-950"
|
||||
onClick={() => openForwardDialog(selectedMessages.map((message) => message.id))}
|
||||
>
|
||||
Forward
|
||||
</button>
|
||||
{!channelOnlyDeleteForAll ? (
|
||||
<button className="rounded bg-red-500 px-2 py-1 font-semibold text-white" onClick={() => void deleteSelectedForMe()}>
|
||||
Delete for me
|
||||
@@ -763,14 +783,10 @@ export function MessageList() {
|
||||
Edit
|
||||
</button>
|
||||
) : null}
|
||||
<button
|
||||
className="block w-full rounded px-2 py-1.5 text-left text-sm hover:bg-slate-800"
|
||||
onClick={() => {
|
||||
setForwardMessageId(ctx.messageId);
|
||||
setForwardQuery("");
|
||||
setForwardError(null);
|
||||
setForwardSelectedChatIds(new Set());
|
||||
setForwardIncludeAuthor(true);
|
||||
<button
|
||||
className="block w-full rounded px-2 py-1.5 text-left text-sm hover:bg-slate-800"
|
||||
onClick={() => {
|
||||
openForwardDialog([ctx.messageId]);
|
||||
setCtx(null);
|
||||
}}
|
||||
>
|
||||
@@ -874,10 +890,12 @@ export function MessageList() {
|
||||
)
|
||||
: null}
|
||||
|
||||
{forwardMessageId ? (
|
||||
<div className="absolute inset-0 z-50 flex items-end justify-center bg-slate-950/55 p-3" onClick={() => setForwardMessageId(null)}>
|
||||
{forwardMessageIds.length > 0 ? (
|
||||
<div className="absolute inset-0 z-50 flex items-end justify-center bg-slate-950/55 p-3" onClick={() => setForwardMessageIds([])}>
|
||||
<div className="w-full rounded-xl border border-slate-700/80 bg-slate-900 p-3" onClick={(event) => event.stopPropagation()}>
|
||||
<p className="mb-2 text-sm font-semibold">Forward message</p>
|
||||
<p className="mb-2 text-sm font-semibold">
|
||||
Forward {forwardMessageIds.length > 1 ? `${forwardMessageIds.length} messages` : "message"}
|
||||
</p>
|
||||
<input
|
||||
className="mb-2 w-full rounded-lg border border-slate-700/80 bg-slate-800/80 px-3 py-2 text-sm outline-none placeholder:text-slate-400 focus:border-sky-500"
|
||||
placeholder="Search chats"
|
||||
@@ -923,7 +941,7 @@ export function MessageList() {
|
||||
<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)}>
|
||||
<button className="w-full rounded bg-slate-700 px-3 py-2 text-sm" onClick={() => setForwardMessageIds([])}>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user