From b08e4d193a2c6dea82a6f00432203cfad097e708 Mon Sep 17 00:00:00 2001 From: 0neGal Date: Fri, 21 Jul 2023 23:22:44 +0200 Subject: rename mods.list() properties to use snake case I may or may not have missed some properties or something somewhere, perhaps we'll see if something ends up broken in the future... --- src/app/js/browser.js | 20 ++++++++++---------- src/app/js/mods.js | 18 +++++++++--------- src/app/main.js | 13 +++++++++---- 3 files changed, 28 insertions(+), 23 deletions(-) (limited to 'src/app') diff --git a/src/app/js/browser.js b/src/app/js/browser.js index 206b80e..3c3786f 100644 --- a/src/app/js/browser.js +++ b/src/app/js/browser.js @@ -133,9 +133,9 @@ var Browser = { for (let ii = 0; ii < modsobj.all.length; ii++) { let mod = modsobj.all[ii]; - if (normalize(mod.Name) === normalized) { - local_name = mod.Name; - local_version = version.format(mod.Version); + if (normalize(mod.name) === normalized) { + local_name = mod.name; + local_version = version.format(mod.version); if (version.is_newer(remote_version, local_version)) { has_update = true; } @@ -270,13 +270,13 @@ var Browser = { setTimeout(() => { for (let i = 0; i < modsobj.all.length; i++) { - let modname = normalize(modsobj.all[i].Name); - let modfolder = normalize(modsobj.all[i].FolderName); + let modname = normalize(modsobj.all[i].name); + let modfolder = normalize(modsobj.all[i].folder_name); if (mod.includes(modname)) { if (! make(modname)) { - if (modsobj.all[i].ManifestName) { - make(normalize(modsobj.all[i].ManifestName)); + if (modsobj.all[i].manifest_name) { + make(normalize(modsobj.all[i].manifest_name)); } } } @@ -386,7 +386,7 @@ function BrowserEl(properties) { let normalized_mods = []; for (let i = 0; i < modsobj.all; i++) { - normalized_mods.push(normalize(mods_list[i].Name)); + normalized_mods.push(normalize(mods_list[i].name)); } if (properties.pkg.local_version) { @@ -445,8 +445,8 @@ function add_recent_toast(name, timeout = 3000) { ipcRenderer.on("removed-mod", (event, mod) => { setButtons(true); Browser.setbutton(mod.name, lang("gui.browser.install")); - if (mod.manifestname) { - Browser.setbutton(mod.manifestname, lang("gui.browser.install")); + if (mod.manifest_name) { + Browser.setbutton(mod.manifest_name, lang("gui.browser.install")); } }) diff --git a/src/app/js/mods.js b/src/app/js/mods.js index d4e8043..af430e5 100644 --- a/src/app/js/mods.js +++ b/src/app/js/mods.js @@ -6,13 +6,13 @@ mods.load = (mods_obj) => { let normalized_names = []; let set_mod = (mod) => { - let normalized_name = "mod-list-" + normalize(mod.Name); + let normalized_name = "mod-list-" + normalize(mod.name); normalized_names.push(normalized_name); let el = document.getElementById(normalized_name); if (el) { - if (mod.Disabled) { + if (mod.disabled) { el.querySelector(".switch").classList.remove("on"); } else { el.querySelector(".switch").classList.add("on"); @@ -31,30 +31,30 @@ mods.load = (mods_obj) => {
-
${mod.Name}
-
${mod.Description}
+
${mod.name}
+
${mod.description}
- - +
`; - if (mod.Disabled) { + if (mod.disabled) { div.querySelector(".switch").classList.remove("on"); } div.querySelector(".switch").addEventListener("click", () => { - mods.toggle(mod.Name); + mods.toggle(mod.name); }) div.querySelector(".image").style.display = "none"; diff --git a/src/app/main.js b/src/app/main.js index 1dbff40..26410cc 100644 --- a/src/app/main.js +++ b/src/app/main.js @@ -3,7 +3,12 @@ const path = require("path"); const { app, ipcRenderer, shell } = require("electron"); const lang = require("../lang"); -var modsobj = {}; +var modsobj = { + all: [], + enabled: [], + disabled: [] +} + let shouldInstallNorthstar = false; // Base settings @@ -212,11 +217,11 @@ function installFromURL(url, dependencies, clearqueue, author) { function isModInstalled(modname) { for (let i = 0; i < modsobj.all.length; i++) { let mod = modsobj.all[i]; - if (mod.ManifestName) { - if (mod.ManifestName.match(modname)) { + if (mod.manifest_name) { + if (mod.manifest_name.match(modname)) { return true; } - } else if (mod.Name.match(modname)) { + } else if (mod.name.match(modname)) { return true; } } -- cgit v1.2.3 From 73a651b63c29e24774c1ba3952a2d6c977101047 Mon Sep 17 00:00:00 2001 From: 0neGal Date: Sat, 22 Jul 2023 00:29:53 +0200 Subject: unify all mods of a package into one This means instead of showing the invididual mods inside a package, we simply show 1 mod/package, we then use the name, description, version and so forth from the `manifest.json` inside the package folder. Further we now also support a local `icon.png` file, instead of relying on remotely stored icons and trying to match names against each other. --- src/app/js/mods.js | 74 +++++++++++++++++++++++++++++++++++++++++------------ src/modules/mods.js | 24 +++++++++++++++++ 2 files changed, 81 insertions(+), 17 deletions(-) (limited to 'src/app') diff --git a/src/app/js/mods.js b/src/app/js/mods.js index af430e5..2df7205 100644 --- a/src/app/js/mods.js +++ b/src/app/js/mods.js @@ -6,7 +6,12 @@ mods.load = (mods_obj) => { let normalized_names = []; let set_mod = (mod) => { - let normalized_name = "mod-list-" + normalize(mod.name); + let name = mod.name; + if (mod.package) { + name = mod.package.package_name; + } + + let normalized_name = "mod-list-" + normalize(name); normalized_names.push(normalized_name); @@ -25,23 +30,38 @@ mods.load = (mods_obj) => { div.classList.add("el"); div.id = normalized_name; + let mod_details = { + name: mod.name, + version: mod.version, + description: mod.description + } + + if (mod.package) { + mod_details = { + image: mod.package.icon, + name: mod.package.manifest.name, + version: mod.package.manifest.version_number, + description: mod.package.manifest.description + } + } + div.innerHTML += `
- +
-
${mod.name}
-
${mod.description}
+
${mod_details.name}
+
${mod_details.description}
- - +
`; + div.querySelector(".remove").addEventListener("click", () => { + if (! mod.package) { + return mods.remove(mod.name); + } + + for (let i = 0; i < mod.packaged_mods.length; i++) { + mods.remove(mod.packaged_mods[i]); + } + }) + if (mod.disabled) { div.querySelector(".switch").classList.remove("on"); } div.querySelector(".switch").addEventListener("click", () => { - mods.toggle(mod.name); + if (! mod.package) { + return mods.toggle(mod.name); + } + + for (let i = 0; i < mod.packaged_mods.length; i++) { + mods.toggle(mod.packaged_mods[i]); + } }) div.querySelector(".image").style.display = "none"; @@ -87,20 +123,24 @@ mods.load = (mods_obj) => { return; } + + let image_container = mod_els[i].querySelector(".image"); + let image_el = image_container.querySelector("img") + let image_blur_el = image_container.querySelector("img.blur") + if (mod_versions[mod]) { - let image_url = mod_versions[mod].package.versions[0].icon; + image_el.src = mod_versions[mod].package.versions[0].icon; + } - let image_container = mod_els[i].querySelector(".image"); - let image_el = image_container.querySelector("img") - let image_blur_el = image_container.querySelector("img.blur") + if (image_el.getAttribute("src") && + ! image_container.parentElement.classList.contains("has-icon")) { - if (image_url && ! image_el.getAttribute("src")) { - image_container.style.display = null; - image_el.src = image_url; - image_blur_el.src = image_url; + let image_src = image_el.getAttribute("src"); - image_container.parentElement.classList.add("has-icon"); - } + image_blur_el.src = image_src; + image_container.style.display = null; + + image_container.parentElement.classList.add("has-icon"); } if (mod_versions[mod] diff --git a/src/modules/mods.js b/src/modules/mods.js index e3ff990..86c78f1 100644 --- a/src/modules/mods.js +++ b/src/modules/mods.js @@ -54,7 +54,9 @@ mods.list = () => { } let get_in_dir = (dir, package_obj) => { + let packaged_mods = []; let files = fs.readdirSync(dir); + files.forEach((file) => { // return early if `file` isn't a folder if (! fs.statSync(path.join(dir, file)).isDirectory()) { @@ -84,6 +86,7 @@ mods.list = () => { } if (obj.package) { + packaged_mods.push(obj.name); obj.author = obj.package.author; } @@ -114,6 +117,27 @@ mods.list = () => { enabled.push(obj); } }) + + if (packaged_mods.length == 0) { + return; + } + + let add_packaged_mods = (mods_array) => { + for (let i = 0; i < mods_array.length; i++) { + if (mods_array[i].package.package_name !== + package_obj.package_name) { + + continue; + } + + mods_array[i].packaged_mods = packaged_mods; + } + + return mods_array; + } + + enabled = add_packaged_mods(enabled); + disbled = add_packaged_mods(disabled); } // get mods in `mods` folder -- cgit v1.2.3 From c3652b72b7bb3bcce207139ebc718e15f6746e43 Mon Sep 17 00:00:00 2001 From: 0neGal Date: Sat, 22 Jul 2023 01:23:04 +0200 Subject: mostly support installing packages through GUI Install toasts, installing overall, dependencies and so forth, all seem to be fully functional, however more bug testing is probably required to concluce whether that is actually the case or not... This also doesn't break `src/modules/mods.js`, i.e dragging mods in to manually install them still functions the same as always. --- src/app/js/browser.js | 18 ++++++++++++------ src/app/main.js | 8 +++++--- src/index.js | 6 ++++-- src/modules/packages.js | 10 +++++++++- 4 files changed, 30 insertions(+), 12 deletions(-) (limited to 'src/app') diff --git a/src/app/js/browser.js b/src/app/js/browser.js index 3c3786f..b95b0a7 100644 --- a/src/app/js/browser.js +++ b/src/app/js/browser.js @@ -115,7 +115,11 @@ var Browser = { return installFromURL( package_obj.download || package_obj.versions[0].download_url, package_obj.dependencies || package_obj.versions[0].dependencies, - clear_queue, package_obj.owner + clear_queue, + + package_obj.author || package_obj.owner, + package_obj.name || package_obj.pkg.name, + package_obj.version || package_obj.versions[0].version_number ) }, add_pkg_properties: () => { @@ -463,7 +467,7 @@ ipcRenderer.on("failed-mod", (event, modname) => { }) }) -ipcRenderer.on("duped-mod", (event, modname) => { +ipcRenderer.on("legacy-duped-mod", (event, modname) => { if (recent_toasts["duped" + modname]) {return} add_recent_toast("duped" + modname); @@ -490,28 +494,30 @@ ipcRenderer.on("installed-mod", (event, mod) => { if (recent_toasts["installed" + mod.name]) {return} add_recent_toast("installed" + mod.name); + let name = mod.fancy_name || mod.name; + setButtons(true); - Browser.setbutton(mod.name, lang("gui.browser.reinstall")); + Browser.setbutton(name, lang("gui.browser.reinstall")); if (mod.malformed) { new Toast({ timeout: 8000, scheme: "warning", title: lang("gui.toast.title.malformed"), - description: mod.name + " " + lang("gui.toast.desc.malformed") + description: name + " " + lang("gui.toast.desc.malformed") }) } new Toast({ scheme: "success", title: lang("gui.toast.title.installed"), - description: mod.name + " " + lang("gui.toast.desc.installed") + description: name + " " + lang("gui.toast.desc.installed") }) if (installqueue.length != 0) { installFromURL( "https://thunderstore.io/package/download/" + installqueue[0].pkg, - false, false, installqueue[0].author + false, false, installqueue[0].author, installqueue[0].package_name, installqueue[0].version ) installqueue.shift(); diff --git a/src/app/main.js b/src/app/main.js index 26410cc..51d9e73 100644 --- a/src/app/main.js +++ b/src/app/main.js @@ -173,7 +173,7 @@ function installFromPath(path) { } // Tells the main process to install a mod from a URL -function installFromURL(url, dependencies, clearqueue, author) { +function installFromURL(url, dependencies, clearqueue, author, package_name, version) { if (clearqueue) {installqueue = []}; let prettydepends = []; @@ -188,7 +188,9 @@ function installFromURL(url, dependencies, clearqueue, author) { if (! isModInstalled(pkg[1])) { newdepends.push({ pkg: depend, - author: pkg[0] + author: pkg[0], + version: pkg[2], + package_name: pkg[1] }); prettydepends.push(`${pkg[1]} v${pkg[2]} - ${lang("gui.browser.madeby")} ${pkg[0]}`); @@ -207,7 +209,7 @@ function installFromURL(url, dependencies, clearqueue, author) { } setButtons(false); - ipcRenderer.send("install-from-url", url, author); + ipcRenderer.send("install-from-url", url, author, package_name, version); if (dependencies) { installqueue = dependencies; diff --git a/src/index.js b/src/index.js index eb258a5..9e2f31f 100644 --- a/src/index.js +++ b/src/index.js @@ -19,9 +19,9 @@ const version = require("./modules/version"); const gamepath = require("./modules/gamepath"); const settings = require("./modules/settings"); const requests = require("./modules/requests"); +const packages = require("./modules/packages"); const is_running = require("./modules/is_running"); -const plugins = require("./modules/packages"); var log = console.log; @@ -113,7 +113,9 @@ function start() { // install calls ipcMain.on("install-from-path", (event, path) => {mods.install(path)}); - ipcMain.on("install-from-url", (event, url, author) => {mods.installFromURL(url, author)}); + ipcMain.on("install-from-url", (event, url, author, package_name, version) => { + packages.install(url, author, package_name, version); + }); win.webContents.on("dom-ready", () => { send("mods", mods.list()); diff --git a/src/modules/packages.js b/src/modules/packages.js index 12659fe..317f0b0 100644 --- a/src/modules/packages.js +++ b/src/modules/packages.js @@ -1,7 +1,7 @@ const path = require("path"); const fs = require("fs-extra"); const unzip = require("unzipper"); -const app = require("electron").app; +const { app, ipcMain } = require("electron"); const https = require("follow-redirects").https; const json = require("./json"); @@ -203,6 +203,8 @@ packages.install = async (url, author, package_name, version) => { } break; default: + ipcMain.emit("failed-mod", name); + // other unhandled error return console.log( "Verification of package failed:", name, @@ -233,10 +235,16 @@ packages.install = async (url, author, package_name, version) => { let moved = packages.move(package_path); if (! moved) { + ipcMain.emit("failed-mod", name); console.log("Moving package failed:", name); return false; } + ipcMain.emit("installed-mod", "", { + name: name, + fancy_name: package_name + }) + console.log("Installed package:", name); return true; } -- cgit v1.2.3 From 8a47471ae6263aa78ed2a5c4e7a545c2e21c8bcf Mon Sep 17 00:00:00 2001 From: 0neGal Date: Mon, 24 Jul 2023 18:42:47 +0200 Subject: fixed updateable packages not being removeable --- src/app/js/mods.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/app') diff --git a/src/app/js/mods.js b/src/app/js/mods.js index 2df7205..0d516d9 100644 --- a/src/app/js/mods.js +++ b/src/app/js/mods.js @@ -69,7 +69,7 @@ mods.load = (mods_obj) => { `; - div.querySelector(".remove").addEventListener("click", () => { + div.querySelector(".remove").onclick = () => { if (! mod.package) { return mods.remove(mod.name); } @@ -77,7 +77,7 @@ mods.load = (mods_obj) => { for (let i = 0; i < mod.packaged_mods.length; i++) { mods.remove(mod.packaged_mods[i]); } - }) + } if (mod.disabled) { div.querySelector(".switch").classList.remove("on"); @@ -123,7 +123,6 @@ mods.load = (mods_obj) => { return; } - let image_container = mod_els[i].querySelector(".image"); let image_el = image_container.querySelector("img") let image_blur_el = image_container.querySelector("img.blur") @@ -158,6 +157,10 @@ mods.load = (mods_obj) => { let mod_el = mod_els[i].cloneNode(true); + // copy click event of the remove button to the new button + mod_el.querySelector(".remove").onclick = + mod_els[i].querySelector(".remove").onclick; + mod_el.classList.add("no-animation"); mod_el.querySelector(".switch").addEventListener("click", () => { -- cgit v1.2.3 From 54d6254c1a502aa77f21ac78f55d1e5d127bb20c Mon Sep 17 00:00:00 2001 From: 0neGal Date: Mon, 24 Jul 2023 19:51:32 +0200 Subject: remove debug console.log() --- src/app/js/browser.js | 1 - 1 file changed, 1 deletion(-) (limited to 'src/app') diff --git a/src/app/js/browser.js b/src/app/js/browser.js index b95b0a7..06d3dd9 100644 --- a/src/app/js/browser.js +++ b/src/app/js/browser.js @@ -111,7 +111,6 @@ var Browser = { browser.classList.toggle("shown"); }, install: (package_obj, clear_queue = false) => { - console.log(package_obj) return installFromURL( package_obj.download || package_obj.versions[0].download_url, package_obj.dependencies || package_obj.versions[0].dependencies, -- cgit v1.2.3