diff --git a/client/pages/filespage/share.js b/client/pages/filespage/share.js index 346c2e53..5579172c 100644 --- a/client/pages/filespage/share.js +++ b/client/pages/filespage/share.js @@ -267,7 +267,7 @@ export class ShareComponent extends React.Component { type="inline" cond={!!this.state.show_advanced}> diff --git a/public/assets/components/decorator_shell_filemanager.css b/public/assets/components/decorator_shell_filemanager.css index 892e7705..ecd20692 100644 --- a/public/assets/components/decorator_shell_filemanager.css +++ b/public/assets/components/decorator_shell_filemanager.css @@ -32,11 +32,14 @@ border-top-right-radius: 30px; } .component_filemanager_shell [data-bind="sidebar"].hidden ~ div > component-breadcrumb > .component_breadcrumb, -.component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [data-bind="filemanager-children"] .container { - width: 95%; +.component_filemanager_shell [data-bind="sidebar"]:empty ~ div > component-breadcrumb > .component_breadcrumb, +.component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [data-bind="filemanager-children"] .container, +.component_filemanager_shell [data-bind="sidebar"]:empty ~ div > [data-bind="filemanager-children"] .container { + width: 98%; margin: 0 auto; max-width: 815px; } + .component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [data-bind="filemanager-children"] { background: rgba(100,100,100,.05); } @@ -50,10 +53,15 @@ } .component_filemanager_shell [data-bind="sidebar"].hidden ~ div [is="component_filesystem"], +.component_filemanager_shell [data-bind="sidebar"]:empty ~ div [is="component_filesystem"], .component_filemanager_shell [data-bind="sidebar"].hidden ~ div [is="component_newitem"], +.component_filemanager_shell [data-bind="sidebar"]:empty ~ div [is="component_newitem"], .component_filemanager_shell [data-bind="sidebar"].hidden ~ div component-menubar, +.component_filemanager_shell [data-bind="sidebar"]:empty ~ div component-menubar, .component_filemanager_shell [data-bind="sidebar"].hidden ~ div component-breadcrumb, -.component_filemanager_shell [data-bind="sidebar"].hidden ~ div [is="component_submenu"] .component_submenu { +.component_filemanager_shell [data-bind="sidebar"]:empty ~ div component-breadcrumb, +.component_filemanager_shell [data-bind="sidebar"].hidden ~ div [is="component_submenu"] .component_submenu, +.component_filemanager_shell [data-bind="sidebar"]:empty ~ div [is="component_submenu"] .component_submenu { padding: 0px; } diff --git a/public/assets/components/modal.css b/public/assets/components/modal.css index 52afdbc1..b546cd5b 100644 --- a/public/assets/components/modal.css +++ b/public/assets/components/modal.css @@ -11,7 +11,7 @@ box-shadow: 1px 2px 20px rgba(0, 0, 0, 0.1); background: white; width: 80%; - max-width: 310px; + max-width: 320px; padding: 20px 20px 0 20px; border-radius: 2px; } diff --git a/public/assets/components/modal.js b/public/assets/components/modal.js index 1d6b2ece..1a603874 100644 --- a/public/assets/components/modal.js +++ b/public/assets/components/modal.js @@ -113,8 +113,10 @@ class ModalComponent extends window.HTMLElement { )); // feature: center horizontally - effect(rxjs.fromEvent(window, "resize").pipe( - rxjs.startWith(null), + effect(rxjs.merge( + rxjs.fromEvent(window, "resize"), + rxjs.of(null), + ).pipe( rxjs.distinct(() => document.body.offsetHeight), rxjs.map(() => { let size = targetHeight; diff --git a/public/assets/components/sidebar.css b/public/assets/components/sidebar.css index 561ab530..82b79e3e 100644 --- a/public/assets/components/sidebar.css +++ b/public/assets/components/sidebar.css @@ -27,6 +27,15 @@ padding-right: 5px; cursor: pointer; } +.component_filemanager_shell .component_sidebar h3 input::placeholder { + text-transform: capitalize; +} +.component_filemanager_shell .component_sidebar h3 input { + border: none; + color: var(--dark); + font-weight: bold; + font-size: inherit; +} .component_filemanager_shell .component_sidebar [data-bind="your-files"] > ul { margin-left: 0px; } .component_filemanager_shell .component_sidebar ul { margin-top: 0px; @@ -44,7 +53,12 @@ padding-left: 5px; margin-top: 0px; } - +.component_filemanager_shell .search .component_sidebar ul { + margin: 0; +} +.component_filemanager_shell .search .component_sidebar ul li { + padding-left: 0; +} .component_filemanager_shell .component_sidebar a { display: flex; padding: 5px 5px 5px 10px; diff --git a/public/assets/components/sidebar.js b/public/assets/components/sidebar.js index 3190b2eb..46867c6b 100644 --- a/public/assets/components/sidebar.js +++ b/public/assets/components/sidebar.js @@ -1,8 +1,7 @@ import { createElement, onDestroy } from "../lib/skeleton/index.js"; import rxjs, { effect, onClick } from "../lib/rx.js"; import { fromHref, toHref } from "../lib/skeleton/router.js"; -import { qs } from "../lib/dom.js"; -import { animate, opacityIn } from "../lib/animate.js"; +import { qs, qsa } from "../lib/dom.js"; import { settingsGet, settingsSave } from "../lib/store.js"; import { loadCSS } from "../helpers/loader.js"; import t from "../locales/index.js"; @@ -20,13 +19,13 @@ const mv = (from, to) => withVirtualLayer( export default async function ctrlSidebar(render) { if (new URL(location).searchParams.get("nav") === "false") return; - else if (document.body.clientWidth < 850) return; // do not waste CPU cycle on small devices + else if (document.body.clientWidth < 850) return; const $page = render(createElement(`

close - ${t("Your Files")} +

@@ -73,16 +72,18 @@ export default async function ctrlSidebar(render) { $page.firstElementChild.scrollTop = state.scrollTop; } onDestroy(() => { + $page.classList.remove("search"); state.$cache = $files.firstElementChild.cloneNode(true); state.scrollTop = $page.firstElementChild.scrollTop }); const chunk = new pathChunk(); const arr = chunk.toArray(); + const fullpath = chunk.toString(); const $tree = document.createDocumentFragment(); for (let i = 0; i { + const inputValue = e.target.value.toLowerCase(); + qsa($page, "li a").forEach(($li) => { + if (inputValue === "") { + $li.classList.remove("hidden"); + $page.classList.remove("search"); + return; + } + $page.classList.add("search"); + qs($li, "div").textContent.toLowerCase().indexOf(inputValue) === -1 ? + $li.classList.add("hidden") : + $li.classList.remove("hidden"); + }) + }), + )); } -async function createListOfFiles(path, currentName) { +async function createListOfFiles(path, currentName, fullpath) { const r = await cache().get(path); const whats = r === null ? (currentName ? [currentName] : []) : r.files .filter(({ type, name }) => type === "directory" && name[0] !== ".") @@ -127,16 +147,22 @@ async function createListOfFiles(path, currentName) { .sort(); const $ul = document.createElement("ul"); for (let i=0; i - - directory +
  • + + directory
    ${whats[i]}
  • `); $ul.appendChild($li); const $link = qs($li, "a"); + if ($li.getAttribute("data-path") === fullpath) { + $link.removeAttribute("href", ""); + $link.removeAttribute("data-link"); + continue; + } $link.ondrop = async (e) => { $link.classList.remove("highlight"); const from = e.dataTransfer.getData("path"); diff --git a/public/assets/lib/ajax.js b/public/assets/lib/ajax.js index 4638b7ba..5f541551 100644 --- a/public/assets/lib/ajax.js +++ b/public/assets/lib/ajax.js @@ -1,3 +1,4 @@ +import { toHref } from "./skeleton/router.js"; import rxjs, { ajax } from "./rx.js"; import { AjaxError } from "./error.js"; @@ -11,14 +12,20 @@ export default function(opts) { const result = res.xhr.responseText; if (opts.responseType === "json") { const json = JSON.parse(result); + res.responseJSON = json; if (json.status !== "ok") { throw new AjaxError("Oups something went wrong", result); } - res.responseJSON = json; } return res; }), - rxjs.catchError((err) => rxjs.throwError(processError(err.xhr, err))), + rxjs.catchError((err) => { + if (err.status === 401) { + location.href = toHref("/login?next=" + location.pathname + location.hash + location.search); + return rxjs.EMPTY; + } + return rxjs.throwError(processError(err.xhr, err)) + }), ); } diff --git a/public/assets/pages/filespage/ctrl_filesystem.js b/public/assets/pages/filespage/ctrl_filesystem.js index 83e4a330..974b4fad 100644 --- a/public/assets/pages/filespage/ctrl_filesystem.js +++ b/public/assets/pages/filespage/ctrl_filesystem.js @@ -326,14 +326,13 @@ function createLink(file, currentPath) { } function gridSize(size, windowSize) { - const DESIRED_FILE_WIDTH_ON_LARGE_SCREEN = 225; - console.log("GS", size, windowSize) + const DESIRED_FILE_WIDTH_ON_LARGE_SCREEN = 210; if (windowSize > 1100) return Math.max( 4, Math.floor(size / DESIRED_FILE_WIDTH_ON_LARGE_SCREEN), ); else if (size > 750) return 4; - else if (size > 550) return 3; + else if (size > 520) return 3; else if (size > 300) return 2; return 1; } diff --git a/public/assets/pages/filespage/modal_share.css b/public/assets/pages/filespage/modal_share.css index 7bedb0f0..ab0c1a1d 100644 --- a/public/assets/pages/filespage/modal_share.css +++ b/public/assets/pages/filespage/modal_share.css @@ -149,6 +149,9 @@ .component_supercheckbox > label { font-size: 0.95em; font-style: italic; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; } .component_supercheckbox > label .label { margin-left: -5px; diff --git a/public/assets/pages/filespage/thing.css b/public/assets/pages/filespage/thing.css index 1aa5bfd6..795b29c6 100644 --- a/public/assets/pages/filespage/thing.css +++ b/public/assets/pages/filespage/thing.css @@ -76,6 +76,9 @@ padding: 2px; border-radius: 50px; } +.touch-yes .component_thing .component_checkbox { + opacity: 1; +} .component_thing .component_checkbox .indicator { top: 7px; left: 6px; @@ -237,6 +240,9 @@ left: 3px; transform: translateX(-5px); } +.touch-yes .list > .component_thing.view-grid .component_checkbox { + transform: translateX(0px); +} .list > .component_thing.view-grid:hover .component_checkbox, .list > .component_thing.view-grid.selected .component_checkbox { transform: translateX(0px); diff --git a/public/assets/pages/viewerpage/application_editor.css b/public/assets/pages/viewerpage/application_editor.css index 005820a8..e3921bad 100644 --- a/public/assets/pages/viewerpage/application_editor.css +++ b/public/assets/pages/viewerpage/application_editor.css @@ -276,6 +276,9 @@ pre.CodeMirror-line { .cm-s-default .cm-quote { color: var(--dark); } +.cm-s-default .cm-invalidchar { + color: var(--error); +} .CodeMirror-gutters { box-shadow: 0px 0px 2px rgba(0, 0, 0, 0.1); diff --git a/public/assets/pages/viewerpage/application_editor.js b/public/assets/pages/viewerpage/application_editor.js index 3c72c3a6..da351956 100644 --- a/public/assets/pages/viewerpage/application_editor.js +++ b/public/assets/pages/viewerpage/application_editor.js @@ -49,15 +49,13 @@ export default async function(render, { acl$ }) { acl$, ).pipe( rxjs.mergeMap(([content, acl]) => { - if (content === null || has_binary(content)) { - return rxjs.from(initDownloader()).pipe( - removeLoader, - rxjs.mergeMap(() => { - ctrlDownloader(render); - return rxjs.EMPTY; - }), - ); - } + if (content === null || has_binary(content)) return rxjs.from(initDownloader()).pipe( + removeLoader, + rxjs.mergeMap(() => { + ctrlDownloader(render); + return rxjs.EMPTY; + }), + ); return rxjs.of(content).pipe( rxjs.mergeMap((content) => rxjs.of(window.CONFIG).pipe( rxjs.mergeMap((config) => rxjs.from(loadKeybinding(config.editor)).pipe(rxjs.mapTo(config))), @@ -233,8 +231,14 @@ function loadMode(ext) { else if (ext === "less" || ext === "scss" || ext === "sass") mode = "sass"; else if (ext === "js" || ext === "json") mode = "javascript"; else if (ext === "jsx") mode = "jsx"; - else if (ext === "php" || ext === "php5" || ext === "php4") mode = "php"; - else if (ext === "elm") mode = "elm"; + else if (ext === "php" || ext === "php5" || ext === "php4") { + mode = "php"; + before = Promise.all([ + loadJS(import.meta.url, "../../lib/vendor/codemirror/mode/xml/xml.js"), + loadJS(import.meta.url, "../../lib/vendor/codemirror/mode/javascript/javascript.js"), + loadJS(import.meta.url, "../../lib/vendor/codemirror/mode/css/css.js"), + ]); + } else if (ext === "elm") mode = "elm"; else if (ext === "erl") mode = "erlang"; else if (ext === "go") mode = "go"; else if (ext === "markdown" || ext === "md") { diff --git a/public/assets/pages/viewerpage/application_video.js b/public/assets/pages/viewerpage/application_video.js index f4cd7e60..8a97124b 100644 --- a/public/assets/pages/viewerpage/application_video.js +++ b/public/assets/pages/viewerpage/application_video.js @@ -2,9 +2,10 @@ import { createElement } from "../../lib/skeleton/index.js"; import rxjs, { effect } from "../../lib/rx.js"; import { animate, slideYIn } from "../../lib/animate.js"; import { loadCSS, loadJS } from "../../helpers/loader.js"; -import { qs } from "../../lib/dom.js"; +import { qs, qsa } from "../../lib/dom.js"; import { settings_get, settings_put } from "../../lib/settings.js"; import assert from "../../lib/assert.js"; +import { ApplicationError } from "../../lib/error.js"; import Hls from "../../lib/vendor/hlsjs/hls.js"; @@ -13,7 +14,7 @@ import ctrlError from "../ctrl_error.js"; import { transition, getFilename, getDownloadUrl } from "./common.js"; import { formatTimecode } from "./common_player.js"; import { ICON } from "./common_icon.js"; -import { renderMenubar, buttonDownload } from "./component_menubar.js"; +import { renderMenubar, buttonDownload, buttonFullscreen } from "./component_menubar.js"; import "../../components/icon.js"; @@ -22,10 +23,6 @@ const STATUS_PAUSED = "PAUSED"; const STATUS_BUFFERING = "BUFFERING"; export default function(render, { mime }) { - if (!Hls.isSupported()) { - ctrlError()(new Error("browser not supporting hls")); - return; - } const $page = createElement(`
    @@ -65,7 +62,7 @@ export default function(render, { mime }) {
    -
    +