feat: add reply/forward/pin message flow across backend and web
Some checks failed
CI / test (push) Failing after 24s
Some checks failed
CI / test (push) Failing after 24s
- add reply_to/forwarded_from message fields and chat pinned_message field - add forward and pin APIs plus reply support in message create - wire web actions: Reply, Fwd, Pin and reply composer state - fix spam policy bug: allow repeated identical messages, keep rate limiting
This commit is contained in:
@@ -10,6 +10,8 @@ export function MessageComposer() {
|
||||
const addOptimisticMessage = useChatStore((s) => s.addOptimisticMessage);
|
||||
const confirmMessageByClientId = useChatStore((s) => s.confirmMessageByClientId);
|
||||
const removeOptimisticMessage = useChatStore((s) => s.removeOptimisticMessage);
|
||||
const replyToByChat = useChatStore((s) => s.replyToByChat);
|
||||
const setReplyToMessage = useChatStore((s) => s.setReplyToMessage);
|
||||
const accessToken = useAuthStore((s) => s.accessToken);
|
||||
const [text, setText] = useState("");
|
||||
const wsRef = useRef<WebSocket | null>(null);
|
||||
@@ -56,11 +58,13 @@ export function MessageComposer() {
|
||||
}
|
||||
const clientMessageId = makeClientMessageId();
|
||||
const textValue = text.trim();
|
||||
const replyToMessageId = activeChatId ? (replyToByChat[activeChatId]?.id ?? undefined) : undefined;
|
||||
addOptimisticMessage({ chatId: activeChatId, senderId: me.id, type: "text", text: textValue, clientMessageId });
|
||||
try {
|
||||
const message = await sendMessageWithClientId(activeChatId, textValue, "text", clientMessageId);
|
||||
const message = await sendMessageWithClientId(activeChatId, textValue, "text", clientMessageId, replyToMessageId);
|
||||
confirmMessageByClientId(activeChatId, clientMessageId, message);
|
||||
setText("");
|
||||
setReplyToMessage(activeChatId, null);
|
||||
const ws = getWs();
|
||||
ws?.send(JSON.stringify({ event: "typing_stop", payload: { chat_id: activeChatId } }));
|
||||
} catch {
|
||||
@@ -77,6 +81,7 @@ export function MessageComposer() {
|
||||
setUploadProgress(0);
|
||||
setUploadError(null);
|
||||
const clientMessageId = makeClientMessageId();
|
||||
const replyToMessageId = activeChatId ? (replyToByChat[activeChatId]?.id ?? undefined) : undefined;
|
||||
try {
|
||||
const upload = await requestUploadUrl(file);
|
||||
await uploadToPresignedUrl(upload.upload_url, upload.required_headers, file, setUploadProgress);
|
||||
@@ -87,9 +92,10 @@ export function MessageComposer() {
|
||||
text: upload.file_url,
|
||||
clientMessageId
|
||||
});
|
||||
const message = await sendMessageWithClientId(activeChatId, upload.file_url, messageType, clientMessageId);
|
||||
const message = await sendMessageWithClientId(activeChatId, upload.file_url, messageType, clientMessageId, replyToMessageId);
|
||||
await attachFile(message.id, upload.file_url, file.type || "application/octet-stream", file.size);
|
||||
confirmMessageByClientId(activeChatId, clientMessageId, message);
|
||||
setReplyToMessage(activeChatId, null);
|
||||
} catch {
|
||||
removeOptimisticMessage(activeChatId, clientMessageId);
|
||||
setUploadError("Upload failed. Please try again.");
|
||||
@@ -239,6 +245,17 @@ export function MessageComposer() {
|
||||
|
||||
return (
|
||||
<div className="border-t border-slate-700/50 bg-slate-900/55 p-3">
|
||||
{activeChatId && replyToByChat[activeChatId] ? (
|
||||
<div className="mb-2 flex items-start justify-between rounded-lg border border-slate-700/80 bg-slate-800/70 px-3 py-2 text-xs">
|
||||
<div className="min-w-0">
|
||||
<p className="font-semibold text-sky-300">Replying</p>
|
||||
<p className="truncate text-slate-300">{replyToByChat[activeChatId]?.text || "[media]"}</p>
|
||||
</div>
|
||||
<button className="ml-2 rounded bg-slate-700 px-2 py-1 text-[11px]" onClick={() => setReplyToMessage(activeChatId, null)}>
|
||||
Cancel
|
||||
</button>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="mb-2 flex items-center gap-2">
|
||||
<label className="cursor-pointer rounded-full bg-slate-700/80 px-3 py-2 text-xs font-semibold hover:bg-slate-700">
|
||||
+
|
||||
|
||||
Reference in New Issue
Block a user