This commit is contained in:
2025-11-01 21:10:31 -07:00
parent c90cf0ed55
commit 3c05196dda
11 changed files with 155 additions and 30 deletions

View File

@@ -1,7 +1,7 @@
{ {
"name": "lncvrt-games-launcher", "name": "lncvrt-games-launcher",
"private": true, "private": true,
"version": "1.0.0", "version": "1.1.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Lncvrt Games Launcher", "productName": "Lncvrt Games Launcher",
"version": "1.0.0", "version": "1.1.0",
"identifier": "xyz.lncvrt.games-launcher", "identifier": "xyz.lncvrt.games-launcher",
"build": { "build": {
"beforeDevCommand": "next dev", "beforeDevCommand": "next dev",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Lncvrt Games Launcher", "productName": "Lncvrt Games Launcher",
"version": "1.0.0", "version": "1.1.0",
"identifier": "xyz.lncvrt.games-launcher", "identifier": "xyz.lncvrt.games-launcher",
"build": { "build": {
"beforeDevCommand": "next dev", "beforeDevCommand": "next dev",

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Lncvrt Games Launcher", "productName": "Lncvrt Games Launcher",
"version": "1.0.0", "version": "1.1.0",
"identifier": "xyz.lncvrt.games-launcher", "identifier": "xyz.lncvrt.games-launcher",
"build": { "build": {
"beforeDevCommand": "next dev", "beforeDevCommand": "next dev",
@@ -32,8 +32,6 @@
"macOS": { "macOS": {
"minimumSystemVersion": "13.7.8" "minimumSystemVersion": "13.7.8"
}, },
"icon": [ "icon": ["icons/icon.icns"]
"icons/icon.icns"
]
} }
} }

View File

@@ -1,7 +1,7 @@
{ {
"$schema": "https://schema.tauri.app/config/2", "$schema": "https://schema.tauri.app/config/2",
"productName": "Lncvrt Games Launcher", "productName": "Lncvrt Games Launcher",
"version": "1.0.0", "version": "1.1.0",
"identifier": "xyz.lncvrt.games-launcher", "identifier": "xyz.lncvrt.games-launcher",
"build": { "build": {
"beforeDevCommand": "next dev", "beforeDevCommand": "next dev",
@@ -30,8 +30,6 @@
}, },
"bundle": { "bundle": {
"active": false, "active": false,
"icon": [ "icon": ["icons/icon.ico"]
"icons/icon.ico"
]
} }
} }

View File

@@ -7,7 +7,6 @@ import { NormalConfig } from './types/NormalConfig'
import { ServerVersionsResponse } from './types/ServerVersionsResponse' import { ServerVersionsResponse } from './types/ServerVersionsResponse'
import { GameVersion } from './types/GameVersion' import { GameVersion } from './types/GameVersion'
import { Game } from './types/Game' import { Game } from './types/Game'
import { ReadonlyURLSearchParams } from 'next/navigation'
type GlobalCtxType = { type GlobalCtxType = {
serverVersionList: ServerVersionsResponse | null serverVersionList: ServerVersionsResponse | null
@@ -31,6 +30,10 @@ type GlobalCtxType = {
getVersionInfo: (id: string | undefined) => GameVersion | undefined getVersionInfo: (id: string | undefined) => GameVersion | undefined
getVersionGame: (id: number | undefined) => Game | undefined getVersionGame: (id: number | undefined) => Game | undefined
getListOfGames: () => Game[] getListOfGames: () => Game[]
getVersionsAmountData: (gameId: number) => {
installed: number
total: number
} | null
} }
const GlobalCtx = createContext<GlobalCtxType | null>(null) const GlobalCtx = createContext<GlobalCtxType | null>(null)

View File

@@ -59,7 +59,7 @@ body {
} }
.popup-entry { .popup-entry {
@apply relative h-[100px] bg-[#323232] m-2 p-2 rounded-lg border border-[#646464]; @apply relative h-fit bg-[#323232] m-2 p-2 rounded-lg border border-[#646464];
} }
.popup-entry button { .popup-entry button {
@@ -77,3 +77,11 @@ body {
.input-field { .input-field {
@apply border-2 border-[#484848] rounded-md bg-[#242424] p-2 px-4 focus:border-blue-600 transition-colors; @apply border-2 border-[#484848] rounded-md bg-[#242424] p-2 px-4 focus:border-blue-600 transition-colors;
} }
.entry-info-item {
@apply flex flex-row items-center gap-1 bg-[rgb(16,16,16)] text-gray-300 py-1 px-2 rounded-lg w-fit text-[16px];
}
.downloads-entry:hover .entry-info-item {
@apply bg-[rgb(32,32,32)];
}

View File

@@ -73,7 +73,8 @@ export default function Installs () {
{getVersionGame(getVersionInfo(entry)?.game)?.name} v {getVersionGame(getVersionInfo(entry)?.game)?.name} v
{getVersionInfo(entry)?.versionName} {getVersionInfo(entry)?.versionName}
</p> </p>
<p className='text-gray-400 text-md'> <div className='entry-info-item'>
<p>
Installed{' '} Installed{' '}
{format( {format(
new Date(downloadedVersionsConfig.timestamps[entry]), new Date(downloadedVersionsConfig.timestamps[entry]),
@@ -81,6 +82,7 @@ export default function Installs () {
)} )}
</p> </p>
</div> </div>
</div>
<div className='flex flex-row items-center gap-2'> <div className='flex flex-row items-center gap-2'>
<button <button
className='button' className='button'

View File

@@ -9,9 +9,13 @@ import { invoke } from '@tauri-apps/api/core'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { import {
faAdd, faAdd,
faCheck,
faChevronLeft, faChevronLeft,
faCode,
faDownload, faDownload,
faRemove, faRemove,
faShieldHalved,
faWarning,
faXmark faXmark
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
import { import {
@@ -35,7 +39,6 @@ import { ServerVersionsResponse } from './types/ServerVersionsResponse'
import { GameVersion } from './types/GameVersion' import { GameVersion } from './types/GameVersion'
import { Game } from './types/Game' import { Game } from './types/Game'
import { listen } from '@tauri-apps/api/event' import { listen } from '@tauri-apps/api/event'
import { usePathname, useSearchParams } from 'next/navigation'
const roboto = Roboto({ const roboto = Roboto({
subsets: ['latin'] subsets: ['latin']
@@ -382,6 +385,48 @@ export default function RootLayout ({
await notifyUser('Downloads Finished', 'All downloads have finished.') await notifyUser('Downloads Finished', 'All downloads have finished.')
} }
function getVersionsAmountData (gameId: number): {
installed: number
total: number
} | null {
if (!downloadedVersionsConfig || !serverVersionList) return null
const p = platform()
const a = arch()
const installed = downloadedVersionsConfig.list.filter(
v => getVersionGame(getVersionInfo(v)?.game)?.id === gameId
).length
const total = serverVersionList.versions
.filter(v => {
if (p === 'macos' || p === 'linux') {
if (normalConfig?.settings.useWineOnUnixWhenNeeded) {
return (
v.platforms.includes('windows-x86') ||
v.platforms.includes('windows-x64') ||
v.platforms.includes(p)
)
}
return v.platforms.includes(p)
}
if (p === 'windows') {
if (a === 'x86_64')
return (
v.platforms.includes('windows-x86') ||
v.platforms.includes('windows-x64')
)
if (a === 'aarch64') return v.platforms.includes('windows-arm64')
}
return false
})
.filter(v => getVersionGame(v?.game)?.id === gameId).length
return { installed, total }
}
return ( return (
<> <>
<html lang='en' className={roboto.className}> <html lang='en' className={roboto.className}>
@@ -430,7 +475,8 @@ export default function RootLayout ({
getVersionInfo, getVersionInfo,
getVersionGame, getVersionGame,
getListOfGames, getListOfGames,
setSelectedGame setSelectedGame,
getVersionsAmountData
}} }}
> >
<div <div
@@ -531,6 +577,52 @@ export default function RootLayout ({
{serverVersionList?.games.map((v, i) => ( {serverVersionList?.games.map((v, i) => (
<div key={i} className='popup-entry'> <div key={i} className='popup-entry'>
<p className='text-2xl'>{v.name}</p> <p className='text-2xl'>{v.name}</p>
<div className='flex gap-2'>
<div className='entry-info-item'>
<p>
{(() => {
const data = getVersionsAmountData(v.id)
if (!data) return 'N/A'
return `${data.installed}/${data.total}`
})()}{' '}
versions installed
</p>
</div>
<div
className='entry-info-item'
hidden={!v.official}
>
<FontAwesomeIcon
icon={faCheck}
color='#19c84b'
/>
<p>Official</p>
</div>
<div
className='entry-info-item'
hidden={v.official}
>
<FontAwesomeIcon
icon={
v.verified ? faShieldHalved : faWarning
}
color={v.verified ? '#19c84b' : '#ffc800'}
/>
<p>
{v.verified ? 'Verified' : 'Unverified'}
</p>
</div>
</div>
<div
className='entry-info-item mt-2'
hidden={v.official}
>
<FontAwesomeIcon
icon={faCode}
color='lightgray'
/>
<p>Developer: {v.developer}</p>
</div>
<button <button
className='button right-2 bottom-2' className='button right-2 bottom-2'
onClick={() => setSelectedGame(v.id)} onClick={() => setSelectedGame(v.id)}

View File

@@ -1,13 +1,15 @@
'use client' 'use client'
import { useEffect } from 'react' import { useEffect } from 'react'
import { platform } from '@tauri-apps/plugin-os'
import './Installs.css' import './Installs.css'
import { format } from 'date-fns'
import { invoke } from '@tauri-apps/api/core'
import { message } from '@tauri-apps/plugin-dialog'
import { useGlobal } from './GlobalProvider' import { useGlobal } from './GlobalProvider'
import Link from 'next/link' import Link from 'next/link'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import {
faCheck,
faShieldHalved,
faWarning
} from '@fortawesome/free-solid-svg-icons'
export default function Installs () { export default function Installs () {
const { const {
@@ -19,11 +21,9 @@ export default function Installs () {
setSelectedVersionList, setSelectedVersionList,
downloadedVersionsConfig, downloadedVersionsConfig,
normalConfig, normalConfig,
setManagingVersion,
getVersionInfo,
getVersionGame,
setSelectedGame, setSelectedGame,
getListOfGames getListOfGames,
getVersionsAmountData
} = useGlobal() } = useGlobal()
useEffect(() => { useEffect(() => {
@@ -59,6 +59,29 @@ export default function Installs () {
<div key={i.id} className='downloads-entry'> <div key={i.id} className='downloads-entry'>
<div className='flex flex-col'> <div className='flex flex-col'>
<p className='text-2xl'>{i.name}</p> <p className='text-2xl'>{i.name}</p>
<div className='flex gap-2'>
<div className='entry-info-item'>
<p>
{(() => {
const data = getVersionsAmountData(i.id)
if (!data) return 'N/A'
return `${data.installed}/${data.total}`
})()}{' '}
versions installed
</p>
</div>
<div className='entry-info-item' hidden={!i.official}>
<FontAwesomeIcon icon={faCheck} color='#19c84b' />
<p>Official</p>
</div>
<div className='entry-info-item' hidden={i.official}>
<FontAwesomeIcon
icon={i.verified ? faShieldHalved : faWarning}
color={i.verified ? '#19c84b' : '#ffc800'}
/>
<p>{i.verified ? 'Verified' : 'Unverified'}</p>
</div>
</div>
</div> </div>
<div className='flex flex-row items-center gap-2'> <div className='flex flex-row items-center gap-2'>
<Link className='button' href={'/game?id=' + i.id}> <Link className='button' href={'/game?id=' + i.id}>

View File

@@ -3,5 +3,6 @@ export interface Game {
name: string name: string
official: boolean official: boolean
verified: boolean verified: boolean
developer: string | null
cutOff: number | null cutOff: number | null
} }