Add view mod info mode
This commit is contained in:
4 files changed
+112
-16
No files matched your search
@@ -13,6 +13,7 @@ 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 { Mod } from '@/types/Mod'
|
||||||
|
|
||||||
type GlobalCtxType = {
|
type GlobalCtxType = {
|
||||||
serverVersionList: ServerVersionsResponse | null
|
serverVersionList: ServerVersionsResponse | null
|
||||||
@@ -53,8 +54,8 @@ type GlobalCtxType = {
|
|||||||
getSpecialVersionsList(game?: number | undefined): GameVersion[]
|
getSpecialVersionsList(game?: number | undefined): GameVersion[]
|
||||||
selectedGame: number | null
|
selectedGame: number | null
|
||||||
setViewingInfoFromDownloads: Dispatch<SetStateAction<boolean>>
|
setViewingInfoFromDownloads: Dispatch<SetStateAction<boolean>>
|
||||||
showModInfo: number
|
showModInfo: Mod | null
|
||||||
setShowModInfo: Dispatch<SetStateAction<number>>
|
setShowModInfo: Dispatch<SetStateAction<Mod | null>>
|
||||||
}
|
}
|
||||||
|
|
||||||
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
const GlobalCtx = createContext<GlobalCtxType | null>(null)
|
||||||
|
|||||||
+6
-5
@@ -39,6 +39,7 @@ import GamesDownloadPopup from '@/componets/popups/GamesDownload'
|
|||||||
import DownloadsPopup from '@/componets/popups/Downloads'
|
import DownloadsPopup from '@/componets/popups/Downloads'
|
||||||
import ManageVersionPopup from '@/componets/popups/ManageVersion'
|
import ManageVersionPopup from '@/componets/popups/ManageVersion'
|
||||||
import ModDownloadsPopup from '@/componets/popups/ModDownloads'
|
import ModDownloadsPopup from '@/componets/popups/ModDownloads'
|
||||||
|
import { Mod } from '@/types/Mod'
|
||||||
|
|
||||||
const roboto = Roboto({
|
const roboto = Roboto({
|
||||||
subsets: ['latin']
|
subsets: ['latin']
|
||||||
@@ -78,7 +79,7 @@ export default function RootLayout ({
|
|||||||
const [selectedGame, setSelectedGame] = useState<number | null>(null)
|
const [selectedGame, setSelectedGame] = useState<number | null>(null)
|
||||||
|
|
||||||
const [category, setCategory] = useState<number>(-1)
|
const [category, setCategory] = useState<number>(-1)
|
||||||
const [showModInfo, setShowModInfo] = useState<number>(-1)
|
const [showModInfo, setShowModInfo] = useState<Mod | null>(null)
|
||||||
|
|
||||||
const pathname = usePathname()
|
const pathname = usePathname()
|
||||||
const revisionCheck = useRef(false)
|
const revisionCheck = useRef(false)
|
||||||
@@ -175,8 +176,8 @@ export default function RootLayout ({
|
|||||||
} else if (viewingInfoFromDownloads) {
|
} else if (viewingInfoFromDownloads) {
|
||||||
setViewingInfoFromDownloads(false)
|
setViewingInfoFromDownloads(false)
|
||||||
setPopupMode(0)
|
setPopupMode(0)
|
||||||
} else if (popupMode == 3 && showModInfo != -1) {
|
} else if (popupMode == 3 && showModInfo) {
|
||||||
setShowModInfo(-1)
|
setShowModInfo(null)
|
||||||
} else {
|
} else {
|
||||||
setFadeOut(true)
|
setFadeOut(true)
|
||||||
setTimeout(() => setShowPopup(false), 200)
|
setTimeout(() => setShowPopup(false), 200)
|
||||||
@@ -687,7 +688,7 @@ export default function RootLayout ({
|
|||||||
className={`popup-overlay ${fadeOut ? 'fade-out' : ''}`}
|
className={`popup-overlay ${fadeOut ? 'fade-out' : ''}`}
|
||||||
onClick={(e: React.MouseEvent<HTMLDivElement>) => {
|
onClick={(e: React.MouseEvent<HTMLDivElement>) => {
|
||||||
if (e.target === e.currentTarget) {
|
if (e.target === e.currentTarget) {
|
||||||
if (showModInfo != -1) setShowModInfo(-1)
|
if (showModInfo) setShowModInfo(null)
|
||||||
if (viewingInfoFromDownloads) {
|
if (viewingInfoFromDownloads) {
|
||||||
setPopupMode(0)
|
setPopupMode(0)
|
||||||
setViewingInfoFromDownloads(false)
|
setViewingInfoFromDownloads(false)
|
||||||
@@ -710,7 +711,7 @@ export default function RootLayout ({
|
|||||||
selectedGame &&
|
selectedGame &&
|
||||||
pathname === '/') ||
|
pathname === '/') ||
|
||||||
viewingInfoFromDownloads ||
|
viewingInfoFromDownloads ||
|
||||||
(popupMode == 3 && showModInfo != -1)
|
(popupMode == 3 && showModInfo)
|
||||||
? faChevronLeft
|
? faChevronLeft
|
||||||
: faXmark
|
: faXmark
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,21 @@ import { useGlobal } from '@/app/GlobalProvider'
|
|||||||
import { verifySignature } from '@/lib/Util'
|
import { verifySignature } from '@/lib/Util'
|
||||||
import { Mod } from '@/types/Mod'
|
import { Mod } from '@/types/Mod'
|
||||||
import {
|
import {
|
||||||
|
faArrowUpRightFromSquare,
|
||||||
|
faClock,
|
||||||
|
faCodeBranch,
|
||||||
faDownload,
|
faDownload,
|
||||||
faGlobe,
|
faGlobe,
|
||||||
|
faPeopleGroup,
|
||||||
faRefresh
|
faRefresh
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
|
||||||
|
import { message } from '@tauri-apps/plugin-dialog'
|
||||||
import { arch, platform } from '@tauri-apps/plugin-os'
|
import { arch, platform } from '@tauri-apps/plugin-os'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
|
|
||||||
export default function ModDownloadsPopup () {
|
export default function ModDownloadsPopup () {
|
||||||
const {
|
const {
|
||||||
getGameInfo,
|
|
||||||
getVersionInfo,
|
getVersionInfo,
|
||||||
managingVersion,
|
managingVersion,
|
||||||
downloadedVersionsConfig,
|
downloadedVersionsConfig,
|
||||||
@@ -26,6 +30,7 @@ export default function ModDownloadsPopup () {
|
|||||||
const [tab, setTab] = useState<number>(0)
|
const [tab, setTab] = useState<number>(0)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!managingVersion) return
|
||||||
;(async () => {
|
;(async () => {
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
`https://games.lncvrt.xyz/api/launcher/mods?platform=${platform()}&arch=${arch()}&version=${managingVersion}`
|
`https://games.lncvrt.xyz/api/launcher/mods?platform=${platform()}&arch=${arch()}&version=${managingVersion}`
|
||||||
@@ -43,7 +48,6 @@ export default function ModDownloadsPopup () {
|
|||||||
if (!managingVersion) return <></>
|
if (!managingVersion) return <></>
|
||||||
|
|
||||||
const versionInfo = getVersionInfo(managingVersion)
|
const versionInfo = getVersionInfo(managingVersion)
|
||||||
const gameInfo = getGameInfo(versionInfo?.game)
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -62,14 +66,21 @@ export default function ModDownloadsPopup () {
|
|||||||
setMods(1)
|
setMods(1)
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
hidden={typeof mods == 'number' || showModInfo != -1}
|
hidden={typeof mods == 'number' || showModInfo != null}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon icon={faRefresh} />
|
<FontAwesomeIcon icon={faRefresh} />
|
||||||
</button>
|
</button>
|
||||||
<p className='text-xl text-center'>
|
<p className='text-xl text-center'>
|
||||||
{versionInfo?.displayName} Mod Manager
|
{!showModInfo
|
||||||
|
? versionInfo?.displayName + ' Mod Manager'
|
||||||
|
: showModInfo.name +
|
||||||
|
' by ' +
|
||||||
|
showModInfo.creators[0] +
|
||||||
|
(showModInfo.creators.length > 1
|
||||||
|
? ' + ' + (showModInfo.creators.length - 1) + ' more'
|
||||||
|
: '')}
|
||||||
</p>
|
</p>
|
||||||
{typeof mods != 'number' && showModInfo == -1 ? (
|
{typeof mods != 'number' && !showModInfo ? (
|
||||||
<div className='flex flex-row justify-center items-center -mb-2 mt-0.5 gap-1.5'>
|
<div className='flex flex-row justify-center items-center -mb-2 mt-0.5 gap-1.5'>
|
||||||
<button
|
<button
|
||||||
className={`button ${tab == 0 ? 'btntheme3' : 'btntheme2'}`}
|
className={`button ${tab == 0 ? 'btntheme3' : 'btntheme2'}`}
|
||||||
@@ -92,7 +103,7 @@ export default function ModDownloadsPopup () {
|
|||||||
<p className='text-2xl flex justify-center items-center h-full'>
|
<p className='text-2xl flex justify-center items-center h-full'>
|
||||||
{mods == 0 ? 'Loading' : 'Failed to load mods'}
|
{mods == 0 ? 'Loading' : 'Failed to load mods'}
|
||||||
</p>
|
</p>
|
||||||
) : (
|
) : !showModInfo ? (
|
||||||
<div className='flex flex-col items-center justify-center gap-2 p-2'>
|
<div className='flex flex-col items-center justify-center gap-2 p-2'>
|
||||||
{mods
|
{mods
|
||||||
.filter(
|
.filter(
|
||||||
@@ -132,7 +143,7 @@ export default function ModDownloadsPopup () {
|
|||||||
</p>
|
</p>
|
||||||
<button
|
<button
|
||||||
className='button btntheme3'
|
className='button btntheme3'
|
||||||
onClick={() => setShowModInfo(v.id)}
|
onClick={() => setShowModInfo(v)}
|
||||||
>
|
>
|
||||||
{tab == 0 ? 'View' : 'Get'}
|
{tab == 0 ? 'View' : 'Get'}
|
||||||
</button>
|
</button>
|
||||||
@@ -141,6 +152,89 @@ export default function ModDownloadsPopup () {
|
|||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className='flex flex-col h-full w-full items-center'>
|
||||||
|
<div className='flex flex-col p-2 h-fit w-fit bg-(--col3) border border-(--col5) rounded-lg m-2 items-center'>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faDownload} className='text-green-400' />{' '}
|
||||||
|
Downloads {showModInfo.downloads}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faClock} /> Released{' '}
|
||||||
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
|
showModInfo.released * 1000
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faClock} /> Updated{' '}
|
||||||
|
{new Intl.DateTimeFormat(undefined).format(
|
||||||
|
showModInfo.updated * 1000
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<FontAwesomeIcon icon={faCodeBranch} /> Version{' '}
|
||||||
|
{showModInfo.latestVersion}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-col p-2 bg-(--col3) border border-(--col5) rounded-lg h-full w-[calc(100%-16px)]'>
|
||||||
|
{showModInfo.description ?? '(No description added)'}
|
||||||
|
</div>
|
||||||
|
<div className='flex flex-row h-fit w-full gap-2 justify-center my-2'>
|
||||||
|
{Object.keys(downloadedVersionsConfig?.mods ?? []).includes(
|
||||||
|
String(showModInfo.id)
|
||||||
|
) ? (
|
||||||
|
<button className='button btntheme2 w-fit'>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faDownload}
|
||||||
|
className='text-green-400'
|
||||||
|
/>{' '}
|
||||||
|
Uninstall
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button className='button btntheme2 w-fit'>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faDownload}
|
||||||
|
className='text-green-400'
|
||||||
|
/>{' '}
|
||||||
|
Install
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
<button
|
||||||
|
className='button btntheme2 w-fit'
|
||||||
|
onClick={async () => {
|
||||||
|
await message(
|
||||||
|
!showModInfo.changelog
|
||||||
|
? '(No changelog provided)'
|
||||||
|
: atob(showModInfo?.changelog ?? ''),
|
||||||
|
{
|
||||||
|
title: 'Changelog for ' + showModInfo.name,
|
||||||
|
kind: 'info'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon
|
||||||
|
icon={faArrowUpRightFromSquare}
|
||||||
|
color='lightgray'
|
||||||
|
/>{' '}
|
||||||
|
View changelog
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
className='button btntheme2 w-fit'
|
||||||
|
hidden={showModInfo.creators.length < 2}
|
||||||
|
onClick={async () => {
|
||||||
|
if (!versionInfo) return
|
||||||
|
await message(showModInfo.creators.join(', '), {
|
||||||
|
title: 'Creators for ' + showModInfo.name,
|
||||||
|
kind: 'info'
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FontAwesomeIcon icon={faPeopleGroup} color='lightgray' /> View
|
||||||
|
all creators
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
export type VersionsConfigData = {
|
export type VersionsConfigData = {
|
||||||
version: string
|
version: string
|
||||||
list: Record<string, number>
|
list: Record<string, number>
|
||||||
mods: Record<string, string>
|
mods: Record<string, Record<string, number>>
|
||||||
}
|
}
|
||||||
|
|
||||||
export class VersionsConfig {
|
export class VersionsConfig {
|
||||||
constructor (
|
constructor (
|
||||||
public version: string,
|
public version: string,
|
||||||
public list: Record<string, number> = {},
|
public list: Record<string, number> = {},
|
||||||
public mods: Record<string, string> = {}
|
public mods: Record<string, Record<string, number>> = {}
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
static import (data: VersionsConfigData) {
|
static import (data: VersionsConfigData) {
|
||||||
|
|||||||
Reference in new issue
Block a user