diff --git a/index.html b/index.html
index bed7e5b..579854c 100644
--- a/index.html
+++ b/index.html
@@ -209,6 +209,88 @@
.animate-spin {
animation: spin 1s linear infinite;
}
+
+ .custom-checkbox {
+ appearance: none;
+ -webkit-appearance: none;
+ width: 20px;
+ height: 20px;
+ background: rgba(10, 10, 10, 0.8);
+ border: 1px solid rgba(147, 51, 234, 0.3);
+ border-radius: 4px;
+ cursor: pointer;
+ transition: all 0.3s ease;
+ position: relative;
+ }
+
+ .custom-checkbox:checked {
+ background: rgba(147, 51, 234, 0.6);
+ border-color: rgba(147, 51, 234, 0.8);
+ }
+
+ .custom-checkbox:checked::after {
+ content: '\f00c';
+ font-family: 'Font Awesome 6 Free';
+ font-weight: 900;
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ color: white;
+ font-size: 12px;
+ }
+
+ .custom-checkbox:hover {
+ border-color: rgba(147, 51, 234, 0.6);
+ box-shadow: 0 0 10px rgba(147, 51, 234, 0.3);
+ }
+
+ .custom-options {
+ max-height: 0;
+ overflow: hidden;
+ opacity: 0;
+ transition: max-height 0.4s ease, opacity 0.3s ease, margin 0.3s ease;
+ margin-top: 0;
+ }
+
+ .custom-options.show {
+ max-height: 200px;
+ opacity: 1;
+ margin-top: 1rem;
+ }
+
+ .browse-btn {
+ background: rgba(147, 51, 234, 0.3);
+ border: 1px solid rgba(147, 51, 234, 0.4);
+ transition: all 0.3s ease;
+ }
+
+ .browse-btn:hover {
+ background: rgba(147, 51, 234, 0.5);
+ border-color: rgba(147, 51, 234, 0.7);
+ box-shadow: 0 0 15px rgba(147, 51, 234, 0.4);
+ }
+
+ .uninstall-btn {
+ background: rgba(239, 68, 68, 0.2);
+ border: 1px solid rgba(239, 68, 68, 0.4);
+ transition: all 0.3s ease;
+ }
+
+ .uninstall-btn:hover {
+ background: rgba(239, 68, 68, 0.4);
+ border-color: rgba(239, 68, 68, 0.7);
+ box-shadow: 0 0 15px rgba(239, 68, 68, 0.4);
+ }
+
+ .no-scrollbar::-webkit-scrollbar {
+ display: none;
+ }
+
+ .no-scrollbar {
+ -ms-overflow-style: none;
+ scrollbar-width: none;
+ }
@@ -233,8 +315,8 @@
-
-
@@ -319,32 +445,73 @@
let isDownloading = false;
const playBtn = document.getElementById('playBtn');
- const playText = document.getElementById('playText');
- const playerNameInput = document.getElementById('playerName');
- const javaPathInput = document.getElementById('javaPath');
- const progressText = document.getElementById('progressText');
- const progressPercent = document.getElementById('progressPercent');
- const progressSpeed = document.getElementById('progressSpeed');
- const progressSize = document.getElementById('progressSize');
- const progressBar = document.getElementById('progressBar');
- const loadingScreen = document.getElementById('loadingScreen');
-
- async function init() {
- try {
- const [savedUsername, javaPath] = await Promise.all([
- window.electronAPI.loadUsername(),
- window.electronAPI.loadJavaPath()
- ]);
- if (savedUsername) {
- playerNameInput.value = savedUsername;
- username = savedUsername;
- }
- if (typeof javaPath === 'string') {
- javaPathInput.value = javaPath;
- }
- } catch (error) {
- console.error('Failed to load username:', error);
- } finally {
+ const playText = document.getElementById('playText');
+ const uninstallBtn = document.getElementById('uninstallBtn');
+ const playerNameInput = document.getElementById('playerName');
+ const javaPathInput = document.getElementById('javaPath');
+ const installPathInput = document.getElementById('installPath');
+ const customInstallCheck = document.getElementById('customInstallCheck');
+ const customOptions = document.getElementById('customOptions');
+ const progressText = document.getElementById('progressText');
+ const progressPercent = document.getElementById('progressPercent');
+ const progressSpeed = document.getElementById('progressSpeed');
+ const progressSize = document.getElementById('progressSize');
+ const progressBar = document.getElementById('progressBar');
+ const loadingScreen = document.getElementById('loadingScreen');
+
+ customInstallCheck.addEventListener('change', () => {
+ if (customInstallCheck.checked) {
+ customOptions.classList.add('show');
+ } else {
+ customOptions.classList.remove('show');
+ }
+ });
+
+ async function browseInstallPath() {
+ const result = await window.electronAPI.selectInstallPath();
+ if (result) {
+ installPathInput.value = result;
+ await window.electronAPI.saveInstallPath(result);
+ }
+ }
+
+ async function init() {
+ try {
+ const [savedUsername, javaPath, installPath, gameInstalled] = await Promise.all([
+ window.electronAPI.loadUsername(),
+ window.electronAPI.loadJavaPath(),
+ window.electronAPI.loadInstallPath(),
+ window.electronAPI.isGameInstalled()
+ ]);
+ if (savedUsername) {
+ playerNameInput.value = savedUsername;
+ username = savedUsername;
+ }
+ if (typeof javaPath === 'string' && javaPath) {
+ javaPathInput.value = javaPath;
+ customInstallCheck.checked = true;
+ customOptions.classList.add('show');
+ }
+ if (typeof installPath === 'string' && installPath) {
+ installPathInput.value = installPath;
+ customInstallCheck.checked = true;
+ customOptions.classList.add('show');
+ }
+
+ if (gameInstalled) {
+ const customInstallContainer = document.querySelector('.w-\\[28rem\\]');
+ if (customInstallContainer) {
+ customInstallContainer.style.display = 'none';
+ }
+ playText.textContent = 'PLAY';
+ uninstallBtn.style.display = 'flex';
+ } else {
+ playText.textContent = 'INSTALL';
+ uninstallBtn.style.display = 'none';
+ }
+ } catch (error) {
+ console.error('Failed to load settings:', error);
+ } finally {
setTimeout(() => {
loadingScreen.style.opacity = '0';
loadingScreen.style.transition = 'opacity 0.5s ease';
@@ -386,34 +553,35 @@
updateProgress(data);
});
- playerNameInput.addEventListener('input', async () => {
- const playerName = playerNameInput.value.trim();
- if (playerName) {
- await window.electronAPI.saveUsername(playerName);
- }
- });
-
- javaPathInput.addEventListener('input', async () => {
- await window.electronAPI.saveJavaPath(javaPathInput.value.trim());
- });
-
- async function launch() {
- const playerName = playerNameInput.value.trim() || 'Player';
- const javaPath = javaPathInput.value.trim();
-
- await window.electronAPI.saveUsername(playerName);
-
- if (isDownloading || playBtn.disabled) return;
+ playerNameInput.addEventListener('input', async () => {
+ const playerName = playerNameInput.value.trim();
+ if (playerName) {
+ await window.electronAPI.saveUsername(playerName);
+ }
+ });
+
+ javaPathInput.addEventListener('input', async () => {
+ await window.electronAPI.saveJavaPath(javaPathInput.value.trim());
+ });
+
+ async function launch() {
+ const playerName = playerNameInput.value.trim() || 'Player';
+ const javaPath = javaPathInput.value.trim();
+ const installPath = installPathInput.value.trim();
+
+ await window.electronAPI.saveUsername(playerName);
+
+ if (isDownloading || playBtn.disabled) return;
isDownloading = true;
playBtn.disabled = true;
playText.textContent = 'PROCESSING...';
try {
- const result = await window.electronAPI.launchGame(playerName, javaPath);
-
- if (result.success) {
- progressText.textContent = 'Game started!';
+ const result = await window.electronAPI.launchGame(playerName, javaPath, installPath);
+
+ if (result.success) {
+ progressText.textContent = 'Game started!';
setTimeout(() => {
window.electronAPI.closeWindow();
}, 2000);
@@ -439,6 +607,35 @@
window.electronAPI.minimizeWindow();
}
+ async function uninstallGame() {
+ if (!confirm('Are you sure you want to uninstall Hytale? All game files will be deleted.')) {
+ return;
+ }
+
+ uninstallBtn.disabled = true;
+ progressText.textContent = 'Uninstalling game...';
+
+ try {
+ const result = await window.electronAPI.uninstallGame();
+
+ if (result.success) {
+ progressText.textContent = 'Game uninstalled successfully!';
+ playText.textContent = 'INSTALL';
+ uninstallBtn.style.display = 'none';
+ const customInstallContainer = document.querySelector('.w-\\[28rem\\]');
+ if (customInstallContainer) {
+ customInstallContainer.style.display = 'block';
+ }
+ } else {
+ progressText.textContent = `Uninstall failed: ${result.error}`;
+ }
+ } catch (error) {
+ progressText.textContent = `Uninstall failed: ${error.message}`;
+ } finally {
+ uninstallBtn.disabled = false;
+ }
+ }
+
playerNameInput.addEventListener('keypress', (e) => {
if (e.key === 'Enter') {
launch();