From 816ab87f13b3e5530633e3c68ab34d28848c9b51 Mon Sep 17 00:00:00 2001 From: nathan Date: Fri, 6 May 2022 15:07:07 -0600 Subject: [PATCH] Et2VfsMime added as WebComponent --- api/js/etemplate/Expose/ExposeMixin.ts | 14 +- api/js/etemplate/Vfs/Et2VfsMime.ts | 208 +++++++++++++++++++++++++ api/js/etemplate/etemplate2.ts | 1 + 3 files changed, 212 insertions(+), 11 deletions(-) create mode 100644 api/js/etemplate/Vfs/Et2VfsMime.ts diff --git a/api/js/etemplate/Expose/ExposeMixin.ts b/api/js/etemplate/Expose/ExposeMixin.ts index 326b1036d7..c54c1f9493 100644 --- a/api/js/etemplate/Expose/ExposeMixin.ts +++ b/api/js/etemplate/Expose/ExposeMixin.ts @@ -45,6 +45,8 @@ export interface ExposeValue path : any; mime : string, download_url? : string + // File modification time + mtime? : number } /** @@ -727,8 +729,6 @@ export function ExposeMixin>(superclass : B) } event.stopImmediatePropagation(); - // @ts-ignore Wants an argument, but does not require it - let fe = egw_get_file_editor_prefered_mimes(); if(this.exposeValue.mime.match(MIME_REGEX) && !this.exposeValue.mime.match(MIME_AUDIO_REGEX)) { @@ -740,15 +740,7 @@ export function ExposeMixin>(superclass : B) this._audio_player(this.exposeValue); return false; } - else if(fe && fe.mime && fe.edit && fe.mime[this.exposeValue.mime]) - { - egw.open_link(egw.link('/index.php', { - menuaction: fe.edit.menuaction, - path: this.exposeValue.path, - cd: 'no' // needed to not reload framework in sharing - }), '', fe.edit_popup); - return false; - } + return true; } diff --git a/api/js/etemplate/Vfs/Et2VfsMime.ts b/api/js/etemplate/Vfs/Et2VfsMime.ts new file mode 100644 index 0000000000..c1a01a49e0 --- /dev/null +++ b/api/js/etemplate/Vfs/Et2VfsMime.ts @@ -0,0 +1,208 @@ +import {ExposeValue} from "../Expose/ExposeMixin"; +import {et2_vfsMode} from "../et2_widget_vfs"; +import {Et2ImageExpose} from "../Expose/Et2ImageExpose"; +import {css, html} from "@lion/core"; + + +export class Et2VfsMime extends Et2ImageExpose +{ + static get styles() + { + return [ + ...super.styles, + css` + :host { + position: relative + } + img.overlay { + position: absolute; + bottom: 0px; + right: 0px; + z-index: 1; + } + `, + ]; + } + + static get properties() + { + return { + ...super.properties, + + /** + * Mime type we're displaying + */ + mime: {type: String, reflect: true}, + /** + * Mark the file as a link + */ + symlink: {type: Boolean, reflect: true} + } + } + + /** + * Mime type of directories + */ + static readonly DIR_MIME_TYPE : string = 'httpd/unix-directory'; + private __mime : string; + private __symlink : boolean; + + constructor() + { + super(); + this.__mime = ""; + this.__symlink = false; + } + + /** + * Used to determine if this widget is exposable. Images always are, even if we don't actually + * know the mime type. + * + * @returns {ExposeValue} + */ + get exposeValue() : ExposeValue + { + return Object.assign(super.exposeValue, { + mime: this.mime, + }); + } + + /** + * Overridden here because while some files cannot actually be put in the gallery, we still want to handle them + * in some way. Some files we'll open directly on click + * + * @returns {boolean} + */ + isExposable() : boolean + { + let gallery = super.isExposable(); + + // @ts-ignore Wants an argument, but does not require it + let fe = egw_get_file_editor_prefered_mimes(); + if(fe && fe.mime && fe.edit && fe.mime[this.exposeValue.mime]) + { + return true; + } + + return gallery; + } + + /** + * Some files cannot be opened in gallery, but we still want to do something with them + * Editable files we open on click. + * + * @param {MouseEvent} event + * @returns {boolean} + * @protected + */ + protected expose_onclick(event : MouseEvent) + { + // super.expose_onclick returns false when it has handled the event, true if it didn't + let super_handled = super.expose_onclick(event); + if(true == super_handled) + { + // @ts-ignore Wants an argument, but does not require it + let fe = egw_get_file_editor_prefered_mimes(); + if(fe && fe.mime && fe.edit && fe.mime[this.exposeValue.mime]) + { + egw.open_link(egw.link('/index.php', { + menuaction: fe.edit.menuaction, + path: this.exposeValue.path, + cd: 'no' // needed to not reload framework in sharing + }), '', fe.edit_popup); + return false; + } + } + return super_handled; + } + + /** + * Function to get media content to feed the expose + * + * @param {type} _value + * @returns {Array} return an array of object consists of media content + */ + getMedia(_value) + { + let mediaContent = Object.assign(super.getMedia(_value)[0], { + title: _value.name, + type: _value.mime, + href: _value.download_url + }); + + // check if download_url is not already an url (some stream-wrappers allow to specify that!) + if(_value.download_url && (_value.download_url[0] == '/' || _value.download_url.substr(0, 4) != 'http')) + { + mediaContent.href = this._processUrl(_value.download_url); + + if(mediaContent.href && mediaContent.href.match(/\/webdav.php/, 'ig')) + { + mediaContent["download_href"] = mediaContent.href + '?download'; + } + } + mediaContent["thumbnail"] = this.egw().mime_icon(_value.mime, _value.path, undefined, _value.mtime); + + return [mediaContent]; + } + + set_value(_value : ExposeValue | any) + { + if(typeof _value !== 'object') + { + this.egw().debug("warn", "%s only has path, needs array with path & mime", this.id, _value); + // Keep going, will be 'unknown type' + } + + if(_value.mime) + { + this.mime = _value.mime; + } + if(_value.path) + { + this.href = _value.path; + } + let src = this.egw().mime_icon(_value.mime, _value.path, undefined, _value.mtime); + if(src) + { + this.src = src; + } + // add/remove link icon, if file is (not) a symlink + this.symlink = typeof _value.mode !== "undefined" && ((_value.mode & et2_vfsMode.types.l) == et2_vfsMode.types.l) + } + + get src() + { + return super.src; + } + + set src(_value) + { + super.src = _value; + this._set_tooltip(); + } + + render() + { + return html` + + ${this.__symlink ? html`` : ""} + `; + } + + private _set_tooltip() + { + // tooltip for mimetypes with available detailed thumbnail + if(this.mime && this.mime.match(/application\/vnd\.oasis\.opendocument\.(text|presentation|spreadsheet|chart)/)) + { + this.egw().tooltipBind(this, '', true); + } + else + { + this.egw().tooltipUnbind(this); + } + } + +} + +customElements.define("et2-vfs-mime", Et2VfsMime as any, {extends: 'img'}); \ No newline at end of file diff --git a/api/js/etemplate/etemplate2.ts b/api/js/etemplate/etemplate2.ts index 202c3f8760..d06f31b960 100644 --- a/api/js/etemplate/etemplate2.ts +++ b/api/js/etemplate/etemplate2.ts @@ -59,6 +59,7 @@ import './Et2Url/Et2UrlPhoneReadonly'; import './Et2Url/Et2UrlFax'; import './Et2Url/Et2UrlFaxReadonly'; import "./Layout/Et2Split/Et2Split"; +import "./Vfs/Et2VfsMime"; /* Include all widget classes here, we only care about them registering, not importing anything*/ import './et2_widget_vfs'; // Vfs must be first (before et2_widget_file) due to import cycle