updated gamebanner
This commit is contained in:
parent
fb200876d0
commit
844ac4fe33
@ -200,16 +200,22 @@ export default function GameBanner(props: GameBannerProps = {}) {
|
||||
|
||||
// optional: Connect-URI vom Server holen
|
||||
useEffect(() => {
|
||||
(async () => {
|
||||
try {
|
||||
const r = await fetch('/api/cs2/server', { cache: 'no-store' })
|
||||
if (!r.ok) return
|
||||
const j = await r.json()
|
||||
if (j.connectHref) setConnectHref(j.connectHref)
|
||||
} catch {}
|
||||
})()
|
||||
}, [])
|
||||
|
||||
(async () => {
|
||||
try {
|
||||
const r = await fetch('/api/cs2/server', { cache: 'no-store' })
|
||||
if (!r.ok) return
|
||||
const j = await r.json()
|
||||
// akzeptiere mehrere mögliche Feldnamen aus deiner API/DB
|
||||
const href: unknown =
|
||||
j?.connectHref ?? j?.connectUri ?? j?.connectURL ?? j?.connect_url
|
||||
if (typeof href === 'string' && href.trim()) {
|
||||
setConnectHref(href.trim())
|
||||
}
|
||||
} catch {
|
||||
// ignore network errors
|
||||
}
|
||||
})()
|
||||
}, [])
|
||||
// WS lifecycle
|
||||
const aliveRef = useRef(true)
|
||||
const retryRef = useRef<number | null>(null)
|
||||
@ -320,9 +326,11 @@ export default function GameBanner(props: GameBannerProps = {}) {
|
||||
const scoreStr = scoreProp ?? ((score.a == null || score.b == null) ? '– : –' : `${score.a} : ${score.b}`)
|
||||
|
||||
const envConnect =
|
||||
process.env.NEXT_PUBLIC_CONNECT_HREF ||
|
||||
process.env.NEXT_PUBLIC_STEAM_CONNECT_URI ||
|
||||
process.env.NEXT_PUBLIC_CS2_CONNECT_URI ||
|
||||
'steam://rungameid/730//+retry'
|
||||
'steam://connect/94.130.66.149:27015/0000' // <- normaler connect-Link als letzter Fallback
|
||||
|
||||
const connectUri = connectUriProp ?? connectHref ?? envConnect
|
||||
|
||||
// --- Animation + Höhe an Spacer melden
|
||||
|
||||
@ -1,81 +0,0 @@
|
||||
// /src/app/[locale]/components/GameBannerHost.tsx
|
||||
'use client'
|
||||
import useSWR from 'swr'
|
||||
import { useSession } from 'next-auth/react'
|
||||
import GameBanner from './GameBanner'
|
||||
import { useGameBannerStore } from '@/lib/useGameBannerStore'
|
||||
|
||||
type LiveCfg = {
|
||||
activeMatchId: string | null
|
||||
activeMapKey: string | null
|
||||
activeMapLabel: string | null
|
||||
activeMapBg: string | null
|
||||
activeParticipants: string[] | null
|
||||
activeSince: string | null
|
||||
bannerExpiresAt?: string | null
|
||||
updatedAt?: string
|
||||
}
|
||||
const fetcher = (url: string) => fetch(url, { cache: 'no-store' }).then(r => r.json())
|
||||
|
||||
export default function GameBannerHost() {
|
||||
const banner = useGameBannerStore(s => s.gameBanner)
|
||||
const setBanner = useGameBannerStore(s => s.setGameBanner)
|
||||
|
||||
const { data: session } = useSession()
|
||||
const meId = session?.user?.steamId ? String(session.user.steamId) : null
|
||||
|
||||
const { data } = useSWR<{ ok: boolean; data: LiveCfg | null }>(
|
||||
'/api/cs2/server/live',
|
||||
fetcher,
|
||||
{
|
||||
revalidateOnMount: true,
|
||||
revalidateIfStale: true,
|
||||
dedupingInterval: 0,
|
||||
refreshInterval: 30000,
|
||||
fallbackData: { ok: true, data: null },
|
||||
}
|
||||
)
|
||||
const cfg = data?.data ?? null
|
||||
|
||||
console.debug('[BannerHost] meId=', meId, 'participants=', cfg?.activeParticipants);
|
||||
|
||||
// --- robust notExpired (invalid date-strings => nicht blockieren)
|
||||
const expiresMs = cfg?.bannerExpiresAt ? new Date(cfg.bannerExpiresAt).getTime() : null
|
||||
const notExpired = expiresMs == null || Number.isFinite(expiresMs) && expiresMs > Date.now()
|
||||
|
||||
// --- Teilnehmer-Check (nur das!)
|
||||
const meIsParticipant =
|
||||
!!meId &&
|
||||
Array.isArray(cfg?.activeParticipants) &&
|
||||
cfg.activeParticipants.map(String).includes(meId)
|
||||
|
||||
// nur diese beiden Bedingungen:
|
||||
const canShow = meIsParticipant && notExpired
|
||||
|
||||
if (!canShow) return null
|
||||
|
||||
const connectUriFallback =
|
||||
process.env.NEXT_PUBLIC_STEAM_CONNECT_URI ||
|
||||
process.env.NEXT_PUBLIC_CS2_CONNECT_URI ||
|
||||
'steam://rungameid/730//+retry'
|
||||
|
||||
return (
|
||||
<GameBanner
|
||||
variant={banner?.variant ?? 'disconnected'}
|
||||
visible={true}
|
||||
zIndex={banner?.zIndex ?? 9999}
|
||||
inline={banner?.inline ?? false}
|
||||
serverLabel={banner?.serverLabel}
|
||||
mapKey={banner?.mapKey ?? cfg?.activeMapKey ?? undefined}
|
||||
mapLabel={banner?.mapLabel ?? cfg?.activeMapLabel ?? undefined}
|
||||
bgUrl={banner?.bgUrl ?? cfg?.activeMapBg ?? undefined}
|
||||
iconUrl={banner?.iconUrl}
|
||||
connectUri={banner?.connectUri ?? connectUriFallback}
|
||||
score={banner?.score ?? '– : –'}
|
||||
connectedCount={banner?.connectedCount ?? 0}
|
||||
totalExpected={banner?.totalExpected ?? (cfg?.activeParticipants?.length ?? 0)}
|
||||
onReconnect={() => {/* optional: auf connectUri navigieren */}}
|
||||
onDisconnect={() => setBanner(null)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
@ -409,7 +409,6 @@ export default function MapVotePanel({ match }: Props) {
|
||||
const holdMapRef = useRef<string | null>(null)
|
||||
const submittedRef = useRef<boolean>(false)
|
||||
const [progressByMap, setProgressByMap] = useState<Record<string, number>>({})
|
||||
const lastEvtKeyRef = useRef<string>(''); // Dedupe gleicher Events
|
||||
|
||||
const resetHold = useCallback(() => {
|
||||
if (rafRef.current) cancelAnimationFrame(rafRef.current)
|
||||
@ -781,18 +780,7 @@ export default function MapVotePanel({ match }: Props) {
|
||||
|
||||
const shouldRefresh = isRefreshEvent(type);
|
||||
if (shouldRefresh) {
|
||||
// einfache Dedupe: gleicher Event-Key in kurzer Folge -> ignorieren
|
||||
const evtKey = [
|
||||
type,
|
||||
evtMatchId ?? '',
|
||||
evtTeamId ?? '',
|
||||
actionType ?? '',
|
||||
actionData ?? '',
|
||||
].join('|');
|
||||
if (evtKey === lastEvtKeyRef.current) return;
|
||||
lastEvtKeyRef.current = evtKey;
|
||||
|
||||
scheduleReload(); // <— statt load()
|
||||
scheduleReload();
|
||||
}
|
||||
}, [lastEvent, match.id, match.teamA?.id, match.teamB?.id, matchBaseTs, teamSteamIds, applyLeaderChange, scheduleReload]);
|
||||
|
||||
@ -1391,7 +1379,9 @@ export default function MapVotePanel({ match }: Props) {
|
||||
src={mapLogo}
|
||||
alt={label}
|
||||
className="max-h-[70%] max-w-[88%] object-contain drop-shadow-lg"
|
||||
fill
|
||||
sizes={"max-h-[70%] max-w-[88%]"}
|
||||
width={48}
|
||||
height={48}
|
||||
/>
|
||||
<span className="px-2 py-0.5 rounded-md text-white/90 font-semibold text-xs md:text-sm">
|
||||
{label}
|
||||
|
||||
@ -66,7 +66,7 @@ export default async function RootLayout({children, params}: Props) {
|
||||
<main className="flex-1 min-w-0 min-h-0 overflow-auto">
|
||||
<div className="h-full min-h-0 box-border p-4 sm:p-6">{children}</div>
|
||||
</main>
|
||||
<GameBanner /> {/* ⬅️ nur noch diese */}
|
||||
<GameBanner />
|
||||
<GameBannerSpacer className="hidden sm:block" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user