Initial commit

This commit is contained in:
2025-10-31 22:35:12 -07:00
commit 426fe66baa
38 changed files with 2239 additions and 0 deletions

BIN
src/app/assets/Icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

9
src/app/globals.css Normal file
View File

@@ -0,0 +1,9 @@
@import "tailwindcss";
body {
@apply bg-[rgb(24,24,24)] text-white select-none;
}
button {
@apply bg-[rgb(48,48,48)] hover:bg-[rgb(56,56,56)] border border-[rgb(72,72,72)] hover:border-[rgb(80,80,80)] transition-colors px-2 py-1 rounded-md cursor-pointer;
}

35
src/app/layout.tsx Normal file
View File

@@ -0,0 +1,35 @@
'use client'
import { Lexend } from 'next/font/google'
import './globals.css'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { useEffect } from 'react'
const lexend = Lexend({
subsets: ['latin']
})
export default function RootLayout ({
children
}: Readonly<{
children: React.ReactNode
}>) {
const handleMouseDown = (e: React.MouseEvent<HTMLDivElement>) => {
if ((e.target as HTMLElement).closest('button')) return
getCurrentWindow().startDragging()
}
useEffect(() => {
document.body.addEventListener('mousedown', handleMouseDown as any)
return () =>
document.body.removeEventListener('mousedown', handleMouseDown as any)
}, [])
return (
<html lang='en'>
<body className={lexend.className}>
<div className='w-max h-screen'>{children}</div>
</body>
</html>
)
}

127
src/app/page.tsx Normal file
View File

@@ -0,0 +1,127 @@
'use client'
import Image from 'next/image'
import Icon from './assets/Icon.png'
import { useEffect, useState } from 'react'
import axios from 'axios'
import { app } from '@tauri-apps/api'
import { invoke } from '@tauri-apps/api/core'
import { arch, platform } from '@tauri-apps/plugin-os'
import { LauncherUpdate } from './types/LauncherUpdate'
import { openUrl } from '@tauri-apps/plugin-opener'
export default function Home () {
const [state, setState] = useState<string>('Loading...')
useEffect(() => {
;(async () => {
setState('Checking for updates...')
let updaterLatestRequest
let launcherLatestRequest
let launcherUpdateData: LauncherUpdate | null
try {
updaterLatestRequest = await axios.get(
'https://games.lncvrt.xyz/api/launcher/loader/latest'
)
launcherLatestRequest = await axios.get(
'https://games.lncvrt.xyz/api/launcher/latest'
)
} catch {
setState('Failed. Check internet connection.')
return
}
if (
updaterLatestRequest.status !== 200 ||
launcherLatestRequest.status !== 200
) {
setState('Failed. Try again later.')
return
}
const version = await app.getVersion()
if (version !== updaterLatestRequest.data) {
setState('Loader update required')
return
}
const isLatest = await invoke('check_latest_ver', {
version: launcherLatestRequest.data
})
if (isLatest == '1') {
setState('Starting...')
} else {
setState('Downloading new update...')
try {
const launcherUpdateRequest = await axios.get(
'https://games.lncvrt.xyz/api/launcher/loader/update-data'
)
launcherUpdateData = launcherUpdateRequest.data
} catch {
setState('Failed. Check internet connection.')
return
}
if (!launcherUpdateData) return
const downloadResult = await invoke('download', {
url: getDownloadLink(launcherUpdateData),
name: launcherLatestRequest.data
})
if (downloadResult !== '1') {
setState('Failed. Check internet connection.')
return
}
setState('Starting...')
}
invoke('load', {
name: launcherLatestRequest.data
})
})()
}, [])
function getDownloadLink (version: LauncherUpdate): string | undefined {
const p = platform()
const a = arch()
const findUrl = (plat: string) => {
const i = version.platforms.indexOf(plat)
return i >= 0 ? version.downloadUrls[i] : undefined
}
if (p === 'windows') {
if (a === 'x86_64') return findUrl('windows-x64')
if (a === 'aarch64') return findUrl('windows-arm64')
} else if (p === 'macos') {
if (a === 'x86_64') return findUrl('macos-intel')
if (a === 'aarch64') return findUrl('macos-silicon')
} else if (p === 'linux') return findUrl(p)
return undefined
}
return (
<>
<div className='absolute left-1/2 top-[20%] -translate-x-1/2 flex flex-col items-center'>
<Image src={Icon} width={128} height={128} alt='' draggable={false} />
<div
className={`${
state !== 'Loader update required' ? 'mt-10' : 'mt-4'
} text-center`}
>
<p className='whitespace-nowrap'>{state}</p>
<button
hidden={state !== 'Loader update required'}
className='mt-4'
onClick={async () =>
await openUrl('https://games.lncvrt.xyz/download')
}
>
Update
</button>
</div>
</div>
</>
)
}

View File

@@ -0,0 +1,7 @@
export interface LauncherUpdate {
id: string
releaseDate: number
downloadUrls: string[]
platforms: string[]
executables: string[]
}