diff --git a/public/components/breadcrumb.js b/public/components/breadcrumb.js
index 35b2b13d..9d937323 100644
--- a/public/components/breadcrumb.js
+++ b/public/components/breadcrumb.js
@@ -12,10 +12,8 @@ class ComponentBreadcrumb extends HTMLDivElement {
: `
-
- `;
+ `;
const paths = (this.getAttribute("path") || "").split("/");
- console.log(this.getAttribute("path"), paths);
const htmlPathChunks = paths.slice(0, -1).map((chunk, idx) => {
const label = idx === 0 ? "Filestash" : chunk;
const link = paths.slice(0, idx).join("/") + "/";
@@ -54,7 +52,11 @@ class ComponentBreadcrumb extends HTMLDivElement {
`;
}).join("");
+ this.render({ htmlLogout, htmlPathChunks });
+ }
+ async render({ htmlLogout, htmlPathChunks }) {
+ const css = await CSS(import.meta.url, "breadcrumb.css");
this.innerHTML = `
@@ -66,11 +68,8 @@ class ComponentBreadcrumb extends HTMLDivElement {
${htmlPathChunks}
-
- `;
+ `;
}
}
-const css = await CSS(import.meta, "breadcrumb.css");
-
customElements.define("component-breadcrumb", ComponentBreadcrumb, { extends: "div" });
diff --git a/public/components/icon.js b/public/components/icon.js
index ffc90931..ada4fdb8 100644
--- a/public/components/icon.js
+++ b/public/components/icon.js
@@ -14,7 +14,7 @@ class Icon extends window.HTMLElement {
class="component_icon"
draggable="false"
src="${img}"
- alt="${name}" />`;
+ alt="${alt}" />`;
}
_mapOfIcon(name) {
@@ -32,4 +32,4 @@ class Icon extends window.HTMLElement {
}
}
-window.customElements.define("component-icon", Icon);
+customElements.define("component-icon", Icon);
diff --git a/public/components/modal.js b/public/components/modal.js
index 35b78042..ed369f3a 100644
--- a/public/components/modal.js
+++ b/public/components/modal.js
@@ -16,7 +16,7 @@ const free = () => {
export default class Modal extends HTMLElement {
async trigger($node, opts = {}) {
- const { onQuit, leftButton, rightButton } = opts;
+ const { onQuit } = opts;
const $modal = createElement(`
diff --git a/public/jest.setup.js b/public/jest.setup.js
index bf649704..01a8c6de 100644
--- a/public/jest.setup.js
+++ b/public/jest.setup.js
@@ -19,3 +19,6 @@ global.console = {
warn: jest.fn(),
error: jest.fn()
};
+global.customElements = {
+ define: jest.fn(),
+};
diff --git a/public/lib/ajax.js b/public/lib/ajax.js
index 753ff63e..df1ef805 100644
--- a/public/lib/ajax.js
+++ b/public/lib/ajax.js
@@ -6,7 +6,6 @@ export default function(opts) {
else if (typeof opts !== "object") throw new Error("unsupported call");
if (!opts.headers) opts.headers = {};
opts.headers["X-Requested-With"] = "XmlHttpRequest";
- const isJson = opts.responseType;
return ajax({ ...opts, responseType: "text" }).pipe(
rxjs.catchError((err) => rxjs.throwError(processError(err.xhr, err))),
rxjs.map((res) => {
@@ -52,7 +51,6 @@ function processError(xhr, err) {
message || "Oups something went wrong with our servers",
err, "INTERNAL_SERVER_ERROR"
);
- break;
case 401:
return new AjaxError(
message || "Authentication error",
@@ -60,10 +58,9 @@ function processError(xhr, err) {
);
case 403:
return new AjaxError(
- message || "You can\'t do that",
+ message || "You can't do that",
err, "FORBIDDEN"
);
- break;
case 413:
return new AjaxError(
message || "Payload too large",
@@ -77,7 +74,7 @@ function processError(xhr, err) {
case 409:
if (response.error_summary) { // dropbox way to say doesn't exist
return new AjaxError(
- "Doesn\'t exist",
+ "Doesn't exist",
err, "UNKNOWN_PATH"
);
}
@@ -92,7 +89,6 @@ function processError(xhr, err) {
"Service unavailable, if the problem persist, contact your administrator",
err, "INTERNAL_SERVER_ERROR"
);
- break;
default:
return new AjaxError(xhr.responseText, err, "INTERNAL_SERVER_ERROR");
}
diff --git a/public/lib/animate.js b/public/lib/animate.js
index 328dcbd9..2b9bba1c 100644
--- a/public/lib/animate.js
+++ b/public/lib/animate.js
@@ -1,5 +1,4 @@
-import { onDestroy, createElement } from "./skeleton/index.js";
-import rxjs from "./rx.js";
+import { onDestroy } from "./skeleton/index.js";
export function transition($node, opts = {}) {
const {
@@ -18,7 +17,7 @@ export function animate($node, opts = {}) {
else if (typeof $node.animate !== "function") return Promise.resolve();
return new Promise((done) => {
- const run = $node.animate(keyframes, {
+ $node.animate(keyframes, {
duration: time,
fill: "forwards"
}).onfinish = done;
diff --git a/public/lib/locales.js b/public/lib/locales.js
index 7b709ac1..6dfab72d 100644
--- a/public/lib/locales.js
+++ b/public/lib/locales.js
@@ -13,9 +13,9 @@ export default function t(str = "", replacementString, requestedKey) {
// ).replace("{{VALUE}}", replacementString);
}
-function reformat(translated, initial) {
- if (initial[0] && initial[0].toLowerCase() === initial[0]) {
- return translated || "";
- }
- return (translated[0] && translated[0].toUpperCase() + translated.substring(1)) || "";
-}
+// function reformat(translated, initial) {
+// if (initial[0] && initial[0].toLowerCase() === initial[0]) {
+// return translated || "";
+// }
+// return (translated[0] && translated[0].toUpperCase() + translated.substring(1)) || "";
+// }
diff --git a/public/package.json b/public/package.json
index 7f1e21ae..ee3749cf 100644
--- a/public/package.json
+++ b/public/package.json
@@ -5,7 +5,7 @@
"description": "Frontend for Filestash",
"main": "index.js",
"scripts": {
- "check": "tsc",
+ "check": "tsc && eslint .",
"test": "NODE_OPTIONS=--experimental-vm-modules NODE_NO_WARNINGS=1 npx jest"
},
"author": "Mickael Kerjean",
@@ -44,5 +44,33 @@
]
}
}
+ },
+ "eslintConfig": {
+ "env": {
+ "browser": true,
+ "es2021": true,
+ "jest": true
+ },
+ "ignorePatterns": ["lib/vendor/*.js", "*.test.js"],
+ "extends": "standard",
+ "parserOptions": {
+ "ecmaVersion": "latest",
+ "sourceType": "module"
+ },
+ "rules": {
+ "quotes": ["error", "double"],
+ "indent": ["error", 4],
+ "semi": ["error", "always"],
+ "space-before-function-paren": ["error", "never"],
+ "camelcase": ["off"],
+ "dot-notation": ["off"],
+ "no-case-declarations": ["off"],
+ "no-fallthrough": ["off"],
+ "prefer-regex-literals": ["off"],
+ "promise/param-names": ["off"],
+ "no-return-assign": ["off"],
+ "brace-style": ["off"],
+ "no-useless-escape": ["off"]
+ }
}
}
diff --git a/public/pages/adminpage/ctrl_about.js b/public/pages/adminpage/ctrl_about.js
index cba166d1..167bf461 100644
--- a/public/pages/adminpage/ctrl_about.js
+++ b/public/pages/adminpage/ctrl_about.js
@@ -23,4 +23,4 @@ export default AdminOnly(WithShell(async function(render) {
));
}));
-const css = await CSS(import.meta, "ctrl_about.css");
+const css = await CSS(import.meta.url, "ctrl_about.css");
diff --git a/public/pages/adminpage/ctrl_backend.js b/public/pages/adminpage/ctrl_backend.js
index 5812a082..99ebe137 100644
--- a/public/pages/adminpage/ctrl_backend.js
+++ b/public/pages/adminpage/ctrl_backend.js
@@ -51,4 +51,4 @@ function componentStorageBackend(render) {
));
}
-const css = await CSS(import.meta, "ctrl_backend.css");
+const css = await CSS(import.meta.url, "ctrl_backend.css");
diff --git a/public/pages/adminpage/ctrl_home.js b/public/pages/adminpage/ctrl_home.js
deleted file mode 100644
index 3e32ec88..00000000
--- a/public/pages/adminpage/ctrl_home.js
+++ /dev/null
@@ -1,6 +0,0 @@
-import { navigate } from "../../lib/skeleton/index.js";
-import AdminOnly from "./decorator_admin_only.js";
-
-export default AdminOnly(function() {
- navigate("/admin/backend");
-});
diff --git a/public/pages/adminpage/ctrl_logger.js b/public/pages/adminpage/ctrl_logger.js
index 4951d63d..2b6f0cac 100644
--- a/public/pages/adminpage/ctrl_logger.js
+++ b/public/pages/adminpage/ctrl_logger.js
@@ -1,7 +1,7 @@
import { createElement, createRender } from "../../lib/skeleton/index.js";
import rxjs, { effect, stateMutation, applyMutation } from "../../lib/rx.js";
import { qs } from "../../lib/dom.js";
-import { createForm, mutateForm } from "../../lib/form.js";
+import { createForm } from "../../lib/form.js";
import { formTmpl } from "../../components/form.js";
import transition from "./animate.js";
diff --git a/public/pages/adminpage/ctrl_login.js b/public/pages/adminpage/ctrl_login.js
index a3329ca2..4d08bed6 100644
--- a/public/pages/adminpage/ctrl_login.js
+++ b/public/pages/adminpage/ctrl_login.js
@@ -11,7 +11,7 @@ import "../../components/icon.js";
export default function(render) {
const $form = createElement(`
`);
render($page);
@@ -53,8 +53,15 @@ export default function(ctrl) {
// feature: setup the childrens
ctrl(($node) => qs($page, "[data-bind=\"admin\"]").appendChild($node));
+
+ // feature: css loading
+ effect(rxjs.from(CSS(import.meta.url, "decorator_sidemenu.css", "index.css")).pipe(
+ rxjs.mergeMap((cssPromise) => cssPromise),
+ stateMutation(qs($page, `style[id="adminpage::decorator_sidemenu"]`), "textContent"),
+ ));
+
// feature: display the release version
- effect(Release.get().pipe(
+ effect(getRelease().pipe(
rxjs.map(({ version }) => version),
stateMutation(qs($page, "[data-bind=\"version\"]"), "textContent")
));
@@ -79,5 +86,3 @@ export default function(ctrl) {
));
};
}
-
-const css = await CSS(import.meta, "decorator_sidemenu.css", "index.css");
diff --git a/public/pages/adminpage/model_audit.js b/public/pages/adminpage/model_audit.js
index 80c6a9b5..03a3da53 100644
--- a/public/pages/adminpage/model_audit.js
+++ b/public/pages/adminpage/model_audit.js
@@ -4,7 +4,7 @@ import ajax from "../../lib/ajax.js";
class AuditManager {
get(searchParams = {}) {
const p = new URLSearchParams();
- Object.keys(searchParams).map((key) => {
+ Object.keys(searchParams).forEach((key) => {
p.set(key, searchParams[key]);
});
return ajax({
diff --git a/public/pages/adminpage/model_release.js b/public/pages/adminpage/model_release.js
index c47f6d7e..496e3753 100644
--- a/public/pages/adminpage/model_release.js
+++ b/public/pages/adminpage/model_release.js
@@ -6,19 +6,15 @@ const release$ = ajax({
responseType: "text"
}).pipe(rxjs.shareReplay(1));
-class ReleaseImpl {
- get() {
- return release$.pipe(
- rxjs.map(({ response, responseHeaders }) => {
- const a = document.createElement("html");
- a.innerHTML = response;
- return {
- html: a.querySelector("table").outerHTML,
- version: responseHeaders["x-powered-by"].trim().replace(/^Filestash\/([v\.0-9]*).*$/, "$1")
- };
- })
- );
- }
+export function get() {
+ return release$.pipe(
+ rxjs.map(({ response, responseHeaders }) => {
+ const a = document.createElement("html");
+ a.innerHTML = response;
+ return {
+ html: a.querySelector("table").outerHTML,
+ version: responseHeaders["x-powered-by"].trim().replace(/^Filestash\/([v\.0-9]*).*$/, "$1")
+ };
+ })
+ );
}
-
-export default new ReleaseImpl();
diff --git a/public/pages/connectpage/ctrl_form.js b/public/pages/connectpage/ctrl_form.js
index 48391729..5e1bc948 100644
--- a/public/pages/connectpage/ctrl_form.js
+++ b/public/pages/connectpage/ctrl_form.js
@@ -2,7 +2,7 @@ import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect, applyMutation, preventDefault } from "../../lib/rx.js";
import { qs, qsa, safe } from "../../lib/dom.js";
import { animate, slideYIn } from "../../lib/animate.js";
-import { createForm, mutateForm } from "../../lib/form.js";
+import { createForm } from "../../lib/form.js";
import { formTmpl } from "../../components/form.js";
import { CSS } from "../../helpers/loader.js";
diff --git a/public/pages/ctrl_adminpage.js b/public/pages/ctrl_adminpage.js
new file mode 100644
index 00000000..60167a70
--- /dev/null
+++ b/public/pages/ctrl_adminpage.js
@@ -0,0 +1,6 @@
+import { navigate } from "../lib/skeleton/index.js";
+import AdminOnly from "./adminpage/decorator_admin_only.js";
+
+export default AdminOnly(function() {
+ navigate("/admin/backend");
+});
diff --git a/public/pages/ctrl_boot.js b/public/pages/ctrl_boot.js
index 1b71c720..100d7c4f 100644
--- a/public/pages/ctrl_boot.js
+++ b/public/pages/ctrl_boot.js
@@ -103,22 +103,22 @@ async function setup_device() {
});
}
-async function setup_sw() {
- if (!("serviceWorker" in window.navigator)) return;
+// async function setup_sw() {
+// if (!("serviceWorker" in window.navigator)) return;
- if (window.navigator.userAgent.indexOf("Mozilla/") !== -1 &&
- window.navigator.userAgent.indexOf("Firefox/") !== -1 &&
- window.navigator.userAgent.indexOf("Gecko/") !== -1) {
- // Firefox was acting weird with service worker so we disabled it
- // see: https://github.com/mickael-kerjean/filestash/issues/255
- return;
- }
- try {
- await window.navigator.serviceWorker.register("/sw_cache.js");
- } catch (err) {
- report("ServiceWorker registration failed", err);
- }
-}
+// if (window.navigator.userAgent.indexOf("Mozilla/") !== -1 &&
+// window.navigator.userAgent.indexOf("Firefox/") !== -1 &&
+// window.navigator.userAgent.indexOf("Gecko/") !== -1) {
+// // Firefox was acting weird with service worker so we disabled it
+// // see: https://github.com/mickael-kerjean/filestash/issues/255
+// return;
+// }
+// try {
+// await window.navigator.serviceWorker.register("/sw_cache.js");
+// } catch (err) {
+// report("ServiceWorker registration failed", err);
+// }
+// }
async function setup_blue_death_screen() {
window.onerror = function(msg, url, lineNo, colNo, error) {
@@ -127,13 +127,13 @@ async function setup_blue_death_screen() {
};
}
-async function setup_chromecast() {
- if (!window.CONFIG["enable_chromecast"]) {
- return Promise.resolve();
- } else if (!("chrome" in window)) {
- return Promise.resolve();
- } else if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
- return Promise.resolve();
- }
- return window.Chromecast.init();
-}
+// async function setup_chromecast() {
+// if (!window.CONFIG["enable_chromecast"]) {
+// return Promise.resolve();
+// } else if (!("chrome" in window)) {
+// return Promise.resolve();
+// } else if (location.hostname === "localhost" || location.hostname === "127.0.0.1") {
+// return Promise.resolve();
+// }
+// return window.Chromecast.init();
+// }
diff --git a/public/pages/ctrl_error.js b/public/pages/ctrl_error.js
index 3d7510f8..30964160 100644
--- a/public/pages/ctrl_error.js
+++ b/public/pages/ctrl_error.js
@@ -4,7 +4,6 @@ import { qs } from "../lib/dom.js";
import t from "../lib/locales.js";
import { AjaxError, ApplicationError } from "../lib/error.js";
-import { CSS } from "../helpers/loader.js";
import "../components/icon.js";
diff --git a/public/pages/ctrl_filespage.js b/public/pages/ctrl_filespage.js
index c2649ff0..3a2af1cb 100644
--- a/public/pages/ctrl_filespage.js
+++ b/public/pages/ctrl_filespage.js
@@ -1,6 +1,5 @@
import { createElement, createRender } from "../lib/skeleton/index.js";
-import rxjs, { effect, applyMutation } from "../lib/rx.js";
-import { qs } from "../lib/dom.js";
+import rxjs, { effect } from "../lib/rx.js";
import { CSS } from "../helpers/loader.js";
import ctrlError from "./ctrl_error.js";
@@ -9,7 +8,7 @@ import componentFilesystem from "./filespage/filesystem.js";
import "../components/breadcrumb.js";
-export default async function(render) {
+export default function(render) {
const currentPath = location.pathname.replace(new RegExp("/files"), "");
const $page = createElement(`
@@ -21,7 +20,7 @@ export default async function(render) {
-
+
`);
render($page);
@@ -37,3 +36,5 @@ export default async function(render) {
// feature2: render the filesystem
componentFilesystem(createRender($page.querySelector("[is=\"component-filesystem\"]")));
}
+
+const css = await CSS(import.meta.url, "ctrl_filespage.css");
diff --git a/public/pages/ctrl_logout.js b/public/pages/ctrl_logout.js
index 664c7875..06927273 100644
--- a/public/pages/ctrl_logout.js
+++ b/public/pages/ctrl_logout.js
@@ -5,7 +5,7 @@ import { deleteSession } from "../model/session.js";
import ctrlError from "./ctrl_error.js";
import $loader from "../components/loader.js";
-export default function(render) {
+export default async function(render) {
render($loader);
effect(deleteSession().pipe(
diff --git a/public/pages/filespage/filesystem.js b/public/pages/filespage/filesystem.js
index cc2180b4..abfc6822 100644
--- a/public/pages/filespage/filesystem.js
+++ b/public/pages/filespage/filesystem.js
@@ -1,11 +1,11 @@
import { createElement } from "../../lib/skeleton/index.js";
-import rxjs, { applyMutation, effect } from "../../lib/rx.js";
+import rxjs, { effect } from "../../lib/rx.js";
import { qs } from "../../lib/dom.js";
import { toggle as toggleLoader } from "../../components/loader.js";
import { createThing, css as cssThing } from "./thing.js";
-import { getState$, handleError } from "./state.js";
+import { handleError } from "./state.js";
import { ls } from "./model_files.js";
export default async function(render) {
diff --git a/public/pages/filespage/model_files.js b/public/pages/filespage/model_files.js
index 828a8d9d..013c164f 100644
--- a/public/pages/filespage/model_files.js
+++ b/public/pages/filespage/model_files.js
@@ -11,8 +11,8 @@ export function ls() {
);
}
-function repeat(element, times) {
- const result = Array(times);
- for (let i = 0; i < times; i++) result[i] = element;
- return result;
-}
+// function repeat(element, times) {
+// const result = Array(times);
+// for (let i = 0; i < times; i++) result[i] = element;
+// return result;
+// }