2020-02-11 16:35:57 +01:00
|
|
|
//import { MTDocument, ProgressivePreloader, wrapVideo } from "../../components/misc";
|
2020-02-06 16:43:07 +01:00
|
|
|
import appPeersManager from "./appPeersManager";
|
|
|
|
import appDialogsManager from "./appDialogsManager";
|
|
|
|
import appPhotosManager from "./appPhotosManager";
|
|
|
|
import appSidebarRight from "./appSidebarRight";
|
|
|
|
import { $rootScope } from "../utils";
|
|
|
|
import appMessagesManager from "./appMessagesManager";
|
2020-02-11 16:35:57 +01:00
|
|
|
//import { CancellablePromise } from "../mtproto/apiFileManager";
|
2020-02-06 16:43:07 +01:00
|
|
|
import { RichTextProcessor } from "../richtextprocessor";
|
2020-02-07 07:38:55 +01:00
|
|
|
import { logger } from "../polyfill";
|
2020-02-11 16:35:57 +01:00
|
|
|
import ProgressivePreloader from "../../components/preloader";
|
|
|
|
import { wrapVideo } from "../../components/wrappers";
|
2020-02-06 16:43:07 +01:00
|
|
|
|
2020-02-07 07:38:55 +01:00
|
|
|
export class AppMediaViewer {
|
2020-02-06 16:43:07 +01:00
|
|
|
private overlaysDiv = document.querySelector('.overlays') as HTMLDivElement;
|
2020-02-15 06:54:55 +01:00
|
|
|
private mediaViewerDiv = this.overlaysDiv.firstElementChild as HTMLDivElement;
|
2020-02-06 16:43:07 +01:00
|
|
|
private author = {
|
|
|
|
avatarEl: this.overlaysDiv.querySelector('.user-avatar') as HTMLDivElement,
|
|
|
|
nameEl: this.overlaysDiv.querySelector('.media-viewer-name') as HTMLDivElement,
|
|
|
|
date: this.overlaysDiv.querySelector('.media-viewer-date') as HTMLDivElement
|
|
|
|
};
|
|
|
|
private buttons = {
|
|
|
|
delete: this.overlaysDiv.querySelector('.media-viewer-delete-button') as HTMLDivElement,
|
|
|
|
forward: this.overlaysDiv.querySelector('.media-viewer-forward-button') as HTMLDivElement,
|
|
|
|
download: this.overlaysDiv.querySelector('.media-viewer-download-button') as HTMLDivElement,
|
|
|
|
close: this.overlaysDiv.querySelector('.media-viewer-close-button') as HTMLDivElement,
|
|
|
|
prev: this.overlaysDiv.querySelector('.media-viewer-switcher-left') as HTMLDivElement,
|
|
|
|
next: this.overlaysDiv.querySelector('.media-viewer-switcher-right') as HTMLDivElement,
|
|
|
|
};
|
|
|
|
private content = {
|
|
|
|
container: this.overlaysDiv.querySelector('.media-viewer-media') as HTMLDivElement,
|
2020-02-15 06:54:55 +01:00
|
|
|
caption: this.overlaysDiv.querySelector('.media-viewer-caption') as HTMLDivElement,
|
|
|
|
mover: this.overlaysDiv.querySelector('.media-viewer-mover') as HTMLDivElement
|
2020-02-06 16:43:07 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
private reverse = false;
|
2020-02-07 07:38:55 +01:00
|
|
|
public currentMessageID = 0;
|
2020-02-06 16:43:07 +01:00
|
|
|
private higherMsgID: number | undefined = 0;
|
|
|
|
private lowerMsgID: number | undefined = 0;
|
|
|
|
private preloader: ProgressivePreloader = null;
|
2020-02-07 07:38:55 +01:00
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
private lastTarget: HTMLElement = null;
|
|
|
|
private prevTarget: HTMLElement = null;
|
|
|
|
private nextTarget: HTMLElement = null;
|
|
|
|
|
2020-02-07 07:38:55 +01:00
|
|
|
public log: ReturnType<typeof logger>;
|
2020-02-06 16:43:07 +01:00
|
|
|
|
|
|
|
constructor() {
|
2020-02-07 07:38:55 +01:00
|
|
|
this.log = logger('AMV');
|
2020-02-06 16:43:07 +01:00
|
|
|
this.preloader = new ProgressivePreloader();
|
|
|
|
|
|
|
|
this.buttons.close.addEventListener('click', () => {
|
2020-02-15 06:54:55 +01:00
|
|
|
//this.overlaysDiv.classList.remove('active');
|
2020-02-06 16:43:07 +01:00
|
|
|
this.content.container.innerHTML = '';
|
2020-02-07 07:38:55 +01:00
|
|
|
this.currentMessageID = 0;
|
2020-02-15 06:54:55 +01:00
|
|
|
|
|
|
|
this.setMoverToTarget(this.lastTarget, true);
|
2020-02-06 16:43:07 +01:00
|
|
|
});
|
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
/* this.buttons.prev.addEventListener('click', () => {
|
2020-02-06 16:43:07 +01:00
|
|
|
let id = this.reverse ? this.lowerMsgID : this.higherMsgID;
|
|
|
|
if(id) {
|
|
|
|
this.openMedia(appMessagesManager.getMessage(id), this.reverse);
|
|
|
|
} else {
|
|
|
|
this.buttons.prev.style.display = 'none';
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.buttons.next.addEventListener('click', () => {
|
|
|
|
let id = this.reverse ? this.higherMsgID : this.lowerMsgID;
|
|
|
|
if(id) {
|
|
|
|
this.openMedia(appMessagesManager.getMessage(id), this.reverse);
|
|
|
|
} else {
|
|
|
|
this.buttons.next.style.display = 'none';
|
|
|
|
}
|
2020-02-15 06:54:55 +01:00
|
|
|
}); */
|
|
|
|
this.buttons.prev.addEventListener('click', () => {
|
|
|
|
let target = this.prevTarget;
|
|
|
|
if(target) {
|
|
|
|
target.click();
|
|
|
|
} else {
|
|
|
|
this.buttons.prev.style.display = 'none';
|
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
this.buttons.next.addEventListener('click', () => {
|
|
|
|
let target = this.nextTarget;
|
|
|
|
if(target) {
|
|
|
|
target.click();
|
|
|
|
} else {
|
|
|
|
this.buttons.next.style.display = 'none';
|
|
|
|
}
|
2020-02-06 16:43:07 +01:00
|
|
|
});
|
2020-02-14 10:30:06 +01:00
|
|
|
|
|
|
|
this.buttons.download.addEventListener('click', () => {
|
|
|
|
let message = appMessagesManager.getMessage(this.currentMessageID);
|
|
|
|
appPhotosManager.downloadPhoto(message.media.photo.id);
|
|
|
|
});
|
2020-02-15 06:54:55 +01:00
|
|
|
|
|
|
|
this.overlaysDiv.addEventListener('click', (e) => {
|
|
|
|
let target = e.target as HTMLElement;
|
|
|
|
|
|
|
|
if(target == this.mediaViewerDiv || target.tagName == 'IMG') {
|
|
|
|
this.buttons.close.click();
|
|
|
|
}
|
|
|
|
});
|
2020-02-06 16:43:07 +01:00
|
|
|
/* this.buttons.prev.onclick = (e) => {
|
|
|
|
let history = appSidebarRight.historiesStorage[$rootScope.selectedPeerID]['inputMessagesFilterPhotoVideo'].slice();
|
|
|
|
|
|
|
|
let message: any;
|
|
|
|
|
|
|
|
if(!this.reverse) {
|
|
|
|
for(let mid of history) {
|
|
|
|
if(mid > this.currentMessageID) {
|
|
|
|
let _message = appMessagesManager.getMessage(mid);
|
|
|
|
if(_message.media && _message.media.photo) {
|
|
|
|
message = _message;
|
|
|
|
}
|
|
|
|
} else break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for(let mid of history) {
|
|
|
|
if(mid < this.currentMessageID) {
|
|
|
|
let _message = appMessagesManager.getMessage(mid);
|
|
|
|
if(_message.media && _message.media.photo) {
|
|
|
|
message = _message;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(message) {
|
|
|
|
this.openMedia(message.media.photo, message.mid, this.reverse);
|
|
|
|
} else {
|
|
|
|
this.buttons.prev.style.display = 'none';
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
this.buttons.next.onclick = (e) => {
|
|
|
|
let history = appSidebarRight.historiesStorage[$rootScope.selectedPeerID]['inputMessagesFilterPhotoVideo'].slice();
|
|
|
|
|
|
|
|
let message: any;
|
|
|
|
|
|
|
|
if(this.reverse) {
|
|
|
|
for(let mid of history) {
|
|
|
|
if(mid > this.currentMessageID) {
|
|
|
|
let _message = appMessagesManager.getMessage(mid);
|
|
|
|
if(_message.media && _message.media.photo) {
|
|
|
|
message = _message;
|
|
|
|
}
|
|
|
|
} else break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
for(let mid of history) {
|
|
|
|
if(mid < this.currentMessageID) {
|
|
|
|
let _message = appMessagesManager.getMessage(mid);
|
|
|
|
if(_message.media && _message.media.photo) {
|
|
|
|
message = _message;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(message) {
|
|
|
|
this.openMedia(message.media.photo, message.mid, this.reverse);
|
|
|
|
} else {
|
|
|
|
this.buttons.next.style.display = 'none';
|
|
|
|
}
|
|
|
|
}; */
|
|
|
|
}
|
2020-02-15 06:54:55 +01:00
|
|
|
|
|
|
|
public setMoverToTarget(target: HTMLElement, closing = false) {
|
|
|
|
let mover = this.content.mover;
|
|
|
|
|
|
|
|
if(!closing) {
|
|
|
|
mover.innerHTML = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
let rect = target.getBoundingClientRect();
|
|
|
|
let containerRect = this.content.container.getBoundingClientRect();
|
|
|
|
let scaleX = rect.width / containerRect.width;
|
|
|
|
let scaleY = rect.height / containerRect.height;
|
|
|
|
mover.style.transform = `translate(${rect.left}px, ${rect.top}px) scale(${scaleX}, ${scaleY})`;
|
|
|
|
mover.style.width = containerRect.width + 'px';
|
|
|
|
mover.style.height = containerRect.height + 'px';
|
|
|
|
|
|
|
|
if(!closing) {
|
|
|
|
let img: HTMLImageElement;
|
|
|
|
let video: HTMLVideoElement;
|
|
|
|
|
|
|
|
if(target.tagName == 'DIV') { // means backgrounded with cover
|
|
|
|
//img.style.objectFit = 'cover';
|
|
|
|
img = new Image();
|
|
|
|
img.src = target.style.backgroundImage.slice(5, -2);
|
|
|
|
} else if(target.tagName == 'IMG') {
|
|
|
|
img = new Image();
|
|
|
|
img.src = (target as HTMLImageElement).src;
|
|
|
|
img.style.objectFit = 'contain';
|
|
|
|
} else if(target.tagName == 'VIDEO') {
|
|
|
|
video = document.createElement('video');
|
|
|
|
let source = document.createElement('source');
|
|
|
|
source.src = target.querySelector('source').src;
|
|
|
|
video.append(source);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(img) {
|
|
|
|
mover.appendChild(img);
|
|
|
|
} else if(video) {
|
|
|
|
mover.appendChild(video);
|
|
|
|
}
|
|
|
|
|
|
|
|
mover.style.display = '';
|
|
|
|
mover.classList.add('active');
|
|
|
|
} else {
|
|
|
|
setTimeout(() => {
|
|
|
|
this.overlaysDiv.classList.remove('active');
|
|
|
|
}, 125);
|
|
|
|
setTimeout(() => {
|
|
|
|
mover.innerHTML = '';
|
|
|
|
mover.classList.remove('active');
|
|
|
|
mover.style.display = 'none';
|
|
|
|
}, 250);
|
|
|
|
}
|
|
|
|
|
|
|
|
return () => {
|
|
|
|
mover.style.transform = `translate(${containerRect.left}px, ${containerRect.top}px) scale(1, 1)`;
|
|
|
|
};
|
|
|
|
}
|
2020-02-06 16:43:07 +01:00
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
public openMedia(message: any, reverse = false, target?: HTMLElement, prevTarget?: HTMLElement, nextTarget?: HTMLElement) {
|
|
|
|
this.log('openMedia doc:', message, prevTarget, nextTarget);
|
2020-02-10 15:51:24 +01:00
|
|
|
let media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo;
|
2020-02-06 16:43:07 +01:00
|
|
|
|
|
|
|
let isVideo = media.mime_type == 'video/mp4';
|
|
|
|
|
|
|
|
this.currentMessageID = message.mid;
|
|
|
|
this.reverse = reverse;
|
2020-02-15 06:54:55 +01:00
|
|
|
this.prevTarget = prevTarget || null;
|
|
|
|
this.nextTarget = nextTarget || null;
|
2020-02-06 16:43:07 +01:00
|
|
|
|
|
|
|
let container = this.content.container;
|
|
|
|
|
|
|
|
if(container.firstElementChild) {
|
2020-02-07 07:38:55 +01:00
|
|
|
container.innerHTML = '';
|
2020-02-06 16:43:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let date = new Date(media.date * 1000);
|
|
|
|
let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
|
|
|
|
|
|
let dateStr = months[date.getMonth()] + ' ' + date.getDate() + ' at '+ date.getHours() + ':' + ('0' + date.getMinutes()).slice(-2);
|
|
|
|
this.author.date.innerText = dateStr;
|
|
|
|
|
|
|
|
let name = appPeersManager.getPeerTitle(message.fromID);
|
2020-02-10 15:51:24 +01:00
|
|
|
this.author.nameEl.innerHTML = name;
|
2020-02-06 16:43:07 +01:00
|
|
|
|
|
|
|
if(message.message) {
|
|
|
|
this.content.caption.innerHTML = RichTextProcessor.wrapRichText(message.message, {
|
|
|
|
entities: message.totalEntities
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
this.content.caption.innerHTML = '';
|
|
|
|
}
|
|
|
|
|
|
|
|
appDialogsManager.loadDialogPhoto(this.author.avatarEl, message.fromID);
|
|
|
|
|
|
|
|
this.overlaysDiv.classList.add('active');
|
2020-02-07 15:17:39 +01:00
|
|
|
|
|
|
|
container.classList.add('loading');
|
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
// ok set
|
|
|
|
let mover = this.content.mover;
|
|
|
|
|
|
|
|
this.lastTarget = target;
|
|
|
|
//this.setMoverToTarget(target);
|
|
|
|
let maxWidth = appPhotosManager.windowW - 16;
|
|
|
|
let maxHeight = appPhotosManager.windowH - 100;
|
2020-02-06 16:43:07 +01:00
|
|
|
if(isVideo) {
|
2020-02-07 07:38:55 +01:00
|
|
|
//this.preloader.attach(container);
|
2020-02-06 16:43:07 +01:00
|
|
|
//this.preloader.setProgress(75);
|
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
let size = appPhotosManager.setAttachmentSize(media, container, maxWidth, maxHeight);
|
|
|
|
|
|
|
|
this.log('will wrap video', media, size);
|
|
|
|
|
|
|
|
let afterTimeout = this.setMoverToTarget(target);
|
|
|
|
|
|
|
|
setTimeout(() => {
|
|
|
|
afterTimeout();
|
|
|
|
|
|
|
|
wrapVideo.call(this, media, mover, message, false, this.preloader).then(() => {
|
|
|
|
if(this.currentMessageID != message.mid) {
|
|
|
|
this.log.warn('media viewer changed video');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
2020-02-10 15:51:24 +01:00
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
/* appPhotosManager.setAttachmentSize(media, container, appPhotosManager.windowW, appPhotosManager.windowH);
|
2020-02-07 15:17:39 +01:00
|
|
|
wrapVideo.call(this, media, container, message, false, this.preloader).then(() => {
|
2020-02-10 15:51:24 +01:00
|
|
|
if(this.currentMessageID != message.mid) {
|
|
|
|
this.log.warn('media viewer changed video');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-02-07 15:17:39 +01:00
|
|
|
container.classList.remove('loading');
|
2020-02-10 15:51:24 +01:00
|
|
|
container.style.width = '';
|
|
|
|
container.style.height = '';
|
2020-02-15 06:54:55 +01:00
|
|
|
}); */
|
2020-02-06 16:43:07 +01:00
|
|
|
} else {
|
2020-02-15 06:54:55 +01:00
|
|
|
let size = appPhotosManager.setAttachmentSize(media.id, container, maxWidth, maxHeight);
|
|
|
|
|
|
|
|
let afterTimeout = this.setMoverToTarget(target);
|
2020-02-06 16:43:07 +01:00
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
setTimeout(() => {
|
|
|
|
afterTimeout();
|
|
|
|
this.preloader.attach(mover);
|
2020-02-07 15:17:39 +01:00
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
let cancellablePromise = appPhotosManager.preloadPhoto(media.id, size);
|
|
|
|
cancellablePromise.then((blob) => {
|
|
|
|
if(this.currentMessageID != message.mid) {
|
|
|
|
this.log.warn('media viewer changed photo');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
this.log('indochina', blob);
|
|
|
|
|
|
|
|
let image = mover.firstElementChild as HTMLImageElement || new Image();
|
|
|
|
image.src = URL.createObjectURL(blob);
|
|
|
|
mover.append(image);
|
|
|
|
|
|
|
|
this.preloader.detach();
|
|
|
|
}).catch(err => {
|
|
|
|
this.log.error(err);
|
|
|
|
});
|
|
|
|
}, 0);
|
2020-02-06 16:43:07 +01:00
|
|
|
}
|
|
|
|
|
2020-02-15 06:54:55 +01:00
|
|
|
/* let history = appSidebarRight.historiesStorage[$rootScope.selectedPeerID]['inputMessagesFilterPhotoVideo'].slice();
|
2020-02-06 16:43:07 +01:00
|
|
|
let index = history.findIndex(m => m == message.mid);
|
|
|
|
let comparer = (mid: number) => {
|
|
|
|
let _message = appMessagesManager.getMessage(mid);
|
2020-02-13 12:59:55 +01:00
|
|
|
let media = _message.media;
|
|
|
|
|
|
|
|
if(media && (media.photo || (media.document && ['video', 'gif'].indexOf(media.document.type) !== -1))) return true;
|
2020-02-06 16:43:07 +01:00
|
|
|
return false;
|
|
|
|
};
|
|
|
|
|
|
|
|
this.higherMsgID = history.slice(0, index).reverse().find(comparer);
|
|
|
|
this.lowerMsgID = history.slice(index + 1).find(comparer);
|
|
|
|
|
|
|
|
if(this.reverse) {
|
|
|
|
this.buttons.prev.style.display = this.lowerMsgID !== undefined ? '' : 'none';
|
|
|
|
this.buttons.next.style.display = this.higherMsgID !== undefined ? '' : 'none';
|
|
|
|
} else {
|
|
|
|
this.buttons.prev.style.display = this.higherMsgID !== undefined ? '' : 'none';
|
|
|
|
this.buttons.next.style.display = this.lowerMsgID !== undefined ? '' : 'none';
|
2020-02-15 06:54:55 +01:00
|
|
|
} */
|
|
|
|
|
|
|
|
this.buttons.prev.style.display = this.prevTarget ? '' : 'none';
|
|
|
|
this.buttons.next.style.display = this.nextTarget ? '' : 'none';
|
2020-02-06 16:43:07 +01:00
|
|
|
|
|
|
|
//console.log('prev and next', prevMsgID, nextMsgID);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default new AppMediaViewer();
|