aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app/browser.js179
-rw-r--r--src/app/css/theming.css62
-rw-r--r--src/app/css/webview.css14
-rw-r--r--src/app/icons/external.pngbin0 -> 9764 bytes
-rw-r--r--src/app/index.html11
-rw-r--r--src/app/main.css104
-rw-r--r--src/index.js1
-rw-r--r--src/lang/en.json4
-rw-r--r--src/lang/es.json4
-rw-r--r--src/lang/fr.json3
10 files changed, 299 insertions, 83 deletions
diff --git a/src/app/browser.js b/src/app/browser.js
index 5c943ba..fea9dec 100644
--- a/src/app/browser.js
+++ b/src/app/browser.js
@@ -2,9 +2,21 @@ const Fuse = require("fuse.js");
var fuse;
var packages = [];
+var packagecount = 0;
+
var Browser = {
maxentries: 50,
filters: {
+ getpkgs: () => {
+ let pkgs = [];
+ for (let i in packages) {
+ if (! Browser.filters.isfiltered(packages[i].categories)) {
+ pkgs.push(packages[i]);
+ }
+ }
+
+ return pkgs;
+ },
get: () => {
let filtered = [];
let unfiltered = [];
@@ -71,6 +83,7 @@ var Browser = {
Browser.filters.toggle(false);
overlay.classList.remove("shown")
browser.classList.remove("shown")
+ preview.classList.remove("shown")
return
}
}
@@ -81,6 +94,8 @@ var Browser = {
},
loadfront: async () => {
Browser.loading();
+
+ packagecount = 0;
if (packages.length < 1) {
packages = await (await fetch("https://northstar.thunderstore.io/api/v1/package/")).json();
@@ -90,8 +105,15 @@ var Browser = {
})
}
- for (let i in packages) {
- new BrowserElFromObj(packages[i]);
+ let pkgs = Browser.filters.getpkgs();
+ for (let i in pkgs) {
+ if (packagecount >= Browser.maxentries) {
+ Browser.endoflist();
+ break
+ }
+
+ new BrowserElFromObj(pkgs[i]);
+ packagecount++;
}
},
loading: (string) => {
@@ -107,9 +129,31 @@ var Browser = {
browserEntries.innerHTML = `<div class="loading">${lang('gui.browser.loading')}</div>`;
}
},
- endoflist: () => {
- if (browserEntries.querySelector(".message")) {return}
- browserEntries.innerHTML += `<div class="message">${lang('gui.browser.endoflist')}</div>`
+ endoflist: (isEnd) => {
+ let pkgs = [];
+ let filtered = Browser.filters.getpkgs();
+ for (let i = 0; i < filtered.length; i++) {
+ if ([packagecount + i]) {
+ pkgs.push(filtered[packagecount + i]);
+ } else {
+ break
+ }
+ }
+
+ if (browserEntries.querySelector(".message")) {
+ browserEntries.querySelector(".message").remove();
+ }
+
+ if (pkgs.length == 0 || isEnd) {
+ Browser.msg(`${lang('gui.browser.endoflist')}`)
+ return
+ }
+
+ Browser.msg(`<button id="loadmore">${lang("gui.browser.loadmore")}</button>`)
+ loadmore.addEventListener("click", () => {
+ Browser.loadpkgs(pkgs);
+ Browser.endoflist(pkgs);
+ })
},
search: (string) => {
Browser.loading();
@@ -120,8 +164,14 @@ var Browser = {
return
}
+ packagecount = 0;
+
+ let count = 0;
for (let i = 0; i < res.length; i++) {
+ if (count >= Browser.maxentries) {break}
+ if (Browser.filters.isfiltered(res[i].item.categories)) {continue}
new BrowserElFromObj(res[i].item);
+ count++;
}
},
setbutton: (mod, string) => {
@@ -157,6 +207,59 @@ var Browser = {
}
}, 1501)
}
+ },
+ loadpkgs: (pkgs, clear) => {
+ if (clear) {packagecount = 0}
+
+ if (browserEntries.querySelector(".message")) {
+ browserEntries.querySelector(".message").remove();
+ }
+
+ let count = 0;
+ for (let i in pkgs) {
+ if (count >= Browser.maxentries) {
+ if (pkgs[i] === undefined) {
+ Browser.endoflist(true);
+ }
+
+ Browser.endoflist();
+ console.log(pkgs)
+ break
+ }
+
+ try {
+ new BrowserElFromObj(pkgs[i])
+ }catch(e) {}
+
+ count++;
+ packagecount++;
+ }
+ },
+ msg: (html) => {
+ let msg = document.createElement("div");
+ msg.classList.add("message");
+ msg.innerHTML = html;
+
+ browserEntries.appendChild(msg);
+ }
+}
+
+function openExternal(url) {
+ require("electron").shell.openExternal(url);
+}
+
+var view = document.querySelector(".popup#preview webview");
+var Preview = {
+ show: () => {
+ preview.classList.add("shown");
+ },
+ hide: () => {
+ preview.classList.remove("shown");
+ },
+ set: (url, autoshow) => {
+ if (autoshow != false) {Preview.show()}
+ view.src = url;
+ document.querySelector("#preview #external").setAttribute("onclick", `openExternal("${url}")`);
}
}
@@ -179,9 +282,6 @@ function BrowserElFromObj(obj) {
function BrowserEl(properties) {
if (Browser.filters.isfiltered(properties.categories)) {return}
- let entries = browser.querySelectorAll(".el").length;
- if (entries == Browser.maxentries) {Browser.endoflist();return}
-
properties = {
title: "No name",
version: "1.0.0",
@@ -231,23 +331,27 @@ function BrowserEl(properties) {
}
}
}
-
- browserEntries.innerHTML += `
- <div class="el" id="mod-${normalize(properties.title)}">
- <div class="image">
- <img src="${properties.image}">
- <img class="blur" src="${properties.image}">
- </div>
- <div class="text">
- <div class="title">${properties.title}</div>
- <div class="description">${properties.description}</div>
- <button class="install" onclick='installFromURL("${properties.download}", ${JSON.stringify(properties.dependencies)}, true)'>${installstr}</button>
- <button class="info" onclick="require('electron').shell.openExternal('${properties.url}')">${lang('gui.browser.info')}</button>
- <button class="visual">${properties.version}</button>
- <button class="visual">${lang("gui.browser.madeby")} ${properties.author}</button>
- </div>
+
+ let entry = document.createElement("div");
+ entry.classList.add("el");
+ entry.id = `mod-${normalize(properties.title)}`;
+
+ entry.innerHTML = `
+ <div class="image">
+ <img src="${properties.image}">
+ <img class="blur" src="${properties.image}">
+ </div>
+ <div class="text">
+ <div class="title">${properties.title}</div>
+ <div class="description">${properties.description}</div>
+ <button class="install" onclick='installFromURL("${properties.download}", ${JSON.stringify(properties.dependencies)}, true)'>${installstr}</button>
+ <button class="info" onclick="Preview.set('${properties.url}')">${lang('gui.browser.view')}</button>
+ <button class="visual">${properties.version}</button>
+ <button class="visual">${lang("gui.browser.madeby")} ${properties.author}</button>
</div>
`
+
+ browserEntries.appendChild(entry);
}
ipcRenderer.on("removedmod", (event, mod) => {
@@ -329,8 +433,33 @@ search.addEventListener("keyup", () => {
}
})
-browser.addEventListener("scroll", () => {
- Browser.filters.toggle(false);
+let events = ["scroll", "mousedown", "touchdown"];
+events.forEach((event) => {
+ browser.addEventListener(event, () => {
+ Preview.hide();
+ Browser.filters.toggle(false);
+ })
+});
+
+view.addEventListener("dom-ready", () => {
+ let css = [
+ fs.readFileSync(__dirname + "/css/theming.css", "utf8"),
+ fs.readFileSync(__dirname + "/css/webview.css", "utf8")
+ ]
+
+ view.insertCSS(css.join(" "));
+})
+
+view.addEventListener("did-stop-loading", () => {
+ view.style.display = "flex";
+ setTimeout(() => {
+ view.classList.remove("loading");
+ }, 200)
+})
+
+view.addEventListener("did-start-loading", () => {
+ view.style.display = "none";
+ view.classList.add("loading");
})
let checks = document.querySelectorAll(".check");
diff --git a/src/app/css/theming.css b/src/app/css/theming.css
new file mode 100644
index 0000000..2d45b1d
--- /dev/null
+++ b/src/app/css/theming.css
@@ -0,0 +1,62 @@
+/*
+ the only reason some of these properties have an !important property
+ is for it to overwrite Thunderstore's CSS in the preview <webview>
+*/
+
+:root {
+ --red: 199, 119, 127 !important;
+ --red2: 181 97 105;
+
+ --blue: 129, 161, 193;
+ --blue2: 139, 143, 185;
+
+ --orange: 213, 151, 131;
+ --orange2: 197 129 107;
+
+
+ --padding: 25px;
+
+ --bg: rgba(0, 0, 0, 0.5);
+ --selbg: rgba(80, 80, 80, 0.5);
+ --redbg: linear-gradient(45deg, rgb(var(--red)), #FA4343);
+ --bluebg: linear-gradient(45deg, rgb(var(--blue)), #7380ED);
+}
+
+body, button, input {
+ font-family: "Roboto", sans-serif !important;
+}
+
+body, button, img, a {
+ user-select: none;
+ -webkit-user-drag: none;
+}
+
+a {
+ text-decoration: none !important;
+ color: rgb(var(--red)) !important;
+ transition: filter 0.2s ease-in !important;
+}
+
+a:hover {
+ filter: brightness(80%) !important;
+}
+
+
+::-webkit-scrollbar {
+ width: 8px !important;
+}
+
+::-webkit-scrollbar-track {
+ border-radius: 10px !important;
+ background: transparent !important;
+}
+
+::-webkit-scrollbar-thumb {
+ border-radius: 10px !important;
+ background: rgb(var(--red)) !important;
+}
+
+::selection {
+ color: black !important;
+ background: rgb(var(--red)) !important;
+}
diff --git a/src/app/css/webview.css b/src/app/css/webview.css
new file mode 100644
index 0000000..9e26b5d
--- /dev/null
+++ b/src/app/css/webview.css
@@ -0,0 +1,14 @@
+body {
+ overflow-x: hidden;
+ background: transparent !important;
+ background-color: transparent !important;
+}
+
+.navbar, .bottom-padding,
+.card-header, .breadcrumb,
+.list-group, .mb-4, .my-2, .mt-2 {
+ display: none !important;
+}
+
+.mt-2.mb-2 {display: block !important}
+.card {transform: translateY(-1.0rem)}
diff --git a/src/app/icons/external.png b/src/app/icons/external.png
new file mode 100644
index 0000000..0b4f99e
--- /dev/null
+++ b/src/app/icons/external.png
Binary files differ
diff --git a/src/app/index.html b/src/app/index.html
index 02a150f..f67a7a8 100644
--- a/src/app/index.html
+++ b/src/app/index.html
@@ -133,6 +133,17 @@
<div class="loading">%%gui.browser.loading%%</div>
</div>
</div>
+ <div class="popup small" id="preview">
+ <div class="misc fixed vertical">
+ <button id="close" onclick="Preview.hide()">
+ <img src="icons/close.png">
+ </button>
+ <button id="external" onclick="">
+ <img src="icons/external.png">
+ </button>
+ </div>
+ <webview></webview>
+ </div>
<nav class="gamesContainer">
<button id="vpBtn" onclick="page(0)"></button>
diff --git a/src/app/main.css b/src/app/main.css
index 99d806c..3229f6c 100644
--- a/src/app/main.css
+++ b/src/app/main.css
@@ -1,58 +1,15 @@
-:root {
- --red: 199, 119, 127;
- --red2: 181 97 105;
-
- --blue: 129, 161, 193;
- --blue2: 139, 143, 185;
-
- --orange: 213, 151, 131;
- --orange2: 197 129 107;
-
-
- --padding: 25px;
-
- --bg: rgba(0, 0, 0, 0.5);
- --selbg: rgba(80, 80, 80, 0.5);
- --redbg: linear-gradient(45deg, rgb(var(--red)), #FA4343);
- --bluebg: linear-gradient(45deg, rgb(var(--blue)), #7380ED);
-}
+@import "css/theming.css";
.popup, #modsdiv {
outline: 1px solid #444444;
border: 3px solid var(--bg);
}
-::-webkit-scrollbar {
- width: 8px;
-}
-
-::-webkit-scrollbar-track {
- border-radius: 10px;
- background: transparent;
-}
-
-::-webkit-scrollbar-thumb {
- border-radius: 10px;
- background: rgb(var(--red));
-}
-
-::selection {
- color: black;
- background: rgb(var(--red));
-}
-
body {
margin: 0;
overflow: hidden;
}
-body, button, input {font-family: "Roboto", sans-serif}
-
-body, button, img, a {
- -webkit-user-drag: none;
- user-select: none;
-}
-
button {outline: none}
b, strong {font-weight: 700}
body, input, button {font-weight: 500}
@@ -97,6 +54,13 @@ button {
transform: scale(1.0);
}
+.popup.small {
+ left: 20vw;
+ right: 20vw;
+ top: calc(var(--padding) * 2);
+ bottom: calc(var(--padding) * 2);
+}
+
#overlay {
top: 0;
left: 0;
@@ -120,9 +84,28 @@ button {
100% {opacity: 1.0}
}
+#browserEntries {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.popup webview {
+ width: 78%;
+ margin: 0 auto;
+ filter: opacity(1.0);
+ transition: filter 0.15s ease-in-out;
+ margin-top: calc(var(--spacing) / 2);
+ height: calc(100% - calc(var(--spacing) / 2));
+}
+
+.popup webview.loading {
+ filter: opacity(0.0);
+ pointer-events: none;
+}
+
.popup .el, .popup .misc, .popup .loading {
--spacing: calc(var(--padding) / 2);
- --height: calc(var(--padding) * 3);
+ --height: calc(var(--padding) * 3.5);
--mischeight: calc(var(--padding) * 1.5);
animation-duration: 0.15s;
@@ -144,7 +127,7 @@ button {
padding: var(--spacing);
background: var(--selbg);
border-radius: var(--spacing);
- width: calc(100% - var(--spacing) * 4);
+ width: calc(50% - var(--spacing) * 4);
}
.popup .misc, .popup #search, .option .actions input {
@@ -155,6 +138,15 @@ button {
display: flex;
}
+.popup .misc.vertical {
+ display: block;
+}
+
+.popup .misc.fixed {
+ width: 100%;
+ position: fixed;
+}
+
.popup #search, .option .actions input, .option .actions select {
border: none;
outline: none;
@@ -192,10 +184,16 @@ button {
margin-left: 0px !important;
}
+.popup#preview #close,
+.popup .misc.vertical button {
+ margin: var(--spacing) var(--spacing) 0 auto !important;
+}
+
.popup .loading {
width: 100%;
color: white;
display: flex;
+ position: absolute;
text-align: center;
align-items: center;
justify-content: center;
@@ -239,6 +237,10 @@ button {
font-weight: 700;
}
+.popup .message #loadmore {
+ background: rgb(var(--blue2));
+}
+
.popup .el .description {font-size: 0.8em}
.popup .el button {
background: rgb(var(--blue));
@@ -598,16 +600,6 @@ img {pointer-events: none}
background: var(--bluebg);
}
-a {
- color: rgb(var(--red));
- text-decoration: none;
- transition: filter 0.2s ease-in;
-}
-
-a:hover {
- filter: brightness(80%);
-}
-
#nsContent .contentMenu {
margin-bottom: 0;
}
diff --git a/src/index.js b/src/index.js
index 6c3c79c..e718ef9 100644
--- a/src/index.js
+++ b/src/index.js
@@ -29,6 +29,7 @@ function start() {
frame: false,
icon: path.join(__dirname, "assets/icons/512x512.png"),
webPreferences: {
+ webviewTag: true,
nodeIntegration: true,
contextIsolation: false,
},
diff --git a/src/lang/en.json b/src/lang/en.json
index 024b44a..2c068ac 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -71,13 +71,15 @@
"gui.mods.confirmdependencies": "This package has dependencies, shown below, clicking \"Ok\" will install the package and the dependencies.\n\n",
"gui.browser.info": "Info",
+ "gui.browser.view": "View",
"gui.browser.madeby": "by",
"gui.browser.search": "Search...",
"gui.browser.update": "Update",
"gui.browser.install": "Install",
"gui.browser.reinstall": "Re-Install",
"gui.browser.loading": "Loading mods...",
- "gui.browser.endoflist": "Maximum packages has been loaded.<br>Use the search for finding other packages!",
+ "gui.browser.loadmore": "Load more...",
+ "gui.browser.endoflist": "All packages have been loaded.",
"gui.browser.noresults": "No results...",
"gui.browser.filter.mods": "Mods",
"gui.browser.filter.skins": "Skins",
diff --git a/src/lang/es.json b/src/lang/es.json
index c2871f1..8128440 100644
--- a/src/lang/es.json
+++ b/src/lang/es.json
@@ -77,12 +77,14 @@
"gui.browser.install": "Instalar",
"gui.browser.reinstall": "Re-Instalar",
"gui.browser.loading": "Cargando modificaciones...",
- "gui.browser.endoflist": "Se ha cargado el máximo de paquetes.<br>¡Usa la búsqueda para encontrar otros paquetes!",
+ "gui.browser.endoflist": "Todos los paquetes han sido cargados",
"gui.browser.noresults": "Sin resultados...",
"gui.browser.filter.mods": "Modificaciones",
"gui.browser.filter.skins": "Skins",
"gui.browser.filter.client": "Del lado del cliente",
"gui.browser.filter.server": "Del lado del servidor",
+ "gui.browser.view": "Ver",
+ "gui.browser.loadmore": "Cargar más...",
"gui.settings.save": "Guardar",
"gui.settings.discard": "Descartar",
diff --git a/src/lang/fr.json b/src/lang/fr.json
index d162988..1f37948 100644
--- a/src/lang/fr.json
+++ b/src/lang/fr.json
@@ -68,14 +68,17 @@
"gui.mods.installing": "Installation du mod...",
"gui.mods.installedmod": "Mod installé !",
"gui.mods.dragdrop": "Glissez/déposez un mod pour l'installer",
+ "gui.mods.confirmdependencies": "Ce mod a des dépendances (affichées ci-dessous), cliquer \"Ok\" les installera en même temps que le mod.\n\n",
"gui.browser.info": "Info",
+ "gui.browser.view": "Voir",
"gui.browser.madeby": "par",
"gui.browser.search": "Rechercher",
"gui.browser.update": "Mise à jour",
"gui.browser.install": "Installer",
"gui.browser.reinstall": "Réinstaller",
"gui.browser.loading": "Chargement des mods...",
+ "gui.browser.loadmore": "Charger plus de mods...",
"gui.browser.endoflist": "Fin de la liste de mods.<br>Utilisez la barre de recherche pour en trouver davantage !",
"gui.browser.noresults": "Pas de résultat",
"gui.browser.filter.mods": "Mods",