mirror of
https://github.com/Grasscutters/Cultivation.git
synced 2025-12-13 23:54:48 +01:00
Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -15,6 +15,21 @@ export default class MiniDialog extends React.Component<IProps, never> {
|
||||
super(props)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
document.addEventListener('mousedown', (evt) => {
|
||||
const tgt = evt.target as HTMLElement
|
||||
const isInside = tgt.closest('.MiniDialog') !== null
|
||||
|
||||
if (!isInside) {
|
||||
this.props.closeFn()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
document.removeEventListener('mousedown', this.props.closeFn)
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="MiniDialog">
|
||||
|
||||
@@ -59,8 +59,8 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
||||
ip: config.last_ip || '',
|
||||
port: config.last_port || '',
|
||||
ipPlaceholder: await translate('main.ip_placeholder'),
|
||||
portPlaceholder: await translate('main.port_placeholder'),
|
||||
portHelpText: await translate('main.port_help_text')
|
||||
portPlaceholder: await translate('help.port_placeholder'),
|
||||
portHelpText: await translate('help.port_help_text')
|
||||
})
|
||||
}
|
||||
|
||||
@@ -104,6 +104,23 @@ export default class ServerLaunchSection extends React.Component<IProps, IState>
|
||||
|
||||
// Connect to proxy
|
||||
await invoke('connect', { port: 8365, certificatePath: await dataDir() + '\\cultivation\\ca' })
|
||||
|
||||
// Open server as well if the options are set
|
||||
if (config.grasscutter_with_game) {
|
||||
let jarFolder = config.grasscutter_path
|
||||
|
||||
if (jarFolder.includes('/')) {
|
||||
jarFolder = jarFolder.substring(0, config.grasscutter_path.lastIndexOf('/'))
|
||||
} else {
|
||||
jarFolder = jarFolder.substring(0, config.grasscutter_path.lastIndexOf('\\'))
|
||||
}
|
||||
|
||||
await invoke('run_jar', {
|
||||
path: config.grasscutter_path,
|
||||
executeIn: jarFolder,
|
||||
javaPath: config.java_path || ''
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Launch the program
|
||||
|
||||
@@ -20,11 +20,14 @@
|
||||
|
||||
.HelpContents {
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.HelpContents .MiniDialog {
|
||||
bottom: 80%;
|
||||
left: 35%;
|
||||
width: 60%;
|
||||
height: 60%;
|
||||
position: absolute;
|
||||
|
||||
bottom: 40px;
|
||||
right: -450%;
|
||||
width: 200px;
|
||||
height: 120px;
|
||||
}
|
||||
@@ -24,4 +24,8 @@
|
||||
|
||||
.DownloadValue .BigButtonText {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.DownloadMenuSection .HelpButton img {
|
||||
filter: none;
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import Divider from './Divider'
|
||||
import { getConfigOption, setConfigOption } from '../../../utils/configuration'
|
||||
import { invoke } from '@tauri-apps/api'
|
||||
import { listen } from '@tauri-apps/api/event'
|
||||
import HelpButton from '../common/HelpButton'
|
||||
|
||||
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'
|
||||
@@ -73,7 +74,9 @@ export default class Downloads extends React.Component<IProps, IState> {
|
||||
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 !== '',
|
||||
@@ -149,6 +152,15 @@ export default class Downloads extends React.Component<IProps, IState> {
|
||||
async downloadResources() {
|
||||
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 + '\\', () => {
|
||||
// Rename folder to resources
|
||||
invoke('rename', {
|
||||
@@ -183,6 +195,9 @@ export default class Downloads extends React.Component<IProps, IState> {
|
||||
<Tr text={
|
||||
this.state.grasscutter_set ? 'downloads.grasscutter_stable' : 'downloads.grasscutter_stable_update'
|
||||
} />
|
||||
<HelpButton>
|
||||
<Tr text="help.gc_stable_jar" />
|
||||
</HelpButton>
|
||||
</div>
|
||||
<div className='DownloadValue'>
|
||||
<BigButton disabled={this.state.grasscutter_downloading} onClick={this.downloadGrasscutterStable} id="grasscutterStableBtn" >
|
||||
@@ -195,6 +210,9 @@ export default class Downloads extends React.Component<IProps, IState> {
|
||||
<Tr text={
|
||||
this.state.grasscutter_set ? 'downloads.grasscutter_latest' : 'downloads.grasscutter_latest_update'
|
||||
} />
|
||||
<HelpButton>
|
||||
<Tr text="help.gc_dev_jar" />
|
||||
</HelpButton>
|
||||
</div>
|
||||
<div className='DownloadValue'>
|
||||
<BigButton disabled={this.state.grasscutter_downloading} onClick={this.downloadGrasscutterLatest} id="grasscutterLatestBtn" >
|
||||
@@ -210,6 +228,9 @@ export default class Downloads extends React.Component<IProps, IState> {
|
||||
<Tr text={
|
||||
this.state.grasscutter_set ? 'downloads.grasscutter_stable_data' : 'downloads.grasscutter_stable_data_update'
|
||||
} />
|
||||
<HelpButton>
|
||||
<Tr text="help.gc_stable_data" />
|
||||
</HelpButton>
|
||||
</div>
|
||||
<div className='DownloadValue'>
|
||||
<BigButton disabled={this.state.repo_downloading} onClick={this.downloadGrasscutterStableRepo} id="grasscutterStableRepo" >
|
||||
@@ -222,6 +243,9 @@ export default class Downloads extends React.Component<IProps, IState> {
|
||||
<Tr text={
|
||||
this.state.grasscutter_set ? 'downloads.grasscutter_latest_data' : 'downloads.grasscutter_latest_data_update'
|
||||
} />
|
||||
<HelpButton>
|
||||
<Tr text="help.gc_dev_data" />
|
||||
</HelpButton>
|
||||
</div>
|
||||
<div className='DownloadValue'>
|
||||
<BigButton disabled={this.state.repo_downloading} onClick={this.downloadGrasscutterStableRepo} id="grasscutterDevRepo" >
|
||||
@@ -235,6 +259,9 @@ export default class Downloads extends React.Component<IProps, IState> {
|
||||
<div className='DownloadMenuSection'>
|
||||
<div className='DownloadLabel'>
|
||||
<Tr text="downloads.resources" />
|
||||
<HelpButton>
|
||||
<Tr text="help.resources" />
|
||||
</HelpButton>
|
||||
</div>
|
||||
<div className='DownloadValue'>
|
||||
<BigButton disabled={this.state.resources_downloading || !this.state.grasscutter_set || this.state.resources_exist} onClick={this.downloadResources} id="resourcesBtn" >
|
||||
|
||||
@@ -7,6 +7,7 @@ export default class DownloadHandler {
|
||||
path: string,
|
||||
progress: number,
|
||||
total: number,
|
||||
total_downloaded: number,
|
||||
status: string,
|
||||
startTime: number,
|
||||
error?: string,
|
||||
@@ -24,16 +25,25 @@ export default class DownloadHandler {
|
||||
downloaded: string,
|
||||
total: string,
|
||||
path: string,
|
||||
total_downloaded: string,
|
||||
} = payload
|
||||
|
||||
const index = this.downloads.findIndex(download => download.path === obj.path)
|
||||
this.downloads[index].progress = parseInt(obj.downloaded, 10)
|
||||
this.downloads[index].total = parseInt(obj.total, 10)
|
||||
this.downloads[index].total_downloaded = parseInt(obj.total_downloaded, 10)
|
||||
|
||||
// Set download speed based on startTime
|
||||
const now = Date.now()
|
||||
const timeDiff = now - this.downloads[index].startTime
|
||||
const speed = (this.downloads[index].progress / timeDiff) * 1000
|
||||
let speed = (this.downloads[index].progress / timeDiff) * 1000
|
||||
|
||||
if (this.downloads[index].total === 0) {
|
||||
// If our total is 0, then we are downloading a file without a size
|
||||
// Calculate the average speed based total_downloaded and startTme
|
||||
speed = (this.downloads[index].total_downloaded / timeDiff) * 1000
|
||||
}
|
||||
|
||||
this.downloads[index].speed = byteToString(speed) + '/s'
|
||||
})
|
||||
|
||||
@@ -104,6 +114,7 @@ export default class DownloadHandler {
|
||||
path,
|
||||
progress: 0,
|
||||
total: 0,
|
||||
total_downloaded: 0,
|
||||
status: 'downloading',
|
||||
startTime: Date.now(),
|
||||
onFinish,
|
||||
@@ -134,7 +145,7 @@ export default class DownloadHandler {
|
||||
getTotalAverage() {
|
||||
const files = this.downloads.filter(d => d.status === 'downloading')
|
||||
const total = files.reduce((acc, d) => acc + d.total, 0)
|
||||
const progress = files.reduce((acc, d) => acc + d.progress, 0)
|
||||
const progress = files.reduce((acc, d) => d.progress !== 0 ? acc + d.progress : acc + d.total_downloaded, 0)
|
||||
let speedStr = '0 B/s'
|
||||
|
||||
// Get download speed based on startTimes
|
||||
|
||||
@@ -39,7 +39,7 @@ const defaultTheme = {
|
||||
export async function getThemeList() {
|
||||
// Do some invoke to backend to get the theme list
|
||||
const themes = await invoke('get_theme_list', {
|
||||
data_dir: `${await dataDir()}/cultivation`
|
||||
dataDir: `${await dataDir()}/cultivation`
|
||||
}) as BackendThemeList[]
|
||||
const list: ThemeList[] = [
|
||||
// ALWAYS include default theme
|
||||
|
||||
Reference in New Issue
Block a user