fix: search de-sync
This commit is contained in:
+20
-4
@@ -4,7 +4,7 @@ import { AnimatePresence, motion } from "motion/react"
|
|||||||
import logo from "@/app/icon.png"
|
import logo from "@/app/icon.png"
|
||||||
import Image from "next/image"
|
import Image from "next/image"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { useEffect, useRef, useState } from "react"
|
import { useEffect, useLayoutEffect, useRef, useState } from "react"
|
||||||
import { CircleXIcon, Gamepad2Icon, MenuIcon, XIcon } from "lucide-react"
|
import { CircleXIcon, Gamepad2Icon, MenuIcon, XIcon } from "lucide-react"
|
||||||
import { routes } from "@/lib/routes"
|
import { routes } from "@/lib/routes"
|
||||||
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
import { usePathname, useRouter, useSearchParams } from "next/navigation"
|
||||||
@@ -26,19 +26,35 @@ export default function Navbar() {
|
|||||||
const [forceFocusStyles, setForceFocusStyles] = useState(false)
|
const [forceFocusStyles, setForceFocusStyles] = useState(false)
|
||||||
const inputRef = useRef<HTMLInputElement>(null)
|
const inputRef = useRef<HTMLInputElement>(null)
|
||||||
|
|
||||||
|
// When syncing state from the URL (e.g. after navigating from the landing
|
||||||
|
// page), skip the next URL-write cycle so the stale/empty debounced value
|
||||||
|
// doesn't overwrite the URL params before it catches up.
|
||||||
|
const skipNextUrlWrite = useRef(false)
|
||||||
|
|
||||||
const { data: session, isPending: isSessionLoading } =
|
const { data: session, isPending: isSessionLoading } =
|
||||||
useSession()
|
useSession()
|
||||||
const [userMenuOpen, setUserMenuOpen] = useState(false)
|
const [userMenuOpen, setUserMenuOpen] = useState(false)
|
||||||
|
|
||||||
// Sync search query with URL ?q= param
|
// Sync search query with URL ?q= param
|
||||||
useEffect(() => {
|
useLayoutEffect(() => {
|
||||||
const q = searchParams.get("q") || ""
|
const q = searchParams.get("q") || ""
|
||||||
const timeout = setTimeout(() => setSearchQuery(q), 0)
|
// If the URL has a different value than our state, we're syncing after
|
||||||
return () => clearTimeout(timeout)
|
// a navigation — skip the next URL-write to avoid clearing the param
|
||||||
|
if (q !== searchQuery) {
|
||||||
|
skipNextUrlWrite.current = true
|
||||||
|
}
|
||||||
|
setSearchQuery(q)
|
||||||
}, [searchParams])
|
}, [searchParams])
|
||||||
|
|
||||||
// Update URL when debounced query changes (skip if already matches)
|
// Update URL when debounced query changes (skip if already matches)
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// Skip one cycle after syncing from URL so the stale/empty debounced
|
||||||
|
// value doesn't overwrite the URL params before it catches up
|
||||||
|
if (skipNextUrlWrite.current) {
|
||||||
|
skipNextUrlWrite.current = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if (isLanding) return
|
if (isLanding) return
|
||||||
const currentQ = searchParams.get("q") || ""
|
const currentQ = searchParams.get("q") || ""
|
||||||
if (debouncedQuery === currentQ) return
|
if (debouncedQuery === currentQ) return
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const authRoutes = [
|
|||||||
"/reset-password",
|
"/reset-password",
|
||||||
]
|
]
|
||||||
|
|
||||||
export default async function middleware(req: NextRequest) {
|
export default async function proxy(req: NextRequest) {
|
||||||
const path = req.nextUrl.pathname
|
const path = req.nextUrl.pathname
|
||||||
const isAuthRoute = authRoutes.some((route) => path.startsWith(route))
|
const isAuthRoute = authRoutes.some((route) => path.startsWith(route))
|
||||||
|
|
||||||
Reference in New Issue
Block a user