diff --git a/main.js b/main.js index 0536b6c..513aa9c 100644 --- a/main.js +++ b/main.js @@ -1,5 +1,5 @@ // Modules to control application life and create native browser window -const { app, BrowserWindow, Menu, ipcMain } = require("electron"); +const { app, BrowserWindow, Menu, ipcMain, dialog } = require("electron"); const path = require("path"); const serve = require("electron-serve"); const loadURL = serve({ directory: "public" }); @@ -7,6 +7,7 @@ const config = require("./src/config/config"); const { setupTitlebar, attachTitlebarToWindow } = require( "custom-electron-titlebar/main", ); +const { isValidOsuFolder } = require("./src/util/osuUtil"); // Keep a global reference of the window object, if you don't, the window will // be closed automatically when the JavaScript object is garbage collected. @@ -112,6 +113,33 @@ function registerIPCPipes() { return true; }); + ipcMain.handle("ezpplauncher:settings", async (e) => { + return config.all(); + }); + + ipcMain.handle("ezpplauncher:set-folder", async (e) => { + const folderResult = await dialog.showOpenDialog({ + title: "Select osu! installation directory", + properties: ["openDirectory"], + }); + if (!folderResult.canceled) { + const folder = folderResult.filePaths[0]; + if (await isValidOsuFolder(folder)) { + config.set("osuPath", folder); + mainWindow.webContents.send("ezpplauncher:alert", { + type: "success", + message: "osu! path successfully saved!", + }); + } else { + mainWindow.webContents.send("ezpplauncher:alert", { + type: "error", + message: "invalid osu! path!", + }); + } + } + return config.all(); + }); + ipcMain.handle("ezpplauncher:launch", async (e) => { mainWindow.webContents.send("ezpplauncher:launchstatus", { status: "Checking osu! directory...", diff --git a/preload.js b/preload.js index 0c862fb..62af955 100644 --- a/preload.js +++ b/preload.js @@ -22,25 +22,49 @@ window.addEventListener("login-attempt", async (e) => { ); }); -window.addEventListener("autologin-attempt", async (e) => { +window.addEventListener("autologin-attempt", async () => { const loginResult = await ipcRenderer.invoke("ezpplauncher:autologin"); window.dispatchEvent( new CustomEvent("login-result", { detail: loginResult }), ); }); -window.addEventListener("logout", async (e) => { +window.addEventListener("logout", async () => { await ipcRenderer.invoke("ezpplauncher:logout"); }); -window.addEventListener("guest-login", async (e) => { +window.addEventListener("guest-login", async () => { await ipcRenderer.invoke("ezpplauncher:guestlogin"); }); -window.addEventListener("launch", async (e) => { +window.addEventListener("launch", async () => { await ipcRenderer.invoke("ezpplauncher:launch"); }); +window.addEventListener("settings-get", async () => { + const settings = await ipcRenderer.invoke("ezpplauncher:settings"); + window.dispatchEvent( + new CustomEvent("settings-result", { detail: settings }), + ); +}); + +window.addEventListener("folder-set", async (e) => { + const result = await ipcRenderer.invoke("ezpplauncher:set-folder"); + window.dispatchEvent( + new CustomEvent("settings-result", { detail: result }), + ); +}); + +window.addEventListener("settings-set", async (e) => { + await ipcRenderer.invoke("ezpplauncher:settings-set", e.detail); +}); + +ipcRenderer.addListener("ezpplauncher:alert", (e, args) => { + window.dispatchEvent( + new CustomEvent("alert", { detail: args }), + ); +}); + ipcRenderer.addListener("ezpplauncher:launchstatus", (e, args) => { window.dispatchEvent( new CustomEvent("launchStatusUpdate", { detail: args }), diff --git a/src/App.svelte b/src/App.svelte index 0ba0886..e7c4213 100644 --- a/src/App.svelte +++ b/src/App.svelte @@ -22,7 +22,7 @@ import { Page } from "./consts/pages"; import Login from "./pages/Login.svelte"; import Launch from "./pages/Launch.svelte"; - import { Toaster } from "svelte-french-toast"; + import toast, { Toaster } from "svelte-french-toast"; import type { User } from "./types/user"; import Settings from "./pages/Settings.svelte"; @@ -51,6 +51,40 @@ const progress = (e as CustomEvent).detail.progress; launchPercentage.set(progress); }); + + window.addEventListener("alert", (e) => { + console.log((e as CustomEvent).detail); + const toastMessage = (e as CustomEvent).detail; + switch (toastMessage.type) { + case "success": { + toast.success(toastMessage.message, { + position: "bottom-center", + className: + "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", + duration: 1500, + }); + break; + } + case "error": { + toast.error(toastMessage.message, { + position: "bottom-center", + className: + "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", + duration: 1500, + }); + break; + } + default: { + toast(toastMessage.message, { + icon: "ℹ", + position: "bottom-center", + className: + "dark:!bg-gray-800 border-1 dark:!border-gray-700 dark:!text-gray-100", + duration: 1500, + }); + } + } + }); diff --git a/src/config/config.js b/src/config/config.js index ae42aad..ad5e97e 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -38,7 +38,15 @@ const get = ( return result ? result.val ?? undefined : undefined; }; +const all = () => { + const result = db.prepare( + `SELECT configKey key, configValue val FROM config WHERE 1`, + ).all(); + return result ?? undefined; +}; + module.exports = { + all, get, set, remove, diff --git a/src/pages/Settings.svelte b/src/pages/Settings.svelte index 6b1642f..209130a 100644 --- a/src/pages/Settings.svelte +++ b/src/pages/Settings.svelte @@ -3,6 +3,19 @@ import { FolderSolid } from "flowbite-svelte-icons"; import { currentPage } from "../storage/localStore"; import { Page } from "../consts/pages"; + + let folderPath: string = ""; + + window.addEventListener("settings-result", (e) => { + const settings: Record[] = (e as CustomEvent).detail; + const osuPath = settings.find((setting) => setting.key == "osuPath"); + folderPath = osuPath ? osuPath.val : ""; + }); + window.dispatchEvent(new CustomEvent("settings-get")); + + const setFolderPath = () => { + window.dispatchEvent(new CustomEvent("folder-set")); + };
-