chore (migration): migrate viewerpage apps to new structure

This commit is contained in:
MickaelK
2023-12-15 02:28:31 +11:00
parent 7a2e861c46
commit c9b626b3d8
27 changed files with 26660 additions and 80 deletions
@@ -11,7 +11,7 @@ export default function(ctrl) {
<div data-bind="sidebar" class="hidden"></div>
<div style="width:100%;display: flex; flex-direction: column;">
<div is="component-breadcrumb" path="${urlToPath(history.state.previous)}"></div>
<div class="scroll-y" data-bind="filemanager-children"></div>
<div data-bind="filemanager-children"></div>
</div>
</div>
`);
+2 -38
View File
@@ -12,44 +12,8 @@
@import url("./designsystem_utils.css");
@import url("./designsystem_alert.css");
/* latin-ext */
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 400;
src: local("Source Code Pro"), local("SourceCodePro-Regular"), url(/assets/fonts/SourceCodePro-Regular-400-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 400;
src: local("Source Code Pro"), local("SourceCodePro-Regular"), url(/assets/fonts/SourceCodePro-Regular-400-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 600;
src: local("Source Code Pro Semibold"), local("SourceCodePro-Semibold"), url(/assets/fonts/SourceCodePro-Semibold-600-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 600;
src: local("Source Code Pro Semibold"), local("SourceCodePro-Semibold"), url(/assets/fonts/SourceCodePro-Semibold-600-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
:root {
--bg-color: #f8f9fa; /*#fafafa;*/
--bg-color: #f9f9fa; /*#fafafa;*/
--color: #57595A;
--emphasis: #466372;
--primary: #9AD1ED;
@@ -59,7 +23,7 @@
--super-light: #fafafa;
--error: #f26d6d;
--success: #63d9b1;
--dark: #313538;
--dark: #3b4045;
--border: rgba(198,200,204,0.3);
}
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
-2
View File
@@ -4,9 +4,7 @@
height: auto;
min-height: 100%;
width: 100%;
align-self: flex-start;
background: var(--bg-color);
padding-top: 20px;
box-sizing: border-box;
}
+1 -1
View File
@@ -12,7 +12,7 @@ import "../components/breadcrumb.js";
export default WithShell(function(render) {
const $page = createElement(`
<div class="component_page_filespage">
<div class="component_page_filespage scroll-y">
<div is="frequent_access" class="hidden"></div>
<div is="component_submenu"></div>
<div is="component_filesystem"></div>
+14 -2
View File
@@ -27,6 +27,16 @@ function loadModule(appName) {
return import("./viewerpage/application_image.js");
case "download":
return import("./viewerpage/application_downloader.js");
case "form":
return import("./viewerpage/application_form.js");
case "audio":
return import("./viewerpage/application_audio.js");
case "video":
return import("./viewerpage/application_video.js");
case "ebook":
return import("./viewerpage/application_ebook.js");
case "appframe":
return import("./viewerpage/application_iframe.js");
default:
throw new ApplicationError("Internal Error", `Unknown opener app "${appName}" at "${getCurrentPath()}"`);
}
@@ -38,10 +48,12 @@ export default WithShell(async function(render) {
effect(mime$.pipe(
rxjs.map((mimes) => opener(basename(getCurrentPath()), mimes)),
rxjs.mergeMap(([opener]) => loadModule(opener)),
rxjs.map((module) => module.default(createRender($page))),
rxjs.mergeMap(([opener, options]) => rxjs.from(loadModule(opener)).pipe(
rxjs.map((module) => module.default(createRender($page), options)),
)),
rxjs.catchError(ctrlError()),
));
})
export async function init() {
@@ -1,4 +1,5 @@
[is="component_submenu"] {
margin-top: 20px;
position: sticky;
top: 0;
z-index: 3;
@@ -55,6 +56,9 @@
color: var(--light);
font-weight: bold;
}
.dark-mode .scrolling [is="component_submenu"] {
background: var(--bg-color);
}
@@ -0,0 +1,124 @@
body:not(.dark-mode) .component_audioplayer > .audioplayer_container {
background: #525659;
}
.component_audioplayer {
display: flex;
flex-direction: column;
flex: 1;
width: 100%;
}
.component_audioplayer > .audioplayer_container {
display: flex;
flex-direction: column;
flex: 1;
width: 100%;
text-align: center;
height: 100%;
overflow: hidden;
padding: 20px;
box-sizing: border-box;
}
.component_audioplayer > .audioplayer_container .audioplayer_error {
color: white;
margin-top: 30px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box {
background: #f1f1f1;
box-shadow: rgba(0, 0, 0, 0.14) 0px 4px 5px 0px, rgba(0, 0, 0, 0.12) 0px 1px 10px 0px, rgba(0, 0, 0, 0.2) 0px 2px 4px -1px;
position: relative;
border-radius: 3px;
padding: 10px 0 30px 0;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control {
padding-top: 20px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control img {
height: 25px;
width: 25px;
cursor: pointer;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .buttons {
float: left;
padding-left: 15px;
margin-top: -10px;
display: flex;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .buttons > span {
margin-right: 10px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .buttons input[type="range"] {
margin-left: -5px;
width: 60px;
cursor: pointer;
outline: none;
-webkit-appearance: none;
background: transparent;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .buttons input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 12px;
width: 12px;
border: none;
border-radius: 50%;
background: #6f6f6f;
margin-top: -5px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .buttons input[type="range"]::-moz-range-thumb {
-webkit-appearance: none;
height: 12px;
width: 12px;
border: none;
border-radius: 50%;
background: #6f6f6f;
margin-top: -5px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .buttons input[type="range"]::-webkit-slider-runnable-track {
width: 100%;
height: 2px;
background-color: #6f6f6f;
border-radius: 2px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .buttons input[type="range"]::-moz-range-track {
width: 100%;
height: 2px;
background-color: #6f6f6f;
border-radius: 2px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .timecode {
float: right;
padding-right: 25px;
margin-top: -5px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .timecode #separator {
padding: 0 5px;
}
@media screen and (max-width: 450px) {
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .timecode #separator, .component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_control .timecode #currentTime {
display: none;
}
}
.component_audioplayer > .audioplayer_container .audioplayer_box .audioplayer_loader {
height: 260px;
background: var(--color);
position: absolute;
opacity: 0.1;
top: 0;
left: 0;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .component_icon[alt="loading"] {
position: absolute;
margin: 50px 0px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .chromecast_loader .component_icon[alt="loading"] {
margin: 0;
right: 20px;
top: 20px;
width: 30px;
}
.component_audioplayer > .audioplayer_container .audioplayer_box .percent {
position: absolute;
margin: 100px 0px;
width: 120px;
font-size: 1.4rem;
}
@@ -0,0 +1,28 @@
import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect } from "../lib/rx.js";
import WaveSurfer from "../../lib/vendor/wavesurfer.js";
export default function(render) {
const $page = createElement(`
<div class="component_formviewer">
<component-menubar></component-menubar>
<div id="waveform">
AUDIO
</div>
</div>
`);
render($page);
const wavesurfer = WaveSurfer.create({
container: "#waveform",
interact: false,
waveColor: "#323639",
progressColor: "#808080",
cursorColor: "#6f6f6f",
cursorWidth: 3,
height: 200,
barWidth: 1,
});
// onDestroy(() => wavesurfer.destroy());
}
@@ -1,6 +1,45 @@
/* latin-ext */
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 400;
src: local("Source Code Pro"), local("SourceCodePro-Regular"), url(/assets/fonts/SourceCodePro-Regular-400-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 400;
src: local("Source Code Pro"), local("SourceCodePro-Regular"), url(/assets/fonts/SourceCodePro-Regular-400-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* latin-ext */
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 600;
src: local("Source Code Pro Semibold"), local("SourceCodePro-Semibold"), url(/assets/fonts/SourceCodePro-Semibold-600-latin-ext.woff2) format("woff2");
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
/* latin */
@font-face {
font-family: "Source Code Pro";
font-style: normal;
font-weight: 600;
src: local("Source Code Pro Semibold"), local("SourceCodePro-Semibold"), url(/assets/fonts/SourceCodePro-Semibold-600-latin.woff2) format("woff2");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
.CodeMirror {
width: 100%;
height: 100%;
color: #3b4045;
background: var(--bg-color);
font-size: 16px;
font-family: "Source Code Pro", monospace;
}
.CodeMirror-scroll { -webkit-overflow-scrolling: touch; }
@@ -1,26 +1,76 @@
import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect } from "../../lib/rx.js";
import { qs } from "../../lib/dom.js";
import { createLoader } from "../../components/loader.js";
import { loadCSS, loadJS } from "../../helpers/loader.js";
import ajax from "../../lib/ajax.js";
import ctrlError from "../ctrl_error.js";
import ctrlDownloader, { init as initDownloader } from "./application_downloader.js";
import { transition, getDownloadUrl } from "./common.js";
import "../../components/menubar.js";
const TIME_BEFORE_ABORT_EDIT = 5000;
export default async function(render) {
const $page = createElement(`<div></div>`);
const $page = createElement(`
<div class="component_ide">
<component-menubar class="hidden"></component-menubar>
<div class="component_editor scroll-y"></div>
</div>
`);
render($page);
const editor = window.CodeMirror($page, {
value: "Hello WOrld",
lineNumbers: true,
// mode: mode,
// keyMap: ["emacs", "vim"].indexOf(CONFIG["editor"]) === -1 ?
// "sublime" : CONFIG["editor"],
lineWrapping: true,
// readOnly: !this.props.readonly,
foldOptions: {
widget: "...",
},
matchBrackets: {},
autoCloseBrackets: true,
matchTags: { bothTags: true },
autoCloseTags: true,
});
const content$ = ajax(getDownloadUrl()).pipe(
rxjs.map(({ response }) => response),
rxjs.shareReplay(),
);
const removeLoader = createLoader($page);
effect(rxjs.race(
ajax(getDownloadUrl()).pipe(rxjs.map(({ response }) => response)),
ajax("/about").pipe(rxjs.delay(TIME_BEFORE_ABORT_EDIT), rxjs.map(() => null)),
).pipe(
rxjs.mergeMap((content) => {
if (content === null || has_binary(content)) {
return rxjs.from(initDownloader()).pipe(
removeLoader,
rxjs.mergeMap(() => {
ctrlDownloader(render);
return rxjs.EMPTY;
}),
);
}
return rxjs.of(content);
}),
removeLoader,
rxjs.tap((content) => {
window.CodeMirror(qs($page, ".component_editor"), {
value: content,
lineNumbers: true,
// mode: mode,
// keyMap: ["emacs", "vim"].indexOf(CONFIG["editor"]) === -1 ?
// "sublime" : CONFIG["editor"],
lineWrapping: true,
// readOnly: !this.props.readonly,
foldOptions: {
widget: "...",
},
matchBrackets: {},
autoCloseBrackets: true,
matchTags: { bothTags: true },
autoCloseTags: true,
});
transition(qs($page, ".component_editor"));
qs($page, "component-menubar").classList.remove("hidden");
}),
rxjs.catchError(ctrlError()),
))
}
function has_binary(str) {
return /\ufffd/.test(str);
}
export function init() {
@@ -1,11 +1,10 @@
import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect } from "../../lib/rx.js";
import { transition, slideYIn } from "../../lib/animate.js";
import { qs } from "../../lib/dom.js";
import { loadCSS } from "../../helpers/loader.js";
import t from "../../lib/locales.js";
import { getFilename, getDownloadUrl } from "./common.js";
import { transition, getFilename, getDownloadUrl } from "./common.js";
import "../../components/icon.js";
@@ -18,7 +17,7 @@ export default async function(render) {
</div>
</div>
`);
render(transition($page, { timeEnter: 100, enter: slideYIn(2) }));
render(transition($page));
const $link = qs($page, "a");
const $loading = qs($page, "component-icon");
@@ -0,0 +1,13 @@
import { createElement } from "../../lib/skeleton/index.js";
export default function(render) {
const $page = createElement(`
<div class="component_formviewer">
<component-menubar></component-menubar>
<div>
EBOOK
</div>
</div>
`);
render($page);
}
@@ -0,0 +1,71 @@
body:not(.dark-mode) .component_formviewer {
}
.component_formviewer {
background: #525659;
display: flex;
flex-direction: column;
flex: 1;
width: 100%;
color: var(--color);
}
.component_formviewer > .formviewer_container {
padding-top: 20px;
padding-bottom: 50px;
overflow-y: auto;
flex-direction: column;
flex: 1;
width: 100%;
}
.component_formviewer > .formviewer_container .box {
padding: 25px 20px;
box-sizing: border-box;
border-radius: 2px;
background: #fff;
box-shadow: rgba(0,0,0,.14) 0px 4px 5px 0px, rgba(0,0,0,.12) 0px 1px 10px 0px, rgba(0,0,0,.2) 0px 2px 4px -1px;
width: 98%;
max-width: 800px;
margin: 0 auto;
}
.component_formviewer > .formviewer_container .box .formbuilder {
margin-bottom: 10px;
}
.component_formviewer > .formviewer_container .box .formbuilder label.no-select > div {
display: flex;
line-height: 30px;
}
.component_formviewer > .formviewer_container .box .formbuilder label.no-select > div > div {
width: 100%;
}
@media screen and (max-width: 470px) {
.component_formviewer > .formviewer_container .box .formbuilder label.no-select > div {
display: block;
line-height: inherit;
}
.component_formviewer > .formviewer_container .box .formbuilder label.no-select > div span.nothing {
position: absolute;
}
}
.component_formviewer > .formviewer_container .box .formbuilder label.no-select > div > span {
display: inline-block;
width: 160px;
max-width: 160px;
text-align: right;
padding-right: 15px;
color: var(--dark);
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
@media screen and (max-width: 470px) {
.component_formviewer > .formviewer_container .box .formbuilder label.no-select > div > span {
text-align: left;
font-weight: bold;
}
}
.component_formviewer > .formviewer_container .box .formbuilder label.no-select > div > span span.mandatory {
opacity: 0.6;
}
.component_formviewer > .formviewer_container .box .formbuilder label.no-select > div div.description a {
border-bottom: 1px dashed var(--color);
}
@@ -0,0 +1,64 @@
import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect, applyMutation } from "../../lib/rx.js";
import { qs, qsa } from "../../lib/dom.js";
import { loadCSS } from "../../helpers/loader.js";
import { createForm, mutateForm } from "../../lib/form.js";
import { formTmpl } from "../../components/form.js";
import ajax from "../../lib/ajax.js";
import ctrlError from "../ctrl_error.js";
import { transition, getDownloadUrl } from "./common.js";
import "../../components/menubar.js";
export default function(render) {
const $page = createElement(`
<div class="component_formviewer">
<component-menubar></component-menubar>
<div class="formviewer_container">
<form class="sticky box">
</form>
</div>
</div>
`);
render($page);
transition(qs($page, ".formviewer_container"));
const spec$ = ajax(getDownloadUrl()).pipe(
rxjs.map(({ response }) => JSON.parse(response)),
rxjs.share(),
);
const setup$ = spec$.pipe(
rxjs.mergeMap((formSpec) => createForm(formSpec, formTmpl({
renderLeaf: ({ label = "", format = (s) => s, description = "", required = false }) => {
const mandatory = required ? `<span class="mandatory">*</span>` : "";
return createElement(`
<label class="no-select">
<div>
<span> ${format(label)} ${mandatory} </span>
<div data-bind="children"></div>
</div>
<div>
<span class="nothing"></span>
<div class="description">${description}</div>
</div>
</label>
`);
},
}))),
applyMutation(qs($page, "form"), "replaceChildren"),
rxjs.catchError(ctrlError()),
rxjs.share(),
);
effect(setup$);
effect(setup$.pipe(
rxjs.mergeMap(() => qsa($page, "form [name]")),
rxjs.mergeMap(($el) => rxjs.fromEvent($el, "input")),
rxjs.tap(() => console.log("SETUP SAVE BUTTON")),
));
}
export function init() {
return loadCSS(import.meta.url, "./application_form.css");
}
@@ -0,0 +1,14 @@
import { createElement } from "../../lib/skeleton/index.js";
export default function(render, opts) {
console.log("OPTIONS", opts);
const $page = createElement(`
<div class="component_formviewer">
<component-menubar></component-menubar>
<div>
IFRAME
</div>
</div>
`);
render($page);
}
@@ -1,16 +1,36 @@
import { createElement } from "../../lib/skeleton/index.js";
import { createElement, createRender } from "../../lib/skeleton/index.js";
import { loadCSS } from "../../helpers/loader.js";
import { qs } from "../../lib/dom.js";
import { getDownloadUrl } from "./common.js";
import componentMetadata from "./application_image_metadata.js";
import componentPager, { init as initPager} from "./component_pager.js";
import "../../components/menubar.js";
export default function(render) {
const $page = createElement(`
<div class="component_imageviewer">
<component-menubar></component-menubar>
<div class="component_image_container">IMAGE</div>
<div class="component_image_container">
<div class="images_wrapper">
<img class="photo idle" draggable="true" srcset="${getDownloadUrl()}">
</div>
<div class="images_aside scroll-y"></div>
<div class="component_pager"></div>
</div>
</div>
`);
render($page);
componentMetadata(createRender(qs($page, ".images_aside")));
componentPager(createRender(qs($page, ".component_pager")));
}
export function init() {
return loadCSS(import.meta.url, "./application_image.css");
return Promise.all([
loadCSS(import.meta.url, "./application_image.css"),
initPager(), // initMetadata(),
])
}
@@ -0,0 +1,14 @@
import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect } from "../../lib/rx.js";
export default function(render) {
const $component = createElement(`
<div class="header"><div>Info</div><div style="flex: 1 1 0%;"><img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MS45NzYgNTEuOTc2Ij4KICA8cGF0aCBzdHlsZT0iZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eTowLjUzMzMzMjg1O3N0cm9rZS13aWR0aDoxLjQ1NjgxMTE5IiBkPSJtIDQxLjAwNTMxLDQwLjg0NDA2MiBjIC0xLjEzNzc2OCwxLjEzNzc2NSAtMi45ODIwODgsMS4xMzc3NjUgLTQuMTE5ODYxLDAgTCAyNi4wNjg2MjgsMzAuMDI3MjM0IDE0LjczNzU1MSw0MS4zNTgzMSBjIC0xLjEzNzc3MSwxLjEzNzc3MSAtMi45ODIwOTMsMS4xMzc3NzEgLTQuMTE5ODYxLDAgLTEuMTM3NzcyMiwtMS4xMzc3NjggLTEuMTM3NzcyMiwtMi45ODIwODggMCwtNC4xMTk4NjEgTCAyMS45NDg3NjYsMjUuOTA3MzcyIDExLjEzMTkzOCwxNS4wOTA1NTEgYyAtMS4xMzc3NjQ3LC0xLjEzNzc3MSAtMS4xMzc3NjQ3LC0yLjk4MzU1MyAwLC00LjExOTg2MSAxLjEzNzc3NCwtMS4xMzc3NzIxIDIuOTgyMDk4LC0xLjEzNzc3MjEgNC4xMTk4NjUsMCBMIDI2LjA2ODYyOCwyMS43ODc1MTIgMzYuMzY5NzM5LDExLjQ4NjM5OSBjIDEuMTM3NzY4LC0xLjEzNzc2OCAyLjk4MjA5MywtMS4xMzc3NjggNC4xMTk4NjIsMCAxLjEzNzc2NywxLjEzNzc2OSAxLjEzNzc2NywyLjk4MjA5NCAwLDQuMTE5ODYyIEwgMzAuMTg4NDg5LDI1LjkwNzM3MiA0MS4wMDUzMSwzNi43MjQxOTcgYyAxLjEzNzc3MSwxLjEzNzc2NyAxLjEzNzc3MSwyLjk4MjA5MSAwLDQuMTE5ODY1IHoiIC8+Cjwvc3ZnPgo=" alt="close"></div></div><div class="content"><div><div class="content_box"><img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA0NDggNTEyIj4KICA8cGF0aCBzdHlsZT0iZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eTowLjIiIGQ9Ik0gNDAwLDY0IEggMzUyIFYgMTIgQyAzNTIsNS40IDM0Ni42LDAgMzQwLDAgaCAtNDAgYyAtNi42LDAgLTEyLDUuNCAtMTIsMTIgViA2NCBIIDE2MCBWIDEyIEMgMTYwLDUuNCAxNTQuNiwwIDE0OCwwIEggMTA4IEMgMTAxLjQsMCA5Niw1LjQgOTYsMTIgViA2NCBIIDQ4IEMgMjEuNSw2NCAwLDg1LjUgMCwxMTIgdiAzNTIgYyAwLDI2LjUgMjEuNSw0OCA0OCw0OCBoIDM1MiBjIDI2LjUsMCA0OCwtMjEuNSA0OCwtNDggViAxMTIgQyA0NDgsODUuNSA0MjYuNSw2NCA0MDAsNjQgWiBtIC0yLDQwNCBIIDUwIGMgLTMuMywwIC02LjAyMjE0NywtMi43MDAwNyAtNiwtNiBWIDE1NCBoIDM2MCB2IDMwOCBjIDAsMy4zIC0yLjcsNiAtNiw2IHoiIC8+Cjwvc3ZnPgo=" alt="schedule"><div class="headline"><span><span class="">-</span></span></div><div class="description"><span><span class="">-</span></span></div></div><div class="content_box"><img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCA1MTIgNTEyIj4KICA8cGF0aCBzdHlsZT0iZmlsbDojMDAwMDAwO2ZpbGwtb3BhY2l0eTowLjIiIGQ9Ik01MTIgMTQ0djI4OGMwIDI2LjUtMjEuNSA0OC00OCA0OEg0OGMtMjYuNSAwLTQ4LTIxLjUtNDgtNDhWMTQ0YzAtMjYuNSAyMS41LTQ4IDQ4LTQ4aDg4bDEyLjMtMzIuOWM3LTE4LjcgMjQuOS0zMS4xIDQ0LjktMzEuMWgxMjUuNWMyMCAwIDM3LjkgMTIuNCA0NC45IDMxLjFMMzc2IDk2aDg4YzI2LjUgMCA0OCAyMS41IDQ4IDQ4ek0zNzYgMjg4YzAtNjYuMi01My44LTEyMC0xMjAtMTIwcy0xMjAgNTMuOC0xMjAgMTIwIDUzLjggMTIwIDEyMCAxMjAgMTIwLTUzLjggMTIwLTEyMHptLTMyIDBjMCA0OC41LTM5LjUgODgtODggODhzLTg4LTM5LjUtODgtODggMzkuNS04OCA4OC04OCA4OCAzOS41IDg4IDg4eiIgLz4KPC9zdmc+Cg==" alt="camera"><div class="headline"><span><span class="">-</span></span></div><div class="description"><span><span class="">-</span></span></div></div><span></span></div></div>
`);
render($component);
effect(rxjs.fromEvent(document, "keypress").pipe(
rxjs.filter((e) => e.key === "i"),
rxjs.tap(() => $component.parentElement.classList.toggle("open")),
));
}
@@ -39,8 +39,10 @@ function ctrlPDFNative(render) {
removeLoader,
rxjs.tap(($embed) => $embed.classList.remove("hidden")),
rxjs.tap(($embed) => animate($embed, { time: 200, keyframes: opacityIn() })),
rxjs.catchError(ctrlError(render)),
rxjs.catchError(ctrlError),
));
}
async function ctrlPDFJs(render) {
@@ -80,7 +82,7 @@ async function ctrlPDFJs(render) {
}
createBr();
}),
rxjs.catchError(ctrlError(render)),
rxjs.catchError(ctrlError),
));
}
@@ -0,0 +1,189 @@
body:not(.dark-mode) .component_videoplayer {
background: #525659;
}
.component_videoplayer {
display: flex;
flex: 1;
flex-direction: column;
width: 100%;
}
.component_videoplayer .video_container {
display: flex;
flex: 1;
text-align: center;
overflow: hidden;
padding: 15px 10px 65px 10px;
height: 100%;
box-sizing: border-box;
}
.component_videoplayer .video_container > span {
display: flex;
flex: 1;
text-align: center;
overflow: hidden;
height: 100%;
box-sizing: border-box;
}
.component_videoplayer .video_container .video_screen {
background: black;
box-shadow: rgba(0, 0, 0, 0.14) 0px 4px 5px 0px, rgba(0, 0, 0, 0.12) 0px 1px 10px 0px, rgba(0, 0, 0, 0.2) 0px 2px 4px -1px;
position: relative;
border-radius: 3px;
margin: auto;
position: relative;
width: 800px;
}
.component_videoplayer .video_container .video_screen .video_wrapper {
height: 450px;
}
.component_videoplayer .video_container .video_screen .loader {
position: absolute;
top: 30%;
width: 100%;
}
.component_videoplayer .video_container .video_screen.is-casting-yes .videoplayer_control, .component_videoplayer .video_container .video_screen.video-state-pause .videoplayer_control, .component_videoplayer .video_container .video_screen.video-state-buffer .videoplayer_control, .component_videoplayer .video_container .video_screen.video-state-play:hover .videoplayer_control {
opacity: 1;
transition: 0.1s opacity ease;
}
.component_videoplayer .video_container .video_screen .videoplayer_control {
transition: 0.5s opacity ease;
opacity: 0;
display: flex;
text-align: left;
position: absolute;
bottom: 0;
width: 100%;
border-bottom-left-radius: 3px;
border-bottom-right-radius: 3px;
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADCCAYAAACIaaiTAAAAAXNSR0IArs4c6QAAARJJREFUOE9lyNdHBQAAhfHb3nvvuu2997jNe29TJJEkkkgSSSSJJJJEEkkiifRH5jsP56Xz8PM5gcC/xfCIWBNHiXiTQIlEk0SJZJNCiVRIM+mUyDCZlMgy2ZTIMbmUyDP5lCgwhZQoMsWUKDGllCgz5ZSogEpTRYlqU0OJoKmlRJ2pp0SDaaREk2mmRItppUSbaadEh+mkRBd0mx5K9Jo+SvSbAUoMmiFKDJsRSoyaMUqMmwlKhMwkJabMNCVmYNbMUSJsIpSImnlKLJhFSiyZZWoFVmEN1mEDNmELtmEHdmEP9uEADuEIjuEETuEMzuECLuEKruEGbuEO7uEBHuEJnuEFXuEN3uEDPuELvuEHfv8AoRErEi7Uc8UAAAAASUVORK5CYII=);
background-repeat: repeat-x;
background-size: contain;
padding: 0 0 7px 0;
}
.component_videoplayer .video_container .video_screen .videoplayer_control img {
cursor: pointer;
width: 25px;
filter: brightness(0) invert(1);
padding: 5px 5px 5px 10px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control input[type="range"] {
width: 60px;
cursor: pointer;
outline: none;
-webkit-appearance: none;
background: transparent;
}
.component_videoplayer .video_container .video_screen .videoplayer_control input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
height: 12px;
width: 12px;
border: none;
border-radius: 50%;
background: white;
margin-top: -5px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control input[type="range"]::-moz-range-thumb {
-webkit-appearance: none;
height: 12px;
width: 12px;
border: none;
border-radius: 50%;
background: white;
margin-top: -5px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control input[type="range"]::-webkit-slider-runnable-track {
width: 100%;
height: 2px;
background-color: rgba(255, 255, 255, 0.7);
border-radius: 2px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control input[type="range"]::-moz-range-track {
width: 100%;
height: 2px;
background-color: rgba(255, 255, 255, 0.7);
border-radius: 2px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control .timecode {
color: white;
margin: auto 0;
padding-left: 10px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control .timecode .hint {
position: absolute;
top: -40px;
margin-left: -23px;
font-size: 0.9rem;
background: #f1f1f155;
border-radius: 3px;
padding: 2px 5px;
background: var(--dark);
}
.component_videoplayer .video_container .video_screen .videoplayer_control .progress {
position: absolute;
width: 100%;
top: -20px;
height: 20px;
cursor: pointer;
}
.component_videoplayer .video_container .video_screen .videoplayer_control .progress .progress-active, .component_videoplayer .video_container .video_screen .videoplayer_control .progress .progress-buffer, .component_videoplayer .video_container .video_screen .videoplayer_control .progress .progress-placeholder {
top: 10px;
position: absolute;
height: 4px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control .progress .progress-active {
background: var(--primary);
border-top-right-radius: 2px;
border-bottom-right-radius: 2px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control .progress .progress-active .thumb {
display: none;
float: right;
width: 4px;
height: 4px;
background: rgba(255, 255, 255, 0.1);
border-radius: 50%;
margin-top: 0px;
position: relative;
left: 3px;
}
.component_videoplayer .video_container .video_screen .videoplayer_control .progress .progress-buffer {
background: #e2e2e244;
}
.component_videoplayer .video_container .video_screen .videoplayer_control .progress .progress-placeholder {
background: #e2e2e222;
width: 100%;
}
.component_videoplayer .video_container video {
width: 100%;
height: 100%;
}
.component_videoplayer .video_container .video_screen .videoplayer_control:hover .progress .progress-active .thumb {
display: block;
}
.video-enter, .video-appear {
opacity: 0;
}
.video-enter.video-enter-active, .video-appear.video-appear-active {
transition: top .3s,right .3s,bottom .3s,left .3s,max-width .3s,max-height .3s;
-webkit-animation-name: zoomIn;
animation-name: zoomIn;
animation-duration: .3s;
-webkit-animation-timing-function: cubic-bezier(0.51, 0.92, 0.24, 1.15);
animation-timing-function: cubic-bezier(0.51, 0.92, 0.24, 1.15);
opacity: 1;
}
@keyframes zoomIn {
0% {
opacity: 0;
transform: scale(0.85);
}
100% {
opacity: 1;
transform: scale(1);
}
}
@@ -0,0 +1,98 @@
import { createElement } from "../../lib/skeleton/index.js";
import rxjs, { effect } from "../../lib/rx.js";
import { loadCSS } from "../../helpers/loader.js";
import { qs } from "../../lib/dom.js";
import Hls from "../../lib/vendor/hlsjs/hls.js";
import ctrlError from "../ctrl_error.js";
import { getDownloadUrl } from "./common.js";
import "../../components/menubar.js";
export default function(render, { mime }) {
if (!Hls.isSupported()) {
ctrlError()(new Error("browser not supporting hls"));
return;
}
const $page = createElement(`
<div class="component_videoplayer">
<component-menubar></component-menubar>
<div class="video_container">
<span>
<div class="video_screen video-state-pause is-casting-no">
<div class="video_wrapper" style="max-height: 819px;">
<video></video>
</div>
<div class="videoplayer_control no-select">
<div class="progress">
<div class="progress-buffer" style="left: 0.0155149%; width: 4.58182%;"></div>
<div class="progress-active" style="width: 0%;">
<div class="thumb"></div>
</div>
<div class="progress-placeholder"></div>
</div>
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzZmNmY2ZiIgc3Ryb2tlLXdpZHRoPSIyLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CiAgPHBhdGggZD0iTSA4LjkyODE3MjQsMi41OTk4MDI5IEMgOC4yMjE2MTQ5LDIuMTUzMjg3MyA3LjA3MjExNDMsMi4zOTIwOTE4IDcuMDcxODI3NywzLjQwMDE5NzEgbCAtMC4wMDQ4OSwxNy4yMDUwNDU5IGMgLTIuODg5ZS00LDEuMDE1NzE1IDEuMjEyMTk3OSwxLjE2MDM3MiAxLjg2NjEzMDcsMC43ODk1MTMgQyAyMy45NzU3NCw4LjcyODk4NTYgMjMuOTMwMTUyLDE0LjEwNDQ2MyA4LjkyODE1ODQsMi41OTk4MDI5IFoiIC8+Cjwvc3ZnPgo=" alt="play">
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgMjQgMjQiIGZpbGw9Im5vbmUiIHN0cm9rZT0iIzZmNmY2ZiIgc3Ryb2tlLXdpZHRoPSIyIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPgogIDxwYXRoIGQ9Im0gMTYuMzUwMjI1LDguMTkzNzg3IGMgMS40NDk2MjYsMS45MzM1NTkgMS40NDk2MjYsNS42Nzg4ODQgMCw3LjYxMjQ0NiIgLz4KICA8cGF0aCBkPSJNIDEuMTI1MzM1NiwxNS4yMTc4OTcgViA4Ljc4MTAzMjggYyAwLC0wLjYyNDIyMDUgMC40ODcxOTY3LC0xLjEzMDk5MTcgMS4wODc0OTIzLC0xLjEzMDk5MTcgSCA2LjExMjU3NDggQSAxLjA2NTc0MjIsMS4wNjU3NDIyIDAgMCAwIDYuODgxNDMxOCw3LjMxODM1NjIgTCAxMC4xNDM5MDksMy42MzM5MzI4IGMgMC42ODUxMiwtMC43MTMzOTUgMS44NTYzNDUsLTAuMjA3NzExMSAxLjg1NjM0NSwwLjgwMDM5NDIgdiAxNS4xMzEzNjggYyAwLDEuMDE1NzE1IC0xLjE4NTM2MiwxLjUxNzA0NSAtMS44NjYxMzEsMC43ODk1MTMgTCA2Ljg4MjUxOSwxNi42OTE0NSBBIDEuMDY1NzQyMiwxLjA2NTc0MjIgMCAwIDAgNi4xMDM4NzQ4LDE2LjM0OTk3NSBIIDIuMjEyODI3OSBjIC0wLjYwMDI5NTYsMCAtMS4wODc0OTIzLC0wLjUwNjc2OCAtMS4wODc0OTIzLC0xLjEzMjA3OCB6IiAvPgo8L3N2Zz4K" alt="volume_low">
<input type="range" min="0" max="100" value="13">
<span class="timecode">00:00&nbsp; / &nbsp;02:17</span>
</div>
</div>
</span>
<div class="component_pager">
<div class="wrapper no-select">
<span>
<a href="/view/Videos/Animation Movie.webm">
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPHBhdGggc3R5bGU9ImZpbGw6I2YyZjJmMjtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MS41MTE4MTEwMjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIgZD0ibSAxNiw3LjE2IC00LjU4LDQuNTkgNC41OCw0LjU5IC0xLjQxLDEuNDEgLTYsLTYgNiwtNiB6IiAvPgogIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0wLS4yNWgyNHYyNEgweiIgLz4KPC9zdmc+Cg==" alt="arrow_left_white">
</a>
<label class="pager">
<form>
<input class="prevent" type="number" value="1" style="width: 12px;">
</form>
<span class="separator">/</span>
<span>3</span>
</label>
<a href="/view/Videos/Animation Movie 2.webm">
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPHBhdGggc3R5bGU9ImZpbGw6I2YyZjJmMjtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MS41MTE4MTEwMjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIgZD0iTTguNTkgMTYuMzRsNC41OC00LjU5LTQuNTgtNC41OUwxMCA1Ljc1bDYgNi02IDZ6IiAvPgogIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0wLS4yNWgyNHYyNEgweiIgLz4KPC9zdmc+Cg==" alt="arrow_right_white">
</a>
</span>
</div>
</div>
</div>
</div>
`);
render($page);
const $video = qs($page, "video");
const hls = new Hls();
hls.loadSource(getDownloadUrl(), mime);
hls.attachMedia($video);
hls.on(Hls.Events.MEDIA_ATTACHED, function () {
console.log('video and hls.js are now bound together !');
});
hls.on(Hls.Events.MANIFEST_PARSED, function (event, data) {
console.log(
'manifest loaded, found ' + data.levels.length + ' quality level',
);
});
effect(rxjs.fromEvent($video, "loadeddata").pipe())
effect(rxjs.fromEvent($video, "ended").pipe())
effect(rxjs.merge(
// rxjs.from(qsa($page, "source")).pipe(rxjs.mergeMap(
// ))
rxjs.fromEvent($video, "error")
).pipe());
effect(rxjs.fromEvent($video, "waiting").pipe());
effect(rxjs.fromEvent($video, "playing").pipe());
effect(rxjs.fromEvent(document.body, "keypress").pipe(
));
}
export function init() {
return Promise.all([
loadCSS(import.meta.url, "./application_video.css"),
loadCSS(import.meta.url, "./component_pager.css"),
]);
}
+5
View File
@@ -1,5 +1,10 @@
import { transition as transitionLib, slideYIn } from "../../lib/animate.js";
import { basename } from "../../lib/path.js";
export function transition($node) {
return transitionLib($node, { timeEnter: 150, enter: slideYIn(2) });
}
export function getFilename() {
return basename(getCurrentPath()) || "untitled.dat";
}
@@ -0,0 +1,46 @@
.component_pager {
position: fixed;
bottom: 0px;
left: 0;
right: 0;
z-index: 2;
}
.component_pager .wrapper {
text-align: center;
color: var(--super-light);
margin: 0 auto;
padding: 15px 0;
text-shadow: 0px 0px 2px var(--dark);
}
.component_pager .wrapper > span {
display: inline-block;
background: var(--dark);
padding: 5px 10px;
border-radius: 5px;
box-shadow: rgba(0, 0, 0, 0.14) 0px 4px 5px 0px, rgba(0, 0, 0, 0.12) 0px 1px 10px 0px, rgba(0, 0, 0, 0.2) 0px 2px 4px -1px;
}
.component_pager .wrapper > span .pager {
line-height: 22px;
}
.component_pager .wrapper > span .pager .separator {
padding: 0 5px;
}
.component_pager .wrapper > span .component_icon {
width: 24px;
}
.component_pager .wrapper > span form {
display: inline-block;
}
.component_pager .wrapper > span form input[type="number"] {
padding: 0;
text-align: right;
background: inherit;
border: none;
color: inherit;
font-size: inherit;
-moz-appearance: textfield;
}
.component_pager .wrapper > span form input[type="number"]::-webkit-inner-spin-button, .component_pager .wrapper > span form input[type="number"]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
@@ -0,0 +1,28 @@
import { createElement } from "../../lib/skeleton/index.js";
import { loadCSS } from "../../helpers/loader.js";
export default function(render) {
render(createElement(`
<div class="wrapper no-select">
<span>
<a href="/view/Documents/assets/background.png">
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPHBhdGggc3R5bGU9ImZpbGw6I2YyZjJmMjtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MS41MTE4MTEwMjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIgZD0ibSAxNiw3LjE2IC00LjU4LDQuNTkgNC41OCw0LjU5IC0xLjQxLDEuNDEgLTYsLTYgNiwtNiB6IiAvPgogIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0wLS4yNWgyNHYyNEgweiIgLz4KPC9zdmc+Cg==" alt="arrow_left_white">
</a>
<label class="pager">
<form>
<input class="prevent" type="number" value="2" style="width: 12px;">
</form>
<span class="separator">/</span>
<span>2</span>
</label>
<a href="/view/Documents/assets/background.png">
<img class="component_icon" draggable="false" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCI+CiAgPHBhdGggc3R5bGU9ImZpbGw6I2YyZjJmMjtmaWxsLW9wYWNpdHk6MTtzdHJva2Utd2lkdGg6MS41MTE4MTEwMjtzdHJva2UtbWl0ZXJsaW1pdDo0O3N0cm9rZS1kYXNoYXJyYXk6bm9uZSIgZD0iTTguNTkgMTYuMzRsNC41OC00LjU5LTQuNTgtNC41OUwxMCA1Ljc1bDYgNi02IDZ6IiAvPgogIDxwYXRoIGZpbGw9Im5vbmUiIGQ9Ik0wLS4yNWgyNHYyNEgweiIgLz4KPC9zdmc+Cg==" alt="arrow_right_white">
</a>
</span>
</div>
`));
}
export function init() {
return loadCSS(import.meta.url, "./component_pager.css");
}
+9 -10
View File
@@ -12,25 +12,24 @@ export function opener(file = "", mimes) {
if (type === "text") {
return ["editor", null];
} else if (mime === "application/pdf") {
return ["pdf", null];
return ["pdf", { mime }];
} else if (type === "image") {
return ["image", null];
return ["image", { mime }];
} else if (["application/javascript", "application/xml", "application/json",
"application/x-perl"].indexOf(mime) !== -1) {
return ["editor", null];
return ["editor", { mime }];
} else if (["audio/wave", "audio/mp3", "audio/flac", "audio/ogg"].indexOf(mime) !== -1) {
return ["audio", null];
return ["audio", { mime }];
} else if (mime === "application/x-form") {
return ["form", null];
return ["form", { mime }];
} else if (type === "video" || mime === "application/ogg") {
return ["video", null];
return ["video", { mime }];
} else if(["application/epub+zip"].indexOf(mime) !== -1) {
return ["ebook", null];
return ["ebook", { mime }];
} else if (type === "application") {
return ["download", null];
return ["download", { mime }];
}
return ["editor", null];
return ["editor", { mime }];
}
function getMimeType(file, mimes = {}) {