diff --git a/public/assets/pages/ctrl_viewerpage.js b/public/assets/pages/ctrl_viewerpage.js index 16fc2faf..307efb91 100644 --- a/public/assets/pages/ctrl_viewerpage.js +++ b/public/assets/pages/ctrl_viewerpage.js @@ -50,6 +50,16 @@ function loadModule(appName) { throw new ApplicationError("Internal Error", `Unknown opener app "${appName}" at "${getCurrentPath()}"`); } }; +const loadModuleWithMemory = (function() { + const memory = {}; + return function(appName) { + if (memory[appName]) return Promise.resolve(memory[appName]); + return loadModule(appName).then((module) => { + memory[appName] = module; + return module; + }); + }; +})(); export default WithShell(async function(render) { const $page = createElement(`
`); @@ -58,7 +68,7 @@ export default WithShell(async function(render) { // feature: render viewer application effect(rxjs.of(getConfig("mime", {})).pipe( rxjs.map((mimes) => opener(basename(getCurrentPath()), mimes)), - rxjs.mergeMap(([opener, opts]) => rxjs.from(loadModule(opener)).pipe(rxjs.switchMap(async(module) => { + rxjs.mergeMap(([opener, opts]) => rxjs.from(loadModuleWithMemory(opener)).pipe(rxjs.switchMap(async(module) => { module.default(createRender($page), { ...opts, acl$: options(), getFilename, getDownloadUrl }); }))), rxjs.catchError(ctrlError()), diff --git a/public/assets/pages/viewerpage/application_image.css b/public/assets/pages/viewerpage/application_image.css index b89db984..db269403 100644 --- a/public/assets/pages/viewerpage/application_image.css +++ b/public/assets/pages/viewerpage/application_image.css @@ -76,11 +76,8 @@ body:not(.dark-mode) .component_imageviewer .component_image_container .fullscre z-index: 1; min-width: 0px; transition: 0.15s ease min-width; - background: #949290; - color: var(--dark); -} -.dark-mode .component_imageviewer .images_aside { background: #f2f2f2; + color: var(--dark); } .component_imageviewer .images_aside.open { min-width: 300px; @@ -129,6 +126,12 @@ body:not(.dark-mode) .component_imageviewer .component_image_container .fullscre height: 18px; float: right; cursor: pointer; + padding: 5px; + margin: -5px -5px 0 0; +} +.component_imageviewer .images_aside .header .component_icon:hover { + background: #0000000a; + border-radius: 50%; } .component_imageviewer .images_aside [data-bind="body"] { padding: 10px 20px 0px 20px; @@ -154,7 +157,7 @@ body:not(.dark-mode) .component_imageviewer .component_image_container .fullscre display: flex; justify-content: space-between; margin: 5px 0; - border-top: 1px solid #ffffff15; + border-top: 1px solid #0000000a; padding-top: 5px; text-align: right; font-size: 0.85em; @@ -163,5 +166,5 @@ body:not(.dark-mode) .component_imageviewer .component_image_container .fullscre margin-right: 5px; } .component_imageviewer .images_aside .meta_key .value { - color: var(--bg-color); + color: var(--light); } diff --git a/public/assets/pages/viewerpage/application_image.js b/public/assets/pages/viewerpage/application_image.js index 9d49d19a..98fa6739 100644 --- a/public/assets/pages/viewerpage/application_image.js +++ b/public/assets/pages/viewerpage/application_image.js @@ -14,11 +14,9 @@ import notification from "../../components/notification.js"; import t from "../../locales/index.js"; import ctrlError from "../ctrl_error.js"; -import { transition } from "./common.js"; - import componentMetadata, { init as initMetadata } from "./application_image_metadata.js"; +import componentToolbox, { init as initToolbox } from "./application_image_toolbox.js"; import ctrlDownloader, { init as initDownloader } from "./application_downloader.js"; -import componentPager, { init as initPager } from "./component_pager.js"; import { renderMenubar, buttonDownload, buttonFullscreen } from "./component_menubar.js"; @@ -33,14 +31,13 @@ export default function(render, { getFilename, getDownloadUrl, mime, hasMenubar
+
-
`); render($page); - transition(qs($page, ".component_image_container")); const $imgContainer = qs($page, ".images_wrapper"); const $photo = qs($page, "img.photo"); @@ -97,14 +94,14 @@ export default function(render, { getFilename, getDownloadUrl, mime, hasMenubar return ctrlError()(err); }), )); - componentPager(createRender(qs($page, ".component_pager"))); + componentToolbox(createRender(qs($page, "[data-bind=\"component_navigation\"]")), { $img: $photo }); } export function init() { return Promise.all([ loadCSS(import.meta.url, "./application_image.css"), loadCSS(import.meta.url, "./component_menubar.css"), - initPager(), initMetadata(), + initToolbox(), initMetadata(), ]); } diff --git a/public/assets/pages/viewerpage/application_image_toolbox.css b/public/assets/pages/viewerpage/application_image_toolbox.css new file mode 100644 index 00000000..0ede7cd3 --- /dev/null +++ b/public/assets/pages/viewerpage/application_image_toolbox.css @@ -0,0 +1,31 @@ +/* PAGINATION */ +.component_pager { + position: absolute; + top: 0; + bottom: 0; + display: flex; + opacity: 0.2; + margin: auto; + padding: 15px; + color: #f2f2f2; + z-index: 1; +} +.component_pager.left { left: 0; padding-right: 150px; } +.component_pager.right { right: 0; padding-left: 150px; } +.component_pager:hover { + opacity: 0.9; + transition: opacity 0.5s ease; +} +.component_pager a { margin: auto; } +.component_pager a svg { + transition: opacity 0.2s ease; + width: 37px; + padding: 5px; + background: var(--dark); + border-radius: 50%; + margin: auto; + opacity: 0.75; +} +.component_pager a svg:hover { + opacity: 1; +} diff --git a/public/assets/pages/viewerpage/application_image_toolbox.js b/public/assets/pages/viewerpage/application_image_toolbox.js new file mode 100644 index 00000000..ec5590d6 --- /dev/null +++ b/public/assets/pages/viewerpage/application_image_toolbox.js @@ -0,0 +1,91 @@ +import { createFragment } from "../../lib/skeleton/index.js"; +import rxjs from "../../lib/rx.js"; +import { qs } from "../../lib/dom.js"; +import { join } from "../../lib/path.js"; +import { animate, slideXOut } from "../../lib/animate.js"; +import { loadCSS } from "../../helpers/loader.js"; +import { get as getConfig } from "../../model/config.js"; + +import { getCurrentPath, getFilename } from "./common.js"; +import { getMimeType } from "./mimetype.js"; +import fscache from "../filespage/cache.js"; +import { sort } from "../filespage/helper.js"; +import { getState$ as getParams$, init as initParams } from "../filespage/state_config.js"; + +export default async function(render, { $img }) { + const lsCache = await fscache().get(join(location, getCurrentPath() + "/../")); + if (!lsCache) return; + const params = await getParams$().pipe(rxjs.first()).toPromise(); + const files = sort(lsCache.files, params["sort"], params["order"]); + const currentFilename = getFilename(); + const mimeTypes = getConfig("mime", {}); + const state = { + prev: null, + curr: null, + next: null, + length: 0, + }; + for (let i=0; i