mirror of
https://github.com/Gabi-Zar/Silk-Fly-Launcher.git
synced 2026-04-17 05:26:04 +02:00
826 lines
30 KiB
JavaScript
826 lines
30 KiB
JavaScript
////////////////// CONST FOR INDEX ///////////////////
|
|
const title = document.getElementById("title");
|
|
const view = document.getElementById("view");
|
|
|
|
const HomeTemplate = document.getElementById("home-template");
|
|
const installedModsTemplate = document.getElementById("installed-mods-template");
|
|
const nexusModsTemplate = document.getElementById("nexus-mods-template");
|
|
const thunderstoreModsTemplate = document.getElementById("thunderstore-mods-template");
|
|
const settingsTemplate = document.getElementById("settings-template");
|
|
const installedModTemplate = document.getElementById("installed-mod-template");
|
|
const modTemplate = document.getElementById("mod-template");
|
|
|
|
let oldPage;
|
|
let actualTheme = [];
|
|
|
|
let searchValueNexus = "";
|
|
let searchValueInstalled = "";
|
|
let searchValueThunderstore = "";
|
|
|
|
let onlineSortFilter = "downloads";
|
|
let installedSortFilter = "name";
|
|
let thunderstoreSortFilter = "downloads";
|
|
|
|
let onlineSortOrder = "DESC";
|
|
let installedSortOrder = "ASC";
|
|
let thunderstoreSortOrder = "DESC";
|
|
|
|
let onlineOffset = 0;
|
|
let installedOffset = 0;
|
|
let thunderstoreOffset = 0;
|
|
|
|
let lastOnlineOffset = 0;
|
|
let lastInstalledOffset = 0;
|
|
let lastThunderstoreOffset = 0;
|
|
|
|
let onlineModsCount = 10;
|
|
let installedModsCount = 10;
|
|
let thunderstoreModsCount = 10;
|
|
|
|
let onlineModsTotalCount;
|
|
let installedModsTotalCount;
|
|
let thunderstoreModsTotalCount;
|
|
|
|
//////////////////////////////////////////////////////
|
|
///////////////// CONST FOR WELCOME //////////////////
|
|
|
|
let actualPage = 0;
|
|
|
|
const pageDiv = document.getElementById("page");
|
|
const buttonDiv = document.getElementById("button-div");
|
|
|
|
const oneButtonTemplate = document.getElementById("one-button-template");
|
|
const twoButtonTemplate = document.getElementById("two-button-template");
|
|
|
|
const welcomeTemplate = document.getElementById("welcome-template");
|
|
const silksongPathTemplate = document.getElementById("path-template");
|
|
const nexusTemplate = document.getElementById("nexus-template");
|
|
const styleTemplate = document.getElementById("style-template");
|
|
|
|
//////////////////////////////////////////////////////
|
|
////////////////////// STARTUP ///////////////////////
|
|
|
|
on_startup();
|
|
|
|
async function on_startup() {
|
|
if ((await electronAPI.getPage()) == "index.html") {
|
|
const theme = await files.loadTheme();
|
|
changeTheme(theme[0], theme[1]);
|
|
navigate("home");
|
|
} else if ((await electronAPI.getPage()) == "welcome.html") {
|
|
changeTheme("Silksong");
|
|
welcomeNavigate();
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
///////////////////// NAVIGATE ///////////////////////
|
|
|
|
async function navigate(page) {
|
|
if (oldPage == page) {
|
|
return;
|
|
}
|
|
if (page == "refresh") {
|
|
page = oldPage;
|
|
}
|
|
oldPage = page;
|
|
|
|
view.replaceChildren();
|
|
switch (page) {
|
|
case "home":
|
|
title.innerText = "Silk Fly Launcher";
|
|
const HomeTemplateCopy = HomeTemplate.content.cloneNode(true);
|
|
versionText = HomeTemplateCopy.getElementById("version-text");
|
|
versionText.innerText = await versions.silkFlyLauncher();
|
|
view.appendChild(HomeTemplateCopy);
|
|
break;
|
|
|
|
case "mods-installed":
|
|
title.innerText = "Installed Mods";
|
|
const installedModsTemplateCopy = installedModsTemplate.content.cloneNode(true);
|
|
const installedModsContainer = installedModsTemplateCopy.getElementById("mods-container");
|
|
const searchFormInstalled = installedModsTemplateCopy.getElementById("search-form");
|
|
const searchInputInstalled = installedModsTemplateCopy.getElementById("search-input");
|
|
|
|
searchFormInstalled.addEventListener("submit", function (event) {
|
|
event.preventDefault();
|
|
});
|
|
searchInputInstalled.value = searchValueInstalled;
|
|
|
|
view.appendChild(installedModsTemplateCopy);
|
|
toggleSelectedListButton("sort-menu", installedSortFilter);
|
|
setSortOrderButton();
|
|
|
|
const { installedModsInfo, installedTotalCount } = await mods.getMods(page);
|
|
installedModsTotalCount = installedTotalCount;
|
|
if (installedModsInfo == []) {
|
|
break;
|
|
}
|
|
|
|
for (const modInfo of installedModsInfo) {
|
|
const installedModTemplateCopy = installedModTemplate.content.cloneNode(true);
|
|
|
|
if (modInfo.name) {
|
|
const modTitleText = installedModTemplateCopy.getElementById("mod-title");
|
|
modTitleText.innerText = modInfo.name;
|
|
}
|
|
if (modInfo.author) {
|
|
const modAuthorText = installedModTemplateCopy.getElementById("mod-author");
|
|
modAuthorText.innerText = `by ${modInfo.author}`;
|
|
}
|
|
if (modInfo.endorsements) {
|
|
const modEndorsementsNumber = installedModTemplateCopy.getElementById("mod-endorsements-number");
|
|
if (modInfo.endorsements > 1) {
|
|
modEndorsementsNumber.innerText = `${modInfo.endorsements} likes`;
|
|
} else {
|
|
modEndorsementsNumber.innerText = `${modInfo.endorsements} like`;
|
|
}
|
|
}
|
|
if (modInfo.downloads) {
|
|
const modDownloadsNumber = installedModTemplateCopy.getElementById("mod-downloads-number");
|
|
if (modInfo.downloads > 1) {
|
|
modDownloadsNumber.innerText = `${modInfo.downloads} downloads`;
|
|
} else {
|
|
modDownloadsNumber.innerText = `${modInfo.downloads} download`;
|
|
}
|
|
}
|
|
if (modInfo.summary) {
|
|
const modDescriptionText = installedModTemplateCopy.getElementById("mod-description");
|
|
modDescriptionText.innerText = modInfo.summary;
|
|
}
|
|
if (modInfo.pictureUrl) {
|
|
const modPicture = installedModTemplateCopy.getElementById("mod-icon");
|
|
modPicture.src = modInfo.pictureUrl;
|
|
}
|
|
if (modInfo.version || modInfo.updatedAt) {
|
|
let text = "";
|
|
if (modInfo.version) {
|
|
text = text.concat(`V${modInfo.version} `);
|
|
}
|
|
if (modInfo.updatedAt) {
|
|
text = text.concat(`last updated on ${modInfo.updatedAt.slice(0, 10)}`);
|
|
}
|
|
const modVersionText = installedModTemplateCopy.getElementById("mod-version");
|
|
modVersionText.innerText = text;
|
|
}
|
|
|
|
const isActivatedCheckbox = installedModTemplateCopy.getElementById("activated-mod");
|
|
if (modInfo.activated) {
|
|
isActivatedCheckbox.checked = true;
|
|
}
|
|
|
|
isActivatedCheckbox.addEventListener("change", async function () {
|
|
if (this.checked) {
|
|
mods.activateMods(modInfo.modId);
|
|
searchInstalledMods();
|
|
} else {
|
|
mods.deactivateMods(modInfo.modId);
|
|
searchInstalledMods();
|
|
}
|
|
});
|
|
|
|
if (modInfo.source && modInfo.source != "local") {
|
|
const modSource = installedModTemplateCopy.getElementById("mod-source");
|
|
modSource.innerText = `From ${modInfo.source}`;
|
|
|
|
const modUrls = {
|
|
nexusmods: `https://www.nexusmods.com/hollowknightsilksong/mods/${modInfo.modId}`,
|
|
thunderstore: `https://new.thunderstore.io/c/hollow-knight-silksong/p/${modInfo.author}/${modInfo.name}`,
|
|
};
|
|
|
|
const modLinkButton = installedModTemplateCopy.getElementById("external-link");
|
|
modLinkButton.href = modUrls[modInfo.source];
|
|
modLinkButton.addEventListener("click", function (event) {
|
|
event.preventDefault();
|
|
const modLink = modLinkButton.href;
|
|
electronAPI.openExternalLink(modLink);
|
|
});
|
|
} else {
|
|
const modLinkButton = installedModTemplateCopy.getElementById("external-link");
|
|
modLinkButton.remove();
|
|
}
|
|
|
|
const uninstallModButton = installedModTemplateCopy.getElementById("uninstall-mod-button");
|
|
uninstallModButton.addEventListener("click", async function (event) {
|
|
event.preventDefault();
|
|
await mods.uninstall(modInfo.modId);
|
|
|
|
navigate("refresh");
|
|
});
|
|
|
|
installedModsContainer.appendChild(installedModTemplateCopy);
|
|
}
|
|
|
|
break;
|
|
|
|
case "mods-online":
|
|
title.innerText = "Nexus Mods";
|
|
const onlineModsTemplateCopy = nexusModsTemplate.content.cloneNode(true);
|
|
const ModsContainer = onlineModsTemplateCopy.getElementById("mods-container");
|
|
const searchFormNexus = onlineModsTemplateCopy.getElementById("search-form");
|
|
const searchInputNexus = onlineModsTemplateCopy.getElementById("search-input");
|
|
|
|
searchFormNexus.addEventListener("submit", async function (event) {
|
|
event.preventDefault();
|
|
});
|
|
searchInputNexus.value = searchValueNexus;
|
|
|
|
view.appendChild(onlineModsTemplateCopy);
|
|
toggleSelectedListButton("sort-menu", onlineSortFilter);
|
|
setSortOrderButton();
|
|
|
|
const { onlineModsInfo, onlineTotalCount } = await mods.getMods(page);
|
|
onlineModsTotalCount = onlineTotalCount;
|
|
if (onlineModsInfo == undefined) {
|
|
break;
|
|
}
|
|
for (const mod of onlineModsInfo) {
|
|
if (mod.name == undefined) {
|
|
continue;
|
|
}
|
|
const modTemplateCopy = modTemplate.content.cloneNode(true);
|
|
if (mod.name) {
|
|
const modTitleText = modTemplateCopy.getElementById("mod-title");
|
|
modTitleText.innerText = mod.name;
|
|
}
|
|
if (mod.author) {
|
|
const modAuthorText = modTemplateCopy.getElementById("mod-author");
|
|
modAuthorText.innerText = `by ${mod.author}`;
|
|
}
|
|
if (mod.endorsements) {
|
|
const modEndorsementsNumber = modTemplateCopy.getElementById("mod-endorsements-number");
|
|
if (mod.endorsements > 1) {
|
|
modEndorsementsNumber.innerText = `${mod.endorsements} likes`;
|
|
} else {
|
|
modEndorsementsNumber.innerText = `${mod.endorsements} like`;
|
|
}
|
|
}
|
|
if (mod.downloads) {
|
|
const modDownloadsNumber = modTemplateCopy.getElementById("mod-downloads-number");
|
|
if (mod.downloads > 1) {
|
|
modDownloadsNumber.innerText = `${mod.downloads} downloads`;
|
|
} else {
|
|
modDownloadsNumber.innerText = `${mod.downloads} download`;
|
|
}
|
|
}
|
|
if (mod.summary) {
|
|
const modDescriptionText = modTemplateCopy.getElementById("mod-description");
|
|
modDescriptionText.innerText = mod.summary;
|
|
}
|
|
if (mod.pictureUrl) {
|
|
const modPicture = modTemplateCopy.getElementById("mod-icon");
|
|
modPicture.src = mod.pictureUrl;
|
|
}
|
|
if (mod.version && mod.updatedAt) {
|
|
const modVersionText = modTemplateCopy.getElementById("mod-version");
|
|
modVersionText.innerText = `V${mod.version} last updated on ${mod.updatedAt.slice(0, 10)}`;
|
|
}
|
|
|
|
const modUrl = `https://www.nexusmods.com/hollowknightsilksong/mods/${mod.modId}`;
|
|
|
|
const modLinkButton = modTemplateCopy.getElementById("external-link");
|
|
modLinkButton.href = modUrl;
|
|
modLinkButton.addEventListener("click", function (event) {
|
|
event.preventDefault();
|
|
const modLink = modLinkButton.href;
|
|
electronAPI.openExternalLink(modLink);
|
|
});
|
|
|
|
modDownloadButton = modTemplateCopy.getElementById("download-mod-button");
|
|
modDownloadButton.addEventListener("click", function (event) {
|
|
event.preventDefault();
|
|
const modDownloadLink = `${modUrl}?tab=files`;
|
|
nexus.download(modDownloadLink);
|
|
});
|
|
|
|
ModsContainer.appendChild(modTemplateCopy);
|
|
}
|
|
break;
|
|
|
|
case "mods-thunderstore":
|
|
title.innerText = "Thunderstore Mods";
|
|
const thunderstoreModsTemplateCopy = thunderstoreModsTemplate.content.cloneNode(true);
|
|
const thunderstoreModsContainer = thunderstoreModsTemplateCopy.getElementById("mods-container");
|
|
const searchFormThunderstore = thunderstoreModsTemplateCopy.getElementById("search-form");
|
|
const searchInputThunderstore = thunderstoreModsTemplateCopy.getElementById("search-input");
|
|
|
|
searchFormThunderstore.addEventListener("submit", async function (event) {
|
|
event.preventDefault();
|
|
});
|
|
searchInputThunderstore.value = searchValueThunderstore;
|
|
|
|
view.appendChild(thunderstoreModsTemplateCopy);
|
|
toggleSelectedListButton("sort-menu", thunderstoreSortFilter);
|
|
setSortOrderButton();
|
|
break;
|
|
case "general-settings":
|
|
title.innerText = "Settings";
|
|
const settingsTemplateCopy = settingsTemplate.content.cloneNode(true);
|
|
const silksongPathInput = settingsTemplateCopy.getElementById("silksong-path-input");
|
|
const nexusAPIForm = settingsTemplateCopy.getElementById("nexus-api-form");
|
|
const versionsList = settingsTemplateCopy.getElementById("versions-list");
|
|
const versionsDictionnary = {
|
|
"Silk-Fly-Launcher": `Silk Fly Launcher: v${await versions.silkFlyLauncher()}`,
|
|
Electron: `Electron: v${versions.electron()}`,
|
|
Node: `Node.js: v${versions.node()}`,
|
|
Chromium: `Chromium: v${versions.chromium()}`,
|
|
};
|
|
const lacePinCheckbox = settingsTemplateCopy.getElementById("lace-pin");
|
|
|
|
silksongPathInput.value = await files.loadSilksongPath();
|
|
silksongPathInput.addEventListener("input", async function (event) {
|
|
let silksongPath = silksongPathInput.value;
|
|
files.saveSilksongPath(silksongPath);
|
|
});
|
|
|
|
nexusAPIForm.addEventListener("submit", function (event) {
|
|
event.preventDefault();
|
|
});
|
|
|
|
for (const element of versionsList.children) {
|
|
element.innerText = versionsDictionnary[element.id];
|
|
}
|
|
|
|
const theme = await files.loadTheme();
|
|
lacePinCheckbox.checked = theme[1];
|
|
|
|
lacePinCheckbox.addEventListener("change", async function () {
|
|
if (this.checked) {
|
|
const theme = await files.loadTheme();
|
|
changeTheme(theme[0], true);
|
|
toggleThemesMenu();
|
|
} else {
|
|
const theme = await files.loadTheme();
|
|
changeTheme(theme[0], false);
|
|
toggleThemesMenu();
|
|
}
|
|
});
|
|
|
|
view.appendChild(settingsTemplateCopy);
|
|
setBepinexVersion();
|
|
setThemeButton();
|
|
toggleSelectedListButton("themes-menu", actualTheme[0]);
|
|
setNexusAPI();
|
|
break;
|
|
}
|
|
}
|
|
|
|
async function welcomeNavigate() {
|
|
pageDiv.replaceChildren();
|
|
switch (actualPage) {
|
|
case 0:
|
|
pageDiv.appendChild(welcomeTemplate.content.cloneNode(true));
|
|
buttonDiv.replaceChildren();
|
|
buttonDiv.appendChild(oneButtonTemplate.content.cloneNode(true));
|
|
break;
|
|
|
|
case 1:
|
|
pageDiv.appendChild(silksongPathTemplate.content.cloneNode(true));
|
|
buttonDiv.replaceChildren();
|
|
buttonDiv.appendChild(twoButtonTemplate.content.cloneNode(true));
|
|
|
|
const silksongPathInput = document.getElementById("silksong-path-input");
|
|
if ((await files.loadSilksongPath()) == "") {
|
|
autoDetectGamePath();
|
|
} else {
|
|
document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
|
|
}
|
|
|
|
silksongPathInput.addEventListener("input", async function (event) {
|
|
let silksongPath = silksongPathInput.value;
|
|
await files.saveSilksongPath(silksongPath);
|
|
});
|
|
break;
|
|
|
|
case 2:
|
|
pageDiv.appendChild(styleTemplate.content.cloneNode(true));
|
|
toggleSelectedListButton("themes-menu", actualTheme[0]);
|
|
break;
|
|
|
|
case 3:
|
|
pageDiv.appendChild(nexusTemplate.content.cloneNode(true));
|
|
const nexusLink = document.getElementById("external-link");
|
|
const nexusAPIForm = document.getElementById("nexus-api-form");
|
|
|
|
nexusLink.addEventListener("click", function (event) {
|
|
event.preventDefault();
|
|
const url = nexusLink.href;
|
|
electronAPI.openExternalLink(url);
|
|
});
|
|
|
|
nexusAPIForm.addEventListener("submit", function (event) {
|
|
event.preventDefault();
|
|
});
|
|
setNexusAPI();
|
|
break;
|
|
|
|
case 4:
|
|
electronAPI.loadMainPage();
|
|
break;
|
|
}
|
|
}
|
|
|
|
function next() {
|
|
actualPage++;
|
|
welcomeNavigate();
|
|
}
|
|
|
|
function back() {
|
|
actualPage--;
|
|
welcomeNavigate();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
/////////////////// DATA HANDLING ////////////////////
|
|
|
|
async function initialImportData() {
|
|
if (await files.import()) {
|
|
electronAPI.loadMainPage();
|
|
}
|
|
}
|
|
|
|
async function importData() {
|
|
await files.import();
|
|
document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
|
|
const lacePinCheckbox = document.getElementById("lace-pin");
|
|
const theme = await files.loadTheme();
|
|
lacePinCheckbox.checked = theme[1];
|
|
changeTheme(theme[0]);
|
|
toggleThemesMenu();
|
|
}
|
|
|
|
async function exportData() {
|
|
await files.export();
|
|
}
|
|
|
|
async function deleteData() {
|
|
const lacePinCheckbox = document.getElementById("lace-pin");
|
|
lacePinCheckbox.checked = false;
|
|
changeTheme("Silksong");
|
|
toggleThemesMenu();
|
|
await files.delete();
|
|
document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
////////////////////// BEPINEX ///////////////////////
|
|
|
|
async function installBepinex() {
|
|
await bepinex.install();
|
|
setBepinexVersion();
|
|
}
|
|
|
|
async function uninstallBepinex() {
|
|
await bepinex.uninstall();
|
|
setBepinexVersion();
|
|
}
|
|
|
|
async function backupBepinex() {
|
|
await bepinex.backup();
|
|
setBepinexVersion();
|
|
}
|
|
|
|
async function deleteBepinexBackup() {
|
|
await bepinex.deleteBackup();
|
|
setBepinexVersion();
|
|
}
|
|
|
|
async function setBepinexVersion() {
|
|
const bepinexVersionText = document.getElementById("bepinex-version-text");
|
|
if (bepinexVersionText == undefined) {
|
|
return;
|
|
}
|
|
|
|
const bepinexVersion = await files.loadBepinexVersion();
|
|
const bepinexBackupVersion = await files.loadBepinexBackupVersion();
|
|
if (bepinexVersion == undefined) {
|
|
if (bepinexBackupVersion == undefined) {
|
|
bepinexVersionText.innerText = "BepInEx is not installed";
|
|
} else {
|
|
bepinexVersionText.innerText = `BepInEx ${bepinexBackupVersion} is backed up`;
|
|
}
|
|
} else {
|
|
bepinexVersionText.innerText = `BepInEx ${bepinexVersion} is installed`;
|
|
}
|
|
}
|
|
|
|
async function searchInstalledMods() {
|
|
const searchInput = document.getElementById("search-input");
|
|
searchValueInstalled = searchInput.value;
|
|
await mods.searchInstalled(searchValueInstalled, installedOffset, installedModsCount, installedSortFilter, installedSortOrder);
|
|
await navigate("refresh");
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
//////////////// NEXUS / THUNDERSTORE ////////////////
|
|
|
|
async function verifyNexusAPI() {
|
|
response = await nexus.verifyAPI();
|
|
|
|
const nexusCheckImage = document.getElementById("nexus-check-image");
|
|
if (nexusCheckImage == undefined) {
|
|
return;
|
|
}
|
|
|
|
if (response) {
|
|
nexusCheckImage.src = "assets/icons/check.svg";
|
|
} else {
|
|
nexusCheckImage.src = "assets/icons/cross.svg";
|
|
}
|
|
}
|
|
|
|
async function searchNexusMods() {
|
|
let searchInput = document.getElementById("search-input");
|
|
searchValueNexus = searchInput.value;
|
|
await nexus.search(searchValueNexus, onlineOffset, onlineModsCount, onlineSortFilter, onlineSortOrder);
|
|
await navigate("refresh");
|
|
searchInput = document.getElementById("search-input");
|
|
searchInput.value = searchValueNexus;
|
|
}
|
|
|
|
async function setNexusAPI() {
|
|
const nexusAPIInput = document.getElementById("nexus-api-input");
|
|
const secretString = "●".repeat(1000);
|
|
if (!(await files.loadNexusAPI())) {
|
|
if (nexusAPIInput.value && nexusAPIInput.value != secretString) {
|
|
await files.saveNexusAPI(nexusAPIInput.value);
|
|
nexusAPIInput.value = secretString;
|
|
nexusAPIInput.readOnly = true;
|
|
} else {
|
|
nexusAPIInput.value = "";
|
|
nexusAPIInput.readOnly = false;
|
|
}
|
|
} else {
|
|
nexusAPIInput.value = secretString;
|
|
nexusAPIInput.readOnly = true;
|
|
}
|
|
verifyNexusAPI();
|
|
}
|
|
|
|
async function resetNexusAPI() {
|
|
if (await files.loadNexusAPI()) {
|
|
await files.saveNexusAPI(undefined);
|
|
setNexusAPI();
|
|
}
|
|
}
|
|
|
|
async function searchThunderstoreMods() {
|
|
let searchInput = document.getElementById("search-input");
|
|
searchValueThunderstore = searchInput.value;
|
|
await thunderstore.search(searchValueThunderstore, thunderstoreOffset, thunderstoreModsCount, thunderstoreSortFilter, thunderstoreSortOrder);
|
|
await navigate("refresh");
|
|
searchInput = document.getElementById("search-input");
|
|
searchInput.value = searchValueThunderstore;
|
|
}
|
|
|
|
async function addOfflineMod() {
|
|
await mods.add();
|
|
searchInstalledMods();
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
//////////////// THEMES / SORT / LIST ////////////////
|
|
|
|
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) {
|
|
const theme = await files.loadTheme();
|
|
themesButton.textContent = theme[0];
|
|
}
|
|
}
|
|
|
|
function changeTheme(theme, state) {
|
|
toggleThemesMenu();
|
|
toggleSelectedListButton("themes-menu", theme);
|
|
|
|
const lacePinCheckbox = document.getElementById("lace-pin");
|
|
if (lacePinCheckbox) {
|
|
lacePinState = lacePinCheckbox.checked;
|
|
} else if (state) {
|
|
lacePinState = state;
|
|
} else {
|
|
lacePinState = false;
|
|
}
|
|
|
|
if (actualTheme[0] == theme && actualTheme[1] == lacePinState) {
|
|
return;
|
|
}
|
|
actualTheme = [theme, lacePinState];
|
|
|
|
files.saveTheme(theme, lacePinState);
|
|
|
|
setThemeButton();
|
|
|
|
// prettier-ignore
|
|
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");
|
|
let backgroundVideoPath = `assets/background/${theme}.mp4`;
|
|
if (lacePinState) {
|
|
backgroundVideoPath = `assets/background/${theme} Lace Pin.mp4`;
|
|
}
|
|
|
|
backgroundVideo.src = backgroundVideoPath;
|
|
}
|
|
|
|
function toggleSortMenu() {
|
|
const sortMenu = document.getElementById("sort-menu");
|
|
if (sortMenu) {
|
|
sortMenu.classList.toggle("show");
|
|
}
|
|
}
|
|
|
|
function setSortOrderButton() {
|
|
let sortOrder;
|
|
if (oldPage == "mods-installed") {
|
|
sortOrder = installedSortOrder;
|
|
} else if (oldPage == "mods-online") {
|
|
sortOrder = onlineSortOrder;
|
|
} else if (oldPage == "mods-thunderstore") {
|
|
sortOrder = thunderstoreSortOrder;
|
|
}
|
|
|
|
const sortOrderButton = document.getElementById("sort-order-image");
|
|
if (sortOrderButton) {
|
|
if (sortOrder == "ASC") {
|
|
sortOrderButton.src = "assets/icons/sort-order-2.svg";
|
|
} else {
|
|
sortOrderButton.src = "assets/icons/sort-order-1.svg";
|
|
}
|
|
}
|
|
}
|
|
|
|
function changeSort(sortFilterParameter) {
|
|
toggleSortMenu();
|
|
toggleSelectedListButton("sort-menu", sortFilterParameter);
|
|
|
|
if (oldPage == "mods-installed") {
|
|
installedSortFilter = sortFilterParameter;
|
|
searchInstalledMods();
|
|
} else if (oldPage == "mods-online") {
|
|
onlineSortFilter = sortFilterParameter;
|
|
searchNexusMods();
|
|
} else if (oldPage == "mods-thunderstore") {
|
|
thunderstoreSortFilter = sortFilterParameter;
|
|
searchThunderstoreMods();
|
|
}
|
|
}
|
|
|
|
function inverseSort() {
|
|
if (oldPage == "mods-installed") {
|
|
if (installedSortOrder == "ASC") {
|
|
installedSortOrder = "DESC";
|
|
} else {
|
|
installedSortOrder = "ASC";
|
|
}
|
|
searchInstalledMods();
|
|
} else if (oldPage == "mods-online") {
|
|
if (onlineSortOrder == "ASC") {
|
|
onlineSortOrder = "DESC";
|
|
} else {
|
|
onlineSortOrder = "ASC";
|
|
}
|
|
searchNexusMods();
|
|
} else if (oldPage == "mods-thunderstore") {
|
|
if (thunderstoreSortOrder == "ASC") {
|
|
thunderstoreSortOrder = "DESC";
|
|
} else {
|
|
thunderstoreSortOrder = "ASC";
|
|
}
|
|
searchThunderstoreMods();
|
|
}
|
|
}
|
|
|
|
function toggleSelectedListButton(ListMenuId, buttonId) {
|
|
const themesMenu = document.getElementById(ListMenuId);
|
|
if (themesMenu) {
|
|
Array.from(themesMenu.children).forEach((child) => {
|
|
child.classList.remove("selected");
|
|
});
|
|
}
|
|
|
|
const themesButton = document.getElementById(buttonId);
|
|
if (themesButton) {
|
|
themesButton.classList.toggle("selected");
|
|
}
|
|
}
|
|
|
|
//////////////////////////////////////////////////////
|
|
//////////////////// UNCATEGORIZE ////////////////////
|
|
|
|
async function launch(mode) {
|
|
await electronAPI.launchGame(mode);
|
|
setBepinexVersion();
|
|
}
|
|
|
|
async function autoDetectGamePath() {
|
|
await files.autoDetectGamePath();
|
|
if (document.getElementById("silksong-path-input")) {
|
|
document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
|
|
}
|
|
}
|
|
|
|
function showToast(message, type = "info", duration = 3000) {
|
|
const toastDiv = document.getElementById("toast-div");
|
|
const toast = document.createElement("p");
|
|
|
|
toast.classList.add("toast", type);
|
|
toast.innerText = message;
|
|
toastDiv.appendChild(toast);
|
|
toast.classList.add("show");
|
|
|
|
setTimeout(() => {
|
|
toast.classList.remove("show");
|
|
toast.addEventListener("transitionend", () => toast.remove());
|
|
}, duration);
|
|
}
|
|
|
|
electronAPI.onShowToast(showToast);
|
|
|
|
function showBanner(message) {
|
|
const bannerDiv = document.getElementById("banner-div");
|
|
const bannerText = document.getElementById("banner-text");
|
|
|
|
console.log(bannerDiv);
|
|
|
|
bannerText.innerHTML = message;
|
|
bannerDiv.classList.add("show");
|
|
}
|
|
|
|
electronAPI.onShowBanner(showBanner);
|
|
|
|
function hideBanner() {
|
|
const bannerDiv = document.getElementById("banner-div");
|
|
bannerDiv.classList.remove("show");
|
|
}
|
|
|
|
function changeModsPage(offsetChange) {
|
|
if (oldPage == "mods-installed") {
|
|
if (offsetChange == "min") {
|
|
installedOffset = 0;
|
|
} else if (offsetChange == "max") {
|
|
installedOffset = installedModsTotalCount;
|
|
} else {
|
|
installedOffset += installedModsCount * offsetChange;
|
|
installedOffset = clamp(installedOffset, 0, installedModsTotalCount);
|
|
}
|
|
installedOffset = Math.floor(installedOffset / 10) * 10;
|
|
if (lastInstalledOffset != installedOffset) {
|
|
lastInstalledOffset = installedOffset;
|
|
searchInstalledMods();
|
|
}
|
|
} else if (oldPage == "mods-online") {
|
|
if (offsetChange == "min") {
|
|
onlineOffset = 0;
|
|
} else if (offsetChange == "max") {
|
|
onlineOffset = onlineModsTotalCount;
|
|
} else {
|
|
onlineOffset += onlineModsCount * offsetChange;
|
|
onlineOffset = clamp(onlineOffset, 0, onlineModsTotalCount);
|
|
}
|
|
onlineOffset = Math.floor(onlineOffset / 10) * 10;
|
|
if (lastOnlineOffset != onlineOffset) {
|
|
lastOnlineOffset = onlineOffset;
|
|
searchNexusMods();
|
|
}
|
|
} else if (oldPage == "mods-thunderstore") {
|
|
if (offsetChange == "min") {
|
|
thunderstoreOffset = 0;
|
|
} else if (offsetChange == "max") {
|
|
thunderstoreOffset = thunderstoreModsTotalCount;
|
|
} else {
|
|
thunderstoreOffset += thunderstoreModsCount * offsetChange;
|
|
thunderstoreOffset = clamp(thunderstoreOffset, 0, thunderstoreModsTotalCount);
|
|
}
|
|
thunderstoreOffset = Math.floor(thunderstoreOffset / 10) * 10;
|
|
if (lastThunderstoreOffset != thunderstoreOffset) {
|
|
lastThunderstoreOffset = thunderstoreOffset;
|
|
searchNexusMods();
|
|
}
|
|
}
|
|
}
|
|
|
|
function clamp(number, min, max) {
|
|
return Math.max(min, Math.min(number, max));
|
|
}
|