mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-14 08:04:52 +01:00
Replaced backslashes in paths with slashes. I did not touch function that do the same with paths. Those can be removed manually. Also dataDir() returns a path that ends with a slash so I got rid of duplicated slashes.
370 lines
13 KiB
TypeScript
370 lines
13 KiB
TypeScript
import React from 'react'
|
|
import Menu from './Menu'
|
|
import Tr from '../../../utils/language'
|
|
import DownloadHandler from '../../../utils/download'
|
|
import { unzip } from '../../../utils/zipUtils'
|
|
import BigButton from '../common/BigButton'
|
|
import { dataDir } from '@tauri-apps/api/path'
|
|
|
|
import './Downloads.css'
|
|
import Divider from './Divider'
|
|
import { getConfigOption } from '../../../utils/configuration'
|
|
import { invoke } from '@tauri-apps/api'
|
|
import { listen } from '@tauri-apps/api/event'
|
|
import HelpButton from '../common/HelpButton'
|
|
|
|
const FULL_BUILD_DOWNLOAD = 'https://github.com/NotThorny/Grasscutter/releases/download/culti-aio/GrasscutterCulti.zip'
|
|
const FULL_QUEST_DOWNLOAD = 'https://github.com/NotThorny/Grasscutter/releases/download/culti-aio/GrasscutterQuests.zip'
|
|
const STABLE_REPO_DOWNLOAD = 'https://github.com/Grasscutters/Grasscutter/archive/refs/heads/stable.zip'
|
|
const DEV_REPO_DOWNLOAD = 'https://github.com/Grasscutters/Grasscutter/archive/refs/heads/development.zip'
|
|
const DEV_DOWNLOAD = 'https://nightly.link/Grasscutters/Grasscutter/workflows/build/development/Grasscutter.zip'
|
|
const RESOURCES_DOWNLOAD = 'https://gitlab.com/api/v4/projects/35984297/repository/archive.zip' // Use Yuuki res as grasscutter crepe res are broken
|
|
const MIGOTO_DOWNLOAD =
|
|
'https://github.com/SilentNightSound/GI-Model-Importer/releases/download/V7.0/3dmigoto-GIMI-for-playing-mods.zip'
|
|
|
|
interface IProps {
|
|
closeFn: () => void
|
|
downloadManager: DownloadHandler
|
|
}
|
|
|
|
interface IState {
|
|
fullbuild_downloading: boolean
|
|
grasscutter_downloading: boolean
|
|
resources_downloading: boolean
|
|
repo_downloading: boolean
|
|
migoto_downloading: boolean
|
|
grasscutter_set: boolean
|
|
resources_exist: boolean
|
|
swag: boolean
|
|
}
|
|
|
|
export default class Downloads extends React.Component<IProps, IState> {
|
|
constructor(props: IProps) {
|
|
super(props)
|
|
|
|
this.state = {
|
|
fullbuild_downloading: this.props.downloadManager.downloadingFullBuild(),
|
|
grasscutter_downloading: this.props.downloadManager.downloadingJar(),
|
|
resources_downloading: this.props.downloadManager.downloadingResources(),
|
|
repo_downloading: this.props.downloadManager.downloadingRepo(),
|
|
migoto_downloading: this.props.downloadManager.downloadingMigoto(),
|
|
grasscutter_set: false,
|
|
resources_exist: false,
|
|
swag: false,
|
|
}
|
|
|
|
this.getGrasscutterFolder = this.getGrasscutterFolder.bind(this)
|
|
this.downloadGrasscutterFullBuild = this.downloadGrasscutterFullBuild.bind(this)
|
|
this.downloadGrasscutterFullQuest = this.downloadGrasscutterFullQuest.bind(this)
|
|
this.downloadGrasscutterStableRepo = this.downloadGrasscutterStableRepo.bind(this)
|
|
this.downloadGrasscutterDevRepo = this.downloadGrasscutterDevRepo.bind(this)
|
|
this.downloadGrasscutterLatest = this.downloadGrasscutterLatest.bind(this)
|
|
this.downloadResources = this.downloadResources.bind(this)
|
|
this.downloadMigoto = this.downloadMigoto.bind(this)
|
|
this.toggleButtons = this.toggleButtons.bind(this)
|
|
}
|
|
|
|
async componentDidMount() {
|
|
const gc_path = await getConfigOption('grasscutter_path')
|
|
const swag = await getConfigOption('swag_mode')
|
|
|
|
this.setState({
|
|
swag: swag || false,
|
|
})
|
|
|
|
listen('jar_extracted', () => {
|
|
this.setState({ grasscutter_set: true }, this.forceUpdate)
|
|
})
|
|
|
|
if (!gc_path || gc_path === '') {
|
|
this.setState({
|
|
grasscutter_set: false,
|
|
resources_exist: false,
|
|
})
|
|
|
|
return
|
|
}
|
|
|
|
const path = gc_path.substring(0, gc_path.lastIndexOf('/'))
|
|
|
|
if (gc_path) {
|
|
const resources_exist: boolean =
|
|
((await invoke('dir_exists', {
|
|
path: path + '/resources',
|
|
})) as boolean) &&
|
|
(!(await invoke('dir_is_empty', {
|
|
path: path + '/resources',
|
|
})) as boolean)
|
|
|
|
this.setState({
|
|
grasscutter_set: gc_path !== '',
|
|
resources_exist,
|
|
})
|
|
}
|
|
}
|
|
|
|
async getGrasscutterFolder() {
|
|
const path = await getConfigOption('grasscutter_path')
|
|
let folderPath
|
|
|
|
// Set to default if not set
|
|
if (!path || path === '') {
|
|
const appdata = await dataDir()
|
|
folderPath = appdata + 'cultivation/grasscutter'
|
|
|
|
// Early return since its formatted properly
|
|
return folderPath
|
|
}
|
|
|
|
if (path.includes('/')) {
|
|
folderPath = path.substring(0, path.lastIndexOf('/'))
|
|
} else {
|
|
folderPath = path.substring(0, path.lastIndexOf('\\'))
|
|
}
|
|
|
|
return folderPath
|
|
}
|
|
|
|
async getCultivationFolder() {
|
|
const folderPath = (await dataDir()) + 'cultivation'
|
|
|
|
return folderPath
|
|
}
|
|
|
|
async downloadGrasscutterFullBuild() {
|
|
const folder = await this.getGrasscutterFolder()
|
|
this.props.downloadManager.addDownload(FULL_BUILD_DOWNLOAD, folder + '/GrasscutterCulti.zip', async () => {
|
|
await unzip(folder + '/GrasscutterCulti.zip', folder + '/', true)
|
|
this.toggleButtons()
|
|
})
|
|
|
|
this.toggleButtons()
|
|
}
|
|
|
|
async downloadGrasscutterFullQuest() {
|
|
const folder = await this.getGrasscutterFolder()
|
|
this.props.downloadManager.addDownload(FULL_QUEST_DOWNLOAD, folder + '/GrasscutterQuests.zip', async () => {
|
|
await unzip(folder + '/GrasscutterQuests.zip', folder + '/', true)
|
|
this.toggleButtons()
|
|
})
|
|
|
|
this.toggleButtons()
|
|
}
|
|
|
|
async downloadGrasscutterStableRepo() {
|
|
const folder = await this.getGrasscutterFolder()
|
|
this.props.downloadManager.addDownload(STABLE_REPO_DOWNLOAD, folder + '/grasscutter_repo.zip', async () => {
|
|
await unzip(folder + '/grasscutter_repo.zip', folder + '/', true)
|
|
this.toggleButtons()
|
|
})
|
|
|
|
this.toggleButtons()
|
|
}
|
|
|
|
async downloadGrasscutterDevRepo() {
|
|
const folder = await this.getGrasscutterFolder()
|
|
this.props.downloadManager.addDownload(DEV_REPO_DOWNLOAD, folder + '/grasscutter_repo.zip', async () => {
|
|
await unzip(folder + '/grasscutter_repo.zip', folder + '/', true)
|
|
this.toggleButtons()
|
|
})
|
|
|
|
this.toggleButtons()
|
|
}
|
|
|
|
async downloadGrasscutterLatest() {
|
|
const folder = await this.getGrasscutterFolder()
|
|
this.props.downloadManager.addDownload(DEV_DOWNLOAD, folder + '/grasscutter.zip', async () => {
|
|
await unzip(folder + '/grasscutter.zip', folder + '/', true)
|
|
this.toggleButtons()
|
|
})
|
|
|
|
// Also add repo download
|
|
this.downloadGrasscutterDevRepo()
|
|
|
|
this.toggleButtons()
|
|
}
|
|
|
|
async downloadResources() {
|
|
// Tell the user this takes some time
|
|
alert(
|
|
'Extracting resources can take time! If your resources appear to be "stuck" extracting for less than 15-20 mins, they likely still are extracting.'
|
|
)
|
|
const folder = await this.getGrasscutterFolder()
|
|
this.props.downloadManager.addDownload(RESOURCES_DOWNLOAD, folder + '/resources.zip', async () => {
|
|
// Delete the existing folder if it exists
|
|
if (
|
|
await invoke('dir_exists', {
|
|
path: folder + '/resources',
|
|
})
|
|
) {
|
|
await invoke('dir_delete', {
|
|
path: folder + '/resources',
|
|
})
|
|
}
|
|
|
|
await unzip(folder + '/resources.zip', folder + '/', true)
|
|
// Rename folder to resources
|
|
invoke('rename', {
|
|
path: folder + '/Resources',
|
|
newName: 'resources',
|
|
})
|
|
|
|
this.toggleButtons()
|
|
})
|
|
|
|
this.toggleButtons()
|
|
}
|
|
|
|
async downloadMigoto() {
|
|
const folder = (await this.getCultivationFolder()) + '/3dmigoto'
|
|
await invoke('dir_create', {
|
|
path: folder,
|
|
})
|
|
|
|
this.props.downloadManager.addDownload(MIGOTO_DOWNLOAD, folder + '/GIMI-3dmigoto.zip', async () => {
|
|
await unzip(folder + '/GIMI-3dmigoto.zip', folder + '/', true)
|
|
this.toggleButtons()
|
|
})
|
|
|
|
this.toggleButtons()
|
|
}
|
|
|
|
async toggleButtons() {
|
|
const gc_path = await getConfigOption('grasscutter_path')
|
|
|
|
// Set states since we know we are downloading something if this is called
|
|
this.setState({
|
|
fullbuild_downloading: this.props.downloadManager.downloadingFullBuild(),
|
|
grasscutter_downloading: this.props.downloadManager.downloadingJar(),
|
|
resources_downloading: this.props.downloadManager.downloadingResources(),
|
|
repo_downloading: this.props.downloadManager.downloadingRepo(),
|
|
migoto_downloading: this.props.downloadManager.downloadingMigoto(),
|
|
grasscutter_set: gc_path !== '',
|
|
})
|
|
}
|
|
|
|
render() {
|
|
return (
|
|
<Menu closeFn={this.props.closeFn} className="Downloads" heading="Downloads">
|
|
<Divider />
|
|
|
|
<div className="HeaderText" id="downloadMenuAIOHeader">
|
|
<Tr text="downloads.aio_header" />
|
|
</div>
|
|
<div className="DownloadMenuSection" id="downloadMenuContainerGCFullBuild">
|
|
<div className="DownloadLabel" id="downloadMenuLabelGCFullBuild">
|
|
<Tr text={'downloads.grasscutter_fullbuild'} />
|
|
<HelpButton contents="help.gc_fullbuild" />
|
|
</div>
|
|
|
|
<div className="DownloadValue" id="downloadMenuButtonGCFullBuild">
|
|
<BigButton
|
|
disabled={this.state.grasscutter_downloading}
|
|
onClick={this.downloadGrasscutterFullBuild}
|
|
id="grasscutterFullBuildBtn"
|
|
>
|
|
<Tr text="components.download" />
|
|
</BigButton>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="DownloadMenuSection" id="downloadMenuContainerGCFullQuest">
|
|
<div className="DownloadLabel" id="downloadMenuLabelGCFullQuest">
|
|
<Tr text={'downloads.grasscutter_fullquest'} />
|
|
<HelpButton contents="help.gc_fullbuild" />
|
|
</div>
|
|
<div className="DownloadValue" id="downloadMenuButtonGCFullQuest">
|
|
<BigButton
|
|
disabled={this.state.grasscutter_downloading}
|
|
onClick={this.downloadGrasscutterFullQuest}
|
|
id="grasscutterFullBuildBtn"
|
|
>
|
|
<Tr text="components.download" />
|
|
</BigButton>
|
|
</div>
|
|
</div>
|
|
<Divider />
|
|
|
|
<div className="HeaderText" id="downloadMenuIndividualHeader">
|
|
<Tr text="downloads.individual_header" />
|
|
</div>
|
|
<div className="DownloadMenuSection" id="downloadMenuContainerGCDev">
|
|
<div className="DownloadLabel" id="downloadMenuLabelGCDev">
|
|
<Tr
|
|
text={this.state.grasscutter_set ? 'downloads.grasscutter_latest' : 'downloads.grasscutter_latest_update'}
|
|
/>
|
|
<HelpButton contents="help.gc_dev_jar" />
|
|
</div>
|
|
<div className="DownloadValue" id="downloadMenuButtonGCDev">
|
|
<BigButton
|
|
disabled={this.state.grasscutter_downloading}
|
|
onClick={this.downloadGrasscutterLatest}
|
|
id="grasscutterLatestBtn"
|
|
>
|
|
<Tr text="components.download" />
|
|
</BigButton>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="DownloadMenuSection" id="downloadMenuContainerGCDevData">
|
|
<div className="DownloadLabel" id="downloadMenuLabelGCDevData">
|
|
<Tr
|
|
text={
|
|
this.state.grasscutter_set
|
|
? 'downloads.grasscutter_latest_data'
|
|
: 'downloads.grasscutter_latest_data_update'
|
|
}
|
|
/>
|
|
<HelpButton contents="help.gc_dev_data" />
|
|
</div>
|
|
<div className="DownloadValue" id="downloadMenuButtonGCDevData">
|
|
<BigButton
|
|
disabled={this.state.repo_downloading}
|
|
onClick={this.downloadGrasscutterStableRepo}
|
|
id="grasscutterDevRepo"
|
|
>
|
|
<Tr text="components.download" />
|
|
</BigButton>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="DownloadMenuSection" id="downloadMenuContainerResources">
|
|
<div className="DownloadLabel" id="downloadMenuLabelResources">
|
|
<Tr text="downloads.resources" />
|
|
<HelpButton contents="help.resources" />
|
|
</div>
|
|
<div className="DownloadValue" id="downloadMenuButtonResources">
|
|
<BigButton
|
|
disabled={this.state.resources_downloading || !this.state.grasscutter_set || this.state.resources_exist}
|
|
onClick={this.downloadResources}
|
|
id="resourcesBtn"
|
|
>
|
|
<Tr text="components.download" />
|
|
</BigButton>
|
|
</div>
|
|
</div>
|
|
|
|
{this.state.swag && (
|
|
<>
|
|
<Divider />
|
|
<div className="HeaderText" id="downloadMenuModsHeader">
|
|
<Tr text="downloads.mods_header" />
|
|
</div>
|
|
<div className="DownloadMenuSection" id="downloadMenuContainerMigoto">
|
|
<div className="DownloadLabel" id="downloadMenuLabelMigoto">
|
|
<Tr text={'downloads.migoto'} />
|
|
<HelpButton contents="help.migoto" />
|
|
</div>
|
|
<div className="DownloadValue" id="downloadMenuButtonMigoto">
|
|
<BigButton disabled={this.state.migoto_downloading} onClick={this.downloadMigoto} id="migotoBtn">
|
|
<Tr text="components.download" />
|
|
</BigButton>
|
|
</div>
|
|
</div>
|
|
</>
|
|
)}
|
|
</Menu>
|
|
)
|
|
}
|
|
}
|