From 76917e3f90264fcc4806ec3ef1d2ea62f57fefdb Mon Sep 17 00:00:00 2001 From: DIKER0K Date: Mon, 7 Jul 2025 04:41:17 +0500 Subject: [PATCH] add: background, custom topbar --- assets/images/heart.svg | 18 +++ package-lock.json | 27 +++++ package.json | 1 + src/main/main.ts | 11 ++ src/main/minecraft-launcher.ts | 4 - src/main/preload.ts | 4 +- src/renderer/App.css | 2 +- src/renderer/App.tsx | 44 +++++-- .../components/MinecraftBackround.tsx | 73 ++++++++++++ src/renderer/components/TopBar.tsx | 109 ++++++++++++++++++ src/renderer/pages/LaunchPage.tsx | 26 +++-- 11 files changed, 291 insertions(+), 28 deletions(-) create mode 100644 assets/images/heart.svg create mode 100644 src/renderer/components/MinecraftBackround.tsx create mode 100644 src/renderer/components/TopBar.tsx diff --git a/assets/images/heart.svg b/assets/images/heart.svg new file mode 100644 index 0000000..0262800 --- /dev/null +++ b/assets/images/heart.svg @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/package-lock.json b/package-lock.json index 32ae3bd..bc047c8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@electron/notarize": "^3.0.0", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.2.0", "@mui/material": "^7.2.0", "@xmcl/core": "^2.14.1", "@xmcl/installer": "^6.1.0", @@ -3638,6 +3639,32 @@ "url": "https://opencollective.com/mui-org" } }, + "node_modules/@mui/icons-material": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-7.2.0.tgz", + "integrity": "sha512-gRCspp3pfjHQyTmSOmYw7kUQTd9Udpdan4R8EnZvqPeoAtHnPzkvjBrBqzKaoAbbBp5bGF7BcD18zZJh4nwu0A==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.27.6" + }, + "engines": { + "node": ">=14.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mui-org" + }, + "peerDependencies": { + "@mui/material": "^7.2.0", + "@types/react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, "node_modules/@mui/material": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@mui/material/-/material-7.2.0.tgz", diff --git a/package.json b/package.json index c746388..d339171 100644 --- a/package.json +++ b/package.json @@ -104,6 +104,7 @@ "@electron/notarize": "^3.0.0", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.1", + "@mui/icons-material": "^7.2.0", "@mui/material": "^7.2.0", "@xmcl/core": "^2.14.1", "@xmcl/installer": "^6.1.0", diff --git a/src/main/main.ts b/src/main/main.ts index 2e56464..37490c5 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -48,6 +48,16 @@ if (isDebug) { require('electron-debug').default(); } +ipcMain.handle('close-app', () => { + app.quit(); + return true; +}); + +ipcMain.handle('minimize-app', () => { + mainWindow?.minimize(); + return true; +}); + const installExtensions = async () => { const installer = require('electron-devtools-installer'); const forceDownload = !!process.env.UPGRADE_EXTENSIONS; @@ -79,6 +89,7 @@ const createWindow = async () => { width: 1024, height: 728, autoHideMenuBar: true, + frame: false, icon: getAssetPath('icon.png'), webPreferences: { webSecurity: false, diff --git a/src/main/minecraft-launcher.ts b/src/main/minecraft-launcher.ts index ed2a53d..b043b6f 100644 --- a/src/main/minecraft-launcher.ts +++ b/src/main/minecraft-launcher.ts @@ -772,9 +772,6 @@ export function initServerStatusHandler() { try { // Формируем адрес с портом, если указан const serverAddress = port ? `${host}:${port}` : host; - console.log( - `Запрос статуса сервера: ${MCSTATUS_API_URL}${serverAddress}`, - ); // Делаем запрос к API mcstatus.io const response = await fetch(`${MCSTATUS_API_URL}${serverAddress}`); @@ -786,7 +783,6 @@ export function initServerStatusHandler() { } const data = await response.json(); - console.log('Получен ответ от API:', data); if (data.online) { return { diff --git a/src/main/preload.ts b/src/main/preload.ts index 8541aae..92a8665 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -5,7 +5,9 @@ export type Channels = | 'download-progress' | 'launch-minecraft' | 'installation-status' - | 'get-server-status'; + | 'get-server-status' + | 'close-app' + | 'minimize-app'; const electronHandler = { ipcRenderer: { diff --git a/src/renderer/App.css b/src/renderer/App.css index 735630a..16d87e1 100644 --- a/src/renderer/App.css +++ b/src/renderer/App.css @@ -16,7 +16,7 @@ body { position: relative; color: white; height: 100vh; - background: linear-gradient(200.96deg, #000000, #3b4187); + background: linear-gradient(242.94deg, #000000 39.07%, #3b4187 184.73%); font-family: 'Benzin-Bold' !important; overflow-y: hidden; display: flex; diff --git a/src/renderer/App.tsx b/src/renderer/App.tsx index a0857c3..38eaa14 100644 --- a/src/renderer/App.tsx +++ b/src/renderer/App.tsx @@ -8,6 +8,9 @@ import Login from './pages/Login'; import LaunchPage from './pages/LaunchPage'; import { ReactNode, useEffect, useState } from 'react'; import './App.css'; +import TopBar from './components/TopBar'; +import { Box } from '@mui/material'; +import MinecraftBackround from './components/MinecraftBackround'; // Переместите launchOptions сюда, вне компонентов const launchOptions = { @@ -71,19 +74,38 @@ const AuthCheck = ({ children }: { children: ReactNode }) => { }; const App = () => { + // Просто используйте window.open без useNavigate + const handleRegister = () => { + window.open('https://account.ely.by/register', '_blank'); + }; + return ( - - } /> - - - - } - /> - + + + + + } /> + + + + } + /> + + ); }; diff --git a/src/renderer/components/MinecraftBackround.tsx b/src/renderer/components/MinecraftBackround.tsx new file mode 100644 index 0000000..eba2d4c --- /dev/null +++ b/src/renderer/components/MinecraftBackround.tsx @@ -0,0 +1,73 @@ +import { Box } from '@mui/material'; +import heart from '../../../assets/images/heart.svg'; + +export default function MinecraftBackround() { + return ( + + + + + + + + + + + + + ); +} diff --git a/src/renderer/components/TopBar.tsx b/src/renderer/components/TopBar.tsx new file mode 100644 index 0000000..fb2e8e3 --- /dev/null +++ b/src/renderer/components/TopBar.tsx @@ -0,0 +1,109 @@ +import { Box, Button, Typography } from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; +import MinimizeIcon from '@mui/icons-material/Minimize'; +import { useLocation } from 'react-router-dom'; + +declare global { + interface Window { + electron: { + ipcRenderer: { + invoke(channel: string, ...args: unknown[]): Promise; + on(channel: string, func: (...args: unknown[]) => void): void; + removeAllListeners(channel: string): void; + }; + }; + } +} + +// Определяем пропсы +interface TopBarProps { + onRegister?: () => void; // Опционально, если нужен обработчик регистрации +} + +export default function TopBar({ onRegister }: TopBarProps) { + // Получаем текущий путь + const location = useLocation(); + const isLoginPage = location.pathname === '/login'; + + return ( + + {/* Правая часть со всеми кнопками */} + + {/* Кнопка регистрации, если на странице логина */} + {isLoginPage && ( + + )} + + {/* Кнопки управления окном */} + + + + + ); +} diff --git a/src/renderer/pages/LaunchPage.tsx b/src/renderer/pages/LaunchPage.tsx index 763c6a2..9e3733a 100644 --- a/src/renderer/pages/LaunchPage.tsx +++ b/src/renderer/pages/LaunchPage.tsx @@ -61,21 +61,25 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => { setDownloadProgress(progress); setBuffer(Math.min(progress + 10, 100)); }; + + const statusListener = (...args: unknown[]) => { + const status = args[0] as { step: string; message: string }; + setInstallStep(status.step); + setInstallMessage(status.message); + }; window.electron.ipcRenderer.on('download-progress', progressListener); - window.electron.ipcRenderer.on( - 'installation-status', - (...args: unknown[]) => { - const status = args[0] as { step: string; message: string }; - setInstallStep(status.step); - setInstallMessage(status.message); - }, - ); + window.electron.ipcRenderer.on('installation-status', statusListener); return () => { - window.electron.ipcRenderer.removeAllListeners('download-progress'); - window.electron.ipcRenderer.removeAllListeners('installation-progress'); - window.electron.ipcRenderer.removeAllListeners('installation-status'); + // Удаляем только конкретных слушателей, а не всех + // Это безопаснее, чем removeAllListeners + const cleanup = window.electron.ipcRenderer.on; + if (typeof cleanup === 'function') { + cleanup('download-progress', progressListener); + cleanup('installation-status', statusListener); + } + // Удаляем использование removeAllListeners }; }, [navigate]);