feat: add share and edit links to preset modal, sync URL preset param

This commit is contained in:
2026-04-28 09:32:18 +08:00
parent f502d120a7
commit a2ff39c1b0
3 changed files with 78 additions and 14 deletions
+31 -3
View File
@@ -1,7 +1,7 @@
"use client"
import { useCallback, useState, useEffect, useMemo, useRef } from "react"
import { useRouter } from "next/navigation"
import { useRouter, useSearchParams } from "next/navigation"
import Image from "next/image"
import {
Gamepad2Icon,
@@ -201,6 +201,7 @@ export function GamePageClient({
gameId,
}: Props) {
const router = useRouter()
const searchParams = useSearchParams()
const { data: session } = useSession()
const [imgError, setImgError] = useState(false)
const [stats, setStats] = useState<StatsResponse | null>(null)
@@ -216,6 +217,32 @@ export function GamePageClient({
const [reportedPresets, setReportedPresets] = useState<Set<string>>(new Set())
const presetsRef = useRef<HTMLDivElement>(null)
// On mount, auto-open preset from URL
useEffect(() => {
const presetId = searchParams.get("preset")
queueMicrotask(() => {
if (presetId) {
setSelectedPresetId(presetId)
} else {
setSelectedPresetId(null)
}
})
}, [searchParams])
const handlePresetOpen = (presetId: string) => {
setSelectedPresetId(presetId)
const url = new URL(window.location.href)
url.searchParams.set("preset", presetId)
router.replace(url.toString(), { scroll: false })
}
const handlePresetClose = () => {
setSelectedPresetId(null)
const url = new URL(window.location.href)
url.searchParams.delete("preset")
router.replace(url.toString(), { scroll: false })
}
const handleDeletePreset = async (presetId: string) => {
try {
const res = await fetch(`/api/performance/${presetId}/user-delete`, {
@@ -751,7 +778,7 @@ export function GamePageClient({
return (
<motion.div
key={preset.id}
onClick={() => setSelectedPresetId(preset.id)}
onClick={() => handlePresetOpen(preset.id)}
className={`shrink-0 w-72 flex flex-col gap-3 p-4 rounded-xl border transition-colors cursor-pointer hover:border-primary/30 ${
raw
? "border-green-500/30 bg-green-500/5"
@@ -992,7 +1019,8 @@ export function GamePageClient({
return (
<PresetDetailModal
preset={preset}
onClose={() => setSelectedPresetId(null)}
gameId={gameId}
onClose={handlePresetClose}
onDelete={handleDeletePreset}
onReport={handleReportPreset}
hasReported={reportedPresets.has(preset.id)}