mirror of
https://github.com/gradenGnostic/LegacyLauncher.git
synced 2026-05-17 19:13:07 +00:00
Add Steam Deck UI mode, repo presets, and stronger hover glow (#2)
This commit is contained in:
parent
3355244dc4
commit
e44695860c
19
index.html
19
index.html
|
|
@ -13,9 +13,9 @@
|
|||
<div class="title-bar">
|
||||
<div class="title-bar-text">LegacyLauncher</div>
|
||||
<div class="window-controls">
|
||||
<div class="win-btn" onclick="minimizeWindow()">−</div>
|
||||
<div class="win-btn" id="maximize-btn" onclick="toggleMaximize()">▢</div>
|
||||
<div class="win-btn close" onclick="closeWindow()">×</div>
|
||||
<div class="win-btn nav-item" onclick="minimizeWindow()" tabindex="0" title="Minimize">−</div>
|
||||
<div class="win-btn nav-item" id="maximize-btn" onclick="toggleMaximize()" tabindex="0" title="Maximize / Restore">▢</div>
|
||||
<div class="win-btn close nav-item" onclick="closeWindow()" tabindex="0" title="Close">×</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
@ -201,6 +201,12 @@
|
|||
<div class="mc-input-group">
|
||||
<label class="mc-label">GitHub Repository Source:</label>
|
||||
<input type="text" id="repo-input" class="mc-input nav-item" placeholder="user/repo" tabindex="0">
|
||||
<label class="mc-label" style="margin-top: 10px;">Repository Preset:</label>
|
||||
<select id="repo-preset-select" class="mc-input nav-item" onchange="applyRepoPreset()" tabindex="0" style="height: 48px; margin-top: 8px;">
|
||||
<option value="custom">Custom</option>
|
||||
<option value="smartcmd/MinecraftConsoles">smartcmd (default)</option>
|
||||
<option value="cath0degaytube/MinecraftConsoles">cath0degaytube (no watermark)</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="mc-input-group">
|
||||
|
|
@ -254,6 +260,13 @@
|
|||
</label>
|
||||
</div>
|
||||
|
||||
<div class="mc-input-group">
|
||||
<label class="mc-label" style="display: flex; align-items: center; cursor: pointer;">
|
||||
<input type="checkbox" id="steamdeck-mode-checkbox" class="nav-item" style="width: 24px; height: 24px; margin-right: 12px; cursor: pointer;" tabindex="0">
|
||||
Use Steam Deck Optimized UI Mode
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-4 w-full mt-4">
|
||||
<div id="btn-options-done" class="btn-mc flex-grow nav-item" onclick="saveOptions()" tabindex="0">DONE</div>
|
||||
<div id="btn-options-cancel" class="btn-mc flex-grow nav-item" onclick="toggleOptions(false)" tabindex="0">CANCEL</div>
|
||||
|
|
|
|||
101
renderer.js
101
renderer.js
|
|
@ -9,6 +9,10 @@ const DEFAULT_REPO = "smartcmd/MinecraftConsoles";
|
|||
const DEFAULT_EXEC = "Minecraft.Client.exe";
|
||||
const TARGET_FILE = "LCEWindows64.zip";
|
||||
const LAUNCHER_REPO = "gradenGnostic/LegacyLauncher";
|
||||
const REPO_PRESETS = {
|
||||
default: 'smartcmd/MinecraftConsoles',
|
||||
noWatermark: 'cath0degaytube/MinecraftConsoles'
|
||||
};
|
||||
|
||||
let instances = [];
|
||||
let currentInstanceId = null;
|
||||
|
|
@ -108,21 +112,22 @@ const GamepadManager = {
|
|||
const left = isPressed(14) || axisX < -threshold;
|
||||
const right = isPressed(15) || axisX > threshold;
|
||||
|
||||
if (up) { this.navigate('up'); this.lastInputTime = now; }
|
||||
else if (down) { this.navigate('down'); this.lastInputTime = now; }
|
||||
else if (left) { this.navigate('left'); this.lastInputTime = now; }
|
||||
else if (right) { this.navigate('right'); this.lastInputTime = now; }
|
||||
if (up) { UiSoundManager.setInputSource('controller'); this.navigate('up'); this.lastInputTime = now; }
|
||||
else if (down) { UiSoundManager.setInputSource('controller'); this.navigate('down'); this.lastInputTime = now; }
|
||||
else if (left) { UiSoundManager.setInputSource('controller'); this.navigate('left'); this.lastInputTime = now; }
|
||||
else if (right) { UiSoundManager.setInputSource('controller'); this.navigate('right'); this.lastInputTime = now; }
|
||||
|
||||
else if (isPressed(4)) { this.cycleActiveSelection(-1); this.lastInputTime = now; }
|
||||
else if (isPressed(5)) { this.cycleActiveSelection(1); this.lastInputTime = now; }
|
||||
else if (isPressed(4)) { UiSoundManager.setInputSource('controller'); this.cycleActiveSelection(-1); this.lastInputTime = now; }
|
||||
else if (isPressed(5)) { UiSoundManager.setInputSource('controller'); this.cycleActiveSelection(1); this.lastInputTime = now; }
|
||||
|
||||
else if (isPressed(1)) { this.cancelCurrent(); this.lastInputTime = now; }
|
||||
else if (isPressed(1)) { UiSoundManager.setInputSource('controller'); this.cancelCurrent(); this.lastInputTime = now; }
|
||||
|
||||
else if (isPressed(2)) { checkForUpdatesManual(); this.lastInputTime = now; }
|
||||
else if (isPressed(2)) { UiSoundManager.setInputSource('controller'); checkForUpdatesManual(); this.lastInputTime = now; }
|
||||
}
|
||||
|
||||
const aPressed = isPressed(0);
|
||||
if (aPressed && !this.lastAPressed) {
|
||||
UiSoundManager.setInputSource('controller');
|
||||
this.clickActive();
|
||||
}
|
||||
this.lastAPressed = aPressed;
|
||||
|
|
@ -218,7 +223,24 @@ const GamepadManager = {
|
|||
if (active && active.classList.contains('nav-item')) {
|
||||
active.classList.add('active-bump');
|
||||
setTimeout(() => active.classList.remove('active-bump'), 100);
|
||||
|
||||
|
||||
if (active.id === 'version-select-box') {
|
||||
this.cycleActiveSelection(1);
|
||||
return;
|
||||
}
|
||||
if (active.id === 'classic-version-select-box') {
|
||||
const classicSelect = document.getElementById('classic-version-select');
|
||||
if (classicSelect) {
|
||||
classicSelect.selectedIndex = (classicSelect.selectedIndex + 1) % classicSelect.options.length;
|
||||
syncVersionFromClassic();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (active.id === 'compat-select-box') {
|
||||
this.cycleActiveSelection(1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (active.tagName === 'INPUT' && active.type === 'checkbox') {
|
||||
active.checked = !active.checked;
|
||||
active.dispatchEvent(new Event('change'));
|
||||
|
|
@ -313,6 +335,15 @@ const UiSoundManager = {
|
|||
lastPlayedAt: {},
|
||||
cooldownMs: 70,
|
||||
lastHoverItem: null,
|
||||
inputSource: 'mouse',
|
||||
|
||||
setInputSource(source) {
|
||||
this.inputSource = source;
|
||||
},
|
||||
|
||||
shouldPlay() {
|
||||
return this.inputSource === 'controller';
|
||||
},
|
||||
|
||||
init() {
|
||||
Object.entries(this.files).forEach(([key, file]) => {
|
||||
|
|
@ -321,6 +352,11 @@ const UiSoundManager = {
|
|||
this.cache[key].volume = key === 'cursor' ? 0.45 : 0.6;
|
||||
});
|
||||
|
||||
const markMouseInput = () => this.setInputSource('mouse');
|
||||
['mousemove', 'mousedown', 'touchstart', 'wheel', 'keydown'].forEach((ev) => {
|
||||
document.addEventListener(ev, markMouseInput, { passive: true });
|
||||
});
|
||||
|
||||
document.addEventListener('focusin', (e) => {
|
||||
if (e.target?.classList?.contains('nav-item')) this.play('cursor');
|
||||
});
|
||||
|
|
@ -349,6 +385,7 @@ const UiSoundManager = {
|
|||
},
|
||||
|
||||
play(name) {
|
||||
if (!this.shouldPlay()) return;
|
||||
const now = Date.now();
|
||||
if (this.lastPlayedAt[name] && now - this.lastPlayedAt[name] < this.cooldownMs) return;
|
||||
this.lastPlayedAt[name] = now;
|
||||
|
|
@ -534,6 +571,24 @@ function focusPrimaryPlayButton() {
|
|||
setTimeout(() => target.classList.remove('controller-active'), 180);
|
||||
}
|
||||
|
||||
function syncRepoPresetFromInput() {
|
||||
const presetSelect = document.getElementById('repo-preset-select');
|
||||
const repoInput = document.getElementById('repo-input');
|
||||
if (!presetSelect || !repoInput) return;
|
||||
|
||||
if (repoInput.value.trim() === REPO_PRESETS.default) presetSelect.value = REPO_PRESETS.default;
|
||||
else if (repoInput.value.trim() === REPO_PRESETS.noWatermark) presetSelect.value = REPO_PRESETS.noWatermark;
|
||||
else presetSelect.value = 'custom';
|
||||
}
|
||||
|
||||
function applyRepoPreset() {
|
||||
const presetSelect = document.getElementById('repo-preset-select');
|
||||
const repoInput = document.getElementById('repo-input');
|
||||
if (!presetSelect || !repoInput) return;
|
||||
if (presetSelect.value === 'custom') return;
|
||||
repoInput.value = presetSelect.value;
|
||||
}
|
||||
|
||||
window.onload = async () => {
|
||||
try {
|
||||
await migrateLegacyConfig();
|
||||
|
|
@ -546,13 +601,17 @@ window.onload = async () => {
|
|||
const serverCheck = document.getElementById('server-checkbox');
|
||||
const installInput = document.getElementById('install-path-input');
|
||||
|
||||
if (repoInput) repoInput.value = currentInstance.repo;
|
||||
if (repoInput) {
|
||||
repoInput.value = currentInstance.repo;
|
||||
repoInput.addEventListener('input', syncRepoPresetFromInput);
|
||||
}
|
||||
if (execInput) execInput.value = currentInstance.execPath;
|
||||
if (usernameInput) usernameInput.value = await Store.get('legacy_username', "");
|
||||
if (ipInput) ipInput.value = currentInstance.ip;
|
||||
if (portInput) portInput.value = currentInstance.port;
|
||||
if (serverCheck) serverCheck.checked = currentInstance.isServer;
|
||||
if (installInput) installInput.value = currentInstance.installPath;
|
||||
syncRepoPresetFromInput();
|
||||
|
||||
if (process.platform === 'linux' || process.platform === 'darwin') {
|
||||
const compatContainer = document.getElementById('compat-option-container');
|
||||
|
|
@ -572,6 +631,7 @@ window.onload = async () => {
|
|||
|
||||
// Initialize features
|
||||
await loadTheme();
|
||||
await loadSteamDeckMode();
|
||||
fetchGitHubData();
|
||||
checkForLauncherUpdates();
|
||||
loadSplashText();
|
||||
|
|
@ -731,6 +791,7 @@ async function switchInstance(id) {
|
|||
await saveInstancesToStore();
|
||||
|
||||
document.getElementById('repo-input').value = currentInstance.repo;
|
||||
syncRepoPresetFromInput();
|
||||
document.getElementById('exec-input').value = currentInstance.execPath;
|
||||
document.getElementById('ip-input').value = currentInstance.ip;
|
||||
document.getElementById('port-input').value = currentInstance.port;
|
||||
|
|
@ -1250,6 +1311,9 @@ function toggleOptions(show) {
|
|||
// Sync classic theme checkbox to current state
|
||||
const cb = document.getElementById('classic-theme-checkbox');
|
||||
if (cb) cb.checked = document.body.classList.contains('classic-theme');
|
||||
const steamDeckCb = document.getElementById('steamdeck-mode-checkbox');
|
||||
if (steamDeckCb) steamDeckCb.checked = document.body.classList.contains('steamdeck-mode');
|
||||
syncRepoPresetFromInput();
|
||||
document.activeElement?.blur(); modal.style.display = 'flex'; modal.style.opacity = '1';
|
||||
UiSoundManager.play('popupOpen');
|
||||
}
|
||||
|
|
@ -1364,8 +1428,11 @@ async function saveOptions() {
|
|||
currentInstance.customCompatPath = customProtonPath;
|
||||
}
|
||||
const isClassic = document.getElementById('classic-theme-checkbox')?.checked || false;
|
||||
const isSteamDeckMode = document.getElementById('steamdeck-mode-checkbox')?.checked || false;
|
||||
await Store.set('legacy_classic_theme', isClassic);
|
||||
await Store.set('legacy_steamdeck_mode', isSteamDeckMode);
|
||||
applyTheme(isClassic);
|
||||
applySteamDeckMode(isSteamDeckMode);
|
||||
await saveInstancesToStore(); toggleOptions(false); fetchGitHubData(); updatePlayButtonText(); showToast("Settings Saved");
|
||||
}
|
||||
|
||||
|
|
@ -1596,6 +1663,19 @@ async function loadTheme() {
|
|||
applyTheme(isClassic);
|
||||
}
|
||||
|
||||
async function loadSteamDeckMode() {
|
||||
const autoSteamDeck = isSteamDeckEnvironment();
|
||||
const saved = await Store.get('legacy_steamdeck_mode', null);
|
||||
const enabled = saved === null ? autoSteamDeck : saved;
|
||||
const cb = document.getElementById('steamdeck-mode-checkbox');
|
||||
if (cb) cb.checked = enabled;
|
||||
applySteamDeckMode(enabled);
|
||||
}
|
||||
|
||||
function applySteamDeckMode(enabled) {
|
||||
document.body.classList.toggle('steamdeck-mode', !!enabled);
|
||||
}
|
||||
|
||||
function applyTheme(isClassic) {
|
||||
document.body.classList.toggle('classic-theme', isClassic);
|
||||
if (isClassic) {
|
||||
|
|
@ -1806,6 +1886,7 @@ window.checkForUpdatesManual = checkForUpdatesManual;
|
|||
window.browseInstallDir = browseInstallDir;
|
||||
window.openGameDir = openGameDir;
|
||||
window.toggleMusic = toggleMusic;
|
||||
window.applyRepoPreset = applyRepoPreset;
|
||||
window.getInstallDir = getInstallDir;
|
||||
window.showToast = showToast;
|
||||
window.toggleInstances = toggleInstances;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,13 @@ document.addEventListener('DOMContentLoaded', () => {
|
|||
if (skinInput) skinInput.addEventListener('change', (e) => handleSkinFile(e.target.files[0]));
|
||||
|
||||
if (dropZone) {
|
||||
dropZone.addEventListener('click', () => skinInput?.click());
|
||||
dropZone.addEventListener('keydown', (e) => {
|
||||
if (e.key === 'Enter' || e.key === ' ') {
|
||||
e.preventDefault();
|
||||
skinInput?.click();
|
||||
}
|
||||
});
|
||||
dropZone.addEventListener('dragover', (e) => {
|
||||
e.preventDefault();
|
||||
dropZone.classList.add('border-green-500');
|
||||
|
|
|
|||
54
style.css
54
style.css
|
|
@ -94,6 +94,15 @@ body {
|
|||
background: #c42b1c;
|
||||
}
|
||||
|
||||
|
||||
.win-btn.nav-item:focus {
|
||||
transform: scale(1.08);
|
||||
z-index: 1001;
|
||||
box-shadow: 0 0 0 1px rgba(255,255,255,0.95), 0 0 8px rgba(255,255,255,0.55) !important;
|
||||
background: #444;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.main-wrapper {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
|
|
@ -364,6 +373,11 @@ body {
|
|||
filter: brightness(1.08);
|
||||
}
|
||||
|
||||
.nav-item:hover {
|
||||
outline: 1px solid rgba(255,255,255,0.92) !important;
|
||||
box-shadow: 0 0 0 1px rgba(255,255,255,0.85), 0 0 12px rgba(255, 255, 255, 0.52), 0 0 24px rgba(90, 170, 255, 0.22) !important;
|
||||
}
|
||||
|
||||
.nav-item.active-bump {
|
||||
transform: scale(0.95) !important;
|
||||
transition: transform 0.1s !important;
|
||||
|
|
@ -402,6 +416,46 @@ body {
|
|||
text-shadow: 2px 2px 0 #000;
|
||||
}
|
||||
|
||||
/* Steam Deck optimized mode */
|
||||
body.steamdeck-mode .title-bar {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
body.steamdeck-mode .title-bar-text {
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
body.steamdeck-mode .btn-mc {
|
||||
min-height: 68px;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
body.steamdeck-mode .btn-play {
|
||||
min-height: 110px;
|
||||
font-size: 52px;
|
||||
}
|
||||
|
||||
body.steamdeck-mode .version-select-box {
|
||||
height: 64px;
|
||||
font-size: 26px;
|
||||
}
|
||||
|
||||
body.steamdeck-mode .mc-input,
|
||||
body.steamdeck-mode #repo-preset-select,
|
||||
body.steamdeck-mode .mc-label,
|
||||
body.steamdeck-mode .classic-link {
|
||||
font-size: 20px !important;
|
||||
}
|
||||
|
||||
body.steamdeck-mode .nav-item:focus {
|
||||
transform: scale(1.06);
|
||||
box-shadow: 0 0 0 2px rgba(255,255,255,0.95), 0 0 22px rgba(255,255,255,0.7), 0 0 34px rgba(90,170,255,0.36) !important;
|
||||
}
|
||||
|
||||
body.steamdeck-mode .sidebar {
|
||||
width: 420px;
|
||||
}
|
||||
|
||||
.version-row {
|
||||
display: flex;
|
||||
width: 500px;
|
||||
|
|
|
|||
Loading…
Reference in a new issue