Files
popa-launcher/src/renderer/pages/LaunchPage.tsx
2025-07-06 22:13:09 +05:00

167 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Box, Typography, Button, Snackbar, Alert } from '@mui/material';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
declare global {
interface Window {
electron: {
ipcRenderer: {
invoke(channel: string, ...args: unknown[]): Promise<any>;
on(channel: string, func: (...args: unknown[]) => void): void;
removeAllListeners(channel: string): void;
};
};
}
}
const LaunchPage = () => {
const navigate = useNavigate();
const [isDownloading, setIsDownloading] = useState(false);
const [downloadProgress, setDownloadProgress] = useState(0);
const [installStatus, setInstallStatus] = useState('');
const [notification, setNotification] = useState<{
open: boolean;
message: string;
severity: 'success' | 'error' | 'info';
}>({ open: false, message: '', severity: 'info' });
const [installStep, setInstallStep] = useState('');
const [installMessage, setInstallMessage] = useState('');
useEffect(() => {
const savedConfig = localStorage.getItem('launcher_config');
if (!savedConfig || !JSON.parse(savedConfig).accessToken) {
navigate('/login');
}
window.electron.ipcRenderer.on('download-progress', (progress: any) => {
setDownloadProgress(progress as number);
});
// Добавляем слушатель для статуса установки
window.electron.ipcRenderer.on('installation-progress', (data: any) => {
setInstallStatus((data as { status: string }).status);
});
// Обновляем слушатель для статуса установки
window.electron.ipcRenderer.on('installation-status', (data: any) => {
const { step, message } = data as { step: string; message: string };
setInstallStep(step);
setInstallMessage(message);
});
return () => {
window.electron.ipcRenderer.removeAllListeners('download-progress');
window.electron.ipcRenderer.removeAllListeners('installation-progress');
window.electron.ipcRenderer.removeAllListeners('installation-status');
};
}, [navigate]);
const handleLogout = () => {
localStorage.removeItem('launcher_config');
navigate('/login');
};
const showNotification = (
message: string,
severity: 'success' | 'error' | 'info',
) => {
setNotification({ open: true, message, severity });
};
const handleCloseNotification = () => {
setNotification({ ...notification, open: false });
};
const handleLaunchMinecraft = async () => {
try {
setIsDownloading(true);
setDownloadProgress(0);
// Сначала проверяем и обновляем файлы
const downloadResult = await window.electron.ipcRenderer.invoke(
'download-and-extract',
);
if (downloadResult?.success) {
if (downloadResult.updated) {
showNotification(
`Сборка успешно обновлена до версии ${downloadResult.version}`,
'success',
);
} else {
showNotification(
`Установлена актуальная версия сборки ${downloadResult.version}`,
'info',
);
}
// Затем запускаем Minecraft
const launchResult =
await window.electron.ipcRenderer.invoke('launch-minecraft');
if (launchResult?.success) {
showNotification('Minecraft успешно запущен!', 'success');
}
}
} catch (error) {
console.error('Error:', error);
showNotification(`Ошибка: ${error.message}`, 'error');
} finally {
setIsDownloading(false);
}
};
return (
<Box sx={{ p: 3 }}>
<Typography variant="h4" sx={{ mb: 3 }}>
Добро пожаловать в лаунчер
</Typography>
{isDownloading ? (
<Box sx={{ mb: 3 }}>
<Typography>Загрузка и установка: {downloadProgress}%</Typography>
{installMessage && (
<Typography variant="body1" sx={{ mt: 1, color: 'white' }}>
{installMessage}
</Typography>
)}
{installStep && (
<Typography variant="body2" sx={{ color: 'white' }}>
Шаг: {installStep}
</Typography>
)}
</Box>
) : (
<Button
variant="contained"
color="primary"
sx={{ mb: 3 }}
onClick={handleLaunchMinecraft}
>
Запустить Minecraft
</Button>
)}
<Button onClick={handleLogout} variant="contained" color="error">
Выйти
</Button>
<Snackbar
open={notification.open}
autoHideDuration={6000}
onClose={handleCloseNotification}
>
<Alert
onClose={handleCloseNotification}
severity={notification.severity}
sx={{ width: '100%' }}
>
{notification.message}
</Alert>
</Snackbar>
</Box>
);
};
export default LaunchPage;