mirror of
https://github.com/mickael-kerjean/filestash
synced 2025-12-12 11:24:40 +01:00
chore (rewrite): scaffold for menubar action button
This commit is contained in:
parent
eb2118c517
commit
07398c21c3
12 changed files with 233 additions and 26 deletions
|
|
@ -5,13 +5,22 @@ import { qs, qsa } from "../lib/dom.js";
|
|||
import { ApplicationError } from "../lib/error.js";
|
||||
import { CSS } from "../helpers/loader.js";
|
||||
|
||||
export default class Modal {
|
||||
class Modal {
|
||||
static open($node, opts = {}) {
|
||||
find().trigger($node, opts);
|
||||
}
|
||||
}
|
||||
|
||||
const createModal = async() => createElement(`
|
||||
export default Modal
|
||||
|
||||
export function createModal(opts) {
|
||||
return ($node, ok = nop) => {
|
||||
if (ok) opts.onQuit = ok;
|
||||
return Modal.open($node, opts);
|
||||
};
|
||||
}
|
||||
|
||||
const create = async() => createElement(`
|
||||
<div class="component_modal" id="modal-box">
|
||||
<style>${await CSS(import.meta.url, "modal.css")}</style>
|
||||
<div>
|
||||
|
|
@ -30,7 +39,7 @@ const createModal = async() => createElement(`
|
|||
|
||||
class ModalComponent extends window.HTMLElement {
|
||||
async trigger($node, opts = {}) {
|
||||
const $modal = await createModal();
|
||||
const $modal = await create();
|
||||
const close$ = new rxjs.Subject();
|
||||
const { onQuit = nop, withButtonsLeft = null, withButtonsRight = null } = opts;
|
||||
|
||||
|
|
@ -44,20 +53,20 @@ class ModalComponent extends window.HTMLElement {
|
|||
|
||||
if (currentLabel === null) return $button.remove();
|
||||
$button.textContent = currentLabel;
|
||||
$button.onclick = () => close$.next(currentLabel);
|
||||
$button.onclick = () => close$.next({ label: currentLabel, id: i+1 });
|
||||
});
|
||||
effect(rxjs.fromEvent($modal, "click").pipe(
|
||||
rxjs.filter((e) => e.target.getAttribute("id") === "modal-box"),
|
||||
rxjs.tap(() => close$.next()),
|
||||
rxjs.tap(() => close$.next({ id: 0 })),
|
||||
));
|
||||
effect(rxjs.fromEvent(window, "keydown").pipe(
|
||||
rxjs.filter((e) => e.keyCode === 27),
|
||||
rxjs.tap(() => close$.next()),
|
||||
rxjs.tap(() => close$.next({ id: 0 })),
|
||||
));
|
||||
|
||||
// feature: closing the modal
|
||||
effect(close$.pipe(
|
||||
rxjs.tap((label) => onQuit(label)),
|
||||
rxjs.tap(onQuit),
|
||||
rxjs.tap(() => animate(qs($modal, "div > div"), {
|
||||
time: 200,
|
||||
keyframes: [
|
||||
|
|
|
|||
|
|
@ -80,4 +80,4 @@ export function createRender($parent) {
|
|||
};
|
||||
}
|
||||
|
||||
export function nop() {}
|
||||
export function nop() { Promise.resolve(); }
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import WithShell, { init as initShell } from "../components/decorator_shell_file
|
|||
import { getState$ } from "./filespage/ctrl_filesystem_state.js";
|
||||
import componentFilesystem, { init as initFilesystem } from "./filespage/ctrl_filesystem.js";
|
||||
import componentSubmenu, { init as initSubmenu } from "./filespage/ctrl_submenu.js";
|
||||
import componentNewItem, { init as initNewItem } from "./filespage/ctrl_newitem.js";
|
||||
|
||||
import "../components/breadcrumb.js";
|
||||
|
||||
|
|
@ -15,6 +16,7 @@ export default WithShell(function(render) {
|
|||
<div class="component_page_filespage scroll-y">
|
||||
<div is="frequent_access" class="hidden"></div>
|
||||
<div is="component_submenu"></div>
|
||||
<div is="component_newitem"></div>
|
||||
<div is="component_filesystem"></div>
|
||||
</div>
|
||||
`);
|
||||
|
|
@ -31,11 +33,14 @@ export default WithShell(function(render) {
|
|||
|
||||
// feature3: render the menubar
|
||||
componentSubmenu(createRender(qs($page, "[is=\"component_submenu\"]")));
|
||||
|
||||
// feature4: render the creation menu
|
||||
componentNewItem(createRender(qs($page, "[is=\"component_newitem\"]")));
|
||||
});
|
||||
|
||||
export function init() {
|
||||
return Promise.all([
|
||||
loadCSS(import.meta.url, "./ctrl_filespage.css"),
|
||||
initShell(), initFilesystem(), initSubmenu(),
|
||||
initShell(), initFilesystem(), initSubmenu(), initNewItem(),
|
||||
]);
|
||||
}
|
||||
|
|
|
|||
10
public/assets/pages/filespage/ctrl_newitem.css
Normal file
10
public/assets/pages/filespage/ctrl_newitem.css
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
.component_newitem {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.component_newitem .component_thing {
|
||||
margin: 0 2px;
|
||||
}
|
||||
.component_newitem .component_thing .component_action {
|
||||
display: block;
|
||||
}
|
||||
92
public/assets/pages/filespage/ctrl_newitem.js
Normal file
92
public/assets/pages/filespage/ctrl_newitem.js
Normal file
|
|
@ -0,0 +1,92 @@
|
|||
import { createElement, onDestroy } from "../../lib/skeleton/index.js";
|
||||
import rxjs, { effect, onClick, preventDefault } from "../../lib/rx.js";
|
||||
import { qs } from "../../lib/dom.js";
|
||||
import { animate } from "../../lib/animate.js";
|
||||
import { loadCSS } from "../../helpers/loader.js";
|
||||
|
||||
import { getAction$ } from "./model_action.js";
|
||||
|
||||
export default async function(render) {
|
||||
const $node = createElement(`
|
||||
<div class="component_newitem container">
|
||||
<div class="component_thing">
|
||||
<div class="mouse-is-hover highlight box">
|
||||
<img class="component_icon" draggable="false" alt="directory">
|
||||
<span class="file-details">
|
||||
<form><input type="text" value=""></form>
|
||||
</span>
|
||||
<span class="component_action">
|
||||
<div class="action">
|
||||
<div>
|
||||
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0ODIuNDI4IDQ4Mi40MjkiPgogIDxwYXRoIHN0eWxlPSJmaWxsOiM2ZjZmNmY7c3Ryb2tlLXdpZHRoOjAuOTQ3MjAwNTQiIGQ9Im0gMjM5LjcxMDM4LDEwLjg1ODU2NyBjIC0yOS4yODYzMywwLjE0ODk1OSAtNTYuMjI4MjEsMjMuMTU4MTY3IC02MS4xMzg4Myw1MS45OTYxMjkgLTAuMDM1OSw1LjUyMjQ0IC04LjExOTM2LDEuNTIzODUyIC0xMS44MTQxMSwyLjczNDMwMSAtMjEuNjU5MywwLjM1NzE4IC00My4zODAyLC0wLjY3Njg3NSAtNjUuMDA3MTksMC40Mzg0NTIgLTI1Ljc0Mzk2MSwyLjgxNDg5NiAtNDcuMDQxMDg0LDI2LjM4MTc2IC00Ny4xNzMxNzIsNTIuMjkyMTMxIC0xLjcyMjExOCwyMi4zMjI3NyAxMS42Nzg0MSw0NC43NzgwOSAzMi4zMjg3NjgsNTMuNTM1MzIgMS41MDI3NjcsNy4xMzU1IDAuMjE0MTksMTYuMTEyMjggMC42NDM4LDIzLjk1NTY4IDAuMTEwMTQ1LDc1LjI4MzExIC0wLjIxODQzMywxNTAuNTc3MzcgMC4xNjA5NSwyMjUuODUzNjcgMS40ODk4MDUsMjUuODUxOTIgMjMuOTUyNDE0LDQ4LjI5NzYgNDkuODA1NzI0LDQ5Ljc2Njg3IDY4Ljk5NTMyLDAuMjc5OTggMTM4LjAxNjU0LDAuMjI5NjYgMjA3LjAxMzE3LDAuMDI0NyAyNi4wMTg1MiwtMS4yNzY5MSA0OC43MjA1LC0yMy44MzQ0MyA1MC4xOTI0OSwtNDkuODM3NjcgMC4zNjUyOCwtODMuMTUzOTggMC4wNDk3LC0xNjYuMzI1MDggMC4xNTUzOCwtMjQ5LjQ4NTU4IDIwLjg0ODU5LC04LjUyMTk5IDM0LjU5NTY3LC0zMC45NzQ5OSAzMi45NzkzNiwtNTMuNDExMzEgMC4wNzUyLC0yNi4wNzE2MTEgLTIxLjMyNDY5LC00OS45MDA0NDIgLTQ3LjIyOTkxLC01Mi42OTkyMDYgLTI0LjY2MTA5LC0xLjA5MzY1MSAtNDkuNDEyODgsLTAuMDg0ODcgLTc0LjEwNTUsLTAuNDMyOSAtMy45NDgzNywwLjYxMjkxMSAtMi4zMDc4NywtNS4zNzQ4NTkgLTMuODc5MTQsLTcuOTc4OTIzIC03LjI2MTcsLTI3LjU4NzA0MiAtMzQuMzcxMDIsLTQ3Ljg1NDgyMzggLTYyLjkzMTc5LC00Ni43NTE2NDMgeiBtIDEuNTA0MDQsMjguNTMwNzE3IGMgMTUuNDcwMDYsLTAuMzA1NjE5IDMwLjI2NjY3LDExLjA4NDk0OCAzNC4wMzQ0NywyNi4xOTk3MTMgLTIyLjY4MzQsLTAuMDA1OSAtNDUuMzk2OTIsMC4wMTIzMyAtNjguMDYxNTQsLTAuMDA5MiAzLjgwNzAyLC0xNS4wNzAyMDQgMTguMzQxMTcsLTI2LjQxOTgyMyAzNC4wMjcwNywtMjYuMTkwNDYzIHogTSAxMDguNjc4NTEsOTQuMTM2MzYzIGMgODkuNDUyNTcsMC4xMzkxNjYgMTc4LjkyODgzLC0wLjI3NzY1MSAyNjguMzY2NjksMC4yMDcyIDEzLjc0MTMxLDEuNDE4NTc4IDIzLjkyNjY0LDE1LjE3NjA3NyAyMi4yNjY2MiwyOC43MDgzMTcgMC4wMzI1LDE0LjU1MDU0IC0xNC4wNzUxNCwyNi41NjAyNiAtMjguNDA0OTIsMjQuODcxNDIgLTg4LjUwNjYsLTAuMTQwMzcgLTE3Ny4wMzY5MSwwLjI4MDA2IC0yNjUuNTI4OCwtMC4yMDkwNiBDIDkxLjEyNTU5LDE0Ni4yNDIyMyA4MC45ODkyODUsMTMxLjcwMTYzIDgzLjE4MTc5NCwxMTcuNzAxNjggODMuOTcwODg3LDEwNC43NDEzIDk1LjU3NzEzMSw5My45MjA1OTYgMTA4LjY3ODUxLDk0LjEzNjM2MyBaIE0gMzY2LjMzLDE3Ni40NzA2NiBjIC0wLjE0MDc3LDgxLjQyODQ4IDAuMjgwNjIsMTYyLjg4MDcgLTAuMjA5MDUsMjQ0LjI5NDQ3IC0xLjQzODYyLDEzLjkxMTUxIC0xNS40NzY4NSwyNC4xMDU4OCAtMjkuMTUyMzIsMjIuMjc1ODggLTY2LjE5Njc4LC0wLjE0MTYyIC0xMzIuNDE3NDMsMC4yODE3NSAtMTk4LjU5OTQ1LC0wLjIwOTA2IC0xMy44OTE2OSwtMS40NDg4IC0yNC4xMTkwOSwtMTUuNDc1NzUgLTIyLjI3MjE2LC0yOS4xNTc4NiAwLC03OS4wNjc4MSAwLC0xNTguMTM1NjEgMCwtMjM3LjIwMzQzIDgzLjQxMDk4LDAgMTY2LjgyMTk4LDAgMjUwLjIzMjk4LDAgeiIvPgogIDxwYXRoIHN0eWxlPSJmaWxsOiM2ZjZmNmY7c3Ryb2tlLXdpZHRoOjAuOTgyMDgxIiBkPSJtIDE3MS42ODY0NCwyNDcuNDczNzkgYyAtOS4zNDY3NiwwLjE1NjQ0IC0xNS43NDAzMiw5Ljg4ODA1IC0xNC4wODY3MywxOC43MTEzMyAwLjEyMzUxLDQ3LjYyNzAxIC0wLjI0NDAxLDk1LjI3OTAzIDAuMTc4MzksMTQyLjg5MDg3IDEuMjA3NjQsMTAuOTcxMzYgMTUuOTE4MDMsMTYuNTI3OTQgMjQuMDcyNDksOS4wODQyNSA4LjQxNzU5LC02LjgxODg3IDQuNDc0NjksLTE4Ljg4MzkyIDUuMzQ3NzQsLTI4LjA4MTM4IC0wLjEyNDM5LC00My4zNzEyNyAwLjI0NTIsLTg2Ljc2Nzg0IC0wLjE3ODM5LC0xMzAuMTIzODEgLTEuMDM3OTUsLTcuMzE0MzkgLTcuOTUwNTQsLTEyLjk1NzA1IC0xNS4zMzM1LC0xMi40ODEyNiB6Ii8+CiAgPHBhdGggc3R5bGU9ImZpbGw6IzZmNmY2ZjtzdHJva2Utd2lkdGg6MC45ODIwODEiIGQ9Im0gMjQwLjUwMTE2LDI0Ny40NzM3OSBjIC05LjM0NjQ5LDAuMTU2MTYgLTE1Ljc0MDY3LDkuODg4MTcgLTE0LjA4NjczLDE4LjcxMTMzIDAuMTIzNTIsNDcuNjI3MDEgLTAuMjQ0MDEsOTUuMjc5MDMgMC4xNzgzOSwxNDIuODkwODcgMS44MDUwNCwxNy41NjQ4OSAzMC4zNzQxMiwxNS4zNDIyNyAyOS40MjAyMywtMi4zMDE3NiAtMC4xMjMzMywtNDguOTM2NDIgMC4yNDM3NywtOTcuODk4MiAtMC4xNzgzOCwtMTQ2LjgxOTE4IC0xLjAzNzM1LC03LjMxNDEgLTcuOTUxMDEsLTEyLjk1Njk0IC0xNS4zMzM1MSwtMTIuNDgxMjYgeiIvPgogIDxwYXRoIHN0eWxlPSJmaWxsOiM2ZjZmNmY7c3Ryb2tlLXdpZHRoOjAuOTgyMDgxIiBkPSJtIDMwOS4zMTU4OCwyNDcuNDczNzkgYyAtOS4zNDcxMSwwLjE1NTMgLTE1Ljc0MzE0LDkuODg3MTMgLTE0LjA4NjcyLDE4LjcxMTMzIDAuMTIzNTQsNDcuNjI0OTkgLTAuMjQ0MDYsOTUuMjc1ODEgMC4xNzgzOCwxNDIuODg1MTEgMS4xOTg1NiwxMC45NzMyMSAxNS45MTY2NCwxNi41MzYwNiAyNC4wNzA1OCw5LjA5MDAxIDguNDE5MzMsLTYuODE3ODcgNC40NzM2NiwtMTguODg0MiA1LjM0Nzc0LC0yOC4wODEzOCAtMC4xMjQ0MiwtNDMuMzcxMjQgMC4yNDUyNCwtODYuNzY4MDQgLTAuMTc4MzksLTEzMC4xMjM4MSAtMS4wMzY3NCwtNy4zMTMyMSAtNy45NTAxMiwtMTIuOTU2NTggLTE1LjMzMTU5LC0xMi40ODEyNiB6Ii8+Cjwvc3ZnPg==" alt="trash">
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`);
|
||||
$node.classList.add("hidden");
|
||||
|
||||
const $input = qs($node, "input[type=\"text\"]");
|
||||
const $icon = qs($node, ".component_icon");
|
||||
const $remove = qs($node, ".action");
|
||||
|
||||
// feature1: setup the dom
|
||||
effect(getAction$().pipe(
|
||||
rxjs.map((targetName) => {
|
||||
if (targetName === "NEW_FILE") return {
|
||||
targetName,
|
||||
alt: "file",
|
||||
img: "PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIGhlaWdodD0iMTYiIHdpZHRoPSIxNiI+CiAgPHBhdGggc3R5bGU9ImNvbG9yOiMwMDAwMDA7dGV4dC1pbmRlbnQ6MDt0ZXh0LXRyYW5zZm9ybTpub25lO2ZpbGw6IzhjOGM4YztmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MC45ODQ4MTA0MSIgZD0ibSAyLDEzLjA4MjQxMiAwLjAxOTQ2MiwxLjQ5MjM0NyBjIDVlLTYsMC4yMjIxNDUgMC4yMDU1OTAyLDAuNDI0MjYyIDAuNDMxMTUwMiwwLjQyNDI3MiBMIDEzLjU4OTYxMiwxNSBDIDEzLjgxNTE3MywxNC45OTk5OTUgMTMuOTk5OTksMTQuNzk3ODc0IDE0LDE0LjU3NTcyOSB2IC0xLjQ5MzMxNyBjIC00LjE3MTg2OTIsMC42NjIwMjMgLTcuNjUxNjkyOCwwLjM5ODY5NiAtMTIsMCB6IiAvPgogIDxwYXRoIHN0eWxlPSJjb2xvcjojMDAwMDAwO3RleHQtaW5kZW50OjA7dGV4dC10cmFuc2Zvcm06bm9uZTtkaXNwbGF5OmlubGluZTtmaWxsOiNhYWFhYWE7c3Ryb2tlLXdpZHRoOjAuOTg0MDgxMjciIGQ9Ik0gMi4zNTAxLDEuMDAxMzMxMiBDIDIuMTUyNTksMS4wMzgzMjQ3IDEuOTk2NTksMS4yMjcyNzIzIDIuMDAwMDksMS40MjQ5MzU2IFYgMTQuMTMzNDU3IGMgNWUtNiwwLjIyMTgxNiAwLjIwNTIzLDAuNDIzNjM0IDAuNDMwNzksMC40MjM2NDQgbCAxMS4xMzksLTEuMDFlLTQgYyAwLjIyNTU2LC02ZS02IDAuNDMwMTEsLTAuMjAwNzU4IDAuNDMwMTIsLTAuNDIyNTc0IGwgNi43ZS00LC05LjgyMjY0MjYgYyAtMi40ODQwNDYsLTEuMzU1MDA2IC0yLjQzNTIzNCwtMi4wMzEyMjU0IC0zLjUwMDEsLTMuMzA5NzA3IC0wLjA0MywtMC4wMTU4ODIgMC4wNDYsMC4wMDE3NCAwLDAgTCAyLjQzMDY3LDEuMDAxMTA4IEMgMi40MDM4MywwLjk5ODU5IDIuMzc2NzQsMC45OTg1OSAyLjM0OTksMS4wMDExMDggWiIgLz4KICA8cGF0aCBzdHlsZT0iZGlzcGxheTppbmxpbmU7ZmlsbDojOGM4YzhjO2ZpbGwtb3BhY2l0eToxO3N0cm9rZTojOWU3NTc1O3N0cm9rZS13aWR0aDowO3N0cm9rZS1saW5lY2FwOmJ1dHQ7c3Ryb2tlLWxpbmVqb2luOm1pdGVyO3N0cm9rZS1taXRlcmxpbWl0OjQ7c3Ryb2tlLWRhc2hhcnJheTpub25lO3N0cm9rZS1vcGFjaXR5OjEiIGQ9Im0gMTAuNTAwNTcsMS4wMDIwNzY0IGMgMCwzLjI3NjgwMjggLTAuMDA1MiwzLjE3MzkxNjEgMC4zNjI5MjEsMy4yNjk4MjAyIDAuMjgwMTA5LDAuMDcyOTg0IDMuMTM3MTgsMC4wMzk4ODcgMy4xMzcxOCwwLjAzOTg4NyAtMS4xMjAwNjcsLTEuMDU1NjY5MiAtMi4zMzM0LC0yLjIwNjQ3MTMgLTMuNTAwMSwtMy4zMDk3MDc0IHoiIC8+Cjwvc3ZnPg==",
|
||||
};
|
||||
if (targetName === "NEW_FOLDER") return {
|
||||
targetName,
|
||||
alt: "directory",
|
||||
img: "PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBoZWlnaHQ9IjE2IiB3aWR0aD0iMTYiPgogIDxnIHRyYW5zZm9ybT0ibWF0cml4KDAuODY2NjY0MzEsMCwwLDAuODY2NjcsLTE3Mi4wNDU3OCwtODY0LjMyNzU5KSIgc3R5bGU9ImZpbGw6Izc1YmJkOTtmaWxsLW9wYWNpdHk6MC45NDExNzY0NztmaWxsLXJ1bGU6ZXZlbm9kZCI+CiAgICA8cGF0aCBzdHlsZT0iZmlsbDojNzViYmQ5O2ZpbGwtb3BhY2l0eTowLjk0MTE3NjQ3O2ZpbGwtcnVsZTpldmVub2RkIiBkPSJtIDIwMC4yLDk5OS43MiBjIC0wLjI4OTEzLDAgLTAuNTMxMjUsMC4yNDIxIC0wLjUzMTI1LDAuNTMxMiB2IDEyLjc4NCBjIDAsMC4yOTg1IDAuMjMyNjQsMC41MzEyIDAuNTMxMjUsMC41MzEyIGggMTUuMDkxIGMgMC4yOTg2LDAgMC41MzEyNCwtMC4yMzI3IDAuNTMxMjQsLTAuNTMxMiBsIDRlLTQsLTEwLjQ3NCBjIDAsLTAuMjg4OSAtMC4yNDIxMSwtMC41MzM4IC0wLjUzMTI0LC0wLjUzMzggbCAtNy41NDU3LDVlLTQgLTIuMzA3NiwtMi4zMDc4MyB6IiAvPgogIDwvZz4KICA8ZyB0cmFuc2Zvcm09Im1hdHJpeCgwLjg2NjY3LDAsMCwwLjg2NjY3LC0xNzIuMDQ2OTIsLTg2NC43ODM0KSIgc3R5bGU9ImZpbGw6IzlhZDFlZDtmaWxsLW9wYWNpdHk6MTtmaWxsLXJ1bGU6ZXZlbm9kZCI+CiAgICA8cGF0aCBzdHlsZT0iZmlsbDojOWFkMWVkO2ZpbGwtb3BhY2l0eToxO2ZpbGwtcnVsZTpldmVub2RkIiBkPSJtIDIwMC4yLDk5OS43MiBjIC0wLjI4OTEzLDAgLTAuNTMxMjUsMC4yNDIxIC0wLjUzMTI1LDAuNTMxMiB2IDEyLjc4NCBjIDAsMC4yOTg1IDAuMjMyNjQsMC41MzEyIDAuNTMxMjUsMC41MzEyIGggMTUuMDkxIGMgMC4yOTg2LDAgMC41MzEyNCwtMC4yMzI3IDAuNTMxMjQsLTAuNTMxMiBsIDRlLTQsLTEwLjQ3NCBjIDAsLTAuMjg4OSAtMC4yNDIxMSwtMC41MzM4IC0wLjUzMTI0LC0wLjUzMzggbCAtNy41NDU3LDVlLTQgLTIuMzA3NiwtMi4zMDc4MyB6IiAvPgogIDwvZz4KPC9zdmc+Cg==",
|
||||
};
|
||||
return null;
|
||||
}),
|
||||
rxjs.filter((val) => val),
|
||||
rxjs.tap(({ img, alt, targetName }) => {
|
||||
$icon.setAttribute("src", `data:image/svg+xml;base64,${img}`);
|
||||
$icon.setAttribute("alt", alt);
|
||||
$input.value = "";
|
||||
if ($node.classList.contains("hidden")) animate($node, {
|
||||
keyframes: [{ height: `0px` }, { height: "50px" }],
|
||||
time: 100, fill: "forwards",
|
||||
});
|
||||
$node.classList.remove("hidden")
|
||||
render($node);
|
||||
$input.focus();
|
||||
}),
|
||||
));
|
||||
|
||||
// feature2: remove the component
|
||||
effect(rxjs.merge(
|
||||
onClick($remove),
|
||||
rxjs.fromEvent(window, "keydown").pipe(
|
||||
rxjs.filter((e) => e.keyCode === 27),
|
||||
),
|
||||
rxjs.fromEvent($input, "blur").pipe(
|
||||
rxjs.filter(() => !$input.value),
|
||||
),
|
||||
).pipe(rxjs.tap(async () => {
|
||||
await animate($node, {
|
||||
keyframes: [{ height: "50px" }, { height: `0px` }],
|
||||
time: 50,
|
||||
fill: "backwards",
|
||||
});
|
||||
$node.classList.add("hidden");
|
||||
})));
|
||||
|
||||
// feature3: submit form
|
||||
effect(rxjs.fromEvent($node, "submit").pipe(
|
||||
preventDefault(),
|
||||
rxjs.tap(() => console.log("SUBMIT")),
|
||||
));
|
||||
}
|
||||
|
||||
export function init() {
|
||||
return loadCSS(import.meta.url, "./ctrl_newitem.css");
|
||||
}
|
||||
|
|
@ -1,13 +1,26 @@
|
|||
import { onDestroy, createElement, createFragment } from "../../lib/skeleton/index.js";
|
||||
import rxjs, { effect, applyMutation, onClick } from "../../lib/rx.js";
|
||||
import { onDestroy, createElement, createFragment, nop } from "../../lib/skeleton/index.js";
|
||||
import rxjs, { effect, applyMutation, onClick, preventDefault } from "../../lib/rx.js";
|
||||
import { animate } from "../../lib/animate.js";
|
||||
import { loadCSS } from "../../helpers/loader.js";
|
||||
import { qs } from "../../lib/dom.js";
|
||||
import { getSelection$, clearSelection } from "./model_files.js";
|
||||
import { setAction } from "./model_action.js";
|
||||
|
||||
import componentShare from "./modal_share.js";
|
||||
import componentEmbed from "./modal_embed.js";
|
||||
import componentTag from "./modal_tag.js";
|
||||
import componentRename from "./modal_rename.js";
|
||||
import componentDelete from "./modal_delete.js";
|
||||
|
||||
import "../../components/dropdown.js";
|
||||
import "../../components/icon.js";
|
||||
|
||||
import { createModal } from "../../components/modal.js";
|
||||
const modalOpt = {
|
||||
withButtonsRight: "OK",
|
||||
withButtonsLeft: "CANCEL",
|
||||
};
|
||||
|
||||
export default async function(render) {
|
||||
const $page = createElement(`
|
||||
<div class="component_submenu container">
|
||||
|
|
@ -48,11 +61,17 @@ export default async function(render) {
|
|||
`)),
|
||||
applyMutation($page, "replaceChildren"),
|
||||
rxjs.mergeMap(() => rxjs.merge(
|
||||
onClick(qs($page, `[data-action="new-file"]`)).pipe(rxjs.mapTo("NEW_FILE")),
|
||||
onClick(qs($page, `[data-action="new-folder"]`)).pipe(rxjs.mapTo("NEW_FOLDER")),
|
||||
rxjs.merge(
|
||||
onClick(qs($page, `[data-action="new-file"]`)).pipe(rxjs.mapTo("NEW_FILE")),
|
||||
onClick(qs($page, `[data-action="new-folder"]`)).pipe(rxjs.mapTo("NEW_FOLDER")),
|
||||
).pipe(rxjs.mergeMap((actionName) => {
|
||||
$scroll.scrollTo({top: 0, behavior: "smooth"});
|
||||
setAction(actionName);
|
||||
return rxjs.EMPTY;
|
||||
})),
|
||||
onClick(qs($page, `[data-action="search"]`)).pipe(rxjs.mapTo("SEARCH")),
|
||||
onClick(qs($page, `[data-action="view"]`)).pipe(rxjs.mapTo("VIEW")),
|
||||
).pipe(rxjs.tap((action) => onMenuSelect(action)))),
|
||||
)),
|
||||
));
|
||||
|
||||
// feature2: update when selection is preset
|
||||
|
|
@ -80,14 +99,25 @@ export default async function(render) {
|
|||
rxjs.tap(() => clearSelection()),
|
||||
rxjs.mergeMap(() => rxjs.EMPTY),
|
||||
),
|
||||
onClick(qs($page, `[data-action="download"]`)).pipe(rxjs.mapTo("DOWNLOAD")),
|
||||
onClick(qs($page, `[data-action="share"]`)).pipe(rxjs.mapTo("SHARE")),
|
||||
onClick(qs($page, `[data-action="embed"]`)).pipe(rxjs.mapTo("EMBED")),
|
||||
onClick(qs($page, `[data-action="tag"]`)).pipe(rxjs.mapTo("TAG")),
|
||||
onClick(qs($page, `[data-action="rename"]`)).pipe(rxjs.mapTo("RENAME")),
|
||||
onClick(qs($page, `[data-action="delete"]`)).pipe(rxjs.mapTo("DELETE")),
|
||||
onClick(qs($page, `[data-action="download"]`)).pipe(
|
||||
rxjs.mergeMap(() => rxjs.EMPTY),
|
||||
),
|
||||
onClick(qs($page, `[data-action="share"]`)).pipe(rxjs.tap(() => {
|
||||
componentShare(createModal(modalOpt));
|
||||
})),
|
||||
onClick(qs($page, `[data-action="embed"]`)).pipe(rxjs.tap(() => {
|
||||
componentEmbed(createModal(modalOpt));
|
||||
})),
|
||||
onClick(qs($page, `[data-action="tag"]`)).pipe(rxjs.tap(() => {
|
||||
componentTag(createModal(modalOpt))
|
||||
})),
|
||||
onClick(qs($page, `[data-action="rename"]`)).pipe(rxjs.tap(() => {
|
||||
componentRename(createModal(modalOpt));
|
||||
})),
|
||||
onClick(qs($page, `[data-action="delete"]`)).pipe(rxjs.tap(() => {
|
||||
componentDelete(createModal(modalOpt));
|
||||
})),
|
||||
)),
|
||||
rxjs.tap((action) => onMenuSelect(action)),
|
||||
));
|
||||
|
||||
// feature3: effect on scroll
|
||||
|
|
@ -100,11 +130,6 @@ export default async function(render) {
|
|||
? $scroll.classList.add("scrolling")
|
||||
: $scroll.classList.remove("scrolling")),
|
||||
));
|
||||
|
||||
}
|
||||
|
||||
function onMenuSelect(action) {
|
||||
console.log(`select "${action}"`);
|
||||
}
|
||||
|
||||
export function init() {
|
||||
|
|
|
|||
10
public/assets/pages/filespage/modal_delete.js
Normal file
10
public/assets/pages/filespage/modal_delete.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { createElement } from "../../lib/skeleton/index.js";
|
||||
|
||||
export default function(render) {
|
||||
const $modal = createElement(`
|
||||
<div>
|
||||
MODAL DELETE
|
||||
</div>
|
||||
`);
|
||||
render($modal);
|
||||
}
|
||||
10
public/assets/pages/filespage/modal_embed.js
Normal file
10
public/assets/pages/filespage/modal_embed.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { createElement } from "../../lib/skeleton/index.js";
|
||||
|
||||
export default function(render) {
|
||||
const $modal = createElement(`
|
||||
<div>
|
||||
EMBED CODE
|
||||
</div>
|
||||
`);
|
||||
render($modal);
|
||||
}
|
||||
10
public/assets/pages/filespage/modal_rename.js
Normal file
10
public/assets/pages/filespage/modal_rename.js
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
import { createElement } from "../../lib/skeleton/index.js";
|
||||
|
||||
export default function(render) {
|
||||
const $modal = createElement(`
|
||||
<div>
|
||||
RENAME CONFIRMATION SCREEN
|
||||
</div>
|
||||
`);
|
||||
render($modal);
|
||||
}
|
||||
12
public/assets/pages/filespage/modal_share.js
Normal file
12
public/assets/pages/filespage/modal_share.js
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { createElement } from "../../lib/skeleton/index.js";
|
||||
|
||||
export default function(render) {
|
||||
const $modal = createElement(`
|
||||
<div>
|
||||
MODAL SHARE
|
||||
</div>
|
||||
`);
|
||||
render($modal, ({ id }) => {
|
||||
if (id !== 1) return;
|
||||
});
|
||||
}
|
||||
13
public/assets/pages/filespage/modal_tag.js
Normal file
13
public/assets/pages/filespage/modal_tag.js
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import { createElement } from "../../lib/skeleton/index.js";
|
||||
|
||||
export default function(render) {
|
||||
const $modal = createElement(`
|
||||
<div>
|
||||
TAG MODAL
|
||||
</div>
|
||||
`);
|
||||
render($modal, ({ id }) => {
|
||||
console.log("QUIT", id)
|
||||
if (id !== 1) return;
|
||||
});
|
||||
}
|
||||
11
public/assets/pages/filespage/model_action.js
Normal file
11
public/assets/pages/filespage/model_action.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import rxjs from "../../lib/rx.js";
|
||||
|
||||
const action$ = new rxjs.Subject();
|
||||
|
||||
export function getAction$() {
|
||||
return action$.asObservable();
|
||||
}
|
||||
|
||||
export function setAction(actionTarget) {
|
||||
action$.next(actionTarget);
|
||||
}
|
||||
Loading…
Reference in a new issue