Mod browser searching

This commit is contained in:
Thoronium
2023-04-25 19:44:23 -06:00
parent df48f888ff
commit e38467f054
4 changed files with 93 additions and 20 deletions

View File

@@ -15,6 +15,7 @@ import Menu from './components/menu/Menu'
import BigButton from './components/common/BigButton'
import Tr from '../utils/language'
import { ModPages } from './components/mods/ModPages'
import TextInput from './components/common/TextInput'
interface IProps {
downloadHandler: DownloadHandler
@@ -25,6 +26,7 @@ interface IState {
category: string
downloadList: { name: string; url: string; mod: ModData }[] | null
page: number
search: string
}
const pages = [
@@ -59,14 +61,17 @@ const headers = [
* @TODO Categorizaiton/sorting (by likes, views, etc)
*/
export class Mods extends React.Component<IProps, IState> {
timeout: number
constructor(props: IProps) {
super(props)
this.timeout = 0
this.state = {
isDownloading: false,
category: '',
downloadList: null,
page: 1,
search: '',
}
this.setCategory = this.setCategory.bind(this)
@@ -137,6 +142,17 @@ export class Mods extends React.Component<IProps, IState> {
)
}
async setSearch(text: string) {
if(this.timeout) clearTimeout(this.timeout);
this.timeout = window.setTimeout(() => {
this.setState({
search: text,
},
this.forceUpdate
)
}, 300)
}
render() {
return (
<div className="Mods">
@@ -190,16 +206,25 @@ export class Mods extends React.Component<IProps, IState> {
{this.state.category != 'installed' && (
<>
<p className="ModPagesPage">{this.state.page} </p>
<div className="ModPagesPage">
<TextInput
id="search"
key="search"
placeholder={this.state.page.toString()}
onChange={(text: string) => {this.setSearch(text)}}
initalValue={''}
/>
</div>
<ModPages onClick={this.setPage} headers={pages} defaultHeader={this.state.page} />
</>
)}
<ModList
key={`${this.state.category}_${this.state.page}`}
key={`${this.state.category}_${this.state.page}_${this.state.search}`}
mode={this.state.category}
addDownload={this.addDownload}
page={this.state.page}
search={this.state.search}
/>
</div>
)

View File

@@ -1,6 +1,6 @@
import React from 'react'
import { getConfigOption } from '../../../utils/configuration'
import { getInstalledMods, getMods, ModData, PartialModData } from '../../../utils/gamebanana'
import { getAllMods, getInstalledMods, getMods, ModData, PartialModData } from '../../../utils/gamebanana'
import { LoadingCircle } from './LoadingCircle'
import './ModList.css'
@@ -9,6 +9,7 @@ import { ModTile } from './ModTile'
interface IProps {
mode: string
page: number
search: string
addDownload: (mod: ModData) => void
}
@@ -16,11 +17,11 @@ interface IState {
horny: boolean
modList: ModData[] | null
installedList:
| {
path: string
info: ModData | PartialModData
}[]
| null
| {
path: string
info: ModData | PartialModData
}[]
| null
}
export class ModList extends React.Component<IProps, IState> {
@@ -63,7 +64,15 @@ export class ModList extends React.Component<IProps, IState> {
return
}
const mods = await getMods(this.props.mode, this.props.page)
let mods: ModData[]
if (!(this.props.search == '')) {
// idk the api so just filter all mods to search
mods = (await getAllMods(this.props.mode)).filter(mod => mod.name.toLowerCase().includes(this.props.search.toLowerCase()))
} else {
mods = await getMods(this.props.mode, this.props.page)
}
const horny = await getConfigOption('horny_mode')
this.setState({
@@ -80,21 +89,21 @@ export class ModList extends React.Component<IProps, IState> {
return (
<div className="ModList">
{(this.state.modList && this.props.mode !== 'installed') ||
(this.state.installedList && this.props.mode === 'installed') ? (
(this.state.installedList && this.props.mode === 'installed') ? (
<div className="ModListInner">
{this.props.mode === 'installed'
? this.state.installedList?.map((mod) => (
<ModTile
horny={this.state.horny}
path={mod.path}
mod={mod.info}
key={mod.info.name}
onClick={this.downloadMod}
/>
))
<ModTile
horny={this.state.horny}
path={mod.path}
mod={mod.info}
key={mod.info.name}
onClick={this.downloadMod}
/>
))
: this.state.modList?.map((mod: ModData) => (
<ModTile horny={this.state.horny} mod={mod} key={mod.id} onClick={this.downloadMod} />
))}
<ModTile horny={this.state.horny} mod={mod} key={mod.id} onClick={this.downloadMod} />
))}
</div>
) : (
<LoadingCircle />

View File

@@ -47,3 +47,20 @@
font-weight: bold;
color: #fff;
}
.ModPagesPage input {
text-align: center;
padding: 3px;
border-radius: 3px;
height: 18px;
font-size: 20px;
font-weight: bold;
color: #fff;
background: rgba(77, 77, 77, 0.6);
}
.ModPagesPage .TextInputWrapper {
background: rgba(77, 77, 77, 0.6);
z-index: -1;
display: inline-block;
}

View File

@@ -132,6 +132,28 @@ export async function getMods(mode: string, page: number) {
return formatGamebananaData(modList)
}
export async function getAllMods(mode: string) {
let modList: GamebananaResponse[] = []
let hadMods = true
let page = 1
while (hadMods) {
const resp = JSON.parse(
await invoke('list_submissions', {
mode,
page: '' + page,
})
)
if (resp.length === 0) hadMods = false
modList = [...modList, ...resp]
page++
}
return formatGamebananaData(modList)
}
export async function formatGamebananaData(obj: GamebananaResponse[]) {
if (!obj) return []