mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-13 07:34:36 +01:00
Improve mod browser load time
Add pages to mod browser Still WIP
This commit is contained in:
@@ -1,21 +1,25 @@
|
||||
use http::header;
|
||||
use once_cell::sync::Lazy;
|
||||
use reqwest::header::{CONTENT_TYPE, USER_AGENT};
|
||||
static CLIENT: Lazy<reqwest::Client> = Lazy::new(|| {
|
||||
let mut headers = header::HeaderMap::new();
|
||||
headers.insert(USER_AGENT, header::HeaderValue::from_static("cultivation"));
|
||||
headers.insert(CONTENT_TYPE, header::HeaderValue::from_static("application/json"));
|
||||
|
||||
let client = reqwest::Client::builder()
|
||||
.default_headers(headers);
|
||||
client.build().unwrap()
|
||||
});
|
||||
|
||||
pub(crate) async fn query(site: &str) -> String {
|
||||
let client = reqwest::Client::new();
|
||||
|
||||
let response = client
|
||||
CLIENT
|
||||
.get(site)
|
||||
.header(USER_AGENT, "cultivation")
|
||||
.header(CONTENT_TYPE, "application/json")
|
||||
.send()
|
||||
.await
|
||||
.ok();
|
||||
|
||||
if response.is_some() {
|
||||
response.unwrap().text().await.unwrap()
|
||||
} else {
|
||||
false.to_string()
|
||||
}
|
||||
.expect("Failed to get web response")
|
||||
.text()
|
||||
.await
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
|
||||
@@ -14,6 +14,7 @@ import Back from '../resources/icons/back.svg'
|
||||
import Menu from './components/menu/Menu'
|
||||
import BigButton from './components/common/BigButton'
|
||||
import Tr from '../utils/language'
|
||||
import { ModPages } from './components/mods/ModPages'
|
||||
|
||||
interface IProps {
|
||||
downloadHandler: DownloadHandler
|
||||
@@ -23,8 +24,20 @@ interface IState {
|
||||
isDownloading: boolean
|
||||
category: string
|
||||
downloadList: { name: string; url: string; mod: ModData }[] | null
|
||||
page: number
|
||||
}
|
||||
|
||||
const pages = [
|
||||
{
|
||||
name: -1,
|
||||
title: '<',
|
||||
},
|
||||
{
|
||||
name: 1,
|
||||
title: '>',
|
||||
}
|
||||
]
|
||||
|
||||
const headers = [
|
||||
{
|
||||
name: 'ripe',
|
||||
@@ -53,10 +66,12 @@ export class Mods extends React.Component<IProps, IState> {
|
||||
isDownloading: false,
|
||||
category: '',
|
||||
downloadList: null,
|
||||
page: 1,
|
||||
}
|
||||
|
||||
this.setCategory = this.setCategory.bind(this)
|
||||
this.addDownload = this.addDownload.bind(this)
|
||||
this.setPage = this.setPage.bind(this)
|
||||
}
|
||||
|
||||
async addDownload(mod: ModData) {
|
||||
@@ -111,6 +126,17 @@ export class Mods extends React.Component<IProps, IState> {
|
||||
)
|
||||
}
|
||||
|
||||
async setPage(value: number) {
|
||||
const current = this.state.page;
|
||||
if (current + value == 0) return;
|
||||
this.setState(
|
||||
{
|
||||
page: current + value,
|
||||
},
|
||||
this.forceUpdate
|
||||
)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="Mods">
|
||||
@@ -162,7 +188,9 @@ export class Mods extends React.Component<IProps, IState> {
|
||||
|
||||
<ModHeader onChange={this.setCategory} headers={headers} defaultHeader={'ripe'} />
|
||||
|
||||
<ModList key={this.state.category} mode={this.state.category} addDownload={this.addDownload} />
|
||||
<ModPages onClick={this.setPage} headers={pages} defaultHeader={1} />
|
||||
|
||||
<ModList key={`${this.state.category}_${this.state.page}`} mode={this.state.category} addDownload={this.addDownload} page={this.state.page} />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import { ModTile } from './ModTile'
|
||||
|
||||
interface IProps {
|
||||
mode: string
|
||||
page: number
|
||||
addDownload: (mod: ModData) => void
|
||||
}
|
||||
|
||||
@@ -62,7 +63,7 @@ export class ModList extends React.Component<IProps, IState> {
|
||||
return
|
||||
}
|
||||
|
||||
const mods = await getMods(this.props.mode)
|
||||
const mods = await getMods(this.props.mode, this.props.page)
|
||||
const horny = await getConfigOption('horny_mode')
|
||||
|
||||
this.setState({
|
||||
|
||||
30
src/ui/components/mods/ModPages.css
Normal file
30
src/ui/components/mods/ModPages.css
Normal file
@@ -0,0 +1,30 @@
|
||||
.ModPages {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
align-items: center;
|
||||
justify-content: space-around;
|
||||
width: 100%;
|
||||
|
||||
padding: 10px;
|
||||
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
color: #fff;
|
||||
background: rgba(77, 77, 77, 0.6);
|
||||
}
|
||||
|
||||
.ModPagesTitle {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
|
||||
width: 100%;
|
||||
max-width: 20%;
|
||||
}
|
||||
|
||||
.ModPagesTitle:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.ModPagesTitle.selected {
|
||||
border-bottom: 0px solid #fff;
|
||||
}
|
||||
54
src/ui/components/mods/ModPages.tsx
Normal file
54
src/ui/components/mods/ModPages.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import React from 'react'
|
||||
|
||||
import './ModPages.css'
|
||||
|
||||
interface IProps {
|
||||
headers: {
|
||||
title: string
|
||||
name: number
|
||||
}[]
|
||||
onClick: (value: number) => void
|
||||
defaultHeader: number
|
||||
}
|
||||
|
||||
interface IState {
|
||||
selected: number
|
||||
}
|
||||
|
||||
export class ModPages extends React.Component<IProps, IState> {
|
||||
constructor(props: IProps) {
|
||||
super(props)
|
||||
|
||||
this.state = {
|
||||
selected: this.props.defaultHeader,
|
||||
}
|
||||
}
|
||||
|
||||
setSelected(value: number) {
|
||||
const current = this.state.selected;
|
||||
if (current + value == 0) return;
|
||||
this.setState({
|
||||
selected: current + value,
|
||||
})
|
||||
|
||||
this.props.onClick(value)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="ModPages">
|
||||
{this.props.headers.map((header, index) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
className={`ModPagesTitle ${this.state.selected === header.name ? 'selected' : ''}`}
|
||||
onClick={() => this.setSelected(header.name)}
|
||||
>
|
||||
{header.title}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -117,12 +117,10 @@ interface ModDownload {
|
||||
containsExe: boolean
|
||||
}
|
||||
|
||||
export async function getMods(mode: string) {
|
||||
export async function getMods(mode: string, page: number) {
|
||||
let modList: GamebananaResponse[] = []
|
||||
let hadMods = true
|
||||
let page = 1
|
||||
|
||||
while (hadMods) {
|
||||
const resp = JSON.parse(
|
||||
await invoke('list_submissions', {
|
||||
mode,
|
||||
@@ -133,13 +131,6 @@ export async function getMods(mode: string) {
|
||||
if (resp.length === 0) hadMods = false
|
||||
|
||||
modList = [...modList, ...resp]
|
||||
page++
|
||||
|
||||
console.log(page)
|
||||
console.log(resp)
|
||||
}
|
||||
|
||||
console.log(modList)
|
||||
|
||||
return formatGamebananaData(modList)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user