feat: improved launch settings

This commit is contained in:
2025-07-07 06:56:30 +05:00
parent b14de1d15a
commit 1b50a7d4e4
8 changed files with 510 additions and 20 deletions

View File

@ -5,11 +5,16 @@ import {
Snackbar,
Alert,
LinearProgress,
Modal,
} from '@mui/material';
import { useEffect, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import ServerStatus from '../components/ServerStatus/ServerStatus';
import PopaPopa from '../components/popa-popa';
import SettingsIcon from '@mui/icons-material/Settings';
import React from 'react';
import MemorySlider from '../components/Login/MemorySlider';
import FilesSelector from '../components/FilesSelector';
declare global {
interface Window {
@ -34,12 +39,19 @@ interface LaunchPageProps {
baseVersion: string;
serverIp: string;
fabricVersion: string;
preserveFiles: string[];
};
}
const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
const navigate = useNavigate();
// Начальное состояние должно быть пустым или с минимальными значениями
const [config, setConfig] = useState<{
memory: number;
preserveFiles: string[];
}>({
memory: 0,
preserveFiles: [],
});
const [isDownloading, setIsDownloading] = useState(false);
const [downloadProgress, setDownloadProgress] = useState(0);
const [buffer, setBuffer] = useState(10);
@ -51,6 +63,9 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
}>({ open: false, message: '', severity: 'info' });
const [installStep, setInstallStep] = useState('');
const [installMessage, setInstallMessage] = useState('');
const [open, setOpen] = React.useState(false);
const handleOpen = () => setOpen(true);
const handleClose = () => setOpen(false);
useEffect(() => {
const savedConfig = localStorage.getItem('launcher_config');
@ -85,6 +100,29 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
};
}, [navigate]);
useEffect(() => {
// Загрузка конфигурации сборки при монтировании
const loadPackConfig = async () => {
try {
const result = await window.electron.ipcRenderer.invoke(
'load-pack-config',
{
packName: launchOptions.packName,
},
);
if (result.success && result.config) {
// Полностью заменяем config значениями из файла
setConfig(result.config);
}
} catch (error) {
console.error('Ошибка при загрузке настроек:', error);
}
};
loadPackConfig();
}, [launchOptions.packName]);
const showNotification = (
message: string,
severity: 'success' | 'error' | 'info',
@ -102,6 +140,19 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
setDownloadProgress(0);
setBuffer(10);
// Загружаем настройки сборки
const result = await window.electron.ipcRenderer.invoke(
'load-pack-config',
{
packName: launchOptions.packName,
},
);
// Используйте уже существующий state вместо локальной переменной
if (result.success && result.config) {
setConfig(result.config); // Обновляем state
}
const savedConfig = JSON.parse(
localStorage.getItem('launcher_config') || '{}',
);
@ -112,7 +163,7 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
apiReleaseUrl: launchOptions.apiReleaseUrl,
versionFileName: launchOptions.versionFileName,
packName: launchOptions.packName,
preserveFiles: launchOptions.preserveFiles,
preserveFiles: config.preserveFiles,
};
// Передаем опции для скачивания
@ -142,7 +193,7 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
accessToken: savedConfig.accessToken,
uuid: savedConfig.uuid,
username: savedConfig.username,
memory: launchOptions.memory,
memory: config.memory, // Используем state
baseVersion: launchOptions.baseVersion,
packName: launchOptions.packName,
serverIp: launchOptions.serverIp,
@ -180,6 +231,29 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
}
};
// Функция для сохранения настроек
const savePackConfig = async () => {
try {
const configToSave = {
memory: config.memory,
preserveFiles: config.preserveFiles || [],
};
await window.electron.ipcRenderer.invoke('save-pack-config', {
packName: launchOptions.packName,
config: configToSave,
});
// Обновляем launchOptions
launchOptions.memory = config.memory;
showNotification('Настройки сохранены', 'success');
} catch (error) {
console.error('Ошибка при сохранении настроек:', error);
showNotification('Ошибка сохранения настроек', 'error');
}
};
return (
<Box sx={{ gap: '1vh', display: 'flex', flexDirection: 'column' }}>
<PopaPopa />
@ -235,13 +309,46 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
</Box>
</Box>
) : (
<Button
variant="contained"
color="primary"
onClick={handleLaunchMinecraft}
<Box
sx={{
display: 'flex',
gap: '1vw',
width: '100%', // родитель занимает всю ширину
}}
>
Запустить Minecraft
</Button>
{/* Первая кнопка — растягивается на всё доступное пространство */}
<Button
variant="contained"
color="primary"
onClick={handleLaunchMinecraft}
sx={{
flexGrow: 1, // занимает всё свободное место
width: 'auto', // ширина подстраивается
borderRadius: '3vw',
fontFamily: 'Benzin-Bold',
background: 'linear-gradient(90deg, #3B96FF 0%, #FFB7ED 100%)',
}}
>
Запустить Minecraft
</Button>
{/* Вторая кнопка — квадратная, фиксированного размера (ширина = высоте) */}
<Button
variant="contained"
sx={{
flexShrink: 0, // не сжимается
aspectRatio: '1', // ширина = высоте
backgroundColor: 'grey',
borderRadius: '3vw',
minHeight: 'unset',
minWidth: 'unset',
height: '100%', // занимает полную высоту родителя
}}
onClick={handleOpen}
>
<SettingsIcon />
</Button>
</Box>
)}
<Snackbar
@ -257,6 +364,66 @@ const LaunchPage = ({ launchOptions }: LaunchPageProps) => {
{notification.message}
</Alert>
</Snackbar>
<Modal
open={open}
onClose={handleClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
>
<Box
sx={{
position: 'absolute',
top: '50%',
left: '50%',
transform: 'translate(-50%, -50%)',
width: 400,
background:
'linear-gradient(-242.94deg, #000000 39.07%, #3b4187 184.73%)',
border: '2px solid #000',
boxShadow: 24,
p: 4,
borderRadius: '3vw',
gap: '1vh',
display: 'flex',
flexDirection: 'column',
}}
>
<Typography id="modal-modal-title" variant="body1" component="h2">
Файлы и папки, которые будут сохранены после переустановки сборки
</Typography>
<FilesSelector
packName={launchOptions.packName}
initialSelected={config.preserveFiles} // Передаем текущие выбранные файлы
onSelectionChange={(selected) => {
setConfig((prev) => ({ ...prev, preserveFiles: selected }));
}}
/>
<Typography variant="body1" sx={{ color: 'white' }}>
Оперативная память выделенная для Minecraft
</Typography>
<MemorySlider
memory={config.memory}
onChange={(e, value) => {
setConfig((prev) => ({ ...prev, memory: value as number }));
}}
/>
<Button
variant="contained"
color="success"
onClick={() => {
savePackConfig();
handleClose();
}}
sx={{
borderRadius: '3vw',
fontFamily: 'Benzin-Bold',
}}
>
Сохранить
</Button>
</Box>
</Modal>
</Box>
);
};