mirror of
https://github.com/artegoser/pimi-launcher.git
synced 2024-11-21 19:06:21 +03:00
feat: terminal
This commit is contained in:
parent
bff72b3ff8
commit
4b332b8aa2
7 changed files with 136 additions and 77 deletions
|
@ -18,7 +18,7 @@ import { defineConfig, externalizeDepsPlugin } from 'electron-vite'
|
||||||
import react from '@vitejs/plugin-react'
|
import react from '@vitejs/plugin-react'
|
||||||
import commonjsExternals from 'vite-plugin-commonjs-externals'
|
import commonjsExternals from 'vite-plugin-commonjs-externals'
|
||||||
|
|
||||||
const externals = ['pimi-launcher-core', 'path', 'process', 'fs']
|
const externals = ['pimi-launcher-core', 'path', 'process', 'fs', 'console']
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
main: {
|
main: {
|
||||||
|
|
14
package-lock.json
generated
14
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"name": "pimi-launcher",
|
"name": "pimi-launcher",
|
||||||
"version": "1.1.0-alpha",
|
"version": "1.2.0-alpha",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "pimi-launcher",
|
"name": "pimi-launcher",
|
||||||
"version": "1.1.0-alpha",
|
"version": "1.2.0-alpha",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron-toolkit/preload": "^2.0.0",
|
"@electron-toolkit/preload": "^2.0.0",
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
"pimi-launcher-core": "^1.1.1",
|
"pimi-launcher-core": "^1.1.1",
|
||||||
"react-router-dom": "^6.13.0",
|
"react-router-dom": "^6.13.0",
|
||||||
"react-select": "^5.7.3",
|
"react-select": "^5.7.3",
|
||||||
|
"react-terminal-ui": "^1.0.5",
|
||||||
"vite-plugin-commonjs-externals": "^0.1.3"
|
"vite-plugin-commonjs-externals": "^0.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -7530,6 +7531,15 @@
|
||||||
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-terminal-ui": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-terminal-ui/-/react-terminal-ui-1.0.5.tgz",
|
||||||
|
"integrity": "sha512-yR19ej58dwU3koLiTR0m0nLbqJZoOyeThGWg1B3VrwUs+PLraqjP2C4AkRgiGNUwWMn4u6T0djY5DZXq0Zlvjg==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": ">16.13.0",
|
||||||
|
"react-dom": ">16.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-transition-group": {
|
"node_modules/react-transition-group": {
|
||||||
"version": "4.4.5",
|
"version": "4.4.5",
|
||||||
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "pimi-launcher",
|
"name": "pimi-launcher",
|
||||||
"version": "1.1.1-alpha",
|
"version": "1.2.0-alpha",
|
||||||
"description": "Modern Minecraft Launcher",
|
"description": "Modern Minecraft Launcher",
|
||||||
"main": "./out/main/index.js",
|
"main": "./out/main/index.js",
|
||||||
"author": "artegoser",
|
"author": "artegoser",
|
||||||
|
@ -27,6 +27,7 @@
|
||||||
"pimi-launcher-core": "^1.1.1",
|
"pimi-launcher-core": "^1.1.1",
|
||||||
"react-router-dom": "^6.13.0",
|
"react-router-dom": "^6.13.0",
|
||||||
"react-select": "^5.7.3",
|
"react-select": "^5.7.3",
|
||||||
|
"react-terminal-ui": "^1.0.5",
|
||||||
"vite-plugin-commonjs-externals": "^0.1.3"
|
"vite-plugin-commonjs-externals": "^0.1.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|
|
@ -5,3 +5,7 @@
|
||||||
.inputs {
|
.inputs {
|
||||||
@apply bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500;
|
@apply bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::-webkit-scrollbar {
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
|
21
src/renderer/src/components/MinecraftTerminal.jsx
Normal file
21
src/renderer/src/components/MinecraftTerminal.jsx
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
import Terminal, { ColorMode, TerminalOutput } from 'react-terminal-ui'
|
||||||
|
import PropTypes from 'prop-types'
|
||||||
|
|
||||||
|
function MinecraftTerminal({ lines, height = '300px' }) {
|
||||||
|
const terminalLineData = lines.map((line, index) => (
|
||||||
|
<TerminalOutput key={index}>{line}</TerminalOutput>
|
||||||
|
))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Terminal name="Minecraft Console" height={height} colorMode={ColorMode.Light}>
|
||||||
|
{terminalLineData}
|
||||||
|
</Terminal>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
MinecraftTerminal.propTypes = {
|
||||||
|
lines: PropTypes.arrayOf(PropTypes.string),
|
||||||
|
height: PropTypes.string
|
||||||
|
}
|
||||||
|
|
||||||
|
export default MinecraftTerminal
|
|
@ -1,7 +1,14 @@
|
||||||
import { Client, Authenticator } from 'pimi-launcher-core'
|
import { Client, Authenticator } from 'pimi-launcher-core'
|
||||||
|
async function launch(
|
||||||
async function launch(version, setProgress, setDownload, setGameStarted, setStarted) {
|
version,
|
||||||
|
setProgress,
|
||||||
|
setDownload,
|
||||||
|
setGameStarted,
|
||||||
|
setStarted,
|
||||||
|
setTerminalLines
|
||||||
|
) {
|
||||||
const launcher = new Client()
|
const launcher = new Client()
|
||||||
|
let terminalLines = []
|
||||||
|
|
||||||
let opts = {
|
let opts = {
|
||||||
authorization: Authenticator.getAuth(
|
authorization: Authenticator.getAuth(
|
||||||
|
@ -23,13 +30,20 @@ async function launch(version, setProgress, setDownload, setGameStarted, setStar
|
||||||
|
|
||||||
launcher.on('progress', (e) => setProgress(e))
|
launcher.on('progress', (e) => setProgress(e))
|
||||||
launcher.on('download', (e) => setDownload(e))
|
launcher.on('download', (e) => setDownload(e))
|
||||||
launcher.on('debug', (e) => console.log(e))
|
launcher.on('debug', (e) => {
|
||||||
launcher.on('data', (e) => console.log(e))
|
terminalLines = terminalLines.concat(e)
|
||||||
|
setTerminalLines(terminalLines)
|
||||||
|
})
|
||||||
|
launcher.on('data', (e) => {
|
||||||
|
terminalLines = terminalLines.concat(e)
|
||||||
|
setTerminalLines(terminalLines)
|
||||||
|
})
|
||||||
|
|
||||||
launcher.on('arguments', () => setGameStarted(true))
|
launcher.on('arguments', () => setGameStarted(true))
|
||||||
launcher.on('close', () => {
|
launcher.on('close', () => {
|
||||||
setGameStarted(false)
|
setGameStarted(false)
|
||||||
setStarted(false)
|
setStarted(false)
|
||||||
|
setTerminalLines([])
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { launch } from '../components/utils'
|
||||||
import Select from 'react-select'
|
import Select from 'react-select'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import MinecraftTerminal from '../components/MinecraftTerminal'
|
||||||
function Main() {
|
function Main() {
|
||||||
const [versions, setVersions] = useState(false)
|
const [versions, setVersions] = useState(false)
|
||||||
const [version, setVersion] = useState(false)
|
const [version, setVersion] = useState(false)
|
||||||
|
@ -27,6 +28,7 @@ function Main() {
|
||||||
const [started, setStarted] = useState(false)
|
const [started, setStarted] = useState(false)
|
||||||
const [gameStarted, setGameStarted] = useState(false)
|
const [gameStarted, setGameStarted] = useState(false)
|
||||||
const [installed_versions, setInstalledVersions] = useState(false)
|
const [installed_versions, setInstalledVersions] = useState(false)
|
||||||
|
const [terminalLines, setTerminalLines] = useState([])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!versions) {
|
if (!versions) {
|
||||||
|
@ -38,79 +40,86 @@ function Main() {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
console.log('hi')
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
versions && (
|
versions && (
|
||||||
<div className="grid grid-cols-3 gap-4 m-5">
|
<>
|
||||||
<div>
|
<div className="grid grid-cols-3 gap-4 m-5">
|
||||||
<input
|
<div>
|
||||||
type="text"
|
<input
|
||||||
id="name"
|
type="text"
|
||||||
className="inputs"
|
id="name"
|
||||||
placeholder="Your name"
|
className="inputs"
|
||||||
defaultValue={localStorage.getItem('name') || 'Steve'}
|
placeholder="Your name"
|
||||||
onChange={(e) => {
|
defaultValue={localStorage.getItem('name') || 'Steve'}
|
||||||
localStorage.setItem('name', e.target.value)
|
onChange={(e) => {
|
||||||
}}
|
localStorage.setItem('name', e.target.value)
|
||||||
/>
|
}}
|
||||||
</div>
|
/>
|
||||||
<div>
|
</div>
|
||||||
<Select
|
<div>
|
||||||
onChange={(e) => {
|
<Select
|
||||||
setVersion(versions[e.value])
|
onChange={(e) => {
|
||||||
}}
|
setVersion(versions[e.value])
|
||||||
defaultValue={{ value: versions[0], label: versions[0].id }}
|
}}
|
||||||
options={versions.map((version, index) => {
|
defaultValue={{ value: versions[0], label: versions[0].id }}
|
||||||
return {
|
options={versions.map((version, index) => {
|
||||||
value: index,
|
return {
|
||||||
label: version.id,
|
value: index,
|
||||||
type: version.type,
|
label: version.id,
|
||||||
installed: installed_versions?.includes(version.id)
|
type: version.type,
|
||||||
}
|
installed: installed_versions?.includes(version.id)
|
||||||
})}
|
}
|
||||||
styles={{
|
})}
|
||||||
control: (styles) => ({
|
styles={{
|
||||||
...styles,
|
control: (styles) => ({
|
||||||
backgroundColor: 'white'
|
...styles,
|
||||||
}),
|
backgroundColor: 'white'
|
||||||
option: (styles, { data, isFocused }) => ({
|
}),
|
||||||
...styles,
|
option: (styles, { data, isFocused }) => ({
|
||||||
backgroundColor: isFocused ? '#c9d2e7' : data.installed ? '#cccccc' : 'white'
|
...styles,
|
||||||
})
|
backgroundColor: isFocused ? '#c9d2e7' : data.installed ? '#cccccc' : 'white'
|
||||||
}}
|
})
|
||||||
/>
|
}}
|
||||||
</div>
|
/>
|
||||||
<div>
|
</div>
|
||||||
<input
|
<div>
|
||||||
type="button"
|
<input
|
||||||
value="Start"
|
type="button"
|
||||||
className="inputs"
|
value="Start"
|
||||||
onClick={() => {
|
className="inputs"
|
||||||
launch(version, setProgress, setDownload, setGameStarted, setStarted)
|
onClick={() => {
|
||||||
setStarted(true)
|
launch(
|
||||||
}}
|
version,
|
||||||
disabled={started}
|
setProgress,
|
||||||
/>
|
setDownload,
|
||||||
</div>
|
setGameStarted,
|
||||||
|
setStarted,
|
||||||
|
setTerminalLines
|
||||||
|
)
|
||||||
|
setStarted(true)
|
||||||
|
}}
|
||||||
|
disabled={started}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{started && gameStarted && (
|
{started && !gameStarted && (
|
||||||
<>
|
<>
|
||||||
<div className="text-2xl font-bold">Minecraft launches...</div>
|
<div className="text-2xl font-bold">Downloading{'.'.repeat(progress.task % 3)}</div>
|
||||||
</>
|
<div className="break-words text-2xl font-bold">
|
||||||
|
{download || 'please wait'} {`(${progress.type})` || ''}
|
||||||
|
</div>
|
||||||
|
<div className="text-2xl font-bold">
|
||||||
|
{((progress.task / progress.total) * 100 || 0).toFixed(2)}%
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
{started && (
|
||||||
|
<div className="m-5">
|
||||||
|
<MinecraftTerminal lines={terminalLines} />
|
||||||
|
</div>
|
||||||
)}
|
)}
|
||||||
{started && !gameStarted && (
|
</>
|
||||||
<>
|
|
||||||
<div className="text-2xl font-bold">Downloading{'.'.repeat(progress.task % 3)}</div>
|
|
||||||
<div className="break-words text-2xl font-bold">
|
|
||||||
{download || 'please wait'} {`(${progress.type})` || ''}
|
|
||||||
</div>
|
|
||||||
<div className="text-2xl font-bold">
|
|
||||||
{((progress.task / progress.total) * 100 || 0).toFixed(2)}%
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue