Et2ImageExpose

This commit is contained in:
nathan 2022-05-04 17:31:42 -06:00
parent 3c6c2aec1a
commit efcd5bbe51
4 changed files with 102 additions and 15 deletions

View File

@ -74,12 +74,6 @@ export class Et2Image extends Et2Widget(SlotMixin(LitElement)) implements et2_ID
* widthxheight, if popup should be used, eg. 640x480 * widthxheight, if popup should be used, eg. 640x480
*/ */
extra_link_popup: {type: String}, extra_link_popup: {type: String},
/**
* Expose view
* Clicking on an image with href value would popup an expose view, and will show image referenced by href.
*/
expose_view: {type: Boolean},
} }
} }
@ -103,12 +97,13 @@ export class Et2Image extends Et2Widget(SlotMixin(LitElement)) implements et2_ID
this.extra_link_target = "_self"; this.extra_link_target = "_self";
this.extra_link_popup = ""; this.extra_link_popup = "";
this.expose_view = false; this.expose_view = false;
this._handleClick = this._handleClick.bind(this);
} }
connectedCallback() connectedCallback()
{ {
super.connectedCallback(); super.connectedCallback();
this._handleClick = this._handleClick.bind(this);
} }
_imageTemplate() _imageTemplate()

View File

@ -0,0 +1,50 @@
import {ExposeMixin, ExposeValue, MediaValue} from "./ExposeMixin";
import {Et2Image} from "../Et2Image/Et2Image";
import {et2_IDetachedDOM} from "../et2_core_interfaces";
/**
* Shows an image and if you click on it it gets bigger
*
* Set src property for the thumbnail / small image
* Set href property to the URL of the full / large image
*/
export class Et2ImageExpose extends ExposeMixin(Et2Image) implements et2_IDetachedDOM
{
constructor()
{
super();
}
connectedCallback()
{
super.connectedCallback();
}
/**
* 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 {
mime: "image/*",
path: this.href,
download_url: this.href,
};
}
/**
* Get the info needed to show this image as slide(s)
*/
getMedia(_value) : MediaValue[]
{
let media = super.getMedia(_value);
media[0].thumbnail = this.src;
return media;
}
}
customElements.define("et2-image-expose", Et2ImageExpose as any, {extends: 'img'});

View File

@ -11,7 +11,7 @@
// Don't import this more than once // Don't import this more than once
import "../../../../node_modules/blueimp-gallery/js/blueimp-gallery.min"; import "../../../../node_modules/blueimp-gallery/js/blueimp-gallery.min";
import {LitElement} from "@lion/core"; import {html, LitElement, render} from "@lion/core";
import {et2_nextmatch} from "../et2_extension_nextmatch"; import {et2_nextmatch} from "../et2_extension_nextmatch";
import {Et2Dialog} from "../Et2Dialog/Et2Dialog"; import {Et2Dialog} from "../Et2Dialog/Et2Dialog";
import {ET2_DATAVIEW_STEPSIZE} from "../et2_dataview_controller"; import {ET2_DATAVIEW_STEPSIZE} from "../et2_dataview_controller";
@ -90,6 +90,12 @@ export function ExposeMixin<B extends Constructor<LitElement>>(superclass : B)
connectedCallback() connectedCallback()
{ {
super.connectedCallback(); super.connectedCallback();
if(document.body.querySelector('#blueimp-gallery') == null)
{
// Create Gallery DOM structure
render(this._galleryTemplate(), document.body);
}
} }
disconnectedCallback() disconnectedCallback()
@ -164,7 +170,6 @@ export function ExposeMixin<B extends Constructor<LitElement>>(superclass : B)
if(!this.exposeValue || typeof this.exposeValue.mime != 'string' || (!this.exposeValue.mime.match(MIME_REGEX, 'ig') if(!this.exposeValue || typeof this.exposeValue.mime != 'string' || (!this.exposeValue.mime.match(MIME_REGEX, 'ig')
&& (!fe || fe.mime && !fe.mime[this.exposeValue.mime])) || typeof this.exposeValue.download_url == 'undefined') && (!fe || fe.mime && !fe.mime[this.exposeValue.mime])) || typeof this.exposeValue.download_url == 'undefined')
{ {
this.removeEventListener("click", this.expose_onclick);
this.classList.remove("et2_clickable"); this.classList.remove("et2_clickable");
if(this._gallery) if(this._gallery)
{ {
@ -175,12 +180,24 @@ export function ExposeMixin<B extends Constructor<LitElement>>(superclass : B)
if(!this._gallery) if(!this._gallery)
{ {
this.addEventListener("click", this.expose_onclick);
this.classList.add("et2_clickable"); this.classList.add("et2_clickable");
this.addEventListener("click", this.expose_onclick);
// Normal click handler will handle it
} }
} }
/**
* Just override the normal click handler
*
* @param {MouseEvent} _ev
* @returns {boolean}
*/
_handleClick(_ev : MouseEvent) : boolean
{
this.expose_onclick(_ev)
return true;
}
get expose_options() get expose_options()
{ {
return { return {
@ -326,6 +343,22 @@ export function ExposeMixin<B extends Constructor<LitElement>>(superclass : B)
} }
} }
protected _galleryTemplate()
{
return html`
<div id="blueimp-gallery" class="blueimp-gallery">
<div class="slides"></div>
<h3 class="title"></h3>
<a class="prev"></a>
<a class="next"></a>
<a title="' + egw().lang('Close') + '" class="close">×</a><a
title="' + egw().lang('Play/Pause') + '" class="play-pause"></a><a
title="' + egw().lang('Fullscreen') + '" class="fullscreen"></a><a
title="' + egw().lang('Save') + '" class="download"></a>
<ol class="indicator"></ol>
</div>
`;
}
/** /**
* See if the current widget is in a nextmatch, as this allows us to display * See if the current widget is in a nextmatch, as this allows us to display
@ -360,9 +393,13 @@ export function ExposeMixin<B extends Constructor<LitElement>>(superclass : B)
private _init_blueimp_gallery(event, _value) private _init_blueimp_gallery(event, _value)
{ {
// Image list
let mediaContent = []; let mediaContent = [];
// We'll customise default options
let options = this.expose_options;
let nm = this.find_nextmatch(this); let nm = this.find_nextmatch(this);
let current_index = 0;
if(nm && !this._is_target_indepth(nm, event.target)) if(nm && !this._is_target_indepth(nm, event.target))
{ {
// Get the row that was clicked, find its index in the list // Get the row that was clicked, find its index in the list
@ -375,7 +412,7 @@ export function ExposeMixin<B extends Constructor<LitElement>>(superclass : B)
{ {
if('filemanager::' + mediaContent[i].path == current_entry.uid) if('filemanager::' + mediaContent[i].path == current_entry.uid)
{ {
current_index = i; options.index = i;
break; break;
} }
} }
@ -393,11 +430,15 @@ export function ExposeMixin<B extends Constructor<LitElement>>(superclass : B)
// @ts-ignore // @ts-ignore
mediaContent = this.getMedia(_value); mediaContent = this.getMedia(_value);
// Do not show thumbnail indicator on single expose view // Do not show thumbnail indicator on single expose view
this.expose_options.thumbnailIndicators = false; options.thumbnailIndicators = (mediaContent.length > 1);
if(!options.thumbnailIndicators)
{
options.indicatorContainer = 'nope';
}
} }
// @ts-ignore // @ts-ignore
this._gallery = new blueimp.Gallery(mediaContent, Object.assign(this.expose_options, {index: current_index})); this._gallery = new blueimp.Gallery(mediaContent, options);
} }
/** /**

View File

@ -37,6 +37,7 @@ import './Et2Date/Et2DateTimeReadonly';
import './Et2Date/Et2DateTimeToday'; import './Et2Date/Et2DateTimeToday';
import './Et2Description/Et2Description'; import './Et2Description/Et2Description';
import './Et2Dialog/Et2Dialog'; import './Et2Dialog/Et2Dialog';
import './Expose/Et2ImageExpose';
import './Et2Image/Et2Image'; import './Et2Image/Et2Image';
import './Et2Select/Et2Select'; import './Et2Select/Et2Select';
import './Et2Select/Et2SelectAccount'; import './Et2Select/Et2SelectAccount';