This commit is contained in:
Arkaprabha Chakraborty
2025-10-30 20:57:20 +05:30
parent 125887e5aa
commit 1b1b925cd5
9 changed files with 918 additions and 272 deletions

View File

@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import { Textarea } from '@/components/ui/textarea';
import { Card, CardContent, CardHeader } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
@@ -45,6 +45,9 @@ export const CommentsPanel: React.FC<CommentsPageProps> = ({
}) => {
const [newComment, setNewComment] = useState('');
const [selectedLine, setSelectedLine] = useState<number | null>(null);
const [scrollState, setScrollState] = useState({ top: false, bottom: false });
const commentsScrollRef = useRef<HTMLDivElement>(null);
// Update selected line when editor selection changes
useEffect(() => {
@@ -59,6 +62,36 @@ export const CommentsPanel: React.FC<CommentsPageProps> = ({
}
}, [selectedLineStart, selectedLineEnd]);
// Scroll detection function
const handleScroll = () => {
const element = commentsScrollRef.current;
if (!element) return;
const { scrollTop, scrollHeight, clientHeight } = element;
const isScrolledFromTop = scrollTop > 5;
const isScrolledFromBottom = scrollTop < scrollHeight - clientHeight - 5;
setScrollState({
top: isScrolledFromTop,
bottom: isScrolledFromBottom && scrollHeight > clientHeight
});
};
// Add scroll listener
useEffect(() => {
const element = commentsScrollRef.current;
if (element) {
element.addEventListener('scroll', handleScroll);
// Initial check
handleScroll();
return () => {
element.removeEventListener('scroll', handleScroll);
};
}
}, [comments]);
const handleAddComment = () => {
if (newComment.trim() && onAddComment && currentUser) {
const lineRange = selectedLineStart && selectedLineEnd && selectedLineStart !== selectedLineEnd
@@ -74,14 +107,19 @@ export const CommentsPanel: React.FC<CommentsPageProps> = ({
return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
};
if (!isVisible) {
return null;
}
return (
<div className="fixed right-0 top-0 h-full w-80 bg-card border-l border-border shadow-lg z-40 flex flex-col">
<div
className={`fixed right-0 top-0 h-full w-80 bg-card border-l border-border shadow-lg z-40 flex flex-col transition-transform duration-300 ease-in-out ui-font ${
isVisible ? 'transform-none' : 'translate-x-full'
}`}
>
{/* Comments List */}
<div className="flex-1 overflow-y-auto p-2 space-y-2">
<div
ref={commentsScrollRef}
className={`flex-1 overflow-y-auto hide-scrollbar scroll-shadow p-2 space-y-2 ${
scrollState.top ? 'scroll-top' : ''
} ${scrollState.bottom ? 'scroll-bottom' : ''}`}
>
{comments.length === 0 ? (
<div className="text-center text-muted-foreground py-4">
<MessageSquare size={20} className="mx-auto mb-1 opacity-50" />