add: auto update launcher
This commit is contained in:
1
.cursorignore
Normal file
1
.cursorignore
Normal file
@ -0,0 +1 @@
|
|||||||
|
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
|
@ -36,9 +36,15 @@ const configuration: webpack.Configuration = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
optimization: {
|
optimization: {
|
||||||
|
minimize: false,
|
||||||
minimizer: [
|
minimizer: [
|
||||||
new TerserPlugin({
|
new TerserPlugin({
|
||||||
parallel: true,
|
parallel: true,
|
||||||
|
terserOptions: {
|
||||||
|
ecma: 2020,
|
||||||
|
keep_classnames: true,
|
||||||
|
keep_fnames: true,
|
||||||
|
},
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -27,3 +27,4 @@ npm-debug.log.*
|
|||||||
*.css.d.ts
|
*.css.d.ts
|
||||||
*.sass.d.ts
|
*.sass.d.ts
|
||||||
*.scss.d.ts
|
*.scss.d.ts
|
||||||
|
.env
|
||||||
|
18
package.json
18
package.json
@ -18,7 +18,7 @@
|
|||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git+https://github.com/electron-react-boilerplate/electron-react-boilerplate.git"
|
"url": "git+https://git.popa-popa.ru/DIKER/popa-launcher.git"
|
||||||
},
|
},
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": {
|
"author": {
|
||||||
@ -42,14 +42,15 @@
|
|||||||
"postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && npm run build:dll",
|
"postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && npm run build:dll",
|
||||||
"lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx",
|
"lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx",
|
||||||
"lint:fix": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx --fix",
|
"lint:fix": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx --fix",
|
||||||
"package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never && npm run build:dll",
|
"package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish always && npm run build:dll",
|
||||||
"rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app",
|
"rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app",
|
||||||
"prestart": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true NODE_OPTIONS=\"-r ts-node/register --no-warnings\" webpack --config ./.erb/configs/webpack.config.main.dev.ts",
|
"prestart": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true NODE_OPTIONS=\"-r ts-node/register --no-warnings\" webpack --config ./.erb/configs/webpack.config.main.dev.ts",
|
||||||
"start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run prestart && npm run start:renderer",
|
"start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run prestart && npm run start:renderer",
|
||||||
"start:main": "concurrently -k -P \"cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --watch --config ./.erb/configs/webpack.config.main.dev.ts\" \"electronmon . -- {@}\" --",
|
"start:main": "concurrently -k -P \"cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --watch --config ./.erb/configs/webpack.config.main.dev.ts\" \"electronmon . -- {@}\" --",
|
||||||
"start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true NODE_OPTIONS=\"-r ts-node/register --no-warnings\" webpack --config ./.erb/configs/webpack.config.preload.dev.ts",
|
"start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true NODE_OPTIONS=\"-r ts-node/register --no-warnings\" webpack --config ./.erb/configs/webpack.config.preload.dev.ts",
|
||||||
"start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true NODE_OPTIONS=\"-r ts-node/register --no-warnings\" webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts",
|
"start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true NODE_OPTIONS=\"-r ts-node/register --no-warnings\" webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts",
|
||||||
"test": "jest"
|
"test": "jest",
|
||||||
|
"publish-debug": "electron-builder build --publish always"
|
||||||
},
|
},
|
||||||
"browserslist": [
|
"browserslist": [
|
||||||
"extends browserslist-config-erb"
|
"extends browserslist-config-erb"
|
||||||
@ -190,7 +191,7 @@
|
|||||||
"webpack-merge": "^6.0.1"
|
"webpack-merge": "^6.0.1"
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"productName": "ElectronReact",
|
"productName": "popa-launcher",
|
||||||
"appId": "org.erb.ElectronReact",
|
"appId": "org.erb.ElectronReact",
|
||||||
"asar": true,
|
"asar": true,
|
||||||
"afterSign": ".erb/scripts/notarize.js",
|
"afterSign": ".erb/scripts/notarize.js",
|
||||||
@ -249,9 +250,12 @@
|
|||||||
"./assets/**"
|
"./assets/**"
|
||||||
],
|
],
|
||||||
"publish": {
|
"publish": {
|
||||||
"provider": "github",
|
"provider": "generic",
|
||||||
"owner": "electron-react-boilerplate",
|
"url": "https://git.popa-popa.ru/DIKER/popa-launcher/releases/download/v${version}",
|
||||||
"repo": "electron-react-boilerplate"
|
"channel": "latest",
|
||||||
|
"requestHeaders": {
|
||||||
|
"Authorization": "token ${env.GH_TOKEN}"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"collective": {
|
"collective": {
|
||||||
|
8
release/app/package-lock.json
generated
8
release/app/package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "electron-react-boilerplate",
|
"name": "popa-launcher",
|
||||||
"version": "4.6.0",
|
"version": "1.0.0",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "electron-react-boilerplate",
|
"name": "popa-launcher",
|
||||||
"version": "4.6.0",
|
"version": "1.0.0",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "electron-react-boilerplate",
|
"name": "popa-launcher",
|
||||||
"version": "4.6.0",
|
"version": "1.0.0",
|
||||||
"description": "A foundation for scalable desktop apps",
|
"description": "Popa Launcher",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Electron React Boilerplate Maintainers",
|
"name": "DIKER",
|
||||||
"email": "electronreactboilerplate@gmail.com",
|
"email": "diker0k@gmail.com",
|
||||||
"url": "https://github.com/electron-react-boilerplate"
|
"url": "https://github.com/DIKER0K"
|
||||||
},
|
},
|
||||||
"main": "./dist/main/main.js",
|
"main": "./dist/main/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
@ -25,7 +25,36 @@ class AppUpdater {
|
|||||||
constructor() {
|
constructor() {
|
||||||
log.transports.file.level = 'info';
|
log.transports.file.level = 'info';
|
||||||
autoUpdater.logger = log;
|
autoUpdater.logger = log;
|
||||||
|
|
||||||
|
const server = 'https://git.popa-popa.ru/DIKER/popa-launcher';
|
||||||
|
|
||||||
|
// Для Gitea нужно указать конкретную структуру URL
|
||||||
|
// Обратите внимание на использование пути /download/
|
||||||
|
autoUpdater.setFeedURL({
|
||||||
|
provider: 'generic',
|
||||||
|
url: `${server}/releases/download/latest`, // Укажите конкретную версию
|
||||||
|
channel: 'latest',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Проверка обновлений
|
||||||
autoUpdater.checkForUpdatesAndNotify();
|
autoUpdater.checkForUpdatesAndNotify();
|
||||||
|
|
||||||
|
// Периодическая проверка обновлений (каждый час)
|
||||||
|
setInterval(
|
||||||
|
() => {
|
||||||
|
autoUpdater.checkForUpdatesAndNotify();
|
||||||
|
},
|
||||||
|
60 * 60 * 1000,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Обработчики событий обновления
|
||||||
|
autoUpdater.on('update-downloaded', () => {
|
||||||
|
log.info('Обновление загружено. Будет установлено при перезапуске.');
|
||||||
|
// Можно отправить событие в renderer для уведомления пользователя
|
||||||
|
if (mainWindow) {
|
||||||
|
mainWindow.webContents.send('update-available');
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,3 +189,7 @@ app
|
|||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(console.log);
|
.catch(console.log);
|
||||||
|
|
||||||
|
ipcMain.handle('install-update', () => {
|
||||||
|
autoUpdater.quitAndInstall();
|
||||||
|
});
|
||||||
|
@ -9,7 +9,9 @@ export type Channels =
|
|||||||
| 'close-app'
|
| 'close-app'
|
||||||
| 'minimize-app'
|
| 'minimize-app'
|
||||||
| 'save-pack-config'
|
| 'save-pack-config'
|
||||||
| 'load-pack-config';
|
| 'load-pack-config'
|
||||||
|
| 'update-available'
|
||||||
|
| 'install-update';
|
||||||
|
|
||||||
const electronHandler = {
|
const electronHandler = {
|
||||||
ipcRenderer: {
|
ipcRenderer: {
|
||||||
@ -28,7 +30,7 @@ const electronHandler = {
|
|||||||
once(channel: Channels, func: (...args: unknown[]) => void) {
|
once(channel: Channels, func: (...args: unknown[]) => void) {
|
||||||
ipcRenderer.once(channel, (_event, ...args) => func(...args));
|
ipcRenderer.once(channel, (_event, ...args) => func(...args));
|
||||||
},
|
},
|
||||||
invoke(channel: string, ...args: unknown[]) {
|
invoke(channel: Channels, ...args: unknown[]): Promise<any> {
|
||||||
return ipcRenderer.invoke(channel, ...args);
|
return ipcRenderer.invoke(channel, ...args);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -11,6 +11,7 @@ import './App.css';
|
|||||||
import TopBar from './components/TopBar';
|
import TopBar from './components/TopBar';
|
||||||
import { Box } from '@mui/material';
|
import { Box } from '@mui/material';
|
||||||
import MinecraftBackround from './components/MinecraftBackround';
|
import MinecraftBackround from './components/MinecraftBackround';
|
||||||
|
import { Notifier } from './components/Notifier';
|
||||||
|
|
||||||
// Переместите launchOptions сюда, вне компонентов
|
// Переместите launchOptions сюда, вне компонентов
|
||||||
const launchOptions = {
|
const launchOptions = {
|
||||||
@ -94,6 +95,7 @@ const App = () => {
|
|||||||
>
|
>
|
||||||
<MinecraftBackround />
|
<MinecraftBackround />
|
||||||
<TopBar onRegister={handleRegister} />
|
<TopBar onRegister={handleRegister} />
|
||||||
|
<Notifier />
|
||||||
<Routes>
|
<Routes>
|
||||||
<Route path="/login" element={<Login />} />
|
<Route path="/login" element={<Login />} />
|
||||||
<Route
|
<Route
|
||||||
|
63
src/renderer/components/Notifier.tsx
Normal file
63
src/renderer/components/Notifier.tsx
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
import { Alert, Box, Snackbar, Button } from '@mui/material';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
export const Notifier = () => {
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
const [message, setMessage] = useState('');
|
||||||
|
const [severity, setSeverity] = useState<
|
||||||
|
'error' | 'warning' | 'info' | 'success'
|
||||||
|
>('info');
|
||||||
|
const [hasUpdateAvailable, setHasUpdateAvailable] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
// Слушаем событие о наличии обновления
|
||||||
|
window.electron.ipcRenderer.on('update-available', () => {
|
||||||
|
setMessage('Доступно новое обновление');
|
||||||
|
setSeverity('info');
|
||||||
|
setHasUpdateAvailable(true);
|
||||||
|
setOpen(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// Отписываемся от события при размонтировании
|
||||||
|
window.electron.ipcRenderer.removeAllListeners('update-available');
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleClose = () => {
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleUpdate = () => {
|
||||||
|
window.electron.ipcRenderer.invoke('install-update');
|
||||||
|
setOpen(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box>
|
||||||
|
<Snackbar
|
||||||
|
open={open}
|
||||||
|
autoHideDuration={hasUpdateAvailable ? null : 6000}
|
||||||
|
onClose={handleClose}
|
||||||
|
>
|
||||||
|
<Alert
|
||||||
|
severity={severity}
|
||||||
|
action={
|
||||||
|
hasUpdateAvailable && (
|
||||||
|
<>
|
||||||
|
<Button color="primary" size="small" onClick={handleUpdate}>
|
||||||
|
Обновить сейчас
|
||||||
|
</Button>
|
||||||
|
<Button color="secondary" size="small" onClick={handleClose}>
|
||||||
|
Позже
|
||||||
|
</Button>
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{message}
|
||||||
|
</Alert>
|
||||||
|
</Snackbar>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
@ -6,7 +6,7 @@
|
|||||||
http-equiv="Content-Security-Policy"
|
http-equiv="Content-Security-Policy"
|
||||||
content="script-src 'self' 'unsafe-inline'"
|
content="script-src 'self' 'unsafe-inline'"
|
||||||
/>
|
/>
|
||||||
<title>Hello Electron React!</title>
|
<title>popa-launcher</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
|
Reference in New Issue
Block a user