Add a game downloads page that uses the launcher manifest api

This commit is contained in:
Lncvrt committed 2026-03-11 14:58:24 -07:00
1 parent 0ba944bb6a
commit ba9474463d
1 file changed
+108
+108
View File
@@ -0,0 +1,108 @@
'use client'
import { HomeButton } from '../../components/HomeButton'
import { DiscordButton } from '../../components/DiscordButton'
import { useEffect, useRef, useState } from 'react'
import axios from 'axios'
interface Version {
id: string
displayName: string
releaseDate: number
game: number
downloads: Record<string, number>
executables: Record<string, string>
place: number
changelog: string | null
category: number
lastRevision: number
}
interface Game {
id: number
name: string
official: boolean
verified: boolean
developer: string | null
categoryNames: Record<string, string>
}
interface VersionManifest {
versions: Version[]
games: Game[]
}
export default function GameDownloadsPage () {
const [versionManifest, setVersionManifest] = useState<
VersionManifest | 0 | -1
>(0)
const backButtonRef = useRef<HTMLAnchorElement>(null)
useEffect(() => {
document.title = 'Lncvrt Games - Game Downloads'
;(async () => {
try {
const result = await axios.get('/api/launcher/versions')
setVersionManifest(result.data)
} catch {
setVersionManifest(-1)
}
})()
const handleKeyDown = (e: KeyboardEvent) => {
if (e.key === 'Escape') {
backButtonRef.current?.click()
}
}
window.addEventListener('keydown', handleKeyDown)
return () => window.removeEventListener('keydown', handleKeyDown)
}, [])
const downloadFile = async (url: string) => {
const a = document.createElement('a')
a.href = url
a.download = ''
a.click()
}
return (
<div className='box'>
<HomeButton refLink={backButtonRef} />
<DiscordButton />
<p className='text-center text-4xl'>Game Downloads</p>
<p className='text-center text-[18px] mb-2'>
The launcher's download sources, in a website!
</p>
{versionManifest == 0 || versionManifest == -1 ? (
<p className='text-center'>
{versionManifest == 0 ? 'Loading' : 'Failed to get launcher manifest'}
</p>
) : (
<div className='flex flex-col gap-2'>
{versionManifest.versions.map(v => (
<div key={v.game + '-' + v.id} className='sub-box'>
<p className='text-center'>Downloads for {v.displayName}</p>
<div className='flex flex-row gap-2 justify-center'>
{Object.entries(v.downloads).map(([key, value]) => (
<button
key={v.game + '-' + v.id + '-' + key}
onClick={async () => {
const result = await axios.get(
`/api/launcher/download?downloadId=${value}&versionId=${v.id}`
)
downloadFile(result.data.data.url)
}}
>
{key.charAt(0).toUpperCase() +
key.slice(1).replace('-', ' ')}
</button>
))}
</div>
</div>
))}
</div>
)}
</div>
)
}