refactor: Optimize comment deletion handling with optimistic UI updates

This commit is contained in:
Yusuf İpek
2026-02-07 18:23:46 +03:00
parent 42839d4d69
commit 7141763bc6
2 changed files with 70 additions and 43 deletions
@@ -1132,9 +1132,9 @@ export default function VideoPage() {
// Delete a comment // Delete a comment
const handleDeleteComment = useCallback(async (commentId: string) => { const handleDeleteComment = useCallback(async (commentId: string) => {
setDeletingCommentId(commentId); setDeletingCommentId(commentId);
try {
const res = await fetch(`/api/comments/${commentId}`, { method: 'DELETE' }); // Optimistically remove from UI
if (res.ok) { const previousVideo = video;
setVideo((prev) => { setVideo((prev) => {
if (!prev) return prev; if (!prev) return prev;
return { return {
@@ -1154,19 +1154,32 @@ export default function VideoPage() {
), ),
}; };
}); });
try {
const res = await fetch(`/api/comments/${commentId}`, { method: 'DELETE' });
if (!res.ok) {
setVideo(previousVideo);
} }
} catch (err) { } catch (err) {
console.error('Failed to delete comment:', err); console.error('Failed to delete comment:', err);
setVideo(previousVideo);
} finally { } finally {
setDeletingCommentId(null); setDeletingCommentId(null);
} }
}, [activeVersionId]); }, [activeVersionId, video]);
// Poll for new comments every 10 seconds // Poll for new comments every 10 seconds
useEffect(() => { useEffect(() => {
if (!activeVersion) return; if (!activeVersion) return;
const interval = setInterval(async () => { const interval = setInterval(async () => {
try { try {
const hasPendingComments = activeVersion.comments.some(
(c) => c.id.startsWith('temp-')
) || activeVersion.comments.some(
(c) => c.replies.some((r) => r.id.startsWith('temp-'))
);
if (hasPendingComments) return;
const res = await fetch(`/api/projects/${projectId}/videos/${videoId}`); const res = await fetch(`/api/projects/${projectId}/videos/${videoId}`);
if (res.ok) { if (res.ok) {
const data = await res.json(); const data = await res.json();
+19 -5
View File
@@ -1085,9 +1085,9 @@ export default function WatchPage() {
// Delete a comment // Delete a comment
const handleDeleteComment = useCallback(async (commentId: string) => { const handleDeleteComment = useCallback(async (commentId: string) => {
setDeletingCommentId(commentId); setDeletingCommentId(commentId);
try {
const res = await fetch(`/api/comments/${commentId}`, { method: 'DELETE' }); // Optimistically remove from UI
if (res.ok) { const previousVideo = video;
setVideo((prev) => { setVideo((prev) => {
if (!prev) return prev; if (!prev) return prev;
return { return {
@@ -1107,19 +1107,33 @@ export default function WatchPage() {
), ),
}; };
}); });
try {
const res = await fetch(`/api/comments/${commentId}`, { method: 'DELETE' });
if (!res.ok) {
setVideo(previousVideo);
} }
} catch (err) { } catch (err) {
console.error('Failed to delete comment:', err); console.error('Failed to delete comment:', err);
setVideo(previousVideo);
} finally { } finally {
setDeletingCommentId(null); setDeletingCommentId(null);
} }
}, [activeVersionId]); }, [activeVersionId, video]);
// Poll for new comments every 10 seconds // Poll for new comments every 10 seconds
useEffect(() => { useEffect(() => {
if (!video) return; if (!video) return;
const interval = setInterval(async () => { const interval = setInterval(async () => {
try { try {
const activeVersion = video.versions.find((v) => v.id === activeVersionId);
const hasPendingComments = activeVersion?.comments.some(
(c) => c.id.startsWith('temp-')
) || activeVersion?.comments.some(
(c) => c.replies.some((r) => r.id.startsWith('temp-'))
);
if (hasPendingComments) return;
const res = await fetch(`/api/watch/${videoId}`); const res = await fetch(`/api/watch/${videoId}`);
if (res.ok) { if (res.ok) {
const data = await res.json(); const data = await res.json();
@@ -1128,7 +1142,7 @@ export default function WatchPage() {
} catch { /* silent */ } } catch { /* silent */ }
}, 10000); }, 10000);
return () => clearInterval(interval); return () => clearInterval(interval);
}, [video, videoId]); }, [video, videoId, activeVersionId]);
const getEmbedUrl = (version: Version) => { const getEmbedUrl = (version: Version) => {
if (version.providerId === 'youtube') { if (version.providerId === 'youtube') {