Browse Source

Search: open documents in media viewer

Zoom: added downscaling
master
Eduard Kuzmenko 3 years ago
parent
commit
ea01b0edf7
  1. 65
      src/components/appMediaViewer.ts
  2. 22
      src/components/appSearchSuper..ts

65
src/components/appMediaViewer.ts

@ -52,11 +52,10 @@ import { doubleRaf, fastRaf } from "../helpers/schedulers";
import { attachClickEvent } from "../helpers/dom/clickEvent"; import { attachClickEvent } from "../helpers/dom/clickEvent";
import PopupDeleteMessages from "./popups/deleteMessages"; import PopupDeleteMessages from "./popups/deleteMessages";
import RangeSelector from "./rangeSelector"; import RangeSelector from "./rangeSelector";
import attachGrabListeners, { GrabEvent } from "../helpers/dom/attachGrabListeners";
const ZOOM_STEP = 0.5; const ZOOM_STEP = 0.5;
const ZOOM_INITIAL_VALUE = 1; const ZOOM_INITIAL_VALUE = 1;
const ZOOM_MIN_VALUE = 1; const ZOOM_MIN_VALUE = 0.5;
const ZOOM_MAX_VALUE = 4; const ZOOM_MAX_VALUE = 4;
// TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию // TODO: масштабирование картинок (не SVG) при ресайзе, и правильный возврат на исходную позицию
@ -193,7 +192,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
this.zoomElements.btnIn = ButtonIcon('zoomin', {noRipple: true}); this.zoomElements.btnIn = ButtonIcon('zoomin', {noRipple: true});
this.zoomElements.btnIn.addEventListener('click', () => this.changeZoom(true)); this.zoomElements.btnIn.addEventListener('click', () => this.changeZoom(true));
this.zoomElements.rangeSelector = new RangeSelector(ZOOM_STEP, ZOOM_INITIAL_VALUE + ZOOM_STEP, ZOOM_MIN_VALUE, ZOOM_MAX_VALUE, true); this.zoomElements.rangeSelector = new RangeSelector(ZOOM_STEP, ZOOM_INITIAL_VALUE, ZOOM_MIN_VALUE, ZOOM_MAX_VALUE, true);
this.zoomElements.rangeSelector.setListeners(); this.zoomElements.rangeSelector.setListeners();
this.zoomElements.rangeSelector.setHandlers({ this.zoomElements.rangeSelector.setHandlers({
onScrub: this.setZoomValue, onScrub: this.setZoomValue,
@ -272,7 +271,12 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
} }
}); });
this.buttons.zoom.addEventListener('click', () => this.toggleZoom()); this.buttons.zoom.addEventListener('click', () => {
if(this.isZooming()) this.toggleZoom(false);
else {
this.changeZoom(true);
}
});
this.wholeDiv.addEventListener('click', this.onClick); this.wholeDiv.addEventListener('click', this.onClick);
@ -332,7 +336,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
this.buttons.zoom.classList.toggle('zoom-in', !enable); this.buttons.zoom.classList.toggle('zoom-in', !enable);
this.zoomElements.container.classList.toggle('is-visible', enable); this.zoomElements.container.classList.toggle('is-visible', enable);
const zoomValue = enable ? ZOOM_INITIAL_VALUE + ZOOM_STEP : 1; const zoomValue = enable ? this.zoomElements.rangeSelector.value : 1;
this.setZoomValue(zoomValue); this.setZoomValue(zoomValue);
if(this.videoPlayer) { if(this.videoPlayer) {
@ -389,7 +393,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
this.zoomElements.btnOut.classList.toggle('inactive', value === ZOOM_MIN_VALUE); this.zoomElements.btnOut.classList.toggle('inactive', value === ZOOM_MIN_VALUE);
this.zoomElements.btnIn.classList.toggle('inactive', value === ZOOM_MAX_VALUE); this.zoomElements.btnIn.classList.toggle('inactive', value === ZOOM_MAX_VALUE);
this.toggleZoom(value > ZOOM_INITIAL_VALUE); this.toggleZoom(value !== ZOOM_INITIAL_VALUE);
}; };
protected isZooming() { protected isZooming() {
@ -435,7 +439,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
window.removeEventListener('keydown', this.onKeyDown); window.removeEventListener('keydown', this.onKeyDown);
window.removeEventListener('keyup', this.onKeyUp); window.removeEventListener('keyup', this.onKeyUp);
window.removeEventListener('wheel', this.onWheel); window.removeEventListener('wheel', this.onWheel, {capture: true});
promise.finally(() => { promise.finally(() => {
this.wholeDiv.remove(); this.wholeDiv.remove();
@ -493,7 +497,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
return; return;
} }
let good = true; // let good = true;
if(e.key === 'ArrowRight') { if(e.key === 'ArrowRight') {
this.buttons.next.click(); this.buttons.next.click();
} else if(e.key === 'ArrowLeft') { } else if(e.key === 'ArrowLeft') {
@ -502,17 +506,17 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
if(this.ctrlKeyDown) { if(this.ctrlKeyDown) {
this.changeZoom(e.key === '='); this.changeZoom(e.key === '=');
} }
} else { }/* else {
good = false; good = false;
} } */
if(e.ctrlKey || e.metaKey) { if(e.ctrlKey || e.metaKey) {
this.ctrlKeyDown = true; this.ctrlKeyDown = true;
} }
if(good) { // if(good) {
cancelEvent(e); cancelEvent(e);
} // }
}; };
private onKeyUp = (e: KeyboardEvent) => { private onKeyUp = (e: KeyboardEvent) => {
@ -538,6 +542,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
if(this.ctrlKeyDown) { if(this.ctrlKeyDown) {
const scrollingUp = e.deltaY < 0; const scrollingUp = e.deltaY < 0;
// if(!scrollingUp && !this.isZooming()) return;
this.changeZoom(!!scrollingUp); this.changeZoom(!!scrollingUp);
} }
}; };
@ -577,7 +582,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
let rect: DOMRect; let rect: DOMRect;
if(target) { if(target) {
if(target instanceof AvatarElement || target.classList.contains('grid-item')) { if(target instanceof AvatarElement || target.classList.contains('grid-item')/* || target.classList.contains('document-ico') */) {
realParent = target; realParent = target;
rect = target.getBoundingClientRect(); rect = target.getBoundingClientRect();
} else if(target instanceof SVGImageElement || target.parentElement instanceof SVGForeignObjectElement) { } else if(target instanceof SVGImageElement || target.parentElement instanceof SVGForeignObjectElement) {
@ -631,13 +636,13 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
top = rect.top; top = rect.top;
} }
if(zoomValue > 1) { // 33 /* if(zoomValue > 1) { // 33
// const diffX = (rect.width * zoomValue - rect.width) / 4; // const diffX = (rect.width * zoomValue - rect.width) / 4;
const diffX = (rect.width * zoomValue - rect.width) / 2; const diffX = (rect.width * zoomValue - rect.width) / 2;
const diffY = (rect.height * zoomValue - rect.height) / 4; const diffY = (rect.height * zoomValue - rect.height) / 4;
// left -= diffX; // left -= diffX;
// top += diffY; // top += diffY;
} } */
transform += `translate3d(${left}px,${top}px,0) `; transform += `translate3d(${left}px,${top}px,0) `;
@ -697,8 +702,8 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
//let borderRadius = '0px 0px 0px 0px'; //let borderRadius = '0px 0px 0px 0px';
if(closing && zoomValue > 1) { if(closing && zoomValue > 1) {
const width = this.moversContainer.scrollWidth * scaleX; // const width = this.moversContainer.scrollWidth * scaleX;
const height = this.moversContainer.scrollHeight * scaleY; // const height = this.moversContainer.scrollHeight * scaleY;
const willBeLeft = appPhotosManager.windowW / 2 - rect.width / 2; const willBeLeft = appPhotosManager.windowW / 2 - rect.width / 2;
const willBeTop = appPhotosManager.windowH / 2 - rect.height / 2; const willBeTop = appPhotosManager.windowH / 2 - rect.height / 2;
const left = rect.left - willBeLeft/* + (width - rect.width) / 2 */; const left = rect.left - willBeLeft/* + (width - rect.width) / 2 */;
@ -870,7 +875,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
this.wholeDiv.classList.remove('active'); this.wholeDiv.classList.remove('active');
}, 0); }, 0);
return ret; //return ret;
setTimeout(() => { setTimeout(() => {
mover.style.borderRadius = borderRadius; mover.style.borderRadius = borderRadius;
@ -1076,19 +1081,21 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
//if(target instanceof SVGSVGElement) { //if(target instanceof SVGSVGElement) {
const el = target.tagName.toLowerCase() === tagName ? target : target.querySelector(tagName) as HTMLElement; const el = target.tagName.toLowerCase() === tagName ? target : target.querySelector(tagName) as HTMLElement;
if(el) { if(el) {
// two parentElements because element can be contained in aspecter if(!target.classList.contains('document-ico') && findUpClassName(target, 'attachment')) {
const preloader = target.parentElement.parentElement.querySelector('.preloader-container') as HTMLElement; // two parentElements because element can be contained in aspecter
if(preloader) { const preloader = target.parentElement.parentElement.querySelector('.preloader-container') as HTMLElement;
if(tagName === 'video') { if(preloader) {
if(preloader.classList.contains('manual')) { if(tagName === 'video') {
preloader.click(); if(preloader.classList.contains('manual')) {
// return; preloader.click();
// return;
}
return;
} }
return; preloader.remove();
} }
preloader.remove();
} }
renderImageFromUrl(el, url); renderImageFromUrl(el, url);
@ -1226,7 +1233,7 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
} else { } else {
window.addEventListener('keydown', this.onKeyDown); window.addEventListener('keydown', this.onKeyDown);
window.addEventListener('keyup', this.onKeyUp); window.addEventListener('keyup', this.onKeyUp);
if(!isTouchSupported) window.addEventListener('wheel', this.onWheel, {passive: false}); if(!isTouchSupported) window.addEventListener('wheel', this.onWheel, {passive: false, capture: true});
const mainColumns = this.pageEl.querySelector('#main-columns'); const mainColumns = this.pageEl.querySelector('#main-columns');
this.pageEl.insertBefore(this.wholeDiv, mainColumns); this.pageEl.insertBefore(this.wholeDiv, mainColumns);
void this.wholeDiv.offsetLeft; // reflow void this.wholeDiv.offsetLeft; // reflow

22
src/components/appSearchSuper..ts

@ -275,8 +275,8 @@ export default class AppSearchSuper {
this.onTransitionEnd(); this.onTransitionEnd();
}, undefined, navScrollable); }, undefined, navScrollable);
this.tabs.inputMessagesFilterPhotoVideo.addEventListener('click', (e) => { const onMediaClick = (className: string, targetClassName: string, inputFilter: MyInputMessagesFilter, e: MouseEvent) => {
const target = findUpClassName(e.target as HTMLDivElement, 'grid-item'); const target = findUpClassName(e.target as HTMLDivElement, className);
const mid = +target.dataset.mid; const mid = +target.dataset.mid;
if(!mid) { if(!mid) {
@ -286,8 +286,13 @@ export default class AppSearchSuper {
const peerId = +target.dataset.peerId; const peerId = +target.dataset.peerId;
const targets = (Array.from(this.tabs.inputMessagesFilterPhotoVideo.querySelectorAll('.grid-item')) as HTMLElement[]).map(el => { const targets = (Array.from(this.tabs[inputFilter].querySelectorAll('.' + targetClassName)) as HTMLElement[]).map(el => {
return {element: el, mid: +el.dataset.mid, peerId: +el.dataset.peerId}; const containerEl = findUpClassName(el, className);
return {
element: el,
mid: +containerEl.dataset.mid,
peerId: +containerEl.dataset.peerId
};
}); });
//const ids = Object.keys(this.mediaDivsByIds).map(k => +k).sort((a, b) => a - b); //const ids = Object.keys(this.mediaDivsByIds).map(k => +k).sort((a, b) => a - b);
@ -295,9 +300,12 @@ export default class AppSearchSuper {
const message = appMessagesManager.getMessageByPeer(peerId, mid); const message = appMessagesManager.getMessageByPeer(peerId, mid);
new AppMediaViewer() new AppMediaViewer()
.setSearchContext(this.copySearchContext(this.mediaTab.inputFilter)) .setSearchContext(this.copySearchContext(inputFilter))
.openMedia(message, target, 0, false, targets.slice(0, idx), targets.slice(idx + 1)); .openMedia(message, targets[idx].element, 0, false, targets.slice(0, idx), targets.slice(idx + 1));
}); };
this.tabs.inputMessagesFilterPhotoVideo.addEventListener('click', onMediaClick.bind(null, 'grid-item', 'grid-item', 'inputMessagesFilterPhotoVideo'));
this.tabs.inputMessagesFilterDocument.addEventListener('click', onMediaClick.bind(null, 'document-with-thumb', 'media-container', 'inputMessagesFilterDocument'));
this.mediaTab = this.mediaTabs[0]; this.mediaTab = this.mediaTabs[0];

Loading…
Cancel
Save