mirror of
https://github.com/Gabi-Zar/Silk-Fly-Launcher.git
synced 2026-04-17 05:26:04 +02:00
Convert main.js to ESM and prettify code with Prettier
This commit is contained in:
418
main.js
418
main.js
@@ -1,143 +1,140 @@
|
||||
const { app, BrowserWindow , ipcMain, dialog, shell} = require('electron/main');
|
||||
const path = require('node:path');
|
||||
const Store = require('electron-store').default;
|
||||
const fs = require('fs/promises');
|
||||
const { createWriteStream } = require('fs');
|
||||
const { pipeline } = require('stream/promises');
|
||||
const extract = require('extract-zip');
|
||||
const Nexus = require('@nexusmods/nexus-api').default;
|
||||
import { app, BrowserWindow, ipcMain, dialog, shell } from "electron";
|
||||
import path from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import Store from "electron-store";
|
||||
import fs from "fs/promises";
|
||||
import { createWriteStream } from "fs";
|
||||
import { pipeline } from "stream/promises";
|
||||
import extract from "extract-zip";
|
||||
import NexusModule from "@nexusmods/nexus-api";
|
||||
const Nexus = NexusModule.default;
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
|
||||
const store = new Store();
|
||||
const userSavePath = app.getPath('userData')
|
||||
const dataPath = `${userSavePath}\\config.json`
|
||||
let silksongPath = store.get('silksong-path')
|
||||
const userSavePath = app.getPath("userData");
|
||||
const dataPath = `${userSavePath}\\config.json`;
|
||||
let silksongPath = store.get("silksong-path");
|
||||
|
||||
let nexusAPI = store.get('nexus-api')
|
||||
let nexus = undefined
|
||||
createNexus()
|
||||
let nexusAPI = store.get("nexus-api");
|
||||
let nexus = undefined;
|
||||
createNexus();
|
||||
|
||||
let bepinexFolderPath = `${silksongPath}/BepInEx`
|
||||
let bepinexBackupPath = `${silksongPath}/BepInEx-Backup`
|
||||
const bepinexFiles = [
|
||||
".doorstop_version",
|
||||
"changelog.txt",
|
||||
"doorstop_config.ini",
|
||||
"winhttp.dll"
|
||||
]
|
||||
let bepinexFolderPath = `${silksongPath}/BepInEx`;
|
||||
let bepinexBackupPath = `${silksongPath}/BepInEx-Backup`;
|
||||
const bepinexFiles = [".doorstop_version", "changelog.txt", "doorstop_config.ini", "winhttp.dll"];
|
||||
|
||||
let bepinexVersion
|
||||
let bepinexBackupVersion
|
||||
const bepinexStore = new Store({cwd: 'bepinex-version'});
|
||||
let bepinexVersion;
|
||||
let bepinexBackupVersion;
|
||||
const bepinexStore = new Store({ cwd: "bepinex-version" });
|
||||
|
||||
let mainWindow
|
||||
let htmlFile
|
||||
let mainWindow;
|
||||
let htmlFile;
|
||||
|
||||
async function createWindow() {
|
||||
mainWindow = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 720,
|
||||
webPreferences: {
|
||||
preload: path.join(__dirname, 'preload.js')
|
||||
}
|
||||
})
|
||||
preload: path.join(__dirname, "preload.js"),
|
||||
},
|
||||
});
|
||||
|
||||
if(await fileExists(dataPath)) {
|
||||
htmlFile = "index.html"
|
||||
}
|
||||
else {
|
||||
htmlFile = "welcome.html"
|
||||
if (await fileExists(dataPath)) {
|
||||
htmlFile = "index.html";
|
||||
} else {
|
||||
htmlFile = "welcome.html";
|
||||
}
|
||||
|
||||
mainWindow.loadFile(`renderer/${htmlFile}`)
|
||||
mainWindow.loadFile(`renderer/${htmlFile}`);
|
||||
}
|
||||
|
||||
app.whenReady().then(() => {
|
||||
createWindow()
|
||||
createWindow();
|
||||
|
||||
app.on('activate', () => {
|
||||
app.on("activate", () => {
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow()
|
||||
createWindow();
|
||||
}
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
|
||||
app.on('window-all-closed', () => {
|
||||
if (process.platform !== 'darwin') {
|
||||
app.quit()
|
||||
app.on("window-all-closed", () => {
|
||||
if (process.platform !== "darwin") {
|
||||
app.quit();
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
///////////////// SAVING AND LOADING /////////////////
|
||||
ipcMain.handle('save-path', (event, path) => {
|
||||
saveSilksongPath(path)
|
||||
ipcMain.handle("save-path", (event, path) => {
|
||||
saveSilksongPath(path);
|
||||
});
|
||||
function saveSilksongPath(path) {
|
||||
silksongPath = path;
|
||||
bepinexFolderPath = `${silksongPath}/BepInEx`
|
||||
bepinexBackupPath = `${silksongPath}/BepInEx-Backup`
|
||||
store.set('silksong-path', silksongPath);
|
||||
bepinexFolderPath = `${silksongPath}/BepInEx`;
|
||||
bepinexBackupPath = `${silksongPath}/BepInEx-Backup`;
|
||||
store.set("silksong-path", silksongPath);
|
||||
}
|
||||
|
||||
ipcMain.handle('load-path', () => {
|
||||
silksongPath = store.get('silksong-path');
|
||||
ipcMain.handle("load-path", () => {
|
||||
silksongPath = store.get("silksong-path");
|
||||
if (silksongPath == undefined) {
|
||||
return "";
|
||||
}
|
||||
return silksongPath;
|
||||
});
|
||||
|
||||
|
||||
function saveBepinexVersion(version) {
|
||||
bepinexVersion = version;
|
||||
if (bepinexVersion == undefined) {
|
||||
bepinexStore.delete('bepinex-version');
|
||||
bepinexStore.delete("bepinex-version");
|
||||
return;
|
||||
}
|
||||
bepinexStore.set('bepinex-version', version);
|
||||
};
|
||||
bepinexStore.set("bepinex-version", version);
|
||||
}
|
||||
|
||||
ipcMain.handle('load-bepinex-version', () => {
|
||||
bepinexVersion = bepinexStore.get('bepinex-version');
|
||||
ipcMain.handle("load-bepinex-version", () => {
|
||||
bepinexVersion = bepinexStore.get("bepinex-version");
|
||||
return bepinexVersion;
|
||||
});
|
||||
|
||||
|
||||
function saveBepinexBackupVersion(version) {
|
||||
bepinexBackupVersion = version;
|
||||
if (bepinexBackupVersion == undefined) {
|
||||
bepinexStore.delete('bepinex-backup-version');
|
||||
bepinexStore.delete("bepinex-backup-version");
|
||||
return;
|
||||
}
|
||||
bepinexStore.set('bepinex-backup-version', version);
|
||||
};
|
||||
bepinexStore.set("bepinex-backup-version", version);
|
||||
}
|
||||
|
||||
ipcMain.handle('load-bepinex-backup-version', () => {
|
||||
bepinexBackupVersion = bepinexStore.get('bepinex-backup-version');
|
||||
ipcMain.handle("load-bepinex-backup-version", () => {
|
||||
bepinexBackupVersion = bepinexStore.get("bepinex-backup-version");
|
||||
return bepinexBackupVersion;
|
||||
});
|
||||
|
||||
ipcMain.handle('save-nexus-api', (event, api) => {
|
||||
ipcMain.handle("save-nexus-api", (event, api) => {
|
||||
nexusAPI = api;
|
||||
createNexus()
|
||||
store.set('nexus-api', nexusAPI);
|
||||
createNexus();
|
||||
store.set("nexus-api", nexusAPI);
|
||||
});
|
||||
|
||||
ipcMain.handle('load-nexus-api', () => {
|
||||
nexusAPI = store.get('nexus-api');
|
||||
ipcMain.handle("load-nexus-api", () => {
|
||||
nexusAPI = store.get("nexus-api");
|
||||
if (nexusAPI == undefined) {
|
||||
return "";
|
||||
}
|
||||
return nexusAPI;
|
||||
});
|
||||
|
||||
|
||||
ipcMain.handle('save-theme', (event, theme, lacePinState) => {
|
||||
store.set('theme.theme', theme);
|
||||
store.set('theme.lacePinState', lacePinState);
|
||||
ipcMain.handle("save-theme", (event, theme, lacePinState) => {
|
||||
store.set("theme.theme", theme);
|
||||
store.set("theme.lacePinState", lacePinState);
|
||||
});
|
||||
|
||||
ipcMain.handle('load-theme', () => {
|
||||
theme = [store.get('theme.theme'), store.get('theme.lacePinState')];
|
||||
ipcMain.handle("load-theme", () => {
|
||||
const theme = [store.get("theme.theme"), store.get("theme.lacePinState")];
|
||||
if (theme[0] == undefined) {
|
||||
return ["Silksong", false];
|
||||
}
|
||||
@@ -156,45 +153,43 @@ async function 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 () => {
|
||||
if (!await fileExists(dataPath)) {
|
||||
return
|
||||
ipcMain.handle("export-data", async () => {
|
||||
if (!(await fileExists(dataPath))) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { canceled, filePath } = await dialog.showSaveDialog({
|
||||
title: 'Export Data',
|
||||
defaultPath: 'config.json',
|
||||
filters: [
|
||||
{ name: 'JSON', extensions: ['json'] }
|
||||
]
|
||||
})
|
||||
title: "Export Data",
|
||||
defaultPath: "config.json",
|
||||
filters: [{ name: "JSON", extensions: ["json"] }],
|
||||
});
|
||||
|
||||
if (canceled || !filePath) return
|
||||
if (canceled || !filePath) return;
|
||||
|
||||
await fs.copyFile(dataPath, filePath)
|
||||
})
|
||||
await fs.copyFile(dataPath, filePath);
|
||||
});
|
||||
|
||||
ipcMain.handle('import-data', async () => {
|
||||
ipcMain.handle("import-data", async () => {
|
||||
const { canceled, filePaths } = await dialog.showOpenDialog({
|
||||
title: 'Import Data',
|
||||
properties: ['openFile'],
|
||||
filters: [{ name: 'JSON', extensions: ['json'] }]
|
||||
})
|
||||
title: "Import Data",
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "JSON", extensions: ["json"] }],
|
||||
});
|
||||
|
||||
if (canceled || !filePaths) return false
|
||||
if (canceled || !filePaths) return false;
|
||||
|
||||
if(await fileExists(dataPath)) {
|
||||
await fs.unlink(dataPath)
|
||||
if (await fileExists(dataPath)) {
|
||||
await fs.unlink(dataPath);
|
||||
}
|
||||
await fs.copyFile(filePaths[0], dataPath,fs.constants.COPYFILE_EXCL)
|
||||
return true
|
||||
})
|
||||
await fs.copyFile(filePaths[0], dataPath, fs.constants.COPYFILE_EXCL);
|
||||
return true;
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////////////////// BEPINEX ///////////////////////
|
||||
@@ -202,157 +197,151 @@ ipcMain.handle('import-data', async () => {
|
||||
async function installBepinex() {
|
||||
if (await fileExists(bepinexBackupPath)) {
|
||||
if (await fileExists(`${bepinexBackupPath}/BepInEx`)) {
|
||||
await fs.cp(`${bepinexBackupPath}/BepInEx`, bepinexFolderPath, { recursive: true })
|
||||
await fs.cp(`${bepinexBackupPath}/BepInEx`, bepinexFolderPath, {
|
||||
recursive: true,
|
||||
});
|
||||
}
|
||||
|
||||
for (const file of bepinexFiles) {
|
||||
const filePath = `${silksongPath}/${file}`
|
||||
const filePath = `${silksongPath}/${file}`;
|
||||
if (await fileExists(`${bepinexBackupPath}/${file}`)) {
|
||||
await fs.copyFile(`${bepinexBackupPath}/${file}`, filePath)
|
||||
await fs.copyFile(`${bepinexBackupPath}/${file}`, filePath);
|
||||
}
|
||||
}
|
||||
await fs.rm(bepinexBackupPath, { recursive: true })
|
||||
await fs.rm(bepinexBackupPath, { recursive: true });
|
||||
|
||||
bepinexBackupVersion = bepinexStore.get('bepinex-backup-version')
|
||||
saveBepinexVersion(bepinexBackupVersion)
|
||||
saveBepinexBackupVersion(undefined)
|
||||
}
|
||||
else {
|
||||
const GITHUB_URL = "https://api.github.com/repos/bepinex/bepinex/releases/latest"
|
||||
bepinexBackupVersion = bepinexStore.get("bepinex-backup-version");
|
||||
saveBepinexVersion(bepinexBackupVersion);
|
||||
saveBepinexBackupVersion(undefined);
|
||||
} else {
|
||||
const GITHUB_URL = "https://api.github.com/repos/bepinex/bepinex/releases/latest";
|
||||
|
||||
const res = await fetch(GITHUB_URL, {
|
||||
headers: {
|
||||
"User-Agent": "SilkFlyLauncher/1.0.0",
|
||||
"Accept": "application/vnd.github+json",
|
||||
}
|
||||
})
|
||||
Accept: "application/vnd.github+json",
|
||||
},
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`GitHub API error: ${res.status}`)
|
||||
throw new Error(`GitHub API error: ${res.status}`);
|
||||
}
|
||||
|
||||
const release = await res.json();
|
||||
|
||||
const asset = release.assets.find(
|
||||
a => a.name.endsWith(".zip") && a.name.toLowerCase().includes("win_x64")
|
||||
);
|
||||
const asset = release.assets.find((a) => a.name.endsWith(".zip") && a.name.toLowerCase().includes("win_x64"));
|
||||
|
||||
const download = await fetch(asset.browser_download_url)
|
||||
const download = await fetch(asset.browser_download_url);
|
||||
if (!download.ok) {
|
||||
throw new Error("Download error");
|
||||
}
|
||||
const filePath = `${userSavePath}\\bepinex.zip`
|
||||
const filePath = `${userSavePath}\\bepinex.zip`;
|
||||
|
||||
await pipeline(
|
||||
download.body,
|
||||
createWriteStream(filePath)
|
||||
)
|
||||
await pipeline(download.body, createWriteStream(filePath));
|
||||
|
||||
await extract(filePath, { dir: silksongPath})
|
||||
await fs.unlink(filePath)
|
||||
await extract(filePath, { dir: silksongPath });
|
||||
await fs.unlink(filePath);
|
||||
|
||||
saveBepinexVersion(release.tag_name)
|
||||
saveBepinexVersion(release.tag_name);
|
||||
}
|
||||
}
|
||||
|
||||
ipcMain.handle('install-bepinex', async () => {
|
||||
await installBepinex()
|
||||
})
|
||||
ipcMain.handle("install-bepinex", async () => {
|
||||
await installBepinex();
|
||||
});
|
||||
|
||||
async function uninstallBepinex() {
|
||||
if (await fileExists(bepinexFolderPath)) {
|
||||
await fs.rm(bepinexFolderPath, { recursive: true })
|
||||
await fs.rm(bepinexFolderPath, { recursive: true });
|
||||
}
|
||||
|
||||
for (const file of bepinexFiles) {
|
||||
const filePath = `${silksongPath}/${file}`
|
||||
const filePath = `${silksongPath}/${file}`;
|
||||
if (await fileExists(filePath)) {
|
||||
await fs.unlink(filePath)
|
||||
await fs.unlink(filePath);
|
||||
}
|
||||
}
|
||||
saveBepinexVersion(undefined)
|
||||
saveBepinexVersion(undefined);
|
||||
}
|
||||
|
||||
ipcMain.handle('uninstall-bepinex', async () => {
|
||||
await uninstallBepinex()
|
||||
})
|
||||
ipcMain.handle("uninstall-bepinex", async () => {
|
||||
await uninstallBepinex();
|
||||
});
|
||||
|
||||
async function backupBepinex() {
|
||||
if (await fileExists(bepinexBackupPath) == false) {
|
||||
await fs.mkdir(bepinexBackupPath)
|
||||
if ((await fileExists(bepinexBackupPath)) == false) {
|
||||
await fs.mkdir(bepinexBackupPath);
|
||||
}
|
||||
|
||||
if (await fileExists(bepinexFolderPath)) {
|
||||
await fs.cp(bepinexFolderPath, `${bepinexBackupPath}/BepInEx`, { recursive: true })
|
||||
await fs.cp(bepinexFolderPath, `${bepinexBackupPath}/BepInEx`, {
|
||||
recursive: true,
|
||||
});
|
||||
}
|
||||
|
||||
for (const file of bepinexFiles) {
|
||||
const filePath = `${silksongPath}/${file}`
|
||||
const filePath = `${silksongPath}/${file}`;
|
||||
if (await fileExists(filePath)) {
|
||||
await fs.copyFile(filePath, `${bepinexBackupPath}/${file}`)
|
||||
await fs.copyFile(filePath, `${bepinexBackupPath}/${file}`);
|
||||
}
|
||||
}
|
||||
|
||||
saveBepinexBackupVersion(bepinexVersion)
|
||||
await uninstallBepinex()
|
||||
saveBepinexBackupVersion(bepinexVersion);
|
||||
await uninstallBepinex();
|
||||
}
|
||||
|
||||
ipcMain.handle('backup-bepinex', async () => {
|
||||
await backupBepinex()
|
||||
})
|
||||
ipcMain.handle("backup-bepinex", async () => {
|
||||
await backupBepinex();
|
||||
});
|
||||
|
||||
ipcMain.handle('delete-bepinex-backup', async () => {
|
||||
ipcMain.handle("delete-bepinex-backup", async () => {
|
||||
if (await fileExists(bepinexBackupPath)) {
|
||||
await fs.rm(bepinexBackupPath, { recursive: true })
|
||||
saveBepinexBackupVersion(undefined)
|
||||
await fs.rm(bepinexBackupPath, { recursive: true });
|
||||
saveBepinexBackupVersion(undefined);
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
/////////////////////// NEXUS ////////////////////////
|
||||
|
||||
async function createNexus() {
|
||||
if (nexusAPI == undefined) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
nexus = await Nexus.create(
|
||||
nexusAPI,
|
||||
'silk-fly-launcher',
|
||||
'1.0.0',
|
||||
'hollowknightsilksong'
|
||||
);
|
||||
nexus = await Nexus.create(nexusAPI, "silk-fly-launcher", "1.0.0", "hollowknightsilksong");
|
||||
} catch (error) {
|
||||
nexus = undefined
|
||||
console.log(error);
|
||||
nexus = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
ipcMain.handle('verify-nexus-api', async () => {
|
||||
return await verifyNexusAPI()
|
||||
})
|
||||
ipcMain.handle("verify-nexus-api", async () => {
|
||||
return await verifyNexusAPI();
|
||||
});
|
||||
|
||||
async function verifyNexusAPI() {
|
||||
if (nexus == undefined) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
if (await nexus.getValidationResult()) {
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
ipcMain.handle('get-latest-mods', async () => {
|
||||
ipcMain.handle("get-latest-mods", async () => {
|
||||
if (nexus == undefined) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
mods = await nexus.getLatestAdded()
|
||||
return mods
|
||||
})
|
||||
const mods = await nexus.getLatestAdded();
|
||||
return mods;
|
||||
});
|
||||
|
||||
ipcMain.handle('download-mod', async (event, link) => {
|
||||
ipcMain.handle("download-mod", async (event, link) => {
|
||||
if (nexus == undefined) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
const nexusWindow = new BrowserWindow({
|
||||
@@ -362,46 +351,43 @@ ipcMain.handle('download-mod', async (event, link) => {
|
||||
parent: mainWindow,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true
|
||||
}
|
||||
})
|
||||
contextIsolation: true,
|
||||
},
|
||||
});
|
||||
|
||||
nexusWindow.loadURL(link)
|
||||
})
|
||||
nexusWindow.loadURL(link);
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
//////////////////// UNCATEGORIZE ////////////////////
|
||||
|
||||
ipcMain.handle('auto-detect-game-path', async () => {
|
||||
const defaultsSilksongPaths = [
|
||||
":/Program Files (x86)/Steam/steamapps/common/Hollow Knight Silksong",
|
||||
":/SteamLibrary/steamapps/common/Hollow Knight Silksong"
|
||||
]
|
||||
ipcMain.handle("auto-detect-game-path", async () => {
|
||||
const defaultsSilksongPaths = [":/Program Files (x86)/Steam/steamapps/common/Hollow Knight Silksong", ":/SteamLibrary/steamapps/common/Hollow Knight Silksong"];
|
||||
for (const path of defaultsSilksongPaths) {
|
||||
for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) {
|
||||
const fullPath = `${String.fromCharCode(i)}${path}`
|
||||
for (let i = "A".charCodeAt(0); i <= "Z".charCodeAt(0); i++) {
|
||||
const fullPath = `${String.fromCharCode(i)}${path}`;
|
||||
if (await fileExists(fullPath)) {
|
||||
saveSilksongPath(fullPath)
|
||||
return
|
||||
saveSilksongPath(fullPath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
ipcMain.handle('load-main-page', () => {
|
||||
htmlFile = "index.html"
|
||||
mainWindow.loadFile(`renderer/${htmlFile}`)
|
||||
})
|
||||
ipcMain.handle("load-main-page", () => {
|
||||
htmlFile = "index.html";
|
||||
mainWindow.loadFile(`renderer/${htmlFile}`);
|
||||
});
|
||||
|
||||
ipcMain.handle('get-page', () => {
|
||||
return htmlFile
|
||||
})
|
||||
ipcMain.handle("get-page", () => {
|
||||
return htmlFile;
|
||||
});
|
||||
|
||||
ipcMain.handle('open-link', async (event, link) => {
|
||||
await shell.openExternal(link)
|
||||
})
|
||||
ipcMain.handle("open-link", async (event, link) => {
|
||||
await shell.openExternal(link);
|
||||
});
|
||||
|
||||
ipcMain.handle('open-window', async (event, file) => {
|
||||
ipcMain.handle("open-window", async (event, file) => {
|
||||
const win = new BrowserWindow({
|
||||
width: 600,
|
||||
height: 720,
|
||||
@@ -409,32 +395,30 @@ ipcMain.handle('open-window', async (event, file) => {
|
||||
parent: mainWindow,
|
||||
webPreferences: {
|
||||
nodeIntegration: false,
|
||||
contextIsolation: true
|
||||
}
|
||||
})
|
||||
contextIsolation: true,
|
||||
},
|
||||
});
|
||||
|
||||
win.title = file
|
||||
win.loadFile(file)
|
||||
})
|
||||
win.title = file;
|
||||
win.loadFile(file);
|
||||
});
|
||||
|
||||
ipcMain.handle('launch-game', async (event, mode) => {
|
||||
const silksongExecutablePath = `${silksongPath}/Hollow Knight Silksong.exe`
|
||||
if (mode === "modded"){
|
||||
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)
|
||||
await shell.openExternal(silksongExecutablePath);
|
||||
} else {
|
||||
await installBepinex();
|
||||
await shell.openExternal(silksongExecutablePath);
|
||||
}
|
||||
}
|
||||
if (mode === "vanilla"){
|
||||
if (mode === "vanilla") {
|
||||
if (await fileExists(bepinexFolderPath)) {
|
||||
await backupBepinex()
|
||||
await shell.openExternal(silksongExecutablePath)
|
||||
}
|
||||
else {
|
||||
await shell.openExternal(silksongExecutablePath)
|
||||
await backupBepinex();
|
||||
await shell.openExternal(silksongExecutablePath);
|
||||
} else {
|
||||
await shell.openExternal(silksongExecutablePath);
|
||||
}
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
@@ -3,12 +3,13 @@
|
||||
"version": "1.0.0",
|
||||
"description": "A launcher and manager for silksong bepinex mods written in javascript",
|
||||
"main": "main.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "GabiZar",
|
||||
"license": "SEE LICENSE IN LICENSE",
|
||||
"license": "GPL-3.0",
|
||||
"devDependencies": {
|
||||
"electron": "^39.2.7"
|
||||
},
|
||||
|
||||
68
preload.js
68
preload.js
@@ -1,47 +1,47 @@
|
||||
const { contextBridge, ipcRenderer } = require('electron')
|
||||
const { contextBridge, ipcRenderer } = require("electron");
|
||||
|
||||
const VERSION = "1.0.0"
|
||||
const VERSION = "1.0.0";
|
||||
|
||||
contextBridge.exposeInMainWorld('versions', {
|
||||
contextBridge.exposeInMainWorld("versions", {
|
||||
silkFlyLauncher: () => VERSION,
|
||||
node: () => process.versions.node,
|
||||
chromium: () => process.versions.chrome,
|
||||
electron: () => process.versions.electron
|
||||
electron: () => process.versions.electron,
|
||||
});
|
||||
|
||||
contextBridge.exposeInMainWorld('files', {
|
||||
delete: () => ipcRenderer.invoke('delete-data'),
|
||||
export: () => ipcRenderer.invoke('export-data'),
|
||||
import: () => ipcRenderer.invoke('import-data'),
|
||||
contextBridge.exposeInMainWorld("files", {
|
||||
delete: () => ipcRenderer.invoke("delete-data"),
|
||||
export: () => ipcRenderer.invoke("export-data"),
|
||||
import: () => ipcRenderer.invoke("import-data"),
|
||||
|
||||
autoDetectGamePath: () => ipcRenderer.invoke('auto-detect-game-path'),
|
||||
saveSilksongPath: (path) => ipcRenderer.invoke('save-path', path),
|
||||
loadSilksongPath: () => ipcRenderer.invoke('load-path'),
|
||||
loadBepinexVersion: () => ipcRenderer.invoke('load-bepinex-version'),
|
||||
loadBepinexBackupVersion: () => ipcRenderer.invoke('load-bepinex-backup-version'),
|
||||
saveNexusAPI: (api) => ipcRenderer.invoke('save-nexus-api', api),
|
||||
loadNexusAPI: () => ipcRenderer.invoke('load-nexus-api'),
|
||||
saveTheme: (theme, lacePinState) => ipcRenderer.invoke('save-theme', theme, lacePinState),
|
||||
loadTheme: () => ipcRenderer.invoke('load-theme')
|
||||
autoDetectGamePath: () => ipcRenderer.invoke("auto-detect-game-path"),
|
||||
saveSilksongPath: (path) => ipcRenderer.invoke("save-path", path),
|
||||
loadSilksongPath: () => ipcRenderer.invoke("load-path"),
|
||||
loadBepinexVersion: () => ipcRenderer.invoke("load-bepinex-version"),
|
||||
loadBepinexBackupVersion: () => ipcRenderer.invoke("load-bepinex-backup-version"),
|
||||
saveNexusAPI: (api) => ipcRenderer.invoke("save-nexus-api", api),
|
||||
loadNexusAPI: () => ipcRenderer.invoke("load-nexus-api"),
|
||||
saveTheme: (theme, lacePinState) => ipcRenderer.invoke("save-theme", theme, lacePinState),
|
||||
loadTheme: () => ipcRenderer.invoke("load-theme"),
|
||||
});
|
||||
|
||||
contextBridge.exposeInMainWorld('electronAPI', {
|
||||
openExternalLink: (url) => ipcRenderer.invoke('open-link', url),
|
||||
openWindow: (file) => ipcRenderer.invoke('open-window', file),
|
||||
launchGame: (mode) => ipcRenderer.invoke('launch-game', mode),
|
||||
loadMainPage: () => ipcRenderer.invoke('load-main-page'),
|
||||
getPage: () => ipcRenderer.invoke('get-page')
|
||||
contextBridge.exposeInMainWorld("electronAPI", {
|
||||
openExternalLink: (url) => ipcRenderer.invoke("open-link", url),
|
||||
openWindow: (file) => ipcRenderer.invoke("open-window", file),
|
||||
launchGame: (mode) => ipcRenderer.invoke("launch-game", mode),
|
||||
loadMainPage: () => ipcRenderer.invoke("load-main-page"),
|
||||
getPage: () => ipcRenderer.invoke("get-page"),
|
||||
});
|
||||
|
||||
contextBridge.exposeInMainWorld('bepinex', {
|
||||
install: () => ipcRenderer.invoke('install-bepinex'),
|
||||
uninstall: () => ipcRenderer.invoke('uninstall-bepinex'),
|
||||
backup: () => ipcRenderer.invoke('backup-bepinex'),
|
||||
deleteBackup: () => ipcRenderer.invoke('delete-bepinex-backup')
|
||||
})
|
||||
contextBridge.exposeInMainWorld("bepinex", {
|
||||
install: () => ipcRenderer.invoke("install-bepinex"),
|
||||
uninstall: () => ipcRenderer.invoke("uninstall-bepinex"),
|
||||
backup: () => ipcRenderer.invoke("backup-bepinex"),
|
||||
deleteBackup: () => ipcRenderer.invoke("delete-bepinex-backup"),
|
||||
});
|
||||
|
||||
contextBridge.exposeInMainWorld('nexus', {
|
||||
verifyAPI: () => ipcRenderer.invoke('verify-nexus-api'),
|
||||
getLatestMods: () => ipcRenderer.invoke('get-latest-mods'),
|
||||
download: (link) => ipcRenderer.invoke('download-mod', link)
|
||||
})
|
||||
contextBridge.exposeInMainWorld("nexus", {
|
||||
verifyAPI: () => ipcRenderer.invoke("verify-nexus-api"),
|
||||
getLatestMods: () => ipcRenderer.invoke("get-latest-mods"),
|
||||
download: (link) => ipcRenderer.invoke("download-mod", link),
|
||||
});
|
||||
|
||||
1
renderer/assets/github.svg
Normal file
1
renderer/assets/github.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg class="social-github" role="img" focusable="false" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 14"><path d="m 7,1.1480539 c -3.313515,0 -6,2.68652 -6,6 0,2.65087 1.719175,4.9003701 4.103505,5.6933601 C 5.403301,12.897114 5.5,12.711544 5.5,12.552834 l 0,-1.11716 C 3.831039,11.798964 3.483359,10.728164 3.483359,10.728164 3.210913,10.034324 2.817388,9.8497439 2.817388,9.8497439 c -0.544456,-0.37205 0.04101,-0.36474 0.04101,-0.36474 0.602563,0.0425 0.919922,0.6186401 0.919922,0.6186401 0.535136,0.91698 1.403301,0.65187 1.746088,0.49855 0.05371,-0.38773 0.208951,-0.6523401 0.380854,-0.8022501 -1.333048,-0.15137 -2.733437,-0.66603 -2.733437,-2.96534 0,-0.65528 0.234379,-1.19045 0.618204,-1.61036 -0.0625,-0.15137 -0.267612,-0.76171 0.05764,-1.5879 0,0 0.503913,-0.16113 1.650349,0.61523 0.478981,-0.13282 0.992214,-0.19969 1.501981,-0.20214 0.509767,0.002 1.023903,0.0693 1.502913,0.20214 1.145534,-0.77636 1.648427,-0.61523 1.648427,-0.61523 0.326709,0.82616 0.121107,1.4365 0.0591,1.5879 0.384786,0.41991 0.61768,0.95508 0.61768,1.61036 0,2.30467 -1.403797,2.81199 -2.739729,2.96044 0.214806,0.18606 0.411641,0.5517401 0.411641,1.1113201 0,0.80274 0,1.44923 0,1.64647 0,0.15967 0.09615,0.34669 0.400369,0.28812 C 11.283214,12.046534 13,9.7984539 13,7.1480839 c 0,-3.31348 -2.686544,-6.00003 -6,-6.00003 z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -1,49 +1,52 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Silk Fly Launcher</title>
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
|
||||
<video autoplay muted loop class="background-video" id="background-video" src="assets/background/Silksong.mp4" type="video/mp4"></video>
|
||||
|
||||
<!-- Sidebar -->
|
||||
<aside class="sidebar">
|
||||
<div class="logo" onclick="navigate('home')">
|
||||
<img src="assets/logo.png" alt="Silk Fly Launcher Logo" class="logo-img"/>
|
||||
<h5 class="logo-title">Silk Fly Launcher</h1>
|
||||
<img src="assets/logo.png" alt="Silk Fly Launcher Logo" class="logo-img" />
|
||||
<h5 class="logo-title">Silk Fly Launcher</h5>
|
||||
</div>
|
||||
|
||||
<nav class="nav">
|
||||
<div class="nav-section">
|
||||
<span class="nav-title">Execute Silksong</span>
|
||||
<button onclick="launch('vanilla')">
|
||||
<img src="vanilla_launch_icon.png" class="button-icon"/>
|
||||
<img src="vanilla_launch_icon.png" class="button-icon" />
|
||||
Run Vanilla
|
||||
</button>
|
||||
<button onclick="launch('modded')">
|
||||
<img src="modded_launch_icon.png" class="button-icon"/>
|
||||
<img src="modded_launch_icon.png" class="button-icon" />
|
||||
Run Modded
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="nav-section">
|
||||
<span class="nav-title">Mods</span>
|
||||
<button onclick="navigate('mods-installed')">
|
||||
<img src="installed_mods_icon.png" class="button-icon"/>
|
||||
<img src="installed_mods_icon.png" class="button-icon" />
|
||||
Installed
|
||||
</button>
|
||||
<button onclick="navigate('mods-online')">
|
||||
<img src="online_mods_icon.png" class="button-icon"/>
|
||||
<img src="online_mods_icon.png" class="button-icon" />
|
||||
Online
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="nav-section">
|
||||
<span class="nav-title">Settings</span>
|
||||
<button onclick="navigate('general-settings')">
|
||||
<img src="general_settings_icon.png" class="button-icon"/>
|
||||
<img src="general_settings_icon.png" class="button-icon" />
|
||||
General
|
||||
</button>
|
||||
</div>
|
||||
</nav>
|
||||
</aside>
|
||||
@@ -51,8 +54,7 @@
|
||||
<!-- Main content -->
|
||||
<main class="content">
|
||||
<h1 id="title">Silk Fly Launcher</h1>
|
||||
<div class="view" id="view">
|
||||
</div>
|
||||
<div class="view" id="view"></div>
|
||||
</main>
|
||||
</div>
|
||||
|
||||
@@ -61,51 +63,52 @@
|
||||
<h2>About</h2>
|
||||
<div class="horizontal-div separated-div">
|
||||
<div class="horizontal-div">
|
||||
<img src="assets/logo.png" alt="Silk Fly Launcher Logo" class="big-logo-img"/>
|
||||
<img src="assets/logo.png" alt="Silk Fly Launcher Logo" class="big-logo-img" />
|
||||
<div>
|
||||
<h3>Silk Fly Launcher</h3>
|
||||
<p class="transparent-text">v1.0.0</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="horizontal-div">
|
||||
<img onclick="electronAPI.openExternalLink('https://github.com/Gabi-Zar/Silk-Fly-Launcher')" src="data:image/svg+xml,%3csvg%20width='98'%20height='96'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20fill-rule='evenodd'%20clip-rule='evenodd'%20d='M48.854%200C21.839%200%200%2022%200%2049.217c0%2021.756%2013.993%2040.172%2033.405%2046.69%202.427.49%203.316-1.059%203.316-2.362%200-1.141-.08-5.052-.08-9.127-13.59%202.934-16.42-5.867-16.42-5.867-2.184-5.704-5.42-7.17-5.42-7.17-4.448-3.015.324-3.015.324-3.015%204.934.326%207.523%205.052%207.523%205.052%204.367%207.496%2011.404%205.378%2014.235%204.074.404-3.178%201.699-5.378%203.074-6.6-10.839-1.141-22.243-5.378-22.243-24.283%200-5.378%201.94-9.778%205.014-13.2-.485-1.222-2.184-6.275.486-13.038%200%200%204.125-1.304%2013.426%205.052a46.97%2046.97%200%200%201%2012.214-1.63c4.125%200%208.33.571%2012.213%201.63%209.302-6.356%2013.427-5.052%2013.427-5.052%202.67%206.763.97%2011.816.485%2013.038%203.155%203.422%205.015%207.822%205.015%2013.2%200%2018.905-11.404%2023.06-22.324%2024.283%201.78%201.548%203.316%204.481%203.316%209.126%200%206.6-.08%2011.897-.08%2013.526%200%201.304.89%202.853%203.316%202.364%2019.412-6.52%2033.405-24.935%2033.405-46.691C97.707%2022%2075.788%200%2048.854%200z'%20fill='%23fff'/%3e%3c/svg%3e" alt="Github logo" class="logo-img"/>
|
||||
<img onclick="electronAPI.openExternalLink('https://github.com/Gabi-Zar/Silk-Fly-Launcher')" src="assets/github.svg" alt="Github logo" class="logo-img invert-color" />
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<br />
|
||||
<ul>
|
||||
<li>Silk Fly Launcher is a launcher and mod manager for Silksong mods from Nexus, built with Electron.</li>
|
||||
<li>This product is licensed under the <a href="" class="link" onclick="electronAPI.openWindow('LICENSE')">GNU General Public License Version 3</a>.</li>
|
||||
<li>This product uses third-party modules or assets under <a href="" class="link" onclick="electronAPI.openWindow('3RD-PARTY-LICENSES')">third-party licenses</a>.</li>
|
||||
<li>Found a bug or have a feature request? Please <a href="" class="link" onclick="electronAPI.openExternalLink('https://github.com/Gabi-Zar/Silk-Fly-Launcher/issues')">create an issue on GitHub</a>.</li>
|
||||
<li>
|
||||
Found a bug or have a feature request? Please
|
||||
<a href="" class="link" onclick="electronAPI.openExternalLink('https://github.com/Gabi-Zar/Silk-Fly-Launcher/issues')">create an issue on GitHub</a>.
|
||||
</li>
|
||||
<li>Made with ♥ by <a href="" class="link" onclick="electronAPI.openExternalLink('https://github.com/Gabi-Zar')">GabiZar</a>.</li>
|
||||
</ul>
|
||||
<br>
|
||||
<br />
|
||||
</template>
|
||||
|
||||
<template id="installed-mods-template">
|
||||
<h2>List Of Installed Mods</h2>
|
||||
<form class="horizontal-div" id="search-form">
|
||||
<input class="input" id="search-input" type="text" placeholder="Search For Mods...">
|
||||
<input class="input" id="search-input" type="text" placeholder="Search For Mods..." />
|
||||
<button class="default-button" onclick="searchInstalledMods()">Search</button>
|
||||
</form>
|
||||
<div class="mods-container" id="mods-container">
|
||||
</div>
|
||||
<div class="mods-container" id="mods-container"></div>
|
||||
</template>
|
||||
|
||||
<template id="online-mods-template">
|
||||
<h2>List Of Nexus Mods</h2>
|
||||
<form class="horizontal-div" id="search-form">
|
||||
<input class="input" id="search-input" type="text" placeholder="Search For Mods...">
|
||||
<input class="input" id="search-input" type="text" placeholder="Search For Mods..." />
|
||||
<button class="default-button" onclick="searchNexusMods()">Search</button>
|
||||
</form>
|
||||
<div class="mods-container" id="mods-container">
|
||||
</div>
|
||||
<div class="mods-container" id="mods-container"></div>
|
||||
</template>
|
||||
|
||||
<template id="mod-template">
|
||||
<div class="mod-container">
|
||||
<div class="mod-text">
|
||||
<div class="horizontal-div" >
|
||||
<div class="horizontal-div">
|
||||
<h3 id="mod-title">Unknown Title</h3>
|
||||
<p id="mod-author">Unknown author</p>
|
||||
<p id="mod-endorsements-number">? likes</p>
|
||||
@@ -119,7 +122,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<img class="mod-icon" src="assets/placeholder_icon.png" alt="mod icon" id="mod-icon">
|
||||
<img class="mod-icon" src="assets/placeholder_icon.png" alt="mod icon" id="mod-icon" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -127,7 +130,7 @@
|
||||
<h2>General settings</h2>
|
||||
<div class="horizontal-div">
|
||||
<label>Enter Silksong path: </label>
|
||||
<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>
|
||||
</div>
|
||||
<div class="horizontal-div">
|
||||
@@ -145,12 +148,12 @@
|
||||
</div>
|
||||
</div>
|
||||
<label class="lace-pin-checkbox-container">
|
||||
<input type="checkbox" name="lace-pin" id="lace-pin">
|
||||
<input type="checkbox" name="lace-pin" id="lace-pin" />
|
||||
<span class="checkmark"></span>
|
||||
Lace Pin
|
||||
</label>
|
||||
</div>
|
||||
<br>
|
||||
<br />
|
||||
<h2>BepInEx</h2>
|
||||
<p class="transparent-text" id="bepinex-version-text"></p>
|
||||
<div class="horizontal-div">
|
||||
@@ -159,26 +162,26 @@
|
||||
<button class="default-button" onclick="backupBepinex()">Backup</button>
|
||||
<button class="important-button" onclick="deleteBepinexBackup()">Delete Backup</button>
|
||||
</div>
|
||||
<br>
|
||||
<br />
|
||||
<h2>Nexus</h2>
|
||||
<p class="transparent-text" id="bepinex-version-text"></p>
|
||||
<div class="horizontal-div">
|
||||
<label for="nexus-api-label">Enter your nexus api: </label>
|
||||
<input type="text" class="input" id="nexus-api-input" name="nexus-api-input">
|
||||
<img class="nexus-check-image" id="nexus-check-image" src="assets/cross.svg">
|
||||
<input type="text" class="input" id="nexus-api-input" name="nexus-api-input" />
|
||||
<img class="nexus-check-image" id="nexus-check-image" src="assets/cross.svg" />
|
||||
<button class="default-button" onclick="verifyNexusAPI()">Verify</button>
|
||||
</div>
|
||||
<br>
|
||||
<br />
|
||||
<h2>Import/Export</h2>
|
||||
<div class="horizontal-div">
|
||||
<button class="default-button" onclick="importData()">Import Data</button>
|
||||
<button class="default-button" onclick="exportData()">Export Data</button>
|
||||
<button class="important-button" onclick="deleteData()">Delete All Data</button>
|
||||
</div>
|
||||
<br>
|
||||
<br />
|
||||
<h2>Debugging</h2>
|
||||
<div class="horizontal-div">
|
||||
<h3>Versions: </h3>
|
||||
<h3>Versions:</h3>
|
||||
<ul id="versions-list">
|
||||
<li id="Silk-Fly-Launcher"></li>
|
||||
<li id="Electron"></li>
|
||||
@@ -190,6 +193,5 @@
|
||||
</template>
|
||||
|
||||
<script src="renderer.js"></script>
|
||||
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -8,13 +8,13 @@ const onlineModsTemplate = document.getElementById("online-mods-template");
|
||||
const settingsTemplate = document.getElementById("settings-template");
|
||||
const modTemplate = document.getElementById("mod-template");
|
||||
|
||||
let oldPage
|
||||
let actualTheme = []
|
||||
let oldPage;
|
||||
let actualTheme = [];
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
///////////////// CONST FOR WELCOME //////////////////
|
||||
|
||||
let actualPage = 0
|
||||
let actualPage = 0;
|
||||
|
||||
const pageDiv = document.getElementById("page");
|
||||
const buttonDiv = document.getElementById("button-div");
|
||||
@@ -31,16 +31,15 @@ const tutorialTemplate = document.getElementById("tutorial-template");
|
||||
//////////////////////////////////////////////////////
|
||||
////////////////////// STARTUP ///////////////////////
|
||||
|
||||
on_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") {
|
||||
welcomeNavigate()
|
||||
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") {
|
||||
welcomeNavigate();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,223 +48,220 @@ async function on_startup() {
|
||||
|
||||
async function navigate(page) {
|
||||
if (oldPage == page) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
oldPage = page
|
||||
oldPage = page;
|
||||
|
||||
view.replaceChildren()
|
||||
view.replaceChildren();
|
||||
switch (page) {
|
||||
case "home":
|
||||
title.innerText = "Silk Fly Launcher";
|
||||
const HomeTemplateCopy = HomeTemplate.content.cloneNode(true)
|
||||
view.appendChild(HomeTemplateCopy)
|
||||
const HomeTemplateCopy = HomeTemplate.content.cloneNode(true);
|
||||
view.appendChild(HomeTemplateCopy);
|
||||
break;
|
||||
|
||||
case "mods-installed":
|
||||
title.innerText = "Installed Mods";
|
||||
const installedModsTemplateCopy = installedModsTemplate.content.cloneNode(true)
|
||||
const searchFormInstalled = installedModsTemplateCopy.getElementById("search-form")
|
||||
const installedModsTemplateCopy = installedModsTemplate.content.cloneNode(true);
|
||||
const searchFormInstalled = installedModsTemplateCopy.getElementById("search-form");
|
||||
|
||||
searchFormInstalled.addEventListener('submit', async function(event) {
|
||||
event.preventDefault()
|
||||
})
|
||||
searchFormInstalled.addEventListener("submit", async function (event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
view.appendChild(installedModsTemplateCopy)
|
||||
view.appendChild(installedModsTemplateCopy);
|
||||
break;
|
||||
|
||||
case "mods-online":
|
||||
title.innerText = "Online Mods";
|
||||
const onlineModsTemplateCopy = onlineModsTemplate.content.cloneNode(true)
|
||||
const ModsContainer = onlineModsTemplateCopy.getElementById("mods-container")
|
||||
const searchFormNexus = onlineModsTemplateCopy.getElementById("search-form")
|
||||
const onlineModsTemplateCopy = onlineModsTemplate.content.cloneNode(true);
|
||||
const ModsContainer = onlineModsTemplateCopy.getElementById("mods-container");
|
||||
const searchFormNexus = onlineModsTemplateCopy.getElementById("search-form");
|
||||
|
||||
searchFormNexus.addEventListener('submit', async function(event) {
|
||||
event.preventDefault()
|
||||
})
|
||||
searchFormNexus.addEventListener("submit", async function (event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
view.appendChild(onlineModsTemplateCopy)
|
||||
view.appendChild(onlineModsTemplateCopy);
|
||||
|
||||
mods = await nexus.getLatestMods()
|
||||
mods = await nexus.getLatestMods();
|
||||
if (mods == undefined) {
|
||||
break;
|
||||
}
|
||||
for(const mod of mods) {
|
||||
for (const mod of mods) {
|
||||
if (mod.name == undefined) {
|
||||
continue
|
||||
continue;
|
||||
}
|
||||
const modTemplateCopy = modTemplate.content.cloneNode(true)
|
||||
const modTemplateCopy = modTemplate.content.cloneNode(true);
|
||||
if (mod.name) {
|
||||
const modTitleText = modTemplateCopy.getElementById("mod-title")
|
||||
modTitleText.innerText = 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}`
|
||||
const modAuthorText = modTemplateCopy.getElementById("mod-author");
|
||||
modAuthorText.innerText = `by ${mod.author}`;
|
||||
}
|
||||
if (mod.endorsement_count) {
|
||||
const modEndorsementsNumber = modTemplateCopy.getElementById("mod-endorsements-number")
|
||||
const modEndorsementsNumber = modTemplateCopy.getElementById("mod-endorsements-number");
|
||||
if (mod.endorsement_count > 1) {
|
||||
modEndorsementsNumber.innerText = `${mod.endorsement_count} likes`
|
||||
}
|
||||
else {
|
||||
modEndorsementsNumber.innerText = `${mod.endorsement_count} like`
|
||||
modEndorsementsNumber.innerText = `${mod.endorsement_count} likes`;
|
||||
} else {
|
||||
modEndorsementsNumber.innerText = `${mod.endorsement_count} like`;
|
||||
}
|
||||
}
|
||||
if (mod.summary) {
|
||||
const modDescriptionText = modTemplateCopy.getElementById("mod-description")
|
||||
modDescriptionText.innerText = mod.summary
|
||||
const modDescriptionText = modTemplateCopy.getElementById("mod-description");
|
||||
modDescriptionText.innerText = mod.summary;
|
||||
}
|
||||
if (mod.picture_url) {
|
||||
const modPicture = modTemplateCopy.getElementById("mod-icon")
|
||||
modPicture.src = mod.picture_url
|
||||
const modPicture = modTemplateCopy.getElementById("mod-icon");
|
||||
modPicture.src = mod.picture_url;
|
||||
}
|
||||
if (mod.version && mod.updated_timestamp) {
|
||||
const modVersionText = modTemplateCopy.getElementById("mod-version")
|
||||
modVersionText.innerText = `V${mod.version} last updated on ${mod.updated_time.slice(0, 10)}`
|
||||
const modVersionText = modTemplateCopy.getElementById("mod-version");
|
||||
modVersionText.innerText = `V${mod.version} last updated on ${mod.updated_time.slice(0, 10)}`;
|
||||
}
|
||||
|
||||
const modUrl = `https://www.nexusmods.com/hollowknightsilksong/mods/${mod.mod_id}`
|
||||
const modUrl = `https://www.nexusmods.com/hollowknightsilksong/mods/${mod.mod_id}`;
|
||||
|
||||
const modLinkButton = modTemplateCopy.getElementById("external-link")
|
||||
modLinkButton.href = modUrl
|
||||
modLinkButton.addEventListener('click', function(event) {
|
||||
event.preventDefault()
|
||||
const modLink = modLinkButton.href
|
||||
electronAPI.openExternalLink(modLink)
|
||||
})
|
||||
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)
|
||||
})
|
||||
modDownloadButton = modTemplateCopy.getElementById("download-mod-button");
|
||||
modDownloadButton.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
const modDownloadLink = `${modUrl}?tab=files`;
|
||||
nexus.download(modDownloadLink);
|
||||
});
|
||||
|
||||
ModsContainer.appendChild(modTemplateCopy)
|
||||
ModsContainer.appendChild(modTemplateCopy);
|
||||
}
|
||||
break;
|
||||
|
||||
case "general-settings":
|
||||
title.innerText = "Settings";
|
||||
const settingsTemplateCopy = settingsTemplate.content.cloneNode(true)
|
||||
const silksongPathInput = settingsTemplateCopy.getElementById("silksong-path-input")
|
||||
const nexusAPIInput = settingsTemplateCopy.getElementById("nexus-api-input")
|
||||
const versionsList = settingsTemplateCopy.getElementById("versions-list")
|
||||
const settingsTemplateCopy = settingsTemplate.content.cloneNode(true);
|
||||
const silksongPathInput = settingsTemplateCopy.getElementById("silksong-path-input");
|
||||
const nexusAPIInput = settingsTemplateCopy.getElementById("nexus-api-input");
|
||||
const versionsList = settingsTemplateCopy.getElementById("versions-list");
|
||||
const versionsDictionnary = {
|
||||
"Silk-Fly-Launcher": `Silk Fly Launcher: v${versions.silkFlyLauncher()}`,
|
||||
"Electron": `Electron: v${versions.electron()}`,
|
||||
"Node": `Node.js: v${versions.node()}`,
|
||||
"Chromium": `Chromium: v${versions.chromium()}`,
|
||||
}
|
||||
const lacePinCheckbox = settingsTemplateCopy.getElementById('lace-pin');
|
||||
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)
|
||||
silksongPathInput.value = await files.loadSilksongPath();
|
||||
silksongPathInput.addEventListener("input", async function (event) {
|
||||
let silksongPath = silksongPathInput.value;
|
||||
files.saveSilksongPath(silksongPath);
|
||||
});
|
||||
|
||||
nexusAPIInput.value = await files.loadNexusAPI()
|
||||
nexusAPIInput.addEventListener('input', async function(event) {
|
||||
let nexusAPI = nexusAPIInput.value
|
||||
files.saveNexusAPI(nexusAPI)
|
||||
nexusAPIInput.value = await files.loadNexusAPI();
|
||||
nexusAPIInput.addEventListener("input", async function (event) {
|
||||
let nexusAPI = nexusAPIInput.value;
|
||||
files.saveNexusAPI(nexusAPI);
|
||||
});
|
||||
|
||||
for(const element of versionsList.children) {
|
||||
element.innerText = versionsDictionnary[element.id]
|
||||
for (const element of versionsList.children) {
|
||||
element.innerText = versionsDictionnary[element.id];
|
||||
}
|
||||
|
||||
const theme = await files.loadTheme()
|
||||
lacePinCheckbox.checked = theme[1]
|
||||
const theme = await files.loadTheme();
|
||||
lacePinCheckbox.checked = theme[1];
|
||||
|
||||
lacePinCheckbox.addEventListener('change', async function() {
|
||||
lacePinCheckbox.addEventListener("change", async function () {
|
||||
if (this.checked) {
|
||||
const theme = await files.loadTheme();
|
||||
changeTheme(theme[0], true);
|
||||
toggleThemesMenu()
|
||||
}
|
||||
else {
|
||||
toggleThemesMenu();
|
||||
} else {
|
||||
const theme = await files.loadTheme();
|
||||
changeTheme(theme[0], false);
|
||||
toggleThemesMenu()
|
||||
toggleThemesMenu();
|
||||
}
|
||||
});
|
||||
|
||||
view.appendChild(settingsTemplateCopy)
|
||||
setBepinexVersion()
|
||||
setThemeButton()
|
||||
verifyNexusAPI()
|
||||
view.appendChild(settingsTemplateCopy);
|
||||
setBepinexVersion();
|
||||
setThemeButton();
|
||||
verifyNexusAPI();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
async function welcomeNavigate() {
|
||||
pageDiv.replaceChildren()
|
||||
pageDiv.replaceChildren();
|
||||
switch (actualPage) {
|
||||
case 0:
|
||||
pageDiv.appendChild(welcomeTemplate.content.cloneNode(true))
|
||||
buttonDiv.replaceChildren()
|
||||
buttonDiv.appendChild(oneButtonTemplate.content.cloneNode(true))
|
||||
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))
|
||||
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()
|
||||
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)
|
||||
silksongPathInput.addEventListener("input", async function (event) {
|
||||
let silksongPath = silksongPathInput.value;
|
||||
await files.saveSilksongPath(silksongPath);
|
||||
});
|
||||
break;
|
||||
|
||||
case 2:
|
||||
pageDiv.appendChild(nexusTemplate.content.cloneNode(true))
|
||||
const nexusLink = document.getElementById("external-link")
|
||||
nexusLink.addEventListener('click', function(event) {
|
||||
event.preventDefault()
|
||||
const url = nexusLink.href
|
||||
electronAPI.openExternalLink(url)
|
||||
})
|
||||
pageDiv.appendChild(nexusTemplate.content.cloneNode(true));
|
||||
const nexusLink = document.getElementById("external-link");
|
||||
nexusLink.addEventListener("click", function (event) {
|
||||
event.preventDefault();
|
||||
const url = nexusLink.href;
|
||||
electronAPI.openExternalLink(url);
|
||||
});
|
||||
|
||||
const nexusAPIInput = document.getElementById("nexus-api-input")
|
||||
nexusAPIInput.value = await files.loadNexusAPI()
|
||||
nexusAPIInput.addEventListener('input', async function(event) {
|
||||
let nexusAPI = nexusAPIInput.value
|
||||
await files.saveNexusAPI(nexusAPI)
|
||||
const nexusAPIInput = document.getElementById("nexus-api-input");
|
||||
nexusAPIInput.value = await files.loadNexusAPI();
|
||||
nexusAPIInput.addEventListener("input", async function (event) {
|
||||
let nexusAPI = nexusAPIInput.value;
|
||||
await files.saveNexusAPI(nexusAPI);
|
||||
});
|
||||
break;
|
||||
|
||||
case 3:
|
||||
pageDiv.appendChild(styleTemplate.content.cloneNode(true))
|
||||
pageDiv.appendChild(styleTemplate.content.cloneNode(true));
|
||||
break;
|
||||
|
||||
case 4:
|
||||
pageDiv.appendChild(tutorialTemplate.content.cloneNode(true))
|
||||
pageDiv.appendChild(tutorialTemplate.content.cloneNode(true));
|
||||
break;
|
||||
|
||||
case 5:
|
||||
electronAPI.loadMainPage()
|
||||
electronAPI.loadMainPage();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function next() {
|
||||
actualPage++
|
||||
welcomeNavigate()
|
||||
actualPage++;
|
||||
welcomeNavigate();
|
||||
}
|
||||
|
||||
function back() {
|
||||
actualPage--
|
||||
welcomeNavigate()
|
||||
actualPage--;
|
||||
welcomeNavigate();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
@@ -273,149 +269,145 @@ function back() {
|
||||
|
||||
async function initialImportData() {
|
||||
if (await files.import()) {
|
||||
electronAPI.loadMainPage()
|
||||
electronAPI.loadMainPage();
|
||||
}
|
||||
}
|
||||
|
||||
async function importData() {
|
||||
await files.import()
|
||||
document.getElementById("silksong-path-input").value = await files.loadSilksongPath()
|
||||
document.getElementById("nexus-api-input").value = await files.loadNexusAPI()
|
||||
const lacePinCheckbox = document.getElementById('lace-pin')
|
||||
const theme = await files.loadTheme()
|
||||
lacePinCheckbox.checked = theme[1]
|
||||
changeTheme(theme[0])
|
||||
toggleThemesMenu()
|
||||
await files.import();
|
||||
document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
|
||||
document.getElementById("nexus-api-input").value = await files.loadNexusAPI();
|
||||
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()
|
||||
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()
|
||||
document.getElementById("nexus-api-input").value = await files.loadNexusAPI()
|
||||
const lacePinCheckbox = document.getElementById("lace-pin");
|
||||
lacePinCheckbox.checked = false;
|
||||
changeTheme("Silksong");
|
||||
toggleThemesMenu();
|
||||
await files.delete();
|
||||
document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
|
||||
document.getElementById("nexus-api-input").value = await files.loadNexusAPI();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
////////////////////// BEPINEX ///////////////////////
|
||||
|
||||
async function installBepinex() {
|
||||
await bepinex.install()
|
||||
setBepinexVersion()
|
||||
await bepinex.install();
|
||||
setBepinexVersion();
|
||||
}
|
||||
|
||||
async function uninstallBepinex() {
|
||||
await bepinex.uninstall()
|
||||
setBepinexVersion()
|
||||
await bepinex.uninstall();
|
||||
setBepinexVersion();
|
||||
}
|
||||
|
||||
async function backupBepinex() {
|
||||
await bepinex.backup()
|
||||
setBepinexVersion()
|
||||
await bepinex.backup();
|
||||
setBepinexVersion();
|
||||
}
|
||||
|
||||
async function deleteBepinexBackup() {
|
||||
await bepinex.deleteBackup()
|
||||
setBepinexVersion()
|
||||
await bepinex.deleteBackup();
|
||||
setBepinexVersion();
|
||||
}
|
||||
|
||||
async function setBepinexVersion() {
|
||||
const bepinexVersionText = document.getElementById("bepinex-version-text")
|
||||
const bepinexVersionText = document.getElementById("bepinex-version-text");
|
||||
if (bepinexVersionText == undefined) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
const bepinexVersion = await files.loadBepinexVersion()
|
||||
const bepinexBackupVersion = await files.loadBepinexBackupVersion()
|
||||
if(bepinexVersion == undefined) {
|
||||
if(bepinexBackupVersion == undefined) {
|
||||
bepinexVersionText.innerText = "BepInEx is not installed"
|
||||
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 ${bepinexBackupVersion} is backed up`
|
||||
}
|
||||
}
|
||||
else {
|
||||
bepinexVersionText.innerText = `BepInEx ${bepinexVersion} is installed`
|
||||
} else {
|
||||
bepinexVersionText.innerText = `BepInEx ${bepinexVersion} is installed`;
|
||||
}
|
||||
}
|
||||
|
||||
async function searchInstalledMods() {
|
||||
const searchInput = document.getElementById("search-input")
|
||||
console.log(searchInput.value)
|
||||
const searchInput = document.getElementById("search-input");
|
||||
console.log(searchInput.value);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
/////////////////////// NEXUS ////////////////////////
|
||||
|
||||
async function verifyNexusAPI() {
|
||||
response = await nexus.verifyAPI()
|
||||
response = await nexus.verifyAPI();
|
||||
|
||||
const nexusCheckImage = document.getElementById("nexus-check-image")
|
||||
const nexusCheckImage = document.getElementById("nexus-check-image");
|
||||
if (nexusCheckImage == undefined) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
|
||||
if (response) {
|
||||
nexusCheckImage.src = "assets/check.svg"
|
||||
}
|
||||
else {
|
||||
nexusCheckImage.src = "assets/cross.svg"
|
||||
nexusCheckImage.src = "assets/check.svg";
|
||||
} else {
|
||||
nexusCheckImage.src = "assets/cross.svg";
|
||||
}
|
||||
}
|
||||
|
||||
async function searchNexusMods() {
|
||||
const searchInput = document.getElementById("search-input")
|
||||
console.log(searchInput.value)
|
||||
const searchInput = document.getElementById("search-input");
|
||||
console.log(searchInput.value);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
/////////////////////// THEMES ///////////////////////
|
||||
|
||||
function toggleThemesMenu() {
|
||||
const themesMenu = document.getElementById("themes-menu")
|
||||
const themesMenu = document.getElementById("themes-menu");
|
||||
if (themesMenu) {
|
||||
themesMenu.classList.toggle("show")
|
||||
themesMenu.classList.toggle("show");
|
||||
}
|
||||
}
|
||||
|
||||
async function setThemeButton() {
|
||||
const themesButton = document.getElementById("themes-button")
|
||||
const themesButton = document.getElementById("themes-button");
|
||||
if (themesButton) {
|
||||
const theme = await files.loadTheme()
|
||||
themesButton.textContent = theme[0]
|
||||
const theme = await files.loadTheme();
|
||||
themesButton.textContent = theme[0];
|
||||
}
|
||||
}
|
||||
|
||||
function changeTheme(theme, state) {
|
||||
toggleThemesMenu()
|
||||
toggleThemesMenu();
|
||||
|
||||
const lacePinCheckbox = document.getElementById('lace-pin');
|
||||
const lacePinCheckbox = document.getElementById("lace-pin");
|
||||
if (lacePinCheckbox) {
|
||||
lacePinState = lacePinCheckbox.checked;
|
||||
}
|
||||
else if (state) {
|
||||
lacePinState = state
|
||||
}
|
||||
else {
|
||||
lacePinState = false
|
||||
} else if (state) {
|
||||
lacePinState = state;
|
||||
} else {
|
||||
lacePinState = false;
|
||||
}
|
||||
|
||||
if (actualTheme[0] == theme && actualTheme[1] == lacePinState) {
|
||||
return
|
||||
return;
|
||||
}
|
||||
actualTheme = [theme, lacePinState]
|
||||
actualTheme = [theme, lacePinState];
|
||||
|
||||
files.saveTheme(theme, lacePinState)
|
||||
files.saveTheme(theme, lacePinState);
|
||||
|
||||
setThemeButton()
|
||||
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)"],
|
||||
@@ -426,17 +418,18 @@ function changeTheme(theme, state) {
|
||||
"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])
|
||||
|
||||
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`
|
||||
const backgroundVideo = document.getElementById("background-video");
|
||||
let backgroundVideoPath = `assets/background/${theme}.mp4`;
|
||||
if (lacePinState) {
|
||||
backgroundVideoPath = `assets/background/${theme} Lace Pin.mp4`
|
||||
backgroundVideoPath = `assets/background/${theme} Lace Pin.mp4`;
|
||||
}
|
||||
|
||||
backgroundVideo.src = backgroundVideoPath
|
||||
backgroundVideo.src = backgroundVideoPath;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
@@ -444,12 +437,12 @@ function changeTheme(theme, state) {
|
||||
|
||||
async function launch(mode) {
|
||||
await electronAPI.launchGame(mode);
|
||||
setBepinexVersion()
|
||||
setBepinexVersion();
|
||||
}
|
||||
|
||||
async function autoDetectGamePath() {
|
||||
await files.autoDetectGamePath()
|
||||
await files.autoDetectGamePath();
|
||||
if (document.getElementById("silksong-path-input")) {
|
||||
document.getElementById("silksong-path-input").value = await files.loadSilksongPath()
|
||||
document.getElementById("silksong-path-input").value = await files.loadSilksongPath();
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,9 @@
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
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 {
|
||||
@@ -13,7 +15,7 @@
|
||||
--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)
|
||||
--transparent-grey: rgba(30, 30, 30, 0.8);
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -69,6 +71,10 @@ body {
|
||||
height: 100px;
|
||||
}
|
||||
|
||||
.invert-color {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
.nav {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>Welcome to Silk Fly Launcher</title>
|
||||
<link rel="stylesheet" href="welcome.css" />
|
||||
<link rel="stylesheet" href="style.css" />
|
||||
</head>
|
||||
<body>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<video autoplay muted loop class="background-video" id="background-video" src="assets/background/Silksong.mp4" type="video/mp4"></video>
|
||||
|
||||
<div class="welcome-div" id="main-div">
|
||||
<br>
|
||||
<br />
|
||||
<div id="page"></div>
|
||||
<div class="button-div" id="button-div"></div>
|
||||
</div>
|
||||
@@ -40,18 +40,21 @@
|
||||
<p>Please verify the path to your game and edit it if the auto detection didn't work</p>
|
||||
<div class="horizontal-div">
|
||||
<label>Enter Silksong path: </label>
|
||||
<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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template id="nexus-template">
|
||||
<h1 class="title">Enter your nexus API key</h1>
|
||||
<p>Please enter your nexus API key. To get your API key go to <a href="https://www.nexusmods.com/settings/api-keys" class="link" id="external-link">https://www.nexusmods.com/settings/api-keys</a> and click on new personnal API key</p>
|
||||
<p>
|
||||
Please enter your nexus API key. To get your API key go to
|
||||
<a href="https://www.nexusmods.com/settings/api-keys" class="link" id="external-link">https://www.nexusmods.com/settings/api-keys</a> and click on new personnal API key
|
||||
</p>
|
||||
<div class="horizontal-div">
|
||||
<label for="nexus-api-label">Enter your nexus api: </label>
|
||||
<input type="text" class="input" id="nexus-api-input" name="nexus-api-input">
|
||||
<img class="nexus-check-image" id="nexus-check-image" src="assets/cross.svg">
|
||||
<input type="text" class="input" id="nexus-api-input" name="nexus-api-input" />
|
||||
<img class="nexus-check-image" id="nexus-check-image" src="assets/cross.svg" />
|
||||
<button class="default-button" onclick="verifyNexusAPI()">Verify</button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -80,5 +83,5 @@
|
||||
</template>
|
||||
|
||||
<script src="renderer.js"></script>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user