diff --git a/main.js b/main.js index 390d5e0..5df3082 100644 --- a/main.js +++ b/main.js @@ -11,6 +11,7 @@ import { path7za } from "7zip-bin"; import node7z from "node-7z"; const { extractFull } = node7z; import packageJson from "./package.json" with { type: "json" }; +import semverGt from "semver/functions/gt.js"; const __filename = fileURLToPath(import.meta.url); const __dirname = path.dirname(__filename); @@ -79,6 +80,9 @@ async function createWindow() { mainWindow.once("ready-to-show", () => { mainWindow.show(); + if (!isDev) { + verifyUpdate(); + } }); } @@ -115,6 +119,51 @@ app.on("open-url", (event, url) => { handleNxmUrl(url); }); +async function verifyUpdate() { + const GITHUB_URL = "https://api.github.com/repos/Gabi-Zar/Silk-Fly-Launcher/releases"; + + const res = await fetch(GITHUB_URL, { + headers: { + "User-Agent": userAgent, + Accept: "application/vnd.github+json", + }, + }); + + if (!res.ok) { + if (res.status == 403) { + mainWindow.webContents.send("showToast", "Github has blocked the application. Please try again later.", "error"); + } + throw new Error(`GitHub API error: ${res.status}`); + } + + const releases = await res.json(); + const prerelease = releases.find((r) => r.prerelease); + const release = releases.find((r) => !r.prerelease && !r.draft); + + let prereleaseVersion; + let releaseVersion; + let latestVersion; + + if (prerelease) { + prereleaseVersion = prerelease.tag_name.replace(/^v/, ""); + latestVersion = prereleaseVersion; + } + if (release) { + releaseVersion = release.tag_name.replace(/^v/, ""); + latestVersion = releaseVersion; + } + + if (prereleaseVersion && releaseVersion) { + latestVersion = semverGt(prereleaseVersion, releaseVersion) ? prereleaseVersion : releaseVersion; + } + if (latestVersion != VERSION) { + mainWindow.webContents.send( + "showBanner", + `Update v${latestVersion} is available on GitHub! Your current version is ${VERSION}.`, + ); + } +} + ////////////////////////////////////////////////////// ///////////////// SAVING AND LOADING ///////////////// ipcMain.handle("save-path", (event, path) => { diff --git a/package-lock.json b/package-lock.json index f502a14..0e72d76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "silkflylauncher", - "version": "1.0.0", + "version": "1.0.0-dev", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "silkflylauncher", - "version": "1.0.0", + "version": "1.0.0-dev", "license": "GPL-3.0", "dependencies": { "@nexusmods/nexus-api": "^1.1.5", @@ -14,7 +14,8 @@ "electron-store": "^11.0.2", "graphql": "^16.12.0", "graphql-request": "^7.4.0", - "node-7z": "^3.0.0" + "node-7z": "^3.0.0", + "semver": "^7.7.4" }, "devDependencies": { "@electron-forge/cli": "^7.11.1", diff --git a/package.json b/package.json index 4708ce8..136024f 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,8 @@ "electron-store": "^11.0.2", "graphql": "^16.12.0", "graphql-request": "^7.4.0", - "node-7z": "^3.0.0" + "node-7z": "^3.0.0", + "semver": "^7.7.4" }, "AES-key-nexus-api": "__AES_KEY__" } diff --git a/preload.js b/preload.js index 07c4402..7c39da3 100644 --- a/preload.js +++ b/preload.js @@ -34,6 +34,11 @@ contextBridge.exposeInMainWorld("electronAPI", { callback(message, type, duration); }); }, + onShowBanner: (callback) => { + ipcRenderer.on("showBanner", (event, message) => { + callback(message); + }); + }, }); contextBridge.exposeInMainWorld("bepinex", { diff --git a/renderer/index.html b/renderer/index.html index 48ef77c..b87c2e6 100644 --- a/renderer/index.html +++ b/renderer/index.html @@ -58,6 +58,10 @@
+

Silk Fly Launcher

diff --git a/renderer/renderer.js b/renderer/renderer.js index 6b18b36..40c809d 100644 --- a/renderer/renderer.js +++ b/renderer/renderer.js @@ -739,6 +739,23 @@ function showToast(message, type = "info", duration = 3000) { 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") { diff --git a/renderer/style.css b/renderer/style.css index 2ef1607..685943d 100644 --- a/renderer/style.css +++ b/renderer/style.css @@ -447,3 +447,19 @@ body { .long-text { overflow-wrap: anywhere; } + +.banner-div { + display: none; + align-items: center; + justify-content: space-between; + border: 1px solid var(--secondary-color); + background: var(--primary-color); + margin-bottom: 20px; + height: 64px; + border-radius: 12px; + padding: 10px; +} + +.banner-div.show { + display: flex; +}