v2.4.8: UI improvements, update popup fixes, per-profile branch tracking

- Fix auto-update popup: indeterminate progress fallback when no download events, show 100% on complete
- Remove macOS auto-update warning (app is now signed)
- Disable update popup pulse animation
- Remove news tab and news section from home screen
- Center play section vertically, add community links with colored icons
- Add game version + branch display on play page (from manifest)
- Add last played timestamp tracking
- Version badge links to git.sanhost.net releases
- Profiles now store version_branch and version_client per-configuration
- Profile switch restores branch/version and refreshes settings UI
- DevTools enabled in dev mode (electron . --dev)
- Reorder community links: Chat, Discord, TG Channel, TG Group, Source

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
sanasol
2026-02-28 21:47:23 +01:00
parent fcf041be39
commit 57056e5b7a
11 changed files with 337 additions and 146 deletions

89
main.js
View File

@@ -193,7 +193,7 @@ function createWindow() {
preload: path.join(__dirname, 'preload.js'),
nodeIntegration: false,
contextIsolation: true,
devTools: false,
devTools: process.argv.includes('--dev'),
webSecurity: true
}
});
@@ -251,7 +251,7 @@ function createWindow() {
mainWindow.webContents.send('update-error', {
message: err.message,
isMacSigningError: isMacSigningError,
requiresManualDownload: isMacSigningError || process.platform === 'darwin'
requiresManualDownload: isMacSigningError
});
}
});
@@ -272,9 +272,7 @@ function createWindow() {
if (mainWindow && !mainWindow.isDestroyed()) {
mainWindow.webContents.send('update-downloaded', {
version: info.version,
platform: process.platform,
// macOS auto-install often fails on unsigned apps
autoInstallSupported: process.platform !== 'darwin'
platform: process.platform
});
}
});
@@ -286,9 +284,12 @@ function createWindow() {
});
}, 3000);
mainWindow.webContents.on('devtools-opened', () => {
mainWindow.webContents.closeDevTools();
});
const isDev = process.argv.includes('--dev');
if (!isDev) {
mainWindow.webContents.on('devtools-opened', () => {
mainWindow.webContents.closeDevTools();
});
}
mainWindow.webContents.on('before-input-event', (event, input) => {
// Allow standard copy/paste/cut/select-all shortcuts
@@ -301,18 +302,20 @@ function createWindow() {
return; // Don't block these
}
// Block devtools shortcuts
if (input.control && input.shift && input.key.toLowerCase() === 'i') {
event.preventDefault();
}
if (input.control && input.shift && input.key.toLowerCase() === 'j') {
event.preventDefault();
}
if (input.control && input.shift && input.key.toLowerCase() === 'c') {
event.preventDefault();
}
if (input.key === 'F12') {
event.preventDefault();
// Block devtools shortcuts (except in dev mode)
if (!isDev) {
if (input.control && input.shift && input.key.toLowerCase() === 'i') {
event.preventDefault();
}
if (input.control && input.shift && input.key.toLowerCase() === 'j') {
event.preventDefault();
}
if (input.control && input.shift && input.key.toLowerCase() === 'c') {
event.preventDefault();
}
if (input.key === 'F12') {
event.preventDefault();
}
}
if (input.key === 'F5') {
event.preventDefault();
@@ -552,6 +555,9 @@ ipcMain.handle('launch-game', async (event, playerName, javaPath, installPath, g
const result = await launchGameWithVersionCheck(playerName, progressCallback, javaPath, installPath, gpuPreference, null, launchOptions);
if (result.success && result.launched) {
// Save last played timestamp
try { saveConfig({ last_played: Date.now() }); } catch (e) { /* ignore */ }
const closeOnStart = loadCloseLauncherOnStart();
if (closeOnStart) {
console.log('Close Launcher on start enabled, quitting application...');
@@ -608,6 +614,7 @@ ipcMain.handle('launch-game-with-password', async (event, playerName, javaPath,
const result = await launchGameWithVersionCheck(playerName, progressCallback, javaPath, installPath, gpuPreference, null, { password });
if (result.success && result.launched) {
try { saveConfig({ last_played: Date.now() }); } catch (e) { /* ignore */ }
const closeOnStart = loadCloseLauncherOnStart();
if (closeOnStart) {
setTimeout(() => { app.quit(); }, 1000);
@@ -1366,6 +1373,11 @@ ipcMain.handle('get-detected-gpu', () => {
ipcMain.handle('save-version-branch', (event, branch) => {
const { saveVersionBranch } = require('./backend/launcher');
saveVersionBranch(branch);
// Sync to active profile
const activeProfile = profileManager.getActiveProfile();
if (activeProfile) {
profileManager.updateProfile(activeProfile.id, { versionBranch: branch });
}
return { success: true };
});
@@ -1379,6 +1391,43 @@ ipcMain.handle('load-version-client', () => {
return loadVersionClient();
});
ipcMain.handle('get-game-info', async () => {
const { loadVersionClient, loadVersionBranch } = require('./backend/launcher');
const { fetchMirrorManifest } = require('./backend/services/versionManager');
const config = loadConfig();
const branch = loadVersionBranch();
let version = null;
let readableVersion = null;
try {
const manifest = await fetchMirrorManifest();
if (manifest?.versions?.[branch]) {
const branchVersions = manifest.versions[branch];
// Get the highest version number for the current branch
const nums = Object.keys(branchVersions).map(Number).filter(n => !isNaN(n));
if (nums.length > 0) {
const latest = Math.max(...nums).toString();
version = `v${latest}`;
readableVersion = branchVersions[latest]?.version || null;
}
}
} catch (e) {
// Manifest fetch failed, fall back to stored version
version = loadVersionClient();
}
if (!version) {
version = loadVersionClient();
}
return {
version,
readableVersion,
branch,
lastPlayed: config.last_played || null
};
});
ipcMain.handle('window-close', () => {
app.quit();
});