diff --git a/packages/ui/src/components/Comments.tsx b/packages/ui/src/components/Comments.tsx index 64d53d2c..ecbd3844 100644 --- a/packages/ui/src/components/Comments.tsx +++ b/packages/ui/src/components/Comments.tsx @@ -7,7 +7,7 @@ import { User, MessageCircle, Heart, MoreHorizontal, Mic, MicOff, Loader2 } from import { toast } from "sonner"; import { Link } from "react-router-dom"; import MarkdownRenderer from "@/components/MarkdownRenderer"; -import MarkdownEditor from "@/components/MarkdownEditor"; + import { DropdownMenu, DropdownMenuContent, @@ -52,7 +52,7 @@ const Comments = ({ pictureId }: CommentsProps) => { const [userProfiles, setUserProfiles] = useState>(new Map()); const [editingComment, setEditingComment] = useState(null); const [editText, setEditText] = useState(""); - + // Microphone recording state const [isRecording, setIsRecording] = useState(false); const [isTranscribing, setIsTranscribing] = useState(false); @@ -81,12 +81,12 @@ const Comments = ({ pictureId }: CommentsProps) => { .from('comment_likes') .select('comment_id') .eq('user_id', user.id); - + if (!likesError && likesData) { userLikes = likesData.map(like => like.comment_id); } } - + setLikedComments(new Set(userLikes)); // Fetch user profiles for all comment authors @@ -119,14 +119,14 @@ const Comments = ({ pictureId }: CommentsProps) => { // Second pass: organize hierarchy with depth limit data.forEach(comment => { const commentWithReplies = commentsMap.get(comment.id)!; - + if (comment.parent_comment_id) { const parent = commentsMap.get(comment.parent_comment_id); if (parent) { // Calculate depth: parent depth + 1, but max 2 (0, 1, 2 = 3 levels) const newDepth = Math.min(parent.depth + 1, 2); commentWithReplies.depth = newDepth; - + // If we're at max depth, flatten to parent's level instead of nesting deeper if (parent.depth >= 2) { // Find the root ancestor to add this comment to @@ -233,7 +233,7 @@ const Comments = ({ pictureId }: CommentsProps) => { try { const { error } = await supabase .from('comments') - .update({ + .update({ content: editText.trim(), updated_at: new Date().toISOString() }) @@ -269,7 +269,7 @@ const Comments = ({ pictureId }: CommentsProps) => { } const isLiked = likedComments.has(commentId); - + try { if (isLiked) { // Unlike the comment @@ -285,7 +285,7 @@ const Comments = ({ pictureId }: CommentsProps) => { const newLikedComments = new Set(likedComments); newLikedComments.delete(commentId); setLikedComments(newLikedComments); - + // Update comments state const updateCommentsLikes = (comments: Comment[]): Comment[] => { return comments.map(comment => { @@ -314,7 +314,7 @@ const Comments = ({ pictureId }: CommentsProps) => { const newLikedComments = new Set(likedComments); newLikedComments.add(commentId); setLikedComments(newLikedComments); - + // Update comments state const updateCommentsLikes = (comments: Comment[]): Comment[] => { return comments.map(comment => { @@ -340,15 +340,15 @@ const Comments = ({ pictureId }: CommentsProps) => { const commentDate = new Date(dateString); const diffInMs = now.getTime() - commentDate.getTime(); const diffInHours = diffInMs / (1000 * 60 * 60); - + // If more than 24 hours ago, show regular date if (diffInHours >= 24) { return commentDate.toLocaleDateString(); } - + // Show relative time for recent comments const diffInMinutes = Math.floor(diffInMs / (1000 * 60)); - + if (diffInMinutes < 1) { return 'just now'; } else if (diffInMinutes < 60) { @@ -375,16 +375,16 @@ const Comments = ({ pictureId }: CommentsProps) => { } const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); - + const options = { mimeType: 'audio/webm' }; let mediaRecorder: MediaRecorder; - + try { mediaRecorder = new MediaRecorder(stream, options); } catch (e) { mediaRecorder = new MediaRecorder(stream); } - + mediaRecorderRef.current = mediaRecorder; audioChunksRef.current = []; setRecordingFor(type); @@ -397,14 +397,14 @@ const Comments = ({ pictureId }: CommentsProps) => { mediaRecorder.onstop = async () => { setIsTranscribing(true); - + try { const audioBlob = new Blob(audioChunksRef.current, { type: 'audio/webm' }); const audioFile = new File([audioBlob], 'recording.webm', { type: 'audio/webm' }); - + toast.info(translate('Transcribing audio...')); const transcribedText = await transcribeAudio(audioFile); - + if (transcribedText) { if (type === 'new') { setNewComment(prev => { @@ -435,7 +435,7 @@ const Comments = ({ pictureId }: CommentsProps) => { mediaRecorder.start(); setIsRecording(true); toast.info(translate('Recording... Click mic again to stop')); - + } catch (error: any) { console.error('Error accessing microphone:', error); if (error.name === 'NotAllowedError') { @@ -455,14 +455,14 @@ const Comments = ({ pictureId }: CommentsProps) => { return (
- {userProfile?.avatar_url ? ( - {userProfile.display_name ) : ( @@ -473,7 +473,7 @@ const Comments = ({ pictureId }: CommentsProps) => {
- @@ -491,12 +491,12 @@ const Comments = ({ pictureId }: CommentsProps) => { - startEditingComment(comment)} > Edit - handleDeleteComment(comment.id)} className="text-destructive" > @@ -516,14 +516,14 @@ const Comments = ({ pictureId }: CommentsProps) => { autoFocus />
- -
- {comment.depth < 2 && ( - )}
- + {replyingTo === comment.id && (
@@ -588,11 +586,10 @@ const Comments = ({ pictureId }: CommentsProps) => {
- -
- + {comment.replies && comment.replies.length > 0 && (
{comment.replies.map(reply => renderComment(reply))} @@ -652,18 +649,7 @@ const Comments = ({ pictureId }: CommentsProps) => {
{useMarkdown ? ( - { - if ((e.ctrlKey || e.metaKey) && e.key === 'Enter') { - e.preventDefault(); - handleAddComment(); - } - }} - /> +
) : (