diff --git a/public/assets/components/decorator_shell_filemanager.css b/public/assets/components/decorator_shell_filemanager.css
index a940d7e0..e8c81adc 100644
--- a/public/assets/components/decorator_shell_filemanager.css
+++ b/public/assets/components/decorator_shell_filemanager.css
@@ -1,10 +1,11 @@
.component_filemanager_shell {
display: flex;
height: 100%;
+ background: white;
}
.component_filemanager_shell .component_sidebar {
width: 240px;
- padding: 10px;
+ padding: 20px;
}
.component_filemanager_shell .component_sidebar > h3 {
padding-left: 10px;
@@ -25,39 +26,49 @@
}
.component_filemanager_shell [data-bind="filemanager-children"] {
- border-top: 2px solid rgba(0,0,0,0.02);
- border-left: 2px solid rgba(0,0,0,0.02);
+ border-top: 2px solid rgba(0,0,0,0.02);;
+ border-left: 2px solid rgba(0,0,0,0.02);;
+ border-right: 2px solid rgba(0,0,0,0.02);;
transition: 1000ms ease border-color;
- border-top-left-radius: 15px;
+ border-top-left-radius: 20px;
+ border-top-right-radius: 10px;
display: flex;
height: 100%;
overflow: hidden;
- background: white;
- padding-top: 20px;
}
-
.component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [data-bind="filemanager-children"] {
border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ transition: 0.5s ease border-top-left-radius, 0.5s ease border-top-right-radius;
border-left: none;
+ border-right: none;
+}
+.component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [data-bind="filemanager-children"].scrolling {
+ border-top-left-radius: 30px;
+ border-top-right-radius: 30px;
}
.component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [is="component-breadcrumb"] > .component_breadcrumb,
-.component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [data-bind="filemanager-children"] > div {
+.component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [data-bind="filemanager-children"] .container {
width: 95%;
margin: 0 auto;
max-width: 820px;
}
-.component_filemanager_shell [data-bind="sidebar"].hidden ~ div [is="component-breadcrumb"] {
- background: white;
-}
.component_filemanager_shell [data-bind="sidebar"].hidden ~ div > [data-bind="filemanager-children"] {
background: var(--bg-color);
}
-.component_filemanager_shell .component_filesystem {
- padding: 15px;
-}
-.component_filemanager_shell [data-bind="filemanager-children"] > div,
-.component_filemanager_shell [is="component-breadcrumb"] {
+.component_filemanager_shell [data-bind="filemanager-children"] .container,
+.component_filemanager_shell [is="component-breadcrumb"] .container {
max-width: 2100px;
}
+
+.component_filemanager_shell [data-bind="sidebar"] ~ div [is="component_filesystem"],
+.component_filemanager_shell [data-bind="sidebar"] ~ div [is="component_submenu"] .component_submenu{
+ padding: 0 30px;
+}
+
+.component_filemanager_shell [data-bind="sidebar"].hidden ~ div [is="component_filesystem"],
+.component_filemanager_shell [data-bind="sidebar"].hidden ~ div [is="component_submenu"] .component_submenu {
+ padding: 0px;
+}
diff --git a/public/assets/lib/skeleton/index.js b/public/assets/lib/skeleton/index.js
index e785f9a0..69ba8864 100644
--- a/public/assets/lib/skeleton/index.js
+++ b/public/assets/lib/skeleton/index.js
@@ -61,9 +61,21 @@ export function createElement(str) {
return $n.firstElementChild;
}
+export function createFragment(str) {
+ const $n = window.document.createElement("div");
+ $n.innerHTML = str;
+ const $doc = document.createDocumentFragment();
+ for (let i=0; i<$n.children.length; i++) {
+ $doc.appendChild($n.children[i].cloneNode(true));
+ }
+ $n.remove();
+ return $doc;
+}
+
export function createRender($parent) {
+ if (!($parent instanceof window.HTMLElement)) throw new Error(`assert failed: createRender on non HTMLElement`);
return ($view) => {
- if ($view instanceof window.Element) $parent?.replaceChildren($view);
+ if ($view instanceof window.HTMLElement) $parent.replaceChildren($view);
else throw new Error(`Unknown view type: ${typeof $view}`);
};
}
diff --git a/public/assets/pages/ctrl_filespage.css b/public/assets/pages/ctrl_filespage.css
index 3e6198df..78575951 100644
--- a/public/assets/pages/ctrl_filespage.css
+++ b/public/assets/pages/ctrl_filespage.css
@@ -1,36 +1,41 @@
.component_page_filespage {
display: flex;
flex-direction: column;
- height: 100%;
+ height: auto;
+ min-height: 100%;
width: 100%;
+ align-self: flex-start;
+ background: var(--bg-color);
+ padding-top: 20px;
}
-.component_page_filespage .error {
- cursor: pointer;
-}
-.component_page_filespage .container {
- padding: 5px 0 20px 0;
- box-sizing: border-box;
-}
-.component_page_filespage .page_container, .component_page_filespage .selectablegroup {
- flex: 1;
- display: flex;
- overflow: hidden;
-}
-.component_page_filespage .selectablegroup {
- overflow: hidden !important;
-}
-.component_page_filespage .selectablegroup > div[style] span {
- border: 1px dashed var(--light) !important;
-}
-.component_page_filespage .infinite_scroll_loading {
- text-align: center;
-}
-.component_page_filespage .infinite_scroll_loading .component_loader {
- margin-top: -50px;
-}
-.component_page_filespage .infinite_scroll_loading .component_loader svg {
- height: 40px;
-}
+
+/* .component_page_filespage .error { */
+/* cursor: pointer; */
+/* } */
+/* .component_page_filespage .container { */
+/* padding: 5px 0 20px 0; */
+/* box-sizing: border-box; */
+/* } */
+/* .component_page_filespage .page_container, .component_page_filespage .selectablegroup { */
+/* flex: 1; */
+/* display: flex; */
+/* overflow: hidden; */
+/* } */
+/* .component_page_filespage .selectablegroup { */
+/* overflow: hidden !important; */
+/* } */
+/* .component_page_filespage .selectablegroup > div[style] span { */
+/* border: 1px dashed var(--light) !important; */
+/* } */
+/* .component_page_filespage .infinite_scroll_loading { */
+/* text-align: center; */
+/* } */
+/* .component_page_filespage .infinite_scroll_loading .component_loader { */
+/* margin-top: -50px; */
+/* } */
+/* .component_page_filespage .infinite_scroll_loading .component_loader svg { */
+/* height: 40px; */
+/* } */
.scroll-y {
flex: 1;
@@ -38,6 +43,6 @@
overflow-x: hidden !important;
-webkit-overflow-scrolling: touch;
}
-.scroll-y > .container {
- height: 100%;
-}
+/* .scroll-y > .container { */
+/* height: 100%; */
+/* } */
diff --git a/public/assets/pages/ctrl_filespage.js b/public/assets/pages/ctrl_filespage.js
index fae7cba8..79581fce 100644
--- a/public/assets/pages/ctrl_filespage.js
+++ b/public/assets/pages/ctrl_filespage.js
@@ -14,7 +14,7 @@ export default WithShell(function(render) {
const $page = createElement(`
diff --git a/public/assets/pages/filespage/ctrl_filesystem.css b/public/assets/pages/filespage/ctrl_filesystem.css
index 2352a6fd..af507b58 100644
--- a/public/assets/pages/filespage/ctrl_filesystem.css
+++ b/public/assets/pages/filespage/ctrl_filesystem.css
@@ -1,4 +1,3 @@
-.list .container_fs {
- content-visibility: auto;
- contain-intrinsic-size: 1px 2700px;
+[is="component_filesystem"] .component_filesystem {
+ padding-top: 5px;
}
diff --git a/public/assets/pages/filespage/ctrl_filesystem.js b/public/assets/pages/filespage/ctrl_filesystem.js
index ebdebaf6..63dc56c7 100644
--- a/public/assets/pages/filespage/ctrl_filesystem.js
+++ b/public/assets/pages/filespage/ctrl_filesystem.js
@@ -13,18 +13,13 @@ import { ls } from "./model_files.js";
export default async function(render) {
const $page = createElement(`
-
-
+
`);
render($page);
@@ -34,15 +29,15 @@ export default async function(render) {
effect(rxjs.of(path).pipe(
toggleLoader($page, true),
rxjs.mergeMap(() => new Promise((done) => setTimeout(() => done({
- files: new Array(400).fill(1),
+ files: new Array(100).fill(1),
}), 1000))),
toggleLoader($page, false),
rxjs.mergeMap(({ files }) => { // STEP1: setup the list of files
const FILE_HEIGHT = 160;
- const BLOCK_SIZE = Math.ceil(document.body.clientHeight / FILE_HEIGHT) + 1;
- // const BLOCK_SIZE = 7;
- const COLUMN_PER_ROW = 2;
- const VIRTUAL_SCROLL_MINIMUM_TRIGGER = 10;
+ // const BLOCK_SIZE = Math.ceil(document.body.clientHeight / FILE_HEIGHT) + 1;
+ const BLOCK_SIZE = 10;
+ const COLUMN_PER_ROW = 4;
+ const VIRTUAL_SCROLL_MINIMUM_TRIGGER = 20;
let size = files.length;
if (size > VIRTUAL_SCROLL_MINIMUM_TRIGGER) {
size = BLOCK_SIZE * COLUMN_PER_ROW;
diff --git a/public/assets/pages/filespage/ctrl_submenu.css b/public/assets/pages/filespage/ctrl_submenu.css
index 7e2237c8..0144fe72 100644
--- a/public/assets/pages/filespage/ctrl_submenu.css
+++ b/public/assets/pages/filespage/ctrl_submenu.css
@@ -1,133 +1,173 @@
-.component_submenu.sticky {
+[is="component_submenu"] {
position: sticky;
top: 0;
z-index: 3;
- background: var(--bg-color);
- opacity: 0.95;
+ padding: 5px 0 5px 0;
+ backdrop-filter: blur(10px);
+ transition: 0.2s ease box-shadow;
}
-
-.component_submenu {
- padding-left: 0;
- padding-right: 0;
- padding-bottom: 0;
- margin-bottom: -10px;
+.scrolling [is="component_submenu"] {
+ box-shadow: 0 5px 10px rgba(100,100,100,.05);
+ background: rgba(0,0,0,0.01);
}
-.component_submenu .menubar {
- font-size: 15px;
- line-height: 15px;
- height: 15px;
- margin-top: 5px;
- color: var(--light);
- margin: 5px 0 10px 0;
- /* Create Buttons */
+[is="component_submenu"] .component_submenu {
+ display: flex;
+ justify-content: space-between;
+ padding: 0 15px;
}
-.component_submenu .menubar > span, .component_submenu .menubar form label {
- display: inline-block;
- margin-top: -5px;
- border-radius: 2px;
- cursor: pointer;
- background-position: center;
-}
-.component_submenu .menubar > span:active, .component_submenu .menubar > span:hover, .component_submenu .menubar form label:active, .component_submenu .menubar form label:hover {
- color: var(--color);
-}
-.component_submenu .menubar > span:hover, .component_submenu .menubar form label:hover {
- transition: background 0.4s;
- background: #ffffff00 radial-gradient(circle, transparent 1%, var(--bg-color) 1%) center/15000%;
-}
-.component_submenu .menubar > span:active, .component_submenu .menubar form label:active {
- background-color: #00000033;
- background-size: 100%;
- transition: background 0s;
-}
-.component_submenu .menubar > span {
- padding: 5px 8px;
- letter-spacing: 0.06em;
- display: inline-block;
+[is="component_submenu"] .component_submenu .action button {
+ padding: 6px 10px;
+ font-size: 0.8rem;
+ background: transparent;
+ color: #626469fa;
text-transform: uppercase;
- font-size: 12px;
- color: var(--light);
- vertical-align: text-bottom;
+ letter-spacing: 0;
+ border-radius: 5px;
}
-.component_submenu .menubar > div {
- cursor: pointer;
- margin-right: 15px;
+[is="component_submenu"] .component_submenu .action button img {
+ width: 16px;
+ height: 16px;
+ margin-left: -3px;
+ margin-right: -3px;
}
-.component_submenu .menubar .view {
+[is="component_submenu"] .component_submenu .action.left button,
+[is="component_submenu"] .component_submenu .action.right:hover{
+ background: rgba(230,230,230, 0.8);
+
+}
+[is="component_submenu"] .component_submenu .action button:hover {
+ background: rgba(0,0,0,.1);
+}
+[is="component_submenu"] .component_submenu .action button:active {
+ background: rgba(0,0,0,.15);
+}
+
+[is="component_submenu"] .component_submenu .action.right {
float: right;
- padding: 2px;
- transition: 0.15s ease-out background;
- margin-right: 0px;
- margin-left: 0px;
-}
-.component_submenu .menubar .view .search, .component_submenu .menubar .view.list-grid, .component_submenu .menubar .view > .dropdown_button, .component_submenu .menubar .view form > label {
- min-width: inherit;
- border-radius: 2px;
- padding: 5px;
- margin: 2px 0 2px 0;
-}
-.component_submenu .menubar .view.list-grid, .component_submenu .menubar .view .dropdown_button, .component_submenu .menubar .view .search {
- background-position: center;
-}
-.component_submenu .menubar .view.list-grid:hover, .component_submenu .menubar .view .dropdown_button:hover, .component_submenu .menubar .view .search:hover {
- transition: background 0.4s;
- background: #ffffff00 radial-gradient(circle, transparent 1%, var(--bg-color) 1%) center/15000%;
-}
-.component_submenu .menubar .view.list-grid:active, .component_submenu .menubar .view .dropdown_button:active, .component_submenu .menubar .view .search:active {
- background-color: #00000033;
- background-size: 100%;
- transition: background 0s;
-}
-.component_submenu .menubar .view .dropdown_container .component_icon {
- box-sizing: border-box;
- border: 2px solid rgba(0, 0, 0, 0);
-}
-.component_submenu .menubar .view.list-grid, .component_submenu .menubar .view .search {
- margin-top: -5px !important;
-}
-.component_submenu .menubar .view.component_dropdown {
- margin-top: -10px;
-}
-.component_submenu .menubar .view.component_dropdown.active .dropdown_button {
- box-shadow: none;
-}
-.component_submenu .menubar.search_focus form input {
- transition: 0.2s width ease-in;
- opacity: 1;
-}
-.component_submenu .menubar form {
- float: right;
- margin-top: -3px;
-}
-.component_submenu .menubar form input {
- opacity: 0;
- font-size: 1em;
- margin-top: -3px;
- border: none;
- background: inherit;
- border-bottom: 2px solid var(--light);
- color: var(--color);
-}
-.component_submenu .menubar.search_focus > span {
- display: none;
-}
-.component_submenu .menubar .component_icon {
- height: 15px;
- width: 15px;
+ border-radius: 5px;
}
-.component_submenu .submenuwithSelection-appear {
- display: inline-block;
- opacity: 0;
- transform: translateY(3px);
- transition: opacity 0.2s ease, transform 0.4s ease;
-}
-.component_submenu .submenuwithSelection-appear.submenuwithSelection-appear-active {
- opacity: 1;
- transform: translateY(0px);
-}
-.dark-mode .component_submenu input#search {
- color: rgba(255, 255, 255, 0.8);
-}
+
+
+
+/* .component_submenu .menubar { */
+/* font-size: 15px; */
+/* line-height: 15px; */
+/* height: 15px; */
+/* margin-top: 5px; */
+/* color: var(--light); */
+/* margin: 5px 0 10px 0; */
+/* /\* Create Buttons *\/ */
+/* } */
+/* .component_submenu .menubar > span, .component_submenu .menubar form label { */
+/* display: inline-block; */
+/* margin-top: -5px; */
+/* border-radius: 2px; */
+/* cursor: pointer; */
+/* background-position: center; */
+/* } */
+/* .component_submenu .menubar > span:active, .component_submenu .menubar > span:hover, .component_submenu .menubar form label:active, .component_submenu .menubar form label:hover { */
+/* color: var(--color); */
+/* } */
+/* .component_submenu .menubar > span:hover, .component_submenu .menubar form label:hover { */
+/* transition: background 0.4s; */
+/* background: #ffffff00 radial-gradient(circle, transparent 1%, var(--bg-color) 1%) center/15000%; */
+/* } */
+/* .component_submenu .menubar > span:active, .component_submenu .menubar form label:active { */
+/* background-color: #00000033; */
+/* background-size: 100%; */
+/* transition: background 0s; */
+/* } */
+/* .component_submenu .menubar > span { */
+/* padding: 5px 8px; */
+/* letter-spacing: 0.06em; */
+/* display: inline-block; */
+/* text-transform: uppercase; */
+/* font-size: 12px; */
+/* color: var(--light); */
+/* vertical-align: text-bottom; */
+/* } */
+/* .component_submenu .menubar > div { */
+/* cursor: pointer; */
+/* margin-right: 15px; */
+/* } */
+/* .component_submenu .menubar .view { */
+/* float: right; */
+/* padding: 2px; */
+/* transition: 0.15s ease-out background; */
+/* margin-right: 0px; */
+/* margin-left: 0px; */
+/* } */
+/* .component_submenu .menubar .view .search, .component_submenu .menubar .view.list-grid, .component_submenu .menubar .view > .dropdown_button, .component_submenu .menubar .view form > label { */
+/* min-width: inherit; */
+/* border-radius: 2px; */
+/* padding: 5px; */
+/* margin: 2px 0 2px 0; */
+/* } */
+/* .component_submenu .menubar .view.list-grid, .component_submenu .menubar .view .dropdown_button, .component_submenu .menubar .view .search { */
+/* background-position: center; */
+/* } */
+/* .component_submenu .menubar .view.list-grid:hover, .component_submenu .menubar .view .dropdown_button:hover, .component_submenu .menubar .view .search:hover { */
+/* transition: background 0.4s; */
+/* background: #ffffff00 radial-gradient(circle, transparent 1%, var(--bg-color) 1%) center/15000%; */
+/* } */
+/* .component_submenu .menubar .view.list-grid:active, .component_submenu .menubar .view .dropdown_button:active, .component_submenu .menubar .view .search:active { */
+/* background-color: #00000033; */
+/* background-size: 100%; */
+/* transition: background 0s; */
+/* } */
+/* .component_submenu .menubar .view .dropdown_container .component_icon { */
+/* box-sizing: border-box; */
+/* border: 2px solid rgba(0, 0, 0, 0); */
+/* } */
+/* .component_submenu .menubar .view.list-grid, .component_submenu .menubar .view .search { */
+/* margin-top: -5px !important; */
+/* } */
+/* .component_submenu .menubar .view.component_dropdown { */
+/* margin-top: -10px; */
+/* } */
+/* .component_submenu .menubar .view.component_dropdown.active .dropdown_button { */
+/* box-shadow: none; */
+/* } */
+/* .component_submenu .menubar.search_focus form input { */
+/* transition: 0.2s width ease-in; */
+/* opacity: 1; */
+/* } */
+/* .component_submenu .menubar form { */
+/* float: right; */
+/* margin-top: -3px; */
+/* } */
+/* .component_submenu .menubar form input { */
+/* opacity: 0; */
+/* font-size: 1em; */
+/* margin-top: -3px; */
+/* border: none; */
+/* background: inherit; */
+/* border-bottom: 2px solid var(--light); */
+/* color: var(--color); */
+/* } */
+/* .component_submenu .menubar.search_focus > span { */
+/* display: none; */
+/* } */
+/* .component_submenu .menubar .component_icon { */
+/* height: 15px; */
+/* width: 15px; */
+/* } */
+
+/* .component_submenu .submenuwithSelection-appear { */
+/* display: inline-block; */
+/* opacity: 0; */
+/* transform: translateY(3px); */
+/* transition: opacity 0.2s ease, transform 0.4s ease; */
+/* } */
+
+/* .component_submenu .submenuwithSelection-appear.submenuwithSelection-appear-active { */
+/* opacity: 1; */
+/* transform: translateY(0px); */
+/* } */
+
+/* .dark-mode .component_submenu input#search { */
+/* color: rgba(255, 255, 255, 0.8); */
+/* } */
diff --git a/public/assets/pages/filespage/ctrl_submenu.js b/public/assets/pages/filespage/ctrl_submenu.js
index 5c248f53..b21da41b 100644
--- a/public/assets/pages/filespage/ctrl_submenu.js
+++ b/public/assets/pages/filespage/ctrl_submenu.js
@@ -1,61 +1,90 @@
-import { createElement, createRender } from "../../lib/skeleton/index.js";
+import { onDestroy, createElement, createRender, createFragment } from "../../lib/skeleton/index.js";
+import rxjs, { effect, applyMutation, onClick } from "../../lib/rx.js";
+import { animate } from "../../lib/animate.js";
+import { qs } from "../../lib/dom.js";
import { CSS } from "../../helpers/loader.js";
+import { getSelection$, clearSelection } from "./model_files.js";
export default async function(render) {
+ const $page = createElement(``);
+ render($page);
- const $page = createElement(`
-