- Issue not found
+
+
This issue does not exist or has been deleted in this workspace.
+ {!onDelete && (
+
+ )}
);
}
@@ -856,9 +869,30 @@ export function IssueDetail({ issueId, onDelete, defaultSidebarOpen = true, layo
}
}
+ // Coalesce: same actor + same action within 2 min → keep last only
+ const COALESCE_MS = 2 * 60 * 1000;
+ const coalesced: TimelineEntry[] = [];
+ for (const entry of topLevel) {
+ if (entry.type === "activity") {
+ const prev = coalesced[coalesced.length - 1];
+ if (
+ prev?.type === "activity" &&
+ prev.action === entry.action &&
+ prev.actor_type === entry.actor_type &&
+ prev.actor_id === entry.actor_id &&
+ Math.abs(new Date(entry.created_at).getTime() - new Date(prev.created_at).getTime()) <= COALESCE_MS
+ ) {
+ // Replace previous with this one (keep the later result)
+ coalesced[coalesced.length - 1] = entry;
+ continue;
+ }
+ }
+ coalesced.push(entry);
+ }
+
// Group consecutive activities together so the connector line works
const groups: { type: "activities" | "comment"; entries: TimelineEntry[] }[] = [];
- for (const entry of topLevel) {
+ for (const entry of coalesced) {
if (entry.type === "activity") {
const last = groups[groups.length - 1];
if (last?.type === "activities") {
diff --git a/apps/web/features/issues/components/reply-input.tsx b/apps/web/features/issues/components/reply-input.tsx
index dc355509..b95662c4 100644
--- a/apps/web/features/issues/components/reply-input.tsx
+++ b/apps/web/features/issues/components/reply-input.tsx
@@ -34,7 +34,7 @@ function ReplyInput({
const [submitting, setSubmitting] = useState(false);
const handleSubmit = async () => {
- const content = editorRef.current?.getMarkdown()?.trim();
+ const content = editorRef.current?.getMarkdown()?.replace(/(\n\s*)+$/, "").trim();
if (!content || submitting) return;
setSubmitting(true);
try {