mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-06-28 21:49:40 +02:00
feat: refactor long-press functionality in AllPrivateChatsSidebar and AllSharedChatsSidebar to utilize custom hook for improved code reusability and maintainability
This commit is contained in:
parent
2ea67c1764
commit
37e1995546
3 changed files with 41 additions and 49 deletions
|
|
@ -17,6 +17,7 @@ import {
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
import { useLongPress } from "@/hooks/use-long-press";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
|
|
@ -85,23 +86,14 @@ export function AllPrivateChatsSidebar({
|
||||||
const [isRenaming, setIsRenaming] = useState(false);
|
const [isRenaming, setIsRenaming] = useState(false);
|
||||||
const debouncedSearchQuery = useDebouncedValue(searchQuery, 300);
|
const debouncedSearchQuery = useDebouncedValue(searchQuery, 300);
|
||||||
|
|
||||||
const longPressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const pendingThreadIdRef = useRef<number | null>(null);
|
||||||
const longPressTriggeredRef = useRef(false);
|
const { handlers: longPressHandlers, wasLongPress } = useLongPress(
|
||||||
|
useCallback(() => {
|
||||||
const handleLongPressStart = useCallback((threadId: number) => {
|
if (pendingThreadIdRef.current !== null) {
|
||||||
longPressTriggeredRef.current = false;
|
setOpenDropdownId(pendingThreadIdRef.current);
|
||||||
longPressTimerRef.current = setTimeout(() => {
|
}
|
||||||
longPressTriggeredRef.current = true;
|
}, [])
|
||||||
setOpenDropdownId(threadId);
|
);
|
||||||
}, 500);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleLongPressCancel = useCallback(() => {
|
|
||||||
if (longPressTimerRef.current) {
|
|
||||||
clearTimeout(longPressTimerRef.current);
|
|
||||||
longPressTimerRef.current = null;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const isSearchMode = !!debouncedSearchQuery.trim();
|
const isSearchMode = !!debouncedSearchQuery.trim();
|
||||||
|
|
||||||
|
|
@ -376,15 +368,15 @@ export function AllPrivateChatsSidebar({
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (longPressTriggeredRef.current) {
|
if (wasLongPress()) return;
|
||||||
longPressTriggeredRef.current = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handleThreadClick(thread.id);
|
handleThreadClick(thread.id);
|
||||||
}}
|
}}
|
||||||
onTouchStart={() => handleLongPressStart(thread.id)}
|
onTouchStart={() => {
|
||||||
onTouchEnd={handleLongPressCancel}
|
pendingThreadIdRef.current = thread.id;
|
||||||
onTouchMove={handleLongPressCancel}
|
longPressHandlers.onTouchStart();
|
||||||
|
}}
|
||||||
|
onTouchEnd={longPressHandlers.onTouchEnd}
|
||||||
|
onTouchMove={longPressHandlers.onTouchMove}
|
||||||
disabled={isBusy}
|
disabled={isBusy}
|
||||||
className="flex items-center gap-2 flex-1 min-w-0 text-left overflow-hidden"
|
className="flex items-center gap-2 flex-1 min-w-0 text-left overflow-hidden"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ import {
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
import { useTranslations } from "next-intl";
|
import { useTranslations } from "next-intl";
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
||||||
|
import { useLongPress } from "@/hooks/use-long-press";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import {
|
||||||
|
|
@ -85,23 +86,14 @@ export function AllSharedChatsSidebar({
|
||||||
const [isRenaming, setIsRenaming] = useState(false);
|
const [isRenaming, setIsRenaming] = useState(false);
|
||||||
const debouncedSearchQuery = useDebouncedValue(searchQuery, 300);
|
const debouncedSearchQuery = useDebouncedValue(searchQuery, 300);
|
||||||
|
|
||||||
const longPressTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
const pendingThreadIdRef = useRef<number | null>(null);
|
||||||
const longPressTriggeredRef = useRef(false);
|
const { handlers: longPressHandlers, wasLongPress } = useLongPress(
|
||||||
|
useCallback(() => {
|
||||||
const handleLongPressStart = useCallback((threadId: number) => {
|
if (pendingThreadIdRef.current !== null) {
|
||||||
longPressTriggeredRef.current = false;
|
setOpenDropdownId(pendingThreadIdRef.current);
|
||||||
longPressTimerRef.current = setTimeout(() => {
|
}
|
||||||
longPressTriggeredRef.current = true;
|
}, [])
|
||||||
setOpenDropdownId(threadId);
|
);
|
||||||
}, 500);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const handleLongPressCancel = useCallback(() => {
|
|
||||||
if (longPressTimerRef.current) {
|
|
||||||
clearTimeout(longPressTimerRef.current);
|
|
||||||
longPressTimerRef.current = null;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const isSearchMode = !!debouncedSearchQuery.trim();
|
const isSearchMode = !!debouncedSearchQuery.trim();
|
||||||
|
|
||||||
|
|
@ -376,15 +368,15 @@ export function AllSharedChatsSidebar({
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (longPressTriggeredRef.current) {
|
if (wasLongPress()) return;
|
||||||
longPressTriggeredRef.current = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
handleThreadClick(thread.id);
|
handleThreadClick(thread.id);
|
||||||
}}
|
}}
|
||||||
onTouchStart={() => handleLongPressStart(thread.id)}
|
onTouchStart={() => {
|
||||||
onTouchEnd={handleLongPressCancel}
|
pendingThreadIdRef.current = thread.id;
|
||||||
onTouchMove={handleLongPressCancel}
|
longPressHandlers.onTouchStart();
|
||||||
|
}}
|
||||||
|
onTouchEnd={longPressHandlers.onTouchEnd}
|
||||||
|
onTouchMove={longPressHandlers.onTouchMove}
|
||||||
disabled={isBusy}
|
disabled={isBusy}
|
||||||
className="flex items-center gap-2 flex-1 min-w-0 text-left overflow-hidden"
|
className="flex items-center gap-2 flex-1 min-w-0 text-left overflow-hidden"
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
import { useCallback, useRef } from "react";
|
import { useCallback, useEffect, useRef } from "react";
|
||||||
|
|
||||||
const LONG_PRESS_DELAY = 500;
|
const LONG_PRESS_DELAY = 500;
|
||||||
|
|
||||||
|
|
@ -21,6 +21,14 @@ export function useLongPress(onLongPress: () => void, delay = LONG_PRESS_DELAY)
|
||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
if (timerRef.current) {
|
||||||
|
clearTimeout(timerRef.current);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handlers = {
|
const handlers = {
|
||||||
onTouchStart: start,
|
onTouchStart: start,
|
||||||
onTouchEnd: cancel,
|
onTouchEnd: cancel,
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue