import { DateTime } from 'luxon'; import { useEffect, useRef, useState } from 'react'; import type { LauncherWebBanner, StoredData } from '../../../types'; import { fetchJson } from '../../../utils/api'; import { BASE_URL } from '../../../utils/constants'; interface Props { target: { region: 'os' | 'cn'; dirName: string }; lang: string; } const getMirrorUrl = (url: string) => { try { const u = new URL(url); return `https://raw.githubusercontent.com/daydreamer-json/ak-endfield-api-archive/refs/heads/main/output/raw/${u.hostname}${u.pathname}`; } catch { return url; } }; export default function BannerSection({ target, lang }: Props) { const [bannerMap, setBannerMap] = useState< Map >(new Map()); const [loading, setLoading] = useState(false); const [shouldLoad, setShouldLoad] = useState(false); const collapseRef = useRef(null); useEffect(() => { const el = collapseRef.current; if (!el) return; const handleShow = () => setShouldLoad(true); el.addEventListener('show.bs.collapse', handleShow); return () => el.removeEventListener('show.bs.collapse', handleShow); }, []); useEffect(() => { const load = async () => { if (!lang || !shouldLoad) return; setLoading(true); const url = `${BASE_URL}/akEndfield/launcher/web/${target.dirName}/banner/${lang}/all.json`; try { const data = await fetchJson[]>(url); const newBannerMap = new Map(); const sortedData = [...data].sort( (a, b) => DateTime.fromISO(b.updatedAt).toMillis() - DateTime.fromISO(a.updatedAt).toMillis(), ); for (const entry of sortedData) { if (!entry.rsp || !entry.rsp.banners) continue; for (const banner of entry.rsp.banners) { if (!newBannerMap.has(banner.id)) { newBannerMap.set(banner.id, { banner, firstSeen: entry.updatedAt }); } } } setBannerMap(newBannerMap); } catch (e) { setBannerMap(new Map()); } finally { setLoading(false); } }; load(); }, [target, lang, shouldLoad]); return (

Banner

{loading ? (
Loading banners...
) : bannerMap.size === 0 ? (
No banners found.
) : (
{Array.from(bannerMap.entries()).map(([id, { banner, firstSeen }]) => { const dateStr = DateTime.fromISO(firstSeen).toFormat('yyyy/MM/dd HH:mm'); const mirrorUrl = getMirrorUrl(banner.url); const linkUrl = banner.jump_url || mirrorUrl; return ( ); })}
)}
); }