diff --git a/config/mime.json b/config/mime.json
index 66d85313..eb79e623 100644
--- a/config/mime.json
+++ b/config/mime.json
@@ -5,6 +5,7 @@
"3gpp": "video/3gpp",
"7z": "application/x-7z-compressed",
"a": "application/x-archive",
+ "aai": "image/x-dune-aai",
"aco": "application/x-aco",
"ai": "application/pdf",
"aif": "audio/x-aiff",
@@ -17,6 +18,7 @@
"asx": "video/x-ms-asf",
"atom": "application/atom+xml",
"avi": "video/x-msvideo",
+ "avif": "image/avif",
"avro": "application/vnd.apache.avro",
"bin": "application/octet-stream",
"bmp": "image/x-ms-bmp",
@@ -24,16 +26,20 @@
"cab": "application/vnd.ms-cab-compressed",
"cap": "application/x-pcap",
"cco": "application/x-cocoa",
+ "cdr": "application/vnd.corel-draw",
+ "cin": "image/x-cin",
"cr2": "image/x-canon-cr2",
"crt": "application/x-x509-ca-cert",
"crw": "image/x-canon-crw",
"css": "text/css",
"csv": "text/csv",
+ "cur": "image/x-win-bitmap",
"dae": "model/vnd.collada+xml",
"db": "application/x-sqlite3",
"dbf": "application/dbf",
"dcm": "image/dicom",
"dcr": "image/x-kodak-dcr",
+ "dds": "image/x-dds",
"deb": "application/octet-stream",
"der": "application/x-x509-ca-cert",
"dll": "application/x-msdownload",
@@ -45,16 +51,20 @@
"dotx": "application/vnd.openxmlformats-officedocument.wordprocessingml.template",
"dotm": "application/vnd.ms-word.template.macroEnabled.12",
"dpkg": "application/dpkg-www-installer",
+ "dpx": "image/dpx",
"ds_store": "application/octet-stream",
"dxf": "application/dxf",
"dwg": "application/acad",
"dylib": "application/x-dylib",
"ear": "application/java-archive",
+ "emf": "image/emf",
+ "emz": "image/x-emz",
"eot": "application/vnd.ms-fontobject",
"eps": "application/postscript",
"epub": "application/epub+zip",
"erf": "image/x-epson-erf",
"exe": "application/octet-stream",
+ "exr": "image/x-exr",
"fbx": "application/fbx",
"fea": "application/vnd.apache.feather",
"feather": "application/vnd.apache.feather",
@@ -84,10 +94,12 @@
"jad": "text/vnd.sun.j2me.app-descriptor",
"jar": "application/java-archive",
"jardiff": "application/x-java-archive-diff",
+ "jfif": "image/jpeg",
"jng": "image/x-jng",
"jnlp": "application/x-java-jnlp-file",
"jpeg": "image/jpeg",
"jpg": "image/jpeg",
+ "jp2": "image/jp2",
"js": "application/javascript",
"json": "application/json",
"kar": "audio/midi",
@@ -96,6 +108,8 @@
"kicad_sch": "application/vnd.kicad-sch",
"kml": "application/vnd.google-earth.kml+xml",
"kmz": "application/vnd.google-earth.kmz",
+ "ktx": "image/ktx",
+ "ktx2": "image/ktx2",
"m3u8": "application/vnd.apple.mpegurl",
"m4a": "audio/x-m4a",
"m4v": "video/x-m4v",
@@ -135,19 +149,26 @@
"org": "text/org",
"otf": "font/otf",
"parquet": "application/vnd.apache.parquet",
+ "pbm": "image/x-portable-bitmap",
"pdb": "application/x-pilot",
"pcap": "application/vnd.tcpdump.pcap",
"pcapng": "application/x-pcapng",
+ "pcd": "image/x-photo-cd",
+ "pcx": "image/vnd.zbrush.pcx",
"pdf": "application/pdf",
"pef": "image/x-pentax-pef",
"pem": "application/x-x509-ca-cert",
+ "pes": "image/x-pes",
+ "pgm": "image/x-portable-greymap",
"pkg": "application/x-newton-compatible-pkg",
"pl": "application/x-perl",
"pm": "application/x-perl",
"png": "image/png",
+ "pnm": "image/x-portable-anymap",
"potm": "application/vnd.ms-powerpoint.template.macroEnabled.12",
"potx": "application/vnd.openxmlformats-officedocument.presentationml.template",
"ppam": "application/vnd.ms-powerpoint.addin.macroEnabled.12",
+ "ppm": "image/x-portable-pixmap",
"pps": "application/vnd.ms-powerpoint",
"ppsx": "application/vnd.openxmlformats-officedocument.presentationml.slideshow",
"ppsm": "application/vnd.ms-powerpoint.slideshow.macroEnabled.12",
@@ -164,6 +185,8 @@
"ram": "audio/x-pn-realaudio",
"rar": "application/x-rar-compressed",
"raw": "image/x-raw",
+ "rgb": "image/x-rgb",
+ "rgba": "image/x-rgba",
"rpm": "application/x-redhat-package-manager",
"rss": "application/rss+xml",
"rtf": "application/rtf",
@@ -171,15 +194,18 @@
"run": "application/x-makeself",
"rw2": "image/x-panasonic-rw2",
"sea": "application/x-sea",
+ "sgi": "image/x-sgi",
"shtml": "text/html",
"shp": "application/vnd.shp",
"shx": "application/vnd.shx",
"sit": "application/x-stuffit",
+ "sketch": "application/x-sketch",
"so": "application/x-sharedlib",
"sql": "application/x-sqlite3",
"sqlite": "application/x-sqlite3",
"sqlite3": "application/x-sqlite3",
"sr2": "image/x-sony-sr2",
+ "srf": "image/x-sony-srf",
"srw": "image/x-samsung-srw",
"stl": "model/stl",
"step": "model/step",
@@ -189,6 +215,7 @@
"swf": "application/x-shockwave-flash",
"tar": "application/x-tar",
"tcl": "application/x-tcl",
+ "tga": "image/x-tga",
"tgz": "application/x-gzip",
"tif": "image/tiff",
"tiff": "image/tiff",
@@ -214,16 +241,22 @@
"wmv": "video/x-ms-wmv",
"woff": "font/woff",
"woff2": "font/woff2",
+ "wbmp": "image/vnd.wap.wbmp",
"wrl": "x-world/x-vrml",
"x3d": "model/x3d+xml",
"x3dv": "model/x3d-vrml",
"x3db": "model/x3d+fastinfoset",
"x3f": "image/x-x3f",
+ "xbm": "image/x-xbitmap",
+ "xcf": "image/x-xcf",
+ "xd": "application/x-adobe-xd",
"xhtml": "application/xhtml+xml",
"xls": "application/vnd.ms-excel",
"xlsx": "application/excel",
"xml": "application/xml",
"xpi": "application/x-xpinstall",
+ "xpm": "image/x-xpixmap",
+ "xwd": "image/x-xwindowdump",
"xspf": "application/xspf+xml",
"zip": "application/zip"
}
diff --git a/public/assets/pages/viewerpage/application_downloader.js b/public/assets/pages/viewerpage/application_downloader.js
index bd7f87ae..246c88fd 100644
--- a/public/assets/pages/viewerpage/application_downloader.js
+++ b/public/assets/pages/viewerpage/application_downloader.js
@@ -9,10 +9,10 @@ import { transition } from "./common.js";
import "../../components/icon.js";
import "./component_menubar.js";
-export default async function(render, { acl$, getFilename, getDownloadUrl }) {
+export default async function(render, { acl$, getFilename, getDownloadUrl, hasMenubar = true }) {
const $page = createElement(`
-
+
${t("DOWNLOAD")}
diff --git a/public/assets/pages/viewerpage/application_image.css b/public/assets/pages/viewerpage/application_image.css
index 8b01d090..360a76b7 100644
--- a/public/assets/pages/viewerpage/application_image.css
+++ b/public/assets/pages/viewerpage/application_image.css
@@ -2,14 +2,8 @@
body:not(.dark-mode) .component_imageviewer .component_image_container .fullscreen .component_pager .wrapper > span {
background: #525659;
}
-
-.component_imageviewer, .component_imageviewer .component_image_container > .images_wrapper {
- flex: 1;
- display: flex;
- overflow: hidden;
- width: 100%;
- height: 100%;
- flex-direction: column;
+.dark-mode .component_imageviewer .component_image_container {
+ background: #2d2f31;
}
.component_imageviewer .component_image_container {
@@ -19,10 +13,40 @@ body:not(.dark-mode) .component_imageviewer .component_image_container .fullscre
width: 100%;
text-align: center;
overflow: hidden;
- padding: 10px 10px 10px 10px;
height: 100%;
box-sizing: border-box;
}
+.component_imageviewer, .component_imageviewer .images_wrapper {
+ flex: 1;
+ display: flex;
+ overflow: hidden;
+ width: 100%;
+ height: 100%;
+ flex-direction: column;
+ position: relative;
+ justify-content: center;
+}
+.component_imageviewer img.photo {
+ margin: 10px;
+ width: fit-content;
+ max-width: 98%;;
+ min-height: 100px;
+ max-height: 100%;
+ background: var(--dark);
+ 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;
+ border-radius: 2px;
+ align-self: center;
+}
+.component_imageviewer img.photo.idle {
+ transition: 0.2s ease transform;
+}
+@media screen and (max-width: 500px) {
+ .component_imageviewer img.photo {
+ margin: 7px;
+ }
+}
+
+/* fullscreen mode */
.component_imageviewer .component_image_container.fullscreen {
background: var(--dark);
}
@@ -32,161 +56,113 @@ body:not(.dark-mode) .component_imageviewer .component_image_container .fullscre
.component_imageviewer .component_image_container.fullscreen img.photo {
background: var(--color);
}
-@media screen and (max-height: 410px) {
- .component_imageviewer .component_image_container {
- padding: 5px 0px 40px 10px;
- }
- .component_imageviewer .component_image_container .component_pager .wrapper {
- padding: 5px 0;
- }
- .component_imageviewer .component_image_container .component_pager .wrapper > span {
- padding: 2px 5px;
- }
- .component_imageviewer .component_image_container .images_aside {
- margin: -5px -5px -40px 10px !important;
- }
-}
-.component_imageviewer .component_image_container .images_wrapper {
- width: 100%;
- position: relative;
- justify-content: center;
-}
-.component_imageviewer .component_image_container .images_wrapper > span {
- position: absolute;
- top: 0;
- bottom: 0;
- left: 0;
- right: 0;
-}
-.component_imageviewer .component_image_container .images_aside {
- flex: 0;
- text-align: left;
- width: 0;
- z-index: 1;
- min-width: 0px;
- transition: 0.3s ease min-width;
- border-left: 1px solid var(--color);
- background: #949290;
- margin: -15px -10px -65px 10px;
- color: var(--dark);
-}
-.component_imageviewer .component_image_container .images_aside.open {
- min-width: 300px;
- transition: 0.5s ease min-width;
-}
-@media screen and (max-width: 850px) {
- .component_imageviewer .component_image_container .images_aside.open {
- min-width: 250px;
- font-size: 0.94em;
- }
- .component_imageviewer .component_image_container .images_aside.open .header, .component_imageviewer .component_image_container .images_aside.open .content {
- padding: 15px 15px 0px 15px;
- }
-}
-@media screen and (max-width: 650px) {
- .component_imageviewer .component_image_container .images_aside.open {
- min-width: 200px;
- }
-}
-@media screen and (max-width: 580px) {
- .component_imageviewer .component_image_container .images_aside.open {
- width: 0px;
- min-width: 0;
- }
-}
-.component_imageviewer .component_image_container .images_aside.open .content {
- transform: translateX(0px);
- opacity: 1;
-}
-.component_imageviewer .component_image_container .images_aside .content {
- transition: 0.2s ease opacity, 0.3s ease transform;
- opacity: 0;
- transform: translateX(10px);
- transition-delay: 0.2s;
-}
-.component_imageviewer .component_image_container .images_aside .header {
- display: flex;
- line-height: 25px;
- white-space: nowrap;
- padding: 20px 25px;
- font-size: 1.25em;
-}
-.component_imageviewer .component_image_container .images_aside .header .component_icon {
- height: 18px;
- float: right;
- cursor: pointer;
-}
-.component_imageviewer .component_image_container .images_aside .content {
- padding: 10px 20px 0px 20px;
-}
-.component_imageviewer .component_image_container .images_aside .content .content_box {
- clear: both;
- opacity: 0.85;
- margin-bottom: 20px;
-}
-.component_imageviewer .component_image_container .images_aside .content .content_box > div {
- margin: 3px 0;
- width: calc(100% - 40px);
-}
-.component_imageviewer .component_image_container .images_aside .content .content_box .component_icon {
- height: 30px;
- width: 30px;
- float: left;
- padding: 5px 10px 5px 0;
-}
-.component_imageviewer .component_image_container .images_aside .content .component_mapshot {
- margin-bottom: 10px;
-}
-.component_imageviewer .component_image_container .images_aside .content .more, .component_imageviewer .component_image_container .images_aside .content .meta_key {
- text-align: right;
- font-size: 0.9em;
- margin: 10px 0;
-}
-.component_imageviewer .component_image_container .images_aside .content .more_container {
- margin: 30px 0 50px 0;
- padding-bottom: 20px;
-}
-.component_imageviewer .component_image_container .images_aside .content .more_container .meta_key {
- display: flex;
- justify-content: space-between;
- margin: 5px 0;
- border-top: 1px dashed var(--color);
- padding-top: 5px;
-}
-.component_imageviewer .component_image_container .images_aside .content .more_container .meta_key .title {
- margin-right: 5px;
-}
-.component_imageviewer .component_image_container .images_aside .content .more_container .meta_key .value {
- color: var(--bg-color);
-}
-.component_imageviewer .component_image_container img.photo:not(.error) {
- margin: auto;
- max-height: 100%;
- max-width: 100%;
- min-height: 100px;
- background: var(--dark);
- 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;
- border-radius: 2px;
-}
-.component_imageviewer .component_image_container img.photo.idle {
- transition: 0.2s ease transform;
-}
+/* image loading spinner */
.component_imageviewer .component_loader {
margin-top: 0;
}
.component_imageviewer .component_loader img {
width: 40px;
}
-.component_imageviewer .error {
+
+/* error loading image */
+.component_imageviewer .component_filedownloader { margin: 0 auto; }
+
+/* information menu */
+.component_imageviewer .images_aside {
+ flex: 0;
+ text-align: left;
+ width: 0;
+ z-index: 1;
+ min-width: 0px;
+ transition: 0.15s ease min-width;
+ border-left: 1px solid var(--border);
+ background: #949290;
color: var(--dark);
- font-size: 1.3em;
}
-.component_imageviewer .component_image_container img.error {
- filter: contrast(0.8);
- width: 160px;
- margin: 0 auto;
+.dark-mode .component_imageviewer .images_aside {
+ background: #f2f2f2;
}
-.dark-mode .component_imageviewer .component_image_container {
- background: #232426;
+.component_imageviewer .images_aside.open {
+ min-width: 300px;
+ transition: 0.5s ease min-width;
+ transition: 0.3s ease min-width;
+}
+@media screen and (max-width: 850px) {
+ .component_imageviewer .images_aside.open {
+ min-width: 250px;
+ font-size: 0.94em;
+ }
+ .component_imageviewer .images_aside.open [data-bind="header"],
+ .component_imageviewer .images_aside.open [data-bind="body"] {
+ padding: 15px 15px 0px 15px;
+ }
+}
+@media screen and (max-width: 650px) {
+ .component_imageviewer .images_aside.open {
+ min-width: 200px;
+ }
+}
+@media screen and (max-width: 580px) {
+ .component_imageviewer .images_aside.open {
+ width: 0px;
+ min-width: 0;
+ }
+}
+.component_imageviewer .images_aside.open [data-bind="body"] {
+ transform: translateX(0px);
+ opacity: 1;
+}
+.component_imageviewer .images_aside [data-bind="body"] {
+ transition: 0.2s ease opacity, 0.3s ease transform;
+ opacity: 0;
+ transform: translateX(10px);
+ transition-delay: 0.2s;
+}
+.component_imageviewer .images_aside .header {
+ display: flex;
+ line-height: 25px;
+ white-space: nowrap;
+ padding: 20px 25px;
+ font-size: 1.25em;
+}
+.component_imageviewer .images_aside .header .component_icon {
+ height: 18px;
+ float: right;
+ cursor: pointer;
+}
+.component_imageviewer .images_aside [data-bind="body"] {
+ padding: 10px 20px 0px 20px;
+}
+.component_imageviewer .images_aside [data-bind="body"] .content_box {
+ clear: both;
+ opacity: 0.85;
+ margin-bottom: 20px;
+}
+.component_imageviewer .images_aside [data-bind="body"] .content_box > div {
+ width: calc(100% - 40px);
+}
+.component_imageviewer .images_aside [data-bind="body"] .content_box .component_icon {
+ height: 30px;
+ width: 30px;
+ float: left;
+ padding: 5px 10px 5px 0;
+}
+.component_imageviewer .images_aside [data-bind="body"] .component_mapshot {
+ margin-bottom: 10px;
+}
+.component_imageviewer .images_aside .meta_key {
+ display: flex;
+ justify-content: space-between;
+ margin: 5px 0;
+ border-top: 1px solid #ffffff15;
+ padding-top: 5px;
+ text-align: right;
+ font-size: 0.85em;
+}
+.component_imageviewer .images_aside .meta_key .title {
+ margin-right: 5px;
+}
+.component_imageviewer .images_aside .meta_key .value {
+ color: var(--bg-color);
}
diff --git a/public/assets/pages/viewerpage/application_image.js b/public/assets/pages/viewerpage/application_image.js
index 5936ad2e..9d49d19a 100644
--- a/public/assets/pages/viewerpage/application_image.js
+++ b/public/assets/pages/viewerpage/application_image.js
@@ -1,10 +1,12 @@
import { createElement, createRender, onDestroy } from "../../lib/skeleton/index.js";
import { toHref } from "../../lib/skeleton/router.js";
import rxjs, { effect, onLoad, onClick } from "../../lib/rx.js";
+import ajax from "../../lib/ajax.js";
import { animate } from "../../lib/animate.js";
import { extname } from "../../lib/path.js";
import { qs } from "../../lib/dom.js";
import { get as getConfig } from "../../model/config.js";
+import { load as loadPlugin } from "../../model/plugin.js";
import { Chromecast } from "../../model/chromecast.js";
import { loadCSS } from "../../helpers/loader.js";
import { createLoader } from "../../components/loader.js";
@@ -15,17 +17,22 @@ import ctrlError from "../ctrl_error.js";
import { transition } from "./common.js";
import componentMetadata, { init as initMetadata } from "./application_image_metadata.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";
-export default function(render, { getFilename, getDownloadUrl, hasMenubar = true }) {
+class IImage {
+ getSRC() { throw new Error("NOT_IMPLEMENTED"); }
+}
+
+export default function(render, { getFilename, getDownloadUrl, mime, hasMenubar = true, acl$ }) {
const $page = createElement(`
-
}&size=${window.innerWidth})
+
@@ -37,6 +44,7 @@ export default function(render, { getFilename, getDownloadUrl, hasMenubar = true
const $imgContainer = qs($page, ".images_wrapper");
const $photo = qs($page, "img.photo");
+ const $menubar = qs($page, "component-menubar");
const removeLoader = createLoader($imgContainer);
const load$ = new rxjs.BehaviorSubject(null);
const toggleInfo = () => {
@@ -45,17 +53,25 @@ export default function(render, { getFilename, getDownloadUrl, hasMenubar = true
};
renderMenubar(
- qs($page, "component-menubar"),
+ $menubar,
buttonDownload(getFilename(), getDownloadUrl()),
buttonFullscreen(qs($page, ".component_image_container")),
buttonInfo({ toggle: toggleInfo }),
buttonChromecast(getFilename(), getDownloadUrl()),
);
- effect(onLoad($photo).pipe(
- rxjs.tap(() => {
- load$.next($photo);
+ effect(rxjs.from(loadPlugin(mime)).pipe(
+ rxjs.mergeMap(async(loader) => {
+ let src = `${getDownloadUrl()}&size=${window.innerWidth}`;
+ if (loader) {
+ const { response } = await ajax({ url: getDownloadUrl(), responseType: "arraybuffer" }).toPromise();
+ const img = new (await loader(IImage, { mime, $menubar, getFilename, getDownloadUrl }))();
+ src = await img.getSRC(response);
+ }
+ $photo.setAttribute("src", src);
+ await onLoad($photo).toPromise();
}),
+ rxjs.tap(() => load$.next($photo)),
removeLoader,
rxjs.tap(() => animate($photo, {
onEnter: () => $photo.classList.remove("hidden"),
@@ -69,25 +85,18 @@ export default function(render, { getFilename, getDownloadUrl, hasMenubar = true
})),
rxjs.catchError((err) => {
if (err.target instanceof HTMLElement && err.type === "error") {
- return rxjs.of($photo).pipe(
+ return rxjs.of(initDownloader()).pipe(
removeLoader,
- rxjs.tap(($img) => {
- $img.setAttribute("src", "data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+CjxzdmcKICAgaGVpZ2h0PSIxNiIKICAgd2lkdGg9IjE2IgogICB2ZXJzaW9uPSIxLjEiCiAgIGlkPSJzdmcyNzU2IgogICBzb2RpcG9kaTpkb2NuYW1lPSJkb3dubG9hZC5zdmciCiAgIGlua3NjYXBlOnZlcnNpb249IjEuMi4yIChiMGE4NDg2NTQxLCAyMDIyLTEyLTAxKSIKICAgeG1sbnM6aW5rc2NhcGU9Imh0dHA6Ly93d3cuaW5rc2NhcGUub3JnL25hbWVzcGFjZXMvaW5rc2NhcGUiCiAgIHhtbG5zOnNvZGlwb2RpPSJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZCIKICAgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIgogICB4bWxuczpzdmc9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8ZGVmcwogICAgIGlkPSJkZWZzMjc2MCIgLz4KICA8c29kaXBvZGk6bmFtZWR2aWV3CiAgICAgaWQ9Im5hbWVkdmlldzI3NTgiCiAgICAgcGFnZWNvbG9yPSIjZmZmZmZmIgogICAgIGJvcmRlcmNvbG9yPSIjMDAwMDAwIgogICAgIGJvcmRlcm9wYWNpdHk9IjAuMjUiCiAgICAgaW5rc2NhcGU6c2hvd3BhZ2VzaGFkb3c9IjIiCiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9IjAuMCIKICAgICBpbmtzY2FwZTpwYWdlY2hlY2tlcmJvYXJkPSIwIgogICAgIGlua3NjYXBlOmRlc2tjb2xvcj0iI2QxZDFkMSIKICAgICBzaG93Z3JpZD0iZmFsc2UiCiAgICAgaW5rc2NhcGU6em9vbT0iNDEuNzE5MyIKICAgICBpbmtzY2FwZTpjeD0iMTEuMzI1NjkzIgogICAgIGlua3NjYXBlOmN5PSI4LjU1NzE5MDUiCiAgICAgaW5rc2NhcGU6d2luZG93LXdpZHRoPSIxOTA0IgogICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9IjExNTciCiAgICAgaW5rc2NhcGU6d2luZG93LXg9IjciCiAgICAgaW5rc2NhcGU6d2luZG93LXk9IjM0IgogICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9IjEiCiAgICAgaW5rc2NhcGU6Y3VycmVudC1sYXllcj0ic3ZnMjc1NiIgLz4KICA8cGF0aAogICAgIHN0eWxlPSJjb2xvcjojMDAwMDAwO3RleHQtaW5kZW50OjA7dGV4dC10cmFuc2Zvcm06bm9uZTtmaWxsOiMzYjQwNDU7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlLXdpZHRoOjAuOTg0ODEwNDEiCiAgICAgZD0ibSAyLDEzLjA4MjQxMiAwLjAxOTQ2MiwxLjQ5MjM0NyBjIDVlLTYsMC4yMjIxNDUgMC4yMDU1OTAyLDAuNDI0MjYyIDAuNDMxMTUwMiwwLjQyNDI3MiBMIDEzLjU4OTYxMiwxNSBDIDEzLjgxNTE3MywxNC45OTk5OTUgMTMuOTk5OTksMTQuNzk3ODc0IDE0LDE0LjU3NTcyOSB2IC0xLjQ5MzMxNyBjIC00LjE3MTg2OTIsMC42NjIwMjMgLTcuNjUxNjkyOCwwLjM5ODY5NiAtMTIsMCB6IgogICAgIGlkPSJwYXRoMjc1MCIgLz4KICA8cGF0aAogICAgIHN0eWxlPSJjb2xvcjojMDAwMDAwO3RleHQtaW5kZW50OjA7dGV4dC10cmFuc2Zvcm06bm9uZTtkaXNwbGF5OmlubGluZTtmaWxsOiNmOWY5ZmE7c3Ryb2tlLXdpZHRoOjAuOTg0MDgxMjc7ZmlsbC1vcGFjaXR5OjEiCiAgICAgZD0iTSAyLjM1MDEsMS4wMDEzMzEyIEMgMi4xNTI1OSwxLjAzODMyNDcgMS45OTY1OSwxLjIyNzI3MjMgMi4wMDAwOSwxLjQyNDkzNTYgViAxNC4xMzM0NTcgYyA1ZS02LDAuMjIxODE2IDAuMjA1MjMsMC40MjM2MzQgMC40MzA3OSwwLjQyMzY0NCBsIDExLjEzOSwtMS4wMWUtNCBjIDAuMjI1NTYsLTZlLTYgMC40MzAxMSwtMC4yMDA3NTggMC40MzAxMiwtMC40MjI1NzQgbCA2LjdlLTQsLTkuODIyNjQyNiBjIC0yLjQ4NDA0NiwtMS4zNTUwMDYgLTIuNDM1MjM0LC0yLjAzMTIyNTQgLTMuNTAwMSwtMy4zMDk3MDcgLTAuMDQzLC0wLjAxNTg4MiAwLjA0NiwwLjAwMTc0IDAsMCBMIDIuNDMwNjcsMS4wMDExMDggQyAyLjQwMzgzLDAuOTk4NTkgMi4zNzY3NCwwLjk5ODU5IDIuMzQ5OSwxLjAwMTEwOCBaIgogICAgIGlkPSJwYXRoMjc1MiIgLz4KICA8cGF0aAogICAgIHN0eWxlPSJkaXNwbGF5OmlubGluZTtmaWxsOiMzYjQwNDU7ZmlsbC1vcGFjaXR5OjE7c3Ryb2tlOiM5ZTc1NzU7c3Ryb2tlLXdpZHRoOjA7c3Ryb2tlLWxpbmVjYXA6YnV0dDtzdHJva2UtbGluZWpvaW46bWl0ZXI7c3Ryb2tlLW1pdGVybGltaXQ6NDtzdHJva2UtZGFzaGFycmF5Om5vbmU7c3Ryb2tlLW9wYWNpdHk6MSIKICAgICBkPSJtIDEwLjUwMDU3LDEuMDAyMDc2NCBjIDAsMy4yNzY4MDI4IC0wLjAwNTIsMy4xNzM5MTYxIDAuMzYyOTIxLDMuMjY5ODIwMiAwLjI4MDEwOSwwLjA3Mjk4NCAzLjEzNzE4LDAuMDM5ODg3IDMuMTM3MTgsMC4wMzk4ODcgLTEuMTIwMDY3LC0xLjA1NTY2OTIgLTIuMzMzNCwtMi4yMDY0NzEzIC0zLjUwMDEsLTMuMzA5NzA3NCB6IgogICAgIGlkPSJwYXRoMjc1NCIgLz4KPC9zdmc+Cg==");
- $img.classList.remove("hidden");
- $img.classList.add("error");
- $img.parentElement.appendChild(createElement(`
-
- ${t("Not Supported")}
-
- `));
+ rxjs.mergeMap(() => {
+ load$.error(err);
+ ctrlDownloader(createRender(qs($page, ".images_wrapper")), { acl$, getFilename, getDownloadUrl, hasMenubar: false });
+ return rxjs.EMPTY;
}),
- rxjs.catchError(ctrlError()),
);
}
return ctrlError()(err);
}),
));
-
componentPager(createRender(qs($page, ".component_pager")));
}
diff --git a/public/assets/pages/viewerpage/application_image_metadata.js b/public/assets/pages/viewerpage/application_image_metadata.js
index 981a44f2..b298945b 100644
--- a/public/assets/pages/viewerpage/application_image_metadata.js
+++ b/public/assets/pages/viewerpage/application_image_metadata.js
@@ -28,13 +28,12 @@ function componentHeader(render, { toggle }) {
`);
render($header);
-
effect(onClick(qs($header, `[alt="close"]`)).pipe(rxjs.tap(toggle)));
}
function componentBody(render, { load$ }) {
const $page = createElement(`
-
+
-
@@ -63,6 +62,9 @@ function componentBody(render, { load$ }) {
if (metadata.location) await componentMap(createRender(qs($page, `[data-bind="map"]`)), { metadata });
componentMore(createRender(qs($page, `[data-bind="all"]`)), { metadata });
+ }), rxjs.catchError((err) => {
+ qs($page, `[data-bind="all"]`).remove();
+ return rxjs.EMPTY;
})));
}
@@ -155,13 +157,6 @@ async function componentMap(render, { metadata }) {
}
function componentMore(render, { metadata }) {
- const $page = createElement(`
-
- `);
- render($page);
-
const $all = document.createDocumentFragment();
const formatKey = (str) => str.replace(/([A-Z][a-z])/g, " $1");
const formatValue = (str) => {
@@ -209,7 +204,7 @@ function componentMore(render, { metadata }) {
`));
}
});
- qs($page, ".more_container").appendChild($all);
+ render($all);
}
export function init() {
@@ -222,6 +217,7 @@ export function init() {
const extractExif = ($img) => new Promise((resolve) => window.EXIF.getData($img, function() {
const metadata = window.EXIF.getAllTags($img);
const to_date = (str = "") => {
+ if (str === "") return null;
const digits = str.split(/[ :]/).map((digit) => parseInt(digit));
return new Date(
digits[0] || 0,
diff --git a/public/assets/pages/viewerpage/application_skeleton.js b/public/assets/pages/viewerpage/application_skeleton.js
index 864fca31..d78056a8 100644
--- a/public/assets/pages/viewerpage/application_skeleton.js
+++ b/public/assets/pages/viewerpage/application_skeleton.js
@@ -7,10 +7,10 @@ import { createLoader } from "../../components/loader.js";
import ctrlError from "../ctrl_error.js";
import componentDownloader, { init as initDownloader } from "./application_downloader.js";
-export default function(render, { mime, getFilename, getDownloadUrl, acl$ }) {
+export default function(render, { mime, getFilename, getDownloadUrl, acl$, hasMenubar = true }) {
const $page = createElement(`
`);
diff --git a/public/assets/pages/viewerpage/mimetype.js b/public/assets/pages/viewerpage/mimetype.js
index b7a17065..609f01aa 100644
--- a/public/assets/pages/viewerpage/mimetype.js
+++ b/public/assets/pages/viewerpage/mimetype.js
@@ -12,10 +12,7 @@ export function opener(file = "", mimes) {
}
const p = getPlugin(mime);
- if (p) return [
- p[0],
- { mime, loader: p[1] },
- ];
+ if (p) return [p[0], { mime, ...p[1] }];
if (type === "text") {
return ["editor", { mime }];
diff --git a/server/ctrl/plugin.go b/server/ctrl/plugin.go
index f21c2425..7b275eb6 100644
--- a/server/ctrl/plugin.go
+++ b/server/ctrl/plugin.go
@@ -4,6 +4,7 @@ import (
"io"
"net/http"
"os"
+ "path/filepath"
"strings"
. "github.com/mickael-kerjean/filestash/server/common"
@@ -32,7 +33,7 @@ func PluginExportHandler(ctx *App, res http.ResponseWriter, req *http.Request) {
}
plgExports[module["mime"]] = []string{
module["application"],
- WithBase(JoinPath("/plugin/", name+index)),
+ WithBase(JoinPath("/plugin/", filepath.Join(name, index))),
}
}
}