Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d764448af
|
||
|
|
3c05196dda
|
No files matched your search
@@ -25,7 +25,7 @@
|
||||
"@tailwindcss/postcss": "4.1.16",
|
||||
"@tauri-apps/cli": "2.9.2",
|
||||
"@types/crypto-js": "4.2.2",
|
||||
"@types/node": "24.9.2",
|
||||
"@types/node": "24.10.0",
|
||||
"@types/react": "19.2.2",
|
||||
"@types/react-dom": "19.2.2",
|
||||
"crypto-js": "4.2.0",
|
||||
@@ -279,7 +279,7 @@
|
||||
|
||||
"@types/json5": ["@types/json5@0.0.29", "", {}, "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="],
|
||||
|
||||
"@types/node": ["@types/node@24.9.2", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA=="],
|
||||
"@types/node": ["@types/node@24.10.0", "", { "dependencies": { "undici-types": "~7.16.0" } }, "sha512-qzQZRBqkFsYyaSWXuEHc2WR9c0a0CXwiE5FWUvn7ZM+vdy1uZLfCunD38UzhuB7YN/J11ndbDBcTmOdxJo9Q7A=="],
|
||||
|
||||
"@types/react": ["@types/react@19.2.2", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA=="],
|
||||
|
||||
@@ -387,7 +387,7 @@
|
||||
|
||||
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
|
||||
|
||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.21", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-JU0h5APyQNsHOlAM7HnQnPToSDQoEBZqzu/YBlqDnEeymPnZDREeXJA3KBMQee+dKteAxZ2AtvQEvVYdZf241Q=="],
|
||||
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.23", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-616V5YX4bepJFzNyOfce5Fa8fDJMfoxzOIzDCZwaGL8MKVpFrXqfNUoIpRn9YMI5pXf/VKgzjB4htFMsFKKdiQ=="],
|
||||
|
||||
"brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
|
||||
|
||||
@@ -403,7 +403,7 @@
|
||||
|
||||
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
|
||||
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001751", "", {}, "sha512-A0QJhug0Ly64Ii3eIqHu5X51ebln3k4yTUkY1j8drqpWHVreg/VLijN48cZ1bYPiqOQuqpkIKnzr/Ul8V+p6Cw=="],
|
||||
"caniuse-lite": ["caniuse-lite@1.0.30001753", "", {}, "sha512-Bj5H35MD/ebaOV4iDLqPEtiliTN29qkGtEHCwawWn4cYm+bPJM2NsaP30vtZcnERClMzp52J4+aw2UNbK4o+zw=="],
|
||||
|
||||
"chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "lncvrt-games-launcher",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
@@ -34,7 +34,7 @@
|
||||
"@types/react": "19.2.2",
|
||||
"@types/react-dom": "19.2.2",
|
||||
"crypto-js": "4.2.0",
|
||||
"@types/node": "24.9.2",
|
||||
"@types/node": "24.10.0",
|
||||
"tailwindcss": "4.1.16",
|
||||
"typescript": "5.9.3",
|
||||
"eslint": "9.39.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "lncvrt-games-launcher"
|
||||
version = "1.1.0"
|
||||
version = "1.1.1"
|
||||
authors = ["Lncvrt"]
|
||||
edition = "2024"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "Lncvrt Games Launcher",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"identifier": "xyz.lncvrt.games-launcher",
|
||||
"build": {
|
||||
"beforeDevCommand": "next dev",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "Lncvrt Games Launcher",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"identifier": "xyz.lncvrt.games-launcher",
|
||||
"build": {
|
||||
"beforeDevCommand": "next dev",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "Lncvrt Games Launcher",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"identifier": "xyz.lncvrt.games-launcher",
|
||||
"build": {
|
||||
"beforeDevCommand": "next dev",
|
||||
@@ -32,8 +32,6 @@
|
||||
"macOS": {
|
||||
"minimumSystemVersion": "13.7.8"
|
||||
},
|
||||
"icon": [
|
||||
"icons/icon.icns"
|
||||
]
|
||||
"icon": ["icons/icon.icns"]
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"$schema": "https://schema.tauri.app/config/2",
|
||||
"productName": "Lncvrt Games Launcher",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.1",
|
||||
"identifier": "xyz.lncvrt.games-launcher",
|
||||
"build": {
|
||||
"beforeDevCommand": "next dev",
|
||||
@@ -30,8 +30,6 @@
|
||||
},
|
||||
"bundle": {
|
||||
"active": false,
|
||||
"icon": [
|
||||
"icons/icon.ico"
|
||||
]
|
||||
"icon": ["icons/icon.ico"]
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ import { NormalConfig } from './types/NormalConfig'
|
||||
import { ServerVersionsResponse } from './types/ServerVersionsResponse'
|
||||
import { GameVersion } from './types/GameVersion'
|
||||
import { Game } from './types/Game'
|
||||
import { ReadonlyURLSearchParams } from 'next/navigation'
|
||||
|
||||
type GlobalCtxType = {
|
||||
serverVersionList: ServerVersionsResponse | null
|
||||
@@ -31,6 +30,10 @@ type GlobalCtxType = {
|
||||
getVersionInfo: (id: string | undefined) => GameVersion | undefined
|
||||
getVersionGame: (id: number | undefined) => Game | undefined
|
||||
getListOfGames: () => Game[]
|
||||
getVersionsAmountData: (gameId: number) => {
|
||||
installed: number
|
||||
total: number
|
||||
} | null
|
||||
}
|
||||
|
||||
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
||||
|
||||
+9
-1
@@ -59,7 +59,7 @@ body {
|
||||
}
|
||||
|
||||
.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 {
|
||||
@@ -77,3 +77,11 @@ body {
|
||||
.input-field {
|
||||
@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)];
|
||||
}
|
||||
@@ -18,7 +18,7 @@
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
@apply flex flex-col p-4 space-y-1;
|
||||
@apply flex flex-col p-4 space-y-1 overflow-y-auto overflow-x-hidden;
|
||||
}
|
||||
|
||||
.link {
|
||||
|
||||
@@ -20,6 +20,7 @@ import { usePathname, useSearchParams } from 'next/navigation'
|
||||
|
||||
export default function Sidebar () {
|
||||
const {
|
||||
normalConfig,
|
||||
getListOfGames,
|
||||
setShowPopup,
|
||||
setPopupMode,
|
||||
@@ -88,7 +89,11 @@ export default function Sidebar () {
|
||||
? 'active'
|
||||
: ''
|
||||
} ml-auto w-50 ${
|
||||
pathname === '/' || pathname === '/game' ? '' : 'hidden'
|
||||
normalConfig?.settings.alwaysShowGamesInSidebar ||
|
||||
pathname === '/' ||
|
||||
pathname === '/game'
|
||||
? ''
|
||||
: 'hidden'
|
||||
}`}
|
||||
>
|
||||
<FontAwesomeIcon icon={faGamepad} className='mr-1' />{' '}
|
||||
|
||||
@@ -73,13 +73,15 @@ export default function Installs () {
|
||||
{getVersionGame(getVersionInfo(entry)?.game)?.name} v
|
||||
{getVersionInfo(entry)?.versionName}
|
||||
</p>
|
||||
<p className='text-gray-400 text-md'>
|
||||
Installed{' '}
|
||||
{format(
|
||||
new Date(downloadedVersionsConfig.timestamps[entry]),
|
||||
'MM/dd/yyyy'
|
||||
)}
|
||||
</p>
|
||||
<div className='entry-info-item'>
|
||||
<p>
|
||||
Installed{' '}
|
||||
{format(
|
||||
new Date(downloadedVersionsConfig.timestamps[entry]),
|
||||
'MM/dd/yyyy'
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex flex-row items-center gap-2'>
|
||||
<button
|
||||
|
||||
+103
-4
@@ -9,9 +9,13 @@ import { invoke } from '@tauri-apps/api/core'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import {
|
||||
faAdd,
|
||||
faCheck,
|
||||
faChevronLeft,
|
||||
faCode,
|
||||
faDownload,
|
||||
faRemove,
|
||||
faShieldHalved,
|
||||
faWarning,
|
||||
faXmark
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
import {
|
||||
@@ -35,7 +39,7 @@ import { ServerVersionsResponse } from './types/ServerVersionsResponse'
|
||||
import { GameVersion } from './types/GameVersion'
|
||||
import { Game } from './types/Game'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import { usePathname, useSearchParams } from 'next/navigation'
|
||||
import { usePathname } from 'next/navigation'
|
||||
|
||||
const roboto = Roboto({
|
||||
subsets: ['latin']
|
||||
@@ -75,6 +79,8 @@ export default function RootLayout ({
|
||||
}
|
||||
}
|
||||
|
||||
const pathname = usePathname()
|
||||
|
||||
const notifyUser = useCallback(
|
||||
async (title: string, body: string) => {
|
||||
if (!normalConfig?.settings.allowNotifications) return
|
||||
@@ -382,6 +388,48 @@ export default function RootLayout ({
|
||||
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 (
|
||||
<>
|
||||
<html lang='en' className={roboto.className}>
|
||||
@@ -430,7 +478,8 @@ export default function RootLayout ({
|
||||
getVersionInfo,
|
||||
getVersionGame,
|
||||
getListOfGames,
|
||||
setSelectedGame
|
||||
setSelectedGame,
|
||||
getVersionsAmountData
|
||||
}}
|
||||
>
|
||||
<div
|
||||
@@ -466,7 +515,11 @@ export default function RootLayout ({
|
||||
<button
|
||||
className='close-button'
|
||||
onClick={() => {
|
||||
if (popupMode == 0 && selectedGame) {
|
||||
if (
|
||||
popupMode == 0 &&
|
||||
selectedGame &&
|
||||
pathname === '/'
|
||||
) {
|
||||
setSelectedGame(null)
|
||||
setSelectedVersionList([])
|
||||
} else {
|
||||
@@ -477,7 +530,7 @@ export default function RootLayout ({
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
icon={
|
||||
popupMode == 0 && selectedGame
|
||||
popupMode == 0 && selectedGame && pathname === '/'
|
||||
? faChevronLeft
|
||||
: faXmark
|
||||
}
|
||||
@@ -531,6 +584,52 @@ export default function RootLayout ({
|
||||
{serverVersionList?.games.map((v, i) => (
|
||||
<div key={i} className='popup-entry'>
|
||||
<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
|
||||
className='button right-2 bottom-2'
|
||||
onClick={() => setSelectedGame(v.id)}
|
||||
|
||||
+31
-8
@@ -1,13 +1,15 @@
|
||||
'use client'
|
||||
|
||||
import { useEffect } from 'react'
|
||||
import { platform } from '@tauri-apps/plugin-os'
|
||||
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 Link from 'next/link'
|
||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||
import {
|
||||
faCheck,
|
||||
faShieldHalved,
|
||||
faWarning
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
export default function Installs () {
|
||||
const {
|
||||
@@ -19,11 +21,9 @@ export default function Installs () {
|
||||
setSelectedVersionList,
|
||||
downloadedVersionsConfig,
|
||||
normalConfig,
|
||||
setManagingVersion,
|
||||
getVersionInfo,
|
||||
getVersionGame,
|
||||
setSelectedGame,
|
||||
getListOfGames
|
||||
getListOfGames,
|
||||
getVersionsAmountData
|
||||
} = useGlobal()
|
||||
|
||||
useEffect(() => {
|
||||
@@ -59,6 +59,29 @@ export default function Installs () {
|
||||
<div key={i.id} className='downloads-entry'>
|
||||
<div className='flex flex-col'>
|
||||
<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 className='flex flex-row items-center gap-2'>
|
||||
<Link className='button' href={'/game?id=' + i.id}>
|
||||
|
||||
@@ -8,10 +8,12 @@ import { useGlobal } from '../GlobalProvider'
|
||||
|
||||
export default function Settings () {
|
||||
const [allowNotifications, setAllowNotifications] = useState(false)
|
||||
const [alwaysShowGamesInSidebar, setAlwaysShowGamesInSidebar] =
|
||||
useState(false)
|
||||
const [useWineOnUnixWhenNeeded, setUseWineOnUnixWhenNeeded] = useState(false)
|
||||
const [wineOnUnixCommand, setWineOnUnixCommand] = useState('wine %path%')
|
||||
const [loaded, setLoaded] = useState(false)
|
||||
const { normalConfig } = useGlobal()
|
||||
const { normalConfig, setNormalConfig } = useGlobal()
|
||||
|
||||
useEffect(() => {
|
||||
;(async () => {
|
||||
@@ -21,6 +23,9 @@ export default function Settings () {
|
||||
)
|
||||
setWineOnUnixCommand(normalConfig.settings.wineOnUnixCommand)
|
||||
setAllowNotifications(normalConfig.settings.allowNotifications)
|
||||
setAlwaysShowGamesInSidebar(
|
||||
normalConfig.settings.alwaysShowGamesInSidebar
|
||||
)
|
||||
setLoaded(true)
|
||||
break
|
||||
}
|
||||
@@ -44,6 +49,30 @@ export default function Settings () {
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Setting
|
||||
label='Always show games in sidebar'
|
||||
value={alwaysShowGamesInSidebar}
|
||||
onChange={async () => {
|
||||
while (normalConfig != null) {
|
||||
setAlwaysShowGamesInSidebar(!alwaysShowGamesInSidebar)
|
||||
setNormalConfig({
|
||||
...normalConfig,
|
||||
settings: {
|
||||
...normalConfig.settings,
|
||||
alwaysShowGamesInSidebar: !alwaysShowGamesInSidebar
|
||||
}
|
||||
})
|
||||
writeNormalConfig({
|
||||
...normalConfig,
|
||||
settings: {
|
||||
...normalConfig.settings,
|
||||
alwaysShowGamesInSidebar: !alwaysShowGamesInSidebar
|
||||
}
|
||||
})
|
||||
break
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<Setting
|
||||
label='Use wine to launch Berry Dash when needed'
|
||||
value={useWineOnUnixWhenNeeded}
|
||||
|
||||
@@ -3,5 +3,6 @@ export interface Game {
|
||||
name: string
|
||||
official: boolean
|
||||
verified: boolean
|
||||
developer: string | null
|
||||
cutOff: number | null
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
export class SettingsType {
|
||||
constructor(
|
||||
public allowNotifications: boolean = true,
|
||||
public alwaysShowGamesInSidebar: boolean = true,
|
||||
public useWineOnUnixWhenNeeded: boolean = false,
|
||||
public wineOnUnixCommand: string = 'wine %path%'
|
||||
) { }
|
||||
|
||||
Reference in new issue
Block a user