diff options
author | 0neGal <mail@0negal.com> | 2022-05-20 19:14:29 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-05-20 19:14:29 +0200 |
commit | fa6a75629d0a84bb7cde182bfe63b8d3808c7244 (patch) | |
tree | 53b19efe9504259e107159cd97321982f718306b | |
parent | dee10ac8d1d361f51ce316539e45b8a4197c8ad9 (diff) | |
parent | 4fa5caedd43f44fed64c1474449872b8dfc7bb78 (diff) | |
download | Viper-fa6a75629d0a84bb7cde182bfe63b8d3808c7244.tar.gz Viper-fa6a75629d0a84bb7cde182bfe63b8d3808c7244.zip |
Merge pull request #125 from 0neGal/better-browser
feat: Better Browser
-rw-r--r-- | src/app/browser.js | 179 | ||||
-rw-r--r-- | src/app/css/theming.css | 62 | ||||
-rw-r--r-- | src/app/css/webview.css | 14 | ||||
-rw-r--r-- | src/app/icons/external.png | bin | 0 -> 9764 bytes | |||
-rw-r--r-- | src/app/index.html | 11 | ||||
-rw-r--r-- | src/app/main.css | 104 | ||||
-rw-r--r-- | src/index.js | 1 | ||||
-rw-r--r-- | src/lang/en.json | 4 | ||||
-rw-r--r-- | src/lang/es.json | 4 | ||||
-rw-r--r-- | src/lang/fr.json | 3 |
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 Binary files differnew file mode 100644 index 0000000..0b4f99e --- /dev/null +++ b/src/app/icons/external.png 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", |