diff --git a/.gitignore b/.gitignore index efd3369..a893a4f 100644 --- a/.gitignore +++ b/.gitignore @@ -126,3 +126,5 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* + +.pimi diff --git a/build/notarize.js b/build/notarize.js index f3a44b3..126b9bf 100644 --- a/build/notarize.js +++ b/build/notarize.js @@ -15,7 +15,7 @@ module.exports = async (context) => { return } - const appId = 'com.electron.app' + const appId = 'com.pimi-launcher.app' const { appOutDir } = context diff --git a/electron-builder.yml b/electron-builder.yml index 12f7a4b..ff9d327 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -1,4 +1,4 @@ -appId: com.electron.app +appId: com.pimi-launcher.app productName: pimi-launcher directories: buildResources: build diff --git a/electron.vite.config.js b/electron.vite.config.js index 2edac33..7119cf9 100644 --- a/electron.vite.config.js +++ b/electron.vite.config.js @@ -18,7 +18,7 @@ import { defineConfig, externalizeDepsPlugin } from 'electron-vite' import react from '@vitejs/plugin-react' import commonjsExternals from 'vite-plugin-commonjs-externals' -const externals = ['pimi-launcher-core'] +const externals = ['pimi-launcher-core', 'path'] export default defineConfig({ main: { diff --git a/package-lock.json b/package-lock.json index 80ec910..609d817 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,6 +20,7 @@ "devDependencies": { "@electron/notarize": "^1.2.3", "@vitejs/plugin-react": "^4.0.0", + "autoprefixer": "^10.4.14", "electron": "^24.4.1", "electron-builder": "^24.4.0", "electron-vite": "^1.0.23", @@ -27,6 +28,7 @@ "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.32.2", + "postcss": "^8.4.24", "prettier": "^2.8.8", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -2062,6 +2064,39 @@ "node": ">= 4.0.0" } }, + "node_modules/autoprefixer": { + "version": "10.4.14", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", + "integrity": "sha512-FQzyfOsTlwVzjHxKEqRIAdJx9niO6VCBCoEwax/VLSoQF29ggECcPuBqUMZ+u8jCZOPSy8b8/8KnuFbp0SaFZQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + ], + "dependencies": { + "browserslist": "^4.21.5", + "caniuse-lite": "^1.0.30001464", + "fraction.js": "^4.2.0", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.0", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, "node_modules/available-typed-arrays": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", @@ -4306,6 +4341,19 @@ "node": ">= 6" } }, + "node_modules/fraction.js": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz", + "integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==", + "dev": true, + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://www.patreon.com/infusion" + } + }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -6327,6 +6375,15 @@ "node": ">=0.10.0" } }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/normalize-url": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", diff --git a/package.json b/package.json index bbf0315..473e689 100644 --- a/package.json +++ b/package.json @@ -3,8 +3,8 @@ "version": "1.0.0", "description": "An Electron application with React", "main": "./out/main/index.js", - "author": "example.com", - "homepage": "https://www.electronjs.org", + "author": "artegoser", + "homepage": "https://github.com/artegoser/pimi-launcher", "scripts": { "format": "prettier --write .", "lint": "eslint . --ext .js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix", @@ -28,6 +28,7 @@ "devDependencies": { "@electron/notarize": "^1.2.3", "@vitejs/plugin-react": "^4.0.0", + "autoprefixer": "^10.4.14", "electron": "^24.4.1", "electron-builder": "^24.4.0", "electron-vite": "^1.0.23", @@ -35,6 +36,7 @@ "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-react": "^7.32.2", + "postcss": "^8.4.24", "prettier": "^2.8.8", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/postcss.config.js b/postcss.config.js new file mode 100644 index 0000000..85f717c --- /dev/null +++ b/postcss.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: { + tailwindcss: {}, + autoprefixer: {} + } +} diff --git a/src/main/index.js b/src/main/index.js index 162ff0c..1bad0b2 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -57,7 +57,7 @@ function createWindow() { // Some APIs can only be used after this event occurs. app.whenReady().then(() => { // Set app user model id for windows - electronApp.setAppUserModelId('com.electron') + electronApp.setAppUserModelId('com.pimi-launcher') // Default open or close DevTools by F12 in development // and ignore CommandOrControl + R in production. diff --git a/src/preload/index.js b/src/preload/index.js index 3fd54b1..a0636a8 100644 --- a/src/preload/index.js +++ b/src/preload/index.js @@ -13,7 +13,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -import { contextBridge } from 'electron' +import { contextBridge, nativeImage } from 'electron' import { electronAPI } from '@electron-toolkit/preload' // Custom APIs for renderer @@ -24,6 +24,7 @@ const api = {} // just add to the DOM global. if (process.contextIsolated) { try { + contextBridge.exposeInMainWorld('nativeImage', nativeImage) contextBridge.exposeInMainWorld('electron', electronAPI) contextBridge.exposeInMainWorld('api', api) } catch (error) { @@ -32,4 +33,5 @@ if (process.contextIsolated) { } else { window.electron = electronAPI window.api = api + window.nativeImage = nativeImage } diff --git a/src/renderer/src/assets/index.css b/src/renderer/src/assets/index.css index b5c61c9..b9458ed 100644 --- a/src/renderer/src/assets/index.css +++ b/src/renderer/src/assets/index.css @@ -1,3 +1,7 @@ @tailwind base; @tailwind components; @tailwind utilities; + +.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; +} diff --git a/src/renderer/src/components/utils.js b/src/renderer/src/components/utils.js new file mode 100644 index 0000000..25ff393 --- /dev/null +++ b/src/renderer/src/components/utils.js @@ -0,0 +1,36 @@ +import { Client, Authenticator } from 'pimi-launcher-core' + +async function launch(version, setProgress, setDownload, setGameStarted, setStarted) { + console.log(version) + const launcher = new Client() + + let opts = { + authorization: Authenticator.getAuth( + localStorage.getItem('name') || 'Steve', + localStorage.getItem('password') || '' + ), + root: './.pimi', + version: { + number: version.id, + type: version.type + }, + memory: { + max: '6G', + min: '4G' + } + } + + launcher.on('progress', (e) => setProgress(e)) + launcher.on('download', (e) => setDownload(e)) + launcher.on('debug', (e) => console.log(e)) + launcher.on('data', (e) => console.log(e)) + + launcher.on('arguments', () => setGameStarted(true)) + launcher.on('close', () => { + setGameStarted(false) + setStarted(false) + }) + await launcher.launch(opts) +} + +export { launch } diff --git a/src/renderer/src/pages/Main.jsx b/src/renderer/src/pages/Main.jsx index b0c431b..72bf37b 100644 --- a/src/renderer/src/pages/Main.jsx +++ b/src/renderer/src/pages/Main.jsx @@ -15,22 +15,80 @@ import { useState } from 'react' import { utils } from 'pimi-launcher-core' +import { launch } from '../components/utils' function Main() { const [versions, setVersions] = useState(false) + const [version, setVersion] = useState(false) + const [download, setDownload] = useState(false) + const [progress, setProgress] = useState(false) + const [started, setStarted] = useState(false) + const [gameStarted, setGameStarted] = useState(false) utils.getVersions().then((data) => { setVersions(data) + setVersion(data[0]) }) - if (versions) - return versions.map((version) => { - return ( -
- {version.id} + return ( + versions && ( +
+
+ { + localStorage.setItem('name', e.target.value) + }} + />
- ) - }) - else return <> +
+ +
+
+ { + launch(version, setProgress, setDownload, setGameStarted, setStarted) + setStarted(true) + }} + /> +
+ + {started && gameStarted && ( + <> +
Minecraft launches...
+ + )} + {started && !gameStarted && ( + <> +
Downloading{'.'.repeat(progress.task % 3)}
+
+ {download || 'please wait'} {`(${progress.type})` || ''} +
+
{((progress.task / progress.total) * 100 || 0).toFixed(2)}%
+ + )} +
+ ) + ) } export default Main diff --git a/tailwind.config.js b/tailwind.config.js index f901b85..1962e21 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -15,7 +15,7 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ['./src/**/*.{js,jsx,ts,tsx}'], + content: ['./src/renderer/src/**/*.{js,jsx,ts,tsx}'], theme: { extend: {} },