mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-12 15:14:35 +01:00
Mod browser searching
This commit is contained in:
@@ -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>
|
||||
)
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 []
|
||||
|
||||
|
||||
Reference in New Issue
Block a user