mirror of
https://github.com/arkorty/Osborne.git
synced 2026-03-17 16:51:44 +00:00
user fixes
This commit is contained in:
@@ -208,6 +208,7 @@ const Room = () => {
|
||||
const socketRef = useRef<WebSocket | null>(null);
|
||||
const editorRef = useRef<CodeEditorRef>(null);
|
||||
const fileInputRef = useRef<HTMLInputElement>(null);
|
||||
const currentUserRef = useRef<User | null>(null);
|
||||
const [isClient, setIsClient] = useState(false);
|
||||
const [content, setContent] = useState("");
|
||||
const [status, setStatus] = useState("Disconnected");
|
||||
@@ -317,6 +318,10 @@ const Room = () => {
|
||||
contentRef.current = content;
|
||||
}, [content]);
|
||||
|
||||
useEffect(() => {
|
||||
currentUserRef.current = currentUser;
|
||||
}, [currentUser]);
|
||||
|
||||
useEffect(() => {
|
||||
setIsClient(true);
|
||||
|
||||
@@ -604,7 +609,19 @@ const Room = () => {
|
||||
|
||||
const pingInterval = setInterval(() => {
|
||||
if (socketRef.current?.readyState === WebSocket.OPEN) {
|
||||
socketRef.current.send(JSON.stringify({ type: "ping" }));
|
||||
socketRef.current.send(JSON.stringify({ type: "ping", code: roomCode }));
|
||||
|
||||
// Also send user activity update to keep status current
|
||||
if (currentUserRef.current) {
|
||||
const activityMessage: UserActivity = {
|
||||
type: "user-activity",
|
||||
code: roomCode,
|
||||
userId: currentUserRef.current.id,
|
||||
isTyping: false,
|
||||
currentLine: undefined
|
||||
};
|
||||
socketRef.current.send(JSON.stringify(activityMessage));
|
||||
}
|
||||
}
|
||||
}, 30000);
|
||||
|
||||
|
||||
@@ -152,7 +152,7 @@ export const CommentsPanel: React.FC<CommentsPageProps> = ({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-xs font-medium text-foreground">
|
||||
{comment.author}
|
||||
{currentUser && comment.authorId === currentUser.id ? 'You' : comment.author}
|
||||
</span>
|
||||
{comment.lineNumber !== null && (
|
||||
<Badge
|
||||
|
||||
@@ -60,6 +60,7 @@ export const LeftPanel: React.FC<LeftPanelProps> = ({
|
||||
const [localMediaFiles, setLocalMediaFiles] = useState<MediaFile[]>(mediaFiles);
|
||||
const [usersScrollState, setUsersScrollState] = useState({ top: false, bottom: false });
|
||||
const [mediaScrollState, setMediaScrollState] = useState({ top: false, bottom: false });
|
||||
const [statusUpdateTrigger, setStatusUpdateTrigger] = useState(0);
|
||||
|
||||
const usersScrollRef = useRef<HTMLDivElement>(null);
|
||||
const mediaScrollRef = useRef<HTMLDivElement>(null);
|
||||
@@ -69,6 +70,20 @@ export const LeftPanel: React.FC<LeftPanelProps> = ({
|
||||
setActiveUsers(users);
|
||||
}, [users]);
|
||||
|
||||
// Update user statuses periodically
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setStatusUpdateTrigger(prev => prev + 1);
|
||||
}, 5000); // Update every 5 seconds to be more responsive
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// Force re-render when status should be updated (dependency on statusUpdateTrigger)
|
||||
useEffect(() => {
|
||||
// This effect doesn't need to do anything, just triggers re-render
|
||||
}, [statusUpdateTrigger]);
|
||||
|
||||
// Scroll detection function
|
||||
const handleScroll = (element: HTMLDivElement | null, setState: (state: { top: boolean; bottom: boolean }) => void) => {
|
||||
if (!element) return;
|
||||
@@ -579,6 +594,7 @@ export const LeftPanel: React.FC<LeftPanelProps> = ({
|
||||
onClose={() => handleModalChange(null)}
|
||||
onDelete={onFileDelete}
|
||||
getFileUrl={getFileUrl}
|
||||
currentUser={currentUser}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -23,12 +23,22 @@ interface MediaFile {
|
||||
uploadedBy: string;
|
||||
}
|
||||
|
||||
interface User {
|
||||
id: string;
|
||||
name: string;
|
||||
color: string;
|
||||
lastSeen: Date;
|
||||
isTyping?: boolean;
|
||||
currentLine?: number;
|
||||
}
|
||||
|
||||
interface MediaModalProps {
|
||||
file: MediaFile | null;
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onDelete?: (fileId: string) => void;
|
||||
getFileUrl: (file: MediaFile) => string;
|
||||
currentUser?: User | null;
|
||||
}
|
||||
|
||||
export const MediaModal: React.FC<MediaModalProps> = ({
|
||||
@@ -36,7 +46,8 @@ export const MediaModal: React.FC<MediaModalProps> = ({
|
||||
isOpen,
|
||||
onClose,
|
||||
onDelete,
|
||||
getFileUrl
|
||||
getFileUrl,
|
||||
currentUser
|
||||
}) => {
|
||||
if (!isOpen || !file) return null;
|
||||
|
||||
@@ -169,7 +180,7 @@ export const MediaModal: React.FC<MediaModalProps> = ({
|
||||
{file.type.split('/')[1] || 'file'}
|
||||
</Badge>
|
||||
<span className="text-sm text-muted-foreground">
|
||||
Uploaded by {file.uploadedBy}
|
||||
Uploaded by {currentUser && file.uploadedBy === currentUser.name ? 'You' : file.uploadedBy}
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex space-x-2">
|
||||
|
||||
@@ -152,7 +152,7 @@ export const CommentsPanel: React.FC<CommentsPageProps> = ({
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-1">
|
||||
<span className="text-xs font-medium text-foreground">
|
||||
{comment.author}
|
||||
{currentUser && comment.authorId === currentUser.id ? 'You' : comment.author}
|
||||
</span>
|
||||
{comment.lineNumber !== null && (
|
||||
<Badge
|
||||
|
||||
Reference in New Issue
Block a user