Add themes and clean main.js and style.css

This commit is contained in:
2026-02-13 13:18:12 +01:00
parent 585e50f123
commit acfc97a078
9 changed files with 299 additions and 140 deletions

125
main.js
View File

@@ -65,10 +65,10 @@ app.on('window-all-closed', () => {
} }
}) })
///////////////// SAVING AND LOADING /////////////////
ipcMain.handle('save-path', (event, path) => { ipcMain.handle('save-path', (event, path) => {
saveSilksongPath(path) saveSilksongPath(path)
}); });
function saveSilksongPath(path) { function saveSilksongPath(path) {
silksongPath = path; silksongPath = path;
bepinexFolderPath = `${silksongPath}/BepInEx` bepinexFolderPath = `${silksongPath}/BepInEx`
@@ -84,19 +84,6 @@ ipcMain.handle('load-path', () => {
return silksongPath; return silksongPath;
}); });
ipcMain.handle('load-nexus-api', () => {
nexusAPI = store.get('nexus-api');
if (nexusAPI == undefined) {
return "";
}
return nexusAPI;
});
ipcMain.handle('save-nexus-api', (event, api) => {
nexusAPI = api;
createNexus()
store.set('nexus-api', nexusAPI);
});
function saveBepinexVersion(version) { function saveBepinexVersion(version) {
bepinexVersion = version; bepinexVersion = version;
@@ -107,6 +94,12 @@ function saveBepinexVersion(version) {
store.set('bepinex-version', version); store.set('bepinex-version', version);
}; };
ipcMain.handle('load-bepinex-version', () => {
bepinexVersion = store.get('bepinex-version');
return bepinexVersion;
});
function saveBepinexBackupVersion(version) { function saveBepinexBackupVersion(version) {
bepinexBackupVersion = version; bepinexBackupVersion = version;
if (bepinexBackupVersion == undefined) { if (bepinexBackupVersion == undefined) {
@@ -116,16 +109,41 @@ function saveBepinexBackupVersion(version) {
store.set('bepinex-backup-version', version); store.set('bepinex-backup-version', version);
}; };
ipcMain.handle('load-bepinex-version', () => {
bepinexVersion = store.get('bepinex-version');
return bepinexVersion;
});
ipcMain.handle('load-bepinex-backup-version', () => { ipcMain.handle('load-bepinex-backup-version', () => {
bepinexBackupVersion = store.get('bepinex-backup-version'); bepinexBackupVersion = store.get('bepinex-backup-version');
return bepinexBackupVersion; return bepinexBackupVersion;
}); });
ipcMain.handle('save-nexus-api', (event, api) => {
nexusAPI = api;
createNexus()
store.set('nexus-api', nexusAPI);
});
ipcMain.handle('load-nexus-api', () => {
nexusAPI = store.get('nexus-api');
if (nexusAPI == undefined) {
return "";
}
return nexusAPI;
});
ipcMain.handle('save-theme', (event, theme) => {
store.set('theme', theme);
});
ipcMain.handle('load-theme', () => {
theme = store.get('theme');
if (theme == undefined) {
return "Silksong";
}
return theme;
});
//////////////////////////////////////////////////////
/////////////////// DATA HANDLING ////////////////////
async function fileExists(filePath) { async function fileExists(filePath) {
try { try {
await fs.access(filePath); await fs.access(filePath);
@@ -135,15 +153,17 @@ async function fileExists(filePath) {
} }
} }
ipcMain.handle('file-exists', async (_, filePath) => {
return await fileExists(filePath);
});
ipcMain.handle('delete-data', async () => { ipcMain.handle('delete-data', async () => {
if (await fileExists(dataPath)) {
await fs.unlink(dataPath) await fs.unlink(dataPath)
}
}); });
ipcMain.handle('export-data', async () => { ipcMain.handle('export-data', async () => {
if (!await fileExists(dataPath)) {
return
}
const { canceled, filePath } = await dialog.showSaveDialog({ const { canceled, filePath } = await dialog.showSaveDialog({
title: 'Export Data', title: 'Export Data',
defaultPath: 'config.json', defaultPath: 'config.json',
@@ -173,31 +193,8 @@ ipcMain.handle('import-data', async () => {
return true return true
}) })
ipcMain.handle('open-link', async (event, link) => { //////////////////////////////////////////////////////
await shell.openExternal(link) ////////////////////// BEPINEX ///////////////////////
})
ipcMain.handle('launch-game', async (event, mode) => {
const silksongExecutablePath = `${silksongPath}/Hollow Knight Silksong.exe`
if (mode === "modded"){
if (await fileExists(bepinexFolderPath)) {
await shell.openExternal(silksongExecutablePath)
}
else {
await installBepinex()
await shell.openExternal(silksongExecutablePath)
}
}
if (mode === "vanilla"){
if (await fileExists(bepinexFolderPath)) {
await backupBepinex()
await shell.openExternal(silksongExecutablePath)
}
else {
await shell.openExternal(silksongExecutablePath)
}
}
})
async function installBepinex() { async function installBepinex() {
if (await fileExists(bepinexBackupPath)) { if (await fileExists(bepinexBackupPath)) {
@@ -308,6 +305,9 @@ ipcMain.handle('delete-bepinex-backup', async () => {
} }
}) })
//////////////////////////////////////////////////////
/////////////////////// NEXUS ////////////////////////
async function createNexus() { async function createNexus() {
if (nexusAPI == undefined) { if (nexusAPI == undefined) {
return return
@@ -366,6 +366,9 @@ ipcMain.handle('download-mod', async (event, link) => {
nexusWindow.loadURL(link) nexusWindow.loadURL(link)
}) })
//////////////////////////////////////////////////////
//////////////////// UNCATEGORIZE ////////////////////
ipcMain.handle('auto-detect-game-path', async () => { ipcMain.handle('auto-detect-game-path', async () => {
const defaultsSilksongPaths = [ const defaultsSilksongPaths = [
":/Program Files (x86)/Steam/steamapps/common/Hollow Knight Silksong", ":/Program Files (x86)/Steam/steamapps/common/Hollow Knight Silksong",
@@ -385,3 +388,29 @@ ipcMain.handle('auto-detect-game-path', async () => {
ipcMain.handle('load-main-page', () => { ipcMain.handle('load-main-page', () => {
mainWindow.loadFile("renderer/index.html") mainWindow.loadFile("renderer/index.html")
}) })
ipcMain.handle('open-link', async (event, link) => {
await shell.openExternal(link)
})
ipcMain.handle('launch-game', async (event, mode) => {
const silksongExecutablePath = `${silksongPath}/Hollow Knight Silksong.exe`
if (mode === "modded"){
if (await fileExists(bepinexFolderPath)) {
await shell.openExternal(silksongExecutablePath)
}
else {
await installBepinex()
await shell.openExternal(silksongExecutablePath)
}
}
if (mode === "vanilla"){
if (await fileExists(bepinexFolderPath)) {
await backupBepinex()
await shell.openExternal(silksongExecutablePath)
}
else {
await shell.openExternal(silksongExecutablePath)
}
}
})

View File

@@ -7,7 +7,6 @@ contextBridge.exposeInMainWorld('versions', {
}); });
contextBridge.exposeInMainWorld('files', { contextBridge.exposeInMainWorld('files', {
fileExists: (path) => ipcRenderer.invoke('file-exists', path),
delete: () => ipcRenderer.invoke('delete-data'), delete: () => ipcRenderer.invoke('delete-data'),
export: () => ipcRenderer.invoke('export-data'), export: () => ipcRenderer.invoke('export-data'),
import: () => ipcRenderer.invoke('import-data'), import: () => ipcRenderer.invoke('import-data'),
@@ -18,7 +17,9 @@ contextBridge.exposeInMainWorld('files', {
loadBepinexVersion: () => ipcRenderer.invoke('load-bepinex-version'), loadBepinexVersion: () => ipcRenderer.invoke('load-bepinex-version'),
loadBepinexBackupVersion: () => ipcRenderer.invoke('load-bepinex-backup-version'), loadBepinexBackupVersion: () => ipcRenderer.invoke('load-bepinex-backup-version'),
saveNexusAPI: (api) => ipcRenderer.invoke('save-nexus-api', api), saveNexusAPI: (api) => ipcRenderer.invoke('save-nexus-api', api),
loadNexusAPI: () => ipcRenderer.invoke('load-nexus-api') loadNexusAPI: () => ipcRenderer.invoke('load-nexus-api'),
saveTheme: (theme) => ipcRenderer.invoke('save-theme', theme),
loadTheme: () => ipcRenderer.invoke('load-theme')
}); });
contextBridge.exposeInMainWorld('electronAPI', { contextBridge.exposeInMainWorld('electronAPI', {

View File

@@ -9,42 +9,40 @@
<div class="app"> <div class="app">
<video autoplay muted loop id="menu_wallpaper" class="background_video"> <video autoplay muted loop class="background-video" id="background-video" src="assets/background/Silksong.mp4" type="video/mp4"></video>
<source src="assets/background.mp4" type="video/mp4">
</video>
<!-- Sidebar --> <!-- Sidebar -->
<aside class="sidebar"> <aside class="sidebar">
<div class="logo" onclick="navigate('home')"> <div class="logo" onclick="navigate('home')">
<img src="assets/logo.png" alt="Silk Fly Launcher Logo" class="logo_img"/> <img src="assets/logo.png" alt="Silk Fly Launcher Logo" class="logo-img"/>
<h5 class="logo_title">Silk Fly Launcher</h1> <h5 class="logo-title">Silk Fly Launcher</h1>
</div> </div>
<nav class="nav"> <nav class="nav">
<div class="nav-section"> <div class="nav-section">
<span class="nav-title">Execute Silksong</span> <span class="nav-title">Execute Silksong</span>
<button onclick="launch('vanilla')"> <button onclick="launch('vanilla')">
<img src="vanilla_launch_icon.png" class="button_icon"/> <img src="vanilla_launch_icon.png" class="button-icon"/>
Run Vanilla Run Vanilla
<button onclick="launch('modded')"> <button onclick="launch('modded')">
<img src="modded_launch_icon.png" class="button_icon"/> <img src="modded_launch_icon.png" class="button-icon"/>
Run Modded Run Modded
</div> </div>
<div class="nav-section"> <div class="nav-section">
<span class="nav-title">Mods</span> <span class="nav-title">Mods</span>
<button onclick="navigate('mods-installed')"> <button onclick="navigate('mods-installed')">
<img src="installed_mods_icon.png" class="button_icon"/> <img src="installed_mods_icon.png" class="button-icon"/>
Installed Installed
<button onclick="navigate('mods-online')"> <button onclick="navigate('mods-online')">
<img src="online_mods_icon.png" class="button_icon"/> <img src="online_mods_icon.png" class="button-icon"/>
Online Online
</div> </div>
<div class="nav-section"> <div class="nav-section">
<span class="nav-title">Settings</span> <span class="nav-title">Settings</span>
<button onclick="navigate('general-settings')"> <button onclick="navigate('general-settings')">
<img src="general_settings_icon.png" class="button_icon"/> <img src="general_settings_icon.png" class="button-icon"/>
General General
</div> </div>
</nav> </nav>
@@ -90,9 +88,9 @@
<p id="mod-description">No description provided</p> <p id="mod-description">No description provided</p>
<p class="transparent-text" id="mod-version">V1.0.0 last update on 01/01/2026</p> <p class="transparent-text" id="mod-version">V1.0.0 last update on 01/01/2026</p>
<div class="mod-actions"> <div class="horizontal-div">
<a href="https://google.com" class="default-button" id="download-mod-button">Download</a> <a href="www.nexusmods.com/hollowknightsilksong/mods" class="default-button" id="download-mod-button">Download</a>
<a href="https://google.com" class="default-button" id="external-link">Website</a> <a href="www.nexusmods.com/hollowknightsilksong/mods" class="default-button" id="external-link">Website</a>
</div> </div>
</div> </div>
@@ -107,6 +105,21 @@
<input type="text" class="input" id="silksong-path-input" name="silksong-path-input"> <input type="text" class="input" id="silksong-path-input" name="silksong-path-input">
<button class="default-button" onclick="autoDetectGamePath()">Auto Detect</button> <button class="default-button" onclick="autoDetectGamePath()">Auto Detect</button>
</div> </div>
<div class="horizontal-div">
<label for="silksong-path-label">Themes: </label>
<div class="themes-div">
<div class="default-button longer-button" id="themes-button" onclick="toggleThemesMenu()">Silksong</div>
<div class="themes-menu longer-button" id="themes-menu">
<li onclick="changeTheme('Silksong')">Silksong</li>
<li onclick="changeTheme('Citadel of song')">Citadel of song (WIP)</li>
<li onclick="changeTheme('Cradle')">Cradle (WIP)</li>
<li onclick="changeTheme('Abyss')">Abyss (WIP)</li>
<li onclick="changeTheme('Greyroot')">Greyroot (WIP)</li>
<li onclick="changeTheme('Surface')">Surface (WIP)</li>
<li onclick="changeTheme('Steel')">Steel (WIP)</li>
</div>
</div>
</div>
<br> <br>
<h2>BepInEx</h2> <h2>BepInEx</h2>
<p class="transparent-text" id="bepinex-version-text"></p> <p class="transparent-text" id="bepinex-version-text"></p>

View File

@@ -9,7 +9,12 @@ const modTemplate = document.getElementById("mod-template");
const versionText = HomeTemplate.content.getElementById("version-text"); const versionText = HomeTemplate.content.getElementById("version-text");
on_startup()
async function on_startup() {
changeTheme(await files.loadTheme())
navigate("home") navigate("home")
}
async function navigate(page) { async function navigate(page) {
view.replaceChildren() view.replaceChildren()
@@ -105,17 +110,18 @@ async function navigate(page) {
silksongPathInput.value = await files.loadSilksongPath() silksongPathInput.value = await files.loadSilksongPath()
silksongPathInput.addEventListener('input', async function(event) { silksongPathInput.addEventListener('input', async function(event) {
let silksongPath = silksongPathInput.value let silksongPath = silksongPathInput.value
await files.saveSilksongPath(silksongPath) files.saveSilksongPath(silksongPath)
}); });
nexusAPIInput.value = await files.loadNexusAPI() nexusAPIInput.value = await files.loadNexusAPI()
nexusAPIInput.addEventListener('input', async function(event) { nexusAPIInput.addEventListener('input', async function(event) {
let nexusAPI = nexusAPIInput.value let nexusAPI = nexusAPIInput.value
await files.saveNexusAPI(nexusAPI) files.saveNexusAPI(nexusAPI)
}); });
view.appendChild(settingsTemplateCopy) view.appendChild(settingsTemplateCopy)
setBepinexVersion() setBepinexVersion()
setThemeButton()
verifyNexusAPI() verifyNexusAPI()
break; break;
} }
@@ -135,6 +141,8 @@ async function autoDetectGamePath() {
} }
async function deleteData() { async function deleteData() {
changeTheme("Silksong")
toggleThemesMenu()
await files.delete() await files.delete()
document.getElementById("silksong-path-input").value = await files.loadSilksongPath() document.getElementById("silksong-path-input").value = await files.loadSilksongPath()
document.getElementById("nexus-api-input").value = await files.loadNexusAPI() document.getElementById("nexus-api-input").value = await files.loadNexusAPI()
@@ -148,6 +156,8 @@ async function importData() {
await files.import() await files.import()
document.getElementById("silksong-path-input").value = await files.loadSilksongPath() document.getElementById("silksong-path-input").value = await files.loadSilksongPath()
document.getElementById("nexus-api-input").value = await files.loadNexusAPI() document.getElementById("nexus-api-input").value = await files.loadNexusAPI()
changeTheme(await files.loadTheme())
toggleThemesMenu()
} }
async function installBepinex() { async function installBepinex() {
@@ -206,3 +216,42 @@ async function verifyNexusAPI() {
nexusCheckImage.src = "assets/cross.svg" nexusCheckImage.src = "assets/cross.svg"
} }
} }
function toggleThemesMenu() {
const themesMenu = document.getElementById("themes-menu")
if (themesMenu) {
themesMenu.classList.toggle("show")
}
}
async function setThemeButton() {
const themesButton = document.getElementById("themes-button")
if (themesButton) {
themesButton.textContent = await files.loadTheme()
}
}
function changeTheme(theme) {
files.saveTheme(theme)
setThemeButton()
const themesColors = {
"var": ["--primary-color", "--secondary-color", "--background-color"],
"Silksong": ["rgba(255, 25, 0, 0.3)", "#ff6b6b", "rgba(255, 72, 0, 0.2)"],
"Citadel of song": ["rgba(160, 116, 89, 0.3)", "#d3ba91", "rgba(123, 102, 93, 0.2)"],
"Cradle": ["rgba(123, 136, 255, 0.3)", "#7c9fea", "rgba(61, 88, 150, 0.2)"],
"Abyss": ["rgba(255, 255, 255, 0.3)", "#ececec", "rgba(255, 255, 255, 0.2)"],
"Greyroot": ["rgba(181, 255, 180, 0.3)", "#c1ffcd", "rgba(90, 165, 130, 0.2)"],
"Surface": ["rgba(75, 120, 255, 0.3)", "#87c3ff", "rgba(42, 107, 203, 0.2)"],
"Steel": ["rgba(164, 164, 164, 0.3)", "#c5b9b9", "rgba(255, 255, 255, 0.2)"]
}
for(let i = 0; i < 3; i++) {
document.documentElement.style.setProperty(themesColors.var[i], themesColors[theme][i])
}
const backgroundVideo = document.getElementById("background-video")
backgroundVideo.src = `assets/background/${theme}.mp4`
toggleThemesMenu()
}

View File

@@ -1,11 +1,21 @@
* { * {
margin: 0; margin: 0;
padding: 0;
box-sizing: border-box; box-sizing: border-box;
font-family: "Segoe UI", sans-serif; font-family: "Segoe UI", sans-serif;
cursor: url("assets/cursor.png") 0 0, auto !important; cursor: url("assets/cursor.png") 0 0, auto !important;
} }
:root {
--primary-color: rgba(255, 25, 0, 0.3);
--secondary-color: #ff6b6b;
--background-color: rgba(255, 72, 0, 0.2);
--text-color: #eee;
--transparent-black: rgba(0, 0, 0, 0.4);
--darker-transparent-black: rgba(0, 0, 0, 0.8);
--transparent-grey: rgba(30, 30, 30, 0.8)
}
body { body {
background: black; background: black;
color: #eee; color: #eee;
@@ -18,7 +28,7 @@ body {
height: 100vh; height: 100vh;
} }
.background_video { .background-video {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
@@ -31,8 +41,8 @@ body {
.sidebar { .sidebar {
width: 280px; width: 280px;
background: rgba(0, 0, 0, 0.8); background: var(--darker-transparent-black);
border-right: 1px solid rgba(255, 0, 0, 0.15); border-right: 1px solid var(--background-color);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
} }
@@ -43,18 +53,16 @@ body {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 32px; font-size: 32px;
cursor: pointer; border-bottom: 1px solid var(--background-color);
border-bottom: 1px solid rgba(255, 72, 0, 0.2); transition: background 0.2s ease;
transition: background 0.2s;
} }
.logo:hover { .logo:hover {
background: rgba(255, 0, 0, 0.08); background: var(--background-color);
} }
.logo_img { .logo-img {
height: 50px; height: 50px;
width: auto;
} }
.nav { .nav {
@@ -70,11 +78,11 @@ body {
font-size: 13px; font-size: 13px;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 1px; letter-spacing: 1px;
color: #fff; color: var(--text-color);
margin-bottom: 10px; margin-bottom: 10px;
padding: 0 4px 4px; padding: 0 4px 4px;
border-bottom: 1px solid #ff6b6b; border-bottom: 1px solid var(--secondary-color);
} }
.nav button { .nav button {
@@ -82,17 +90,16 @@ body {
padding: 10px 14px; padding: 10px 14px;
margin-bottom: 8px; margin-bottom: 8px;
background: transparent; background: transparent;
border: 1px solid black; border: 1px solid transparent;
border-radius: 4px; border-radius: 4px;
color: #eee; color: var(--text-color);
cursor: pointer;
text-align: left; text-align: left;
transition: all 0.2s ease; transition: all 0.2s ease;
} }
.nav button:hover { .nav button:hover {
background: rgba(255, 72, 0, 0.2); background: var(--background-color);
border-color: rgba(255, 25, 0, 0.3); border-color: var(--primary-color);
} }
.content { .content {
@@ -103,7 +110,7 @@ body {
.content h1 { .content h1 {
font-size: 28px; font-size: 28px;
margin-bottom: 20px; margin-bottom: 20px;
color: #ffffff; color: var(--text-color);
display: flex; display: flex;
justify-content: center; justify-content: center;
} }
@@ -111,19 +118,18 @@ body {
.content h2 { .content h2 {
font-size: 24px; font-size: 24px;
margin-bottom: 20px; margin-bottom: 20px;
color: #ffffff; color: var(--text-color);
padding: 0 4px 4px; padding: 0 4px 4px;
border-bottom: 1px solid #ff6b6b; border-bottom: 1px solid var(--secondary-color);
} }
.view { .view {
width: 100%; background: var(--darker-transparent-black);
background: rgba(0, 0, 0, 0.8);
border-radius: 12px; border-radius: 12px;
padding: 40px; padding: 40px;
position: relative; position: relative;
z-index: 0; z-index: 0;
box-shadow: 0 0 50px rgba(0, 0, 0, 0.15); box-shadow: 0 0 50px var(--darker-transparent-black);
overflow: auto; overflow: auto;
height: 90%; height: 90%;
} }
@@ -139,35 +145,33 @@ body {
flex: 1; flex: 1;
height: 30px; height: 30px;
padding: 0 12px; padding: 0 12px;
background: rgba(0, 0, 0, 0.4); background: var(--transparent-black);
border: 1px solid #ff6b6b; border: 1px solid var(--secondary-color);
border-radius: 4px; border-radius: 4px;
color: #eee; color: var(--text-color);
font-size: 13px; font-size: 13px;
outline: none; outline: none;
transition: all 0.2s ease; transition: all 0.2s ease;
} }
.input:hover { .input:hover {
background: rgba(0, 0, 0, 0.55); background: var(--darker-transparent-black);
border-color: rgba(255, 25, 0, 0.3); border-color: var(--primary-color);
} }
.input:focus { .input:focus {
background: rgba(0, 0, 0, 0.65); background: var(--darker-transparent-black);
border-color: rgba(255, 25, 0, 0.3); border-color: var(--primary-color);
box-shadow: 0 0 0 1px rgba(255, 25, 0, 0.2); box-shadow: 0 0 0 1px var(--primary-color);
} }
.default-button { .default-button {
width: 120px; width: 120px;
height: 40px; height: 40px;
padding: 2px; background: var(--transparent-black);
background: rgba(0, 0, 0, 0.4); border: 1px solid var(--secondary-color);
border: 1px solid #ff6b6b;
border-radius: 4px; border-radius: 4px;
color: #eee; color: var(--text-color);
cursor: pointer;
font-size: 16px; font-size: 16px;
transition: all 0.2s ease; transition: all 0.2s ease;
display: flex; display: flex;
@@ -176,19 +180,17 @@ body {
} }
.default-button:hover { .default-button:hover {
background: rgba(255, 72, 0, 0.2); background: var(--background-color);
border-color: rgba(255, 25, 0, 0.3); border-color: var(--primary-color);
} }
.important-button { .important-button {
width: 120px; width: 120px;
height: 40px; height: 40px;
padding: 2px;
background: rgba(100, 0, 0, 0.4); background: rgba(100, 0, 0, 0.4);
border: 1px solid rgba(200, 25, 0); border: 1px solid rgba(200, 25, 0);
border-radius: 4px; border-radius: 4px;
color: #eee; color: var(--text-color);
cursor: pointer;
font-size: 16px; font-size: 16px;
transition: all 0.2s ease; transition: all 0.2s ease;
display: flex; display: flex;
@@ -208,6 +210,10 @@ body {
font-size: 32px; font-size: 32px;
} }
.longer-button {
width: 240px;
}
.search-container { .search-container {
position: absolute; position: absolute;
left: 50%; left: 50%;
@@ -221,7 +227,7 @@ body {
border: none; border: none;
border-radius: 50px; border-radius: 50px;
background-color: rgba(255, 255, 255, 0.15); background-color: rgba(255, 255, 255, 0.15);
color: #fff; color: var(--text-color);
outline: none; outline: none;
transition: background 0.3s, width 0.3s; transition: background 0.3s, width 0.3s;
} }
@@ -238,20 +244,15 @@ body {
transform: translateY(-50%); transform: translateY(-50%);
background: none; background: none;
border: none; border: none;
color: #fff; color: var(--text-color);
font-size: 18px; font-size: 18px;
cursor: pointer; cursor: pointer;
} }
.mods-container { .mods-container {
width: 100%;
height: 80%; height: 80%;
transform: translateY(50px); transform: translateY(50px);
background: rgba(30, 30, 30, 0.8);
border-radius: 12px;
padding: 20px; padding: 20px;
position: relative;
box-shadow: 0 0 50px rgba(30, 30, 30, 0.15);
overflow: auto; overflow: auto;
} }
@@ -262,12 +263,10 @@ body {
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
} }
.mod-container:not(:last-child) { .mod-container:not(:last-child) {
border-bottom: 1px solid rgba(150, 25, 0, 0.5); border-bottom: 1px solid var(--secondary-color);
} }
.mod-text { .mod-text {
@@ -275,17 +274,10 @@ body {
flex-direction: column; flex-direction: column;
} }
.mod-actions {
margin-top: 12px;
display: flex;
gap: 20px;
}
.mod-icon { .mod-icon {
width: 128px; width: 128px;
height: 128px; height: 128px;
object-fit: contain; object-fit: contain;
opacity: 0.9;
} }
::-webkit-scrollbar { ::-webkit-scrollbar {
@@ -293,16 +285,17 @@ body {
} }
::-webkit-scrollbar-track { ::-webkit-scrollbar-track {
background: #101010; background: var(--transparent-grey);
border-radius: 5px;
} }
::-webkit-scrollbar-thumb { ::-webkit-scrollbar-thumb {
background: rgb(120, 25, 0); background: var(--primary-color);
border-radius: 7px; border-radius: 5px;
} }
::-webkit-scrollbar-thumb:hover { ::-webkit-scrollbar-thumb:hover {
background: rgb(170, 25, 0); background: var(--secondary-color);
} }
.transparent-text { .transparent-text {
@@ -316,10 +309,36 @@ body {
} }
.link { .link {
color: #ffffff; color: var(--text-color);
transition: all 0.2s ease; transition: all 0.2s ease;
} }
.link:hover { .link:hover {
color: #ff6b6b; color: var(--secondary-color);
}
.themes-div {
position: relative;
}
.themes-menu {
display: none;
position: absolute;
background: var(--darker-transparent-black);
border: 1px solid var(--secondary-color);
border-radius: 4px;
}
.themes-menu.show {
display: block;
}
.themes-menu li {
padding: 6px;
display: flex;
justify-content: center;
}
.themes-menu li:hover {
background: var(--background-color);
} }

View File

@@ -1,17 +1,15 @@
.welcome-div { .welcome-div {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%;
flex: 1; flex: 1;
padding: 0 60px; padding: 0 60px;
} }
.title { .title {
display: flex; display: flex;
flex: 1;
font-size: 60px; font-size: 60px;
margin-bottom: 60px; margin-bottom: 60px;
color: #ffffff; color: #eee;
justify-content: center; justify-content: center;
} }
@@ -20,6 +18,4 @@
flex: 2; flex: 2;
align-items: center; align-items: center;
justify-content: space-between; justify-content: space-between;
margin-top: 8px;
gap: 40px;
} }

View File

@@ -8,9 +8,7 @@
</head> </head>
<body> <body>
<div class="app"> <div class="app">
<video autoplay muted loop id="menu_wallpaper" class="background_video"> <video autoplay muted loop class="background-video" id="background-video" src="assets/background/Silksong.mp4" type="video/mp4"></video>
<source src="assets/background.mp4" type="video/mp4">
</video>
<div class="welcome-div" id="main-div"> <div class="welcome-div" id="main-div">
<br> <br>
@@ -59,6 +57,21 @@
<template id="style-template"> <template id="style-template">
<h1 class="title">Chose the theme of the app</h1> <h1 class="title">Chose the theme of the app</h1>
<div class="horizontal-div welcome-div">
<label for="silksong-path-label">Themes: </label>
<div class="themes-div">
<div class="default-button longer-button" id="themes-button" onclick="toggleThemesMenu()">Silksong</div>
<div class="themes-menu longer-button" id="themes-menu">
<li onclick="changeTheme('Silksong')">Silksong</li>
<li onclick="changeTheme('Citadel of song')">Citadel of song (WIP)</li>
<li onclick="changeTheme('Cradle')">Cradle (WIP)</li>
<li onclick="changeTheme('Abyss')">Abyss (WIP)</li>
<li onclick="changeTheme('Greyroot')">Greyroot (WIP)</li>
<li onclick="changeTheme('Surface')">Surface (WIP)</li>
<li onclick="changeTheme('Steel')">Steel (WIP)</li>
</div>
</div>
</div>
</template> </template>
<template id="tutorial-template"> <template id="tutorial-template">

View File

@@ -110,3 +110,42 @@ async function importData() {
electronAPI.loadMainPage() electronAPI.loadMainPage()
} }
} }
function toggleThemesMenu() {
const themesMenu = document.getElementById("themes-menu")
if (themesMenu) {
themesMenu.classList.toggle("show")
}
}
async function setThemeButton() {
const themesButton = document.getElementById("themes-button")
if (themesButton) {
themesButton.textContent = await files.loadTheme()
}
}
function changeTheme(theme) {
files.saveTheme(theme)
setThemeButton()
const themesColors = {
"var": ["--primary-color", "--secondary-color", "--background-color"],
"Silksong": ["rgba(255, 25, 0, 0.3)", "#ff6b6b", "rgba(255, 72, 0, 0.2)"],
"Citadel of song": ["rgba(160, 116, 89, 0.3)", "#d3ba91", "rgba(123, 102, 93, 0.2)"],
"Cradle": ["rgba(123, 136, 255, 0.3)", "#7c9fea", "rgba(61, 88, 150, 0.2)"],
"Abyss": ["rgba(255, 255, 255, 0.3)", "#ececec", "rgba(255, 255, 255, 0.2)"],
"Greyroot": ["rgba(181, 255, 180, 0.3)", "#c1ffcd", "rgba(90, 165, 130, 0.2)"],
"Surface": ["rgba(75, 120, 255, 0.3)", "#87c3ff", "rgba(42, 107, 203, 0.2)"],
"Steel": ["rgba(164, 164, 164, 0.3)", "#c5b9b9", "rgba(255, 255, 255, 0.2)"]
}
for(let i = 0; i < 3; i++) {
document.documentElement.style.setProperty(themesColors.var[i], themesColors[theme][i])
}
const backgroundVideo = document.getElementById("background-video")
backgroundVideo.src = `assets/background/${theme}.mp4`
toggleThemesMenu()
}