update and fix messanger
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
import { useAuth } from '@/components/id/auth-provider';
|
||||
import { apiFetch } from '@/lib/api';
|
||||
import { AVATAR_UPDATED_EVENT } from '@/lib/avatar-events';
|
||||
|
||||
interface AvatarAccessResponse {
|
||||
accessUrl: string;
|
||||
@@ -35,5 +36,17 @@ export function useAvatarUrl(userId: string | undefined, hasAvatar: boolean | un
|
||||
return () => window.clearInterval(timer);
|
||||
}, [hasAvatar, refresh]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!userId || !hasAvatar) return;
|
||||
function handleAvatarUpdated(event: Event) {
|
||||
const detail = (event as CustomEvent<{ userId?: string }>).detail;
|
||||
if (detail?.userId === userId) {
|
||||
void refresh();
|
||||
}
|
||||
}
|
||||
window.addEventListener(AVATAR_UPDATED_EVENT, handleAvatarUpdated);
|
||||
return () => window.removeEventListener(AVATAR_UPDATED_EVENT, handleAvatarUpdated);
|
||||
}, [hasAvatar, refresh, userId]);
|
||||
|
||||
return { avatarUrl, refreshAvatarUrl: refresh };
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
'use client';
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useCallback, useEffect, useRef, useState, type MouseEvent as ReactMouseEvent } from 'react';
|
||||
|
||||
const DRAG_THRESHOLD_PX = 6;
|
||||
|
||||
interface UseChatDragSelectionOptions {
|
||||
selectionMode: boolean;
|
||||
@@ -8,6 +10,16 @@ interface UseChatDragSelectionOptions {
|
||||
addSelectedMessage: (messageId: string) => void;
|
||||
}
|
||||
|
||||
const dragSuppressedUntilRef = { current: 0 };
|
||||
|
||||
export function suppressChatDragSelection(durationMs = 400) {
|
||||
dragSuppressedUntilRef.current = Date.now() + durationMs;
|
||||
}
|
||||
|
||||
function isDragSuppressed() {
|
||||
return Date.now() < dragSuppressedUntilRef.current;
|
||||
}
|
||||
|
||||
export function useChatDragSelection({
|
||||
selectionMode,
|
||||
enterSelectionMode,
|
||||
@@ -15,9 +27,11 @@ export function useChatDragSelection({
|
||||
}: UseChatDragSelectionOptions) {
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const visitedRef = useRef<Set<string>>(new Set());
|
||||
const pendingDragRef = useRef<{ messageId: string; x: number; y: number } | null>(null);
|
||||
|
||||
const startDragSelection = useCallback(
|
||||
(messageId: string) => {
|
||||
if (isDragSuppressed()) return;
|
||||
setIsDragging(true);
|
||||
visitedRef.current = new Set([messageId]);
|
||||
if (!selectionMode) {
|
||||
@@ -29,6 +43,14 @@ export function useChatDragSelection({
|
||||
[addSelectedMessage, enterSelectionMode, selectionMode]
|
||||
);
|
||||
|
||||
const handleMessagePointerDown = useCallback(
|
||||
(messageId: string, event: ReactMouseEvent) => {
|
||||
if (event.button !== 0 || isDragSuppressed()) return;
|
||||
pendingDragRef.current = { messageId, x: event.clientX, y: event.clientY };
|
||||
},
|
||||
[]
|
||||
);
|
||||
|
||||
const handleDragEnterMessage = useCallback(
|
||||
(messageId: string) => {
|
||||
if (!isDragging || visitedRef.current.has(messageId)) return;
|
||||
@@ -39,18 +61,33 @@ export function useChatDragSelection({
|
||||
);
|
||||
|
||||
const endDragSelection = useCallback(() => {
|
||||
pendingDragRef.current = null;
|
||||
setIsDragging(false);
|
||||
visitedRef.current.clear();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const onMouseMove = (event: MouseEvent) => {
|
||||
const pending = pendingDragRef.current;
|
||||
if (!pending || isDragSuppressed()) return;
|
||||
const distance = Math.hypot(event.clientX - pending.x, event.clientY - pending.y);
|
||||
if (distance < DRAG_THRESHOLD_PX) return;
|
||||
const messageId = pending.messageId;
|
||||
pendingDragRef.current = null;
|
||||
startDragSelection(messageId);
|
||||
};
|
||||
|
||||
window.addEventListener('mousemove', onMouseMove);
|
||||
window.addEventListener('mouseup', endDragSelection);
|
||||
return () => window.removeEventListener('mouseup', endDragSelection);
|
||||
}, [endDragSelection]);
|
||||
return () => {
|
||||
window.removeEventListener('mousemove', onMouseMove);
|
||||
window.removeEventListener('mouseup', endDragSelection);
|
||||
};
|
||||
}, [endDragSelection, startDragSelection]);
|
||||
|
||||
return {
|
||||
isDragging,
|
||||
startDragSelection,
|
||||
handleMessagePointerDown,
|
||||
handleDragEnterMessage,
|
||||
endDragSelection
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user