From 26c95ac6f6f44d624bdf246c100e4c33c392764a Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Sat, 15 Feb 2020 15:22:33 +0700 Subject: [PATCH] new mediaviewer animation delay & clearing empty divs in chat --- src/components/scrollable.ts | 2 + src/lib/appManagers/appImManager.ts | 68 +++++++++-- src/lib/appManagers/appMediaViewer.ts | 141 ++-------------------- src/lib/appManagers/appMessagesManager.ts | 40 ++++-- src/lib/appManagers/appSidebarRight.ts | 2 +- src/lib/mtproto/apiFileManager.ts | 2 +- src/scss/partials/_mediaViewer.scss | 3 +- src/scss/style.scss | 12 +- 8 files changed, 110 insertions(+), 160 deletions(-) diff --git a/src/components/scrollable.ts b/src/components/scrollable.ts index 0beda155..3bba42c0 100644 --- a/src/components/scrollable.ts +++ b/src/components/scrollable.ts @@ -284,6 +284,8 @@ export default class Scrollable { } if(this.onAddedBottom) this.onAddedBottom(); + } else { + this.paddingBottomDiv.style.height = '0px'; } //console.log('onscroll', container, firstVisible, lastVisible, hiddenElements); diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts index 14b7f064..ad99bb30 100644 --- a/src/lib/appManagers/appImManager.ts +++ b/src/lib/appManagers/appImManager.ts @@ -529,7 +529,6 @@ export class AppImManager { public peerID = 0; public muted = false; - public lastDialog: any; public bubbles: {[mid: number]: HTMLDivElement} = {}; public dateMessages: {[timestamp: number]: { div: HTMLDivElement, firstTimestamp: number }} = {}; public unreaded: number[] = []; @@ -618,6 +617,8 @@ export class AppImManager { let message = appMessagesManager.getMessage(mid); //this.log('history_update', this.bubbles[mid], mid, message); this.renderMessage(message, false, false, bubble); + + this.deleteEmptySideDivs(); } }); @@ -639,6 +640,7 @@ export class AppImManager { } = e.detail; this.deleteMessagesByIDs(Object.keys(detail.msgs).map(s => +s)); + this.deleteEmptySideDivs(); }); // Calls when message successfully sent and we have an ID @@ -816,7 +818,7 @@ export class AppImManager { return; } - appMediaViewer.openMedia(message, true, target as HTMLImageElement); + appMediaViewer.openMedia(message, target as HTMLImageElement); } //console.log('chatInner click', e); @@ -844,7 +846,7 @@ export class AppImManager { //if(target.tagName == 'INPUT') return; - this.log('onkeydown', e); + //this.log('onkeydown', e); if(this.chatInputC.attachMediaPopUp.container.classList.contains('active')) { if(target.tagName != 'INPUT') { @@ -1011,8 +1013,10 @@ export class AppImManager { }); this.goDownBtn.addEventListener('click', () => { - if(this.lastDialog) { - this.setPeer(this.peerID, this.lastDialog.top_message); + let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0]; + + if(dialog) { + this.setPeer(this.peerID, dialog.top_message); } else { this.scroll.scrollTop = this.scroll.scrollHeight; } @@ -1055,6 +1059,35 @@ export class AppImManager { }); } + public deleteEmptySideDivs() { + let nodes = Array.from(this.chatInner.childNodes) as HTMLDivElement[]; + nodes.filter((node) => { + let childElementCount = node.childElementCount; + + if(!childElementCount) { + node.remove(); + return false; + } else if(childElementCount == 1) { + let child = node.firstElementChild; + if(child.classList.contains('service')) { + node.remove(); + return false; + } + } + + return true; + }).forEach(node => { + let nextNode = node.nextElementSibling; + if(nextNode && node.className == nextNode.className) { + (Array.from(node.childNodes) as HTMLDivElement[]).reverse().forEach(div => { + nextNode.prepend(div); + }); + + node.remove(); + } + }); + } + public loadMediaQueuePush(cb: () => Promise) { this.loadMediaQueue.push(cb); this.loadMediaQueueProcess(); @@ -1220,7 +1253,7 @@ export class AppImManager { } */ // if scroll down after search - if(!willLoad && (!dialog || history.indexOf(/* this.lastDialog */dialog.top_message) === -1)) { + if(!willLoad && (!dialog || history.indexOf(dialog.top_message) === -1)) { let lastMsgIDs = history.slice(-10); for(let msgID of lastMsgIDs) { let bubble = this.bubbles[msgID]; @@ -1384,13 +1417,17 @@ export class AppImManager { let samePeer = this.peerID == peerID; + appMessagesManager.readHistory(this.peerID, lastMsgID); // lol + if(samePeer) { if(!testScroll && !lastMsgID) { return Promise.resolve(true); } if(this.bubbles[lastMsgID]) { - if(this.lastDialog && lastMsgID == this.lastDialog.top_message) { + let dialog = appMessagesManager.getDialogByPeerID(peerID)[0]; + + if(dialog && lastMsgID == dialog.top_message) { this.scroll.scrollTop = this.scroll.scrollHeight; } else { this.bubbles[lastMsgID].scrollIntoView(); @@ -1416,7 +1453,7 @@ export class AppImManager { this.preloader.attach(this.chatInner); - let dialog = this.lastDialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null; + let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null; this.log('setPeer peerID:', this.peerID, dialog, lastMsgID); appDialogsManager.loadDialogPhoto(this.avatarEl, this.peerID); appDialogsManager.loadDialogPhoto(appSidebarRight.profileElements.avatar, this.peerID); @@ -1529,6 +1566,15 @@ export class AppImManager { public deleteMessagesByIDs(msgIDs: number[]) { msgIDs.forEach(id => { + if(this.firstTopMsgID == id) { + let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0]; + + if(dialog) { + this.log('setting firstTopMsgID after delete:', id, dialog.top_message, dialog); + this.firstTopMsgID = dialog.top_message; + } + } + if(!(id in this.bubbles)) return; let bubble = this.bubbles[id]; @@ -1546,6 +1592,7 @@ export class AppImManager { public renderMessagesByIDs(msgIDs: number[]) { if(!this.bubbles[this.firstTopMsgID]) { // seems search active + this.log('seems search is active, skipping render:', msgIDs); return; } @@ -2132,8 +2179,9 @@ export class AppImManager { public getHistory(maxID = 0, reverse = false, isBackLimit = false) { let peerID = this.peerID; - if(!maxID && this.lastDialog && this.lastDialog.top_message) { - maxID = this.lastDialog.top_message/* + 1 */; + let dialog = appMessagesManager.getDialogByPeerID(peerID)[0]; + if(!maxID && dialog && dialog.top_message) { + maxID = dialog.top_message/* + 1 */; } let loadCount = Object.keys(this.bubbles).length > 0 ? diff --git a/src/lib/appManagers/appMediaViewer.ts b/src/lib/appManagers/appMediaViewer.ts index 42c83de4..5e3c33cb 100644 --- a/src/lib/appManagers/appMediaViewer.ts +++ b/src/lib/appManagers/appMediaViewer.ts @@ -1,11 +1,7 @@ -//import { MTDocument, ProgressivePreloader, wrapVideo } from "../../components/misc"; import appPeersManager from "./appPeersManager"; import appDialogsManager from "./appDialogsManager"; import appPhotosManager from "./appPhotosManager"; -import appSidebarRight from "./appSidebarRight"; -import { $rootScope } from "../utils"; import appMessagesManager from "./appMessagesManager"; -//import { CancellablePromise } from "../mtproto/apiFileManager"; import { RichTextProcessor } from "../richtextprocessor"; import { logger } from "../polyfill"; import ProgressivePreloader from "../../components/preloader"; @@ -33,10 +29,7 @@ export class AppMediaViewer { mover: this.overlaysDiv.querySelector('.media-viewer-mover') as HTMLDivElement }; - private reverse = false; public currentMessageID = 0; - private higherMsgID: number | undefined = 0; - private lowerMsgID: number | undefined = 0; private preloader: ProgressivePreloader = null; private lastTarget: HTMLElement = null; @@ -57,23 +50,6 @@ export class AppMediaViewer { this.setMoverToTarget(this.lastTarget, true); }); - /* this.buttons.prev.addEventListener('click', () => { - 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'; - } - }); */ this.buttons.prev.addEventListener('click', () => { let target = this.prevTarget; if(target) { @@ -104,71 +80,6 @@ export class AppMediaViewer { this.buttons.close.click(); } }); - /* 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'; - } - }; */ } public setMoverToTarget(target: HTMLElement, closing = false) { @@ -186,6 +97,8 @@ export class AppMediaViewer { mover.style.width = containerRect.width + 'px'; mover.style.height = containerRect.height + 'px'; + mover.style.borderRadius = window.getComputedStyle(target.parentElement).getPropertyValue('border-radius'); + if(!closing) { let img: HTMLImageElement; let video: HTMLVideoElement; @@ -216,27 +129,30 @@ export class AppMediaViewer { } else { setTimeout(() => { this.overlaysDiv.classList.remove('active'); - }, 125); + }, 200 / 2); setTimeout(() => { mover.innerHTML = ''; mover.classList.remove('active'); mover.style.display = 'none'; - }, 250); + }, 200); } return () => { mover.style.transform = `translate(${containerRect.left}px, ${containerRect.top}px) scale(1, 1)`; + + setTimeout(() => { + mover.style.borderRadius = ''; + }, 200 / 2); }; } - public openMedia(message: any, reverse = false, target?: HTMLElement, prevTarget?: HTMLElement, nextTarget?: HTMLElement) { + public openMedia(message: any, target?: HTMLElement, prevTarget?: HTMLElement, nextTarget?: HTMLElement) { this.log('openMedia doc:', message, prevTarget, nextTarget); let media = message.media.photo || message.media.document || message.media.webpage.document || message.media.webpage.photo; let isVideo = media.mime_type == 'video/mp4'; this.currentMessageID = message.mid; - this.reverse = reverse; this.prevTarget = prevTarget || null; this.nextTarget = nextTarget || null; @@ -273,13 +189,9 @@ export class AppMediaViewer { let mover = this.content.mover; this.lastTarget = target; - //this.setMoverToTarget(target); let maxWidth = appPhotosManager.windowW - 16; let maxHeight = appPhotosManager.windowH - 100; if(isVideo) { - //this.preloader.attach(container); - //this.preloader.setProgress(75); - let size = appPhotosManager.setAttachmentSize(media, container, maxWidth, maxHeight); this.log('will wrap video', media, size); @@ -296,18 +208,6 @@ export class AppMediaViewer { } }); }); - - /* appPhotosManager.setAttachmentSize(media, container, appPhotosManager.windowW, appPhotosManager.windowH); - wrapVideo.call(this, media, container, message, false, this.preloader).then(() => { - if(this.currentMessageID != message.mid) { - this.log.warn('media viewer changed video'); - return; - } - - container.classList.remove('loading'); - container.style.width = ''; - container.style.height = ''; - }); */ } else { let size = appPhotosManager.setAttachmentSize(media.id, container, maxWidth, maxHeight); @@ -337,31 +237,8 @@ export class AppMediaViewer { }, 0); } - /* let history = appSidebarRight.historiesStorage[$rootScope.selectedPeerID]['inputMessagesFilterPhotoVideo'].slice(); - let index = history.findIndex(m => m == message.mid); - let comparer = (mid: number) => { - let _message = appMessagesManager.getMessage(mid); - let media = _message.media; - - if(media && (media.photo || (media.document && ['video', 'gif'].indexOf(media.document.type) !== -1))) return true; - 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'; - } */ - this.buttons.prev.style.display = this.prevTarget ? '' : 'none'; this.buttons.next.style.display = this.nextTarget ? '' : 'none'; - - //console.log('prev and next', prevMsgID, nextMsgID); } } diff --git a/src/lib/appManagers/appMessagesManager.ts b/src/lib/appManagers/appMessagesManager.ts index 16ae53f3..c72172ca 100644 --- a/src/lib/appManagers/appMessagesManager.ts +++ b/src/lib/appManagers/appMessagesManager.ts @@ -974,7 +974,7 @@ export class AppMessagesManager { } public pushDialogToStorage(dialog: any, offsetDate?: number) { - var dialogs = this.dialogsStorage.dialogs; + var dialogs = this.dialogsStorage.dialogs/* .filter(d => d.folder_id == dialog.folder_id) */; var pos = this.getDialogByPeerID(dialog.peerID)[1]; if(pos !== undefined) { dialogs.splice(pos, 1); @@ -1346,9 +1346,18 @@ export class AppMessagesManager { } if(topMessage) { - var wasBefore = this.getDialogByPeerID(peerID).length > 0; + let wasDialogBefore = this.getDialogByPeerID(peerID)[0]; + + // here need to just replace, not FULL replace dialog! WARNING + if(wasDialogBefore.pFlags.pinned) { + if(!dialog.pFlags) dialog.pFlags = {}; + dialog.pFlags.pinned = true; + dialog.pinnedIndex = wasDialogBefore.pinnedIndex; + } + this.saveConversation(dialog); - if(wasBefore) { + + if(wasDialogBefore) { this.clearDialogCache(topMessage); $rootScope.$broadcast('dialog_top', dialog); } else { @@ -1425,7 +1434,6 @@ export class AppMessagesManager { dialog.top_message = mid; dialog.read_inbox_max_id = appMessagesIDsManager.getFullMessageID(dialog.read_inbox_max_id, channelID); - dialog.read_outbox_max_id = appMessagesIDsManager.getFullMessageID(dialog.read_outbox_max_id, channelID); var topDate = message.date; @@ -1439,8 +1447,10 @@ export class AppMessagesManager { if(savedDraft && savedDraft.date > topDate) { topDate = savedDraft.date; } + if(dialog.pFlags.pinned) { - topDate = this.generateDialogPinnedDate(); + topDate = this.generateDialogPinnedDate(dialog); + //console.log('topDate', peerID, topDate); } dialog.index = this.generateDialogIndex(topDate); @@ -2015,8 +2025,20 @@ export class AppMessagesManager { }); } - public generateDialogPinnedDate() { - return 0x7fffff00 + ((this.pinnedIndex++) & 0xff); + public generateDialogPinnedDate(dialog?: any) { + let pinnedIndex: number; + + if(dialog) { + if(dialog.pinnedIndex) { + pinnedIndex = dialog.pinnedIndex; + } else { + dialog.pinnedIndex = pinnedIndex = this.pinnedIndex++; + } + } else { + pinnedIndex = this.pinnedIndex++; + } + + return 0x7fffff00 + (pinnedIndex & 0xff); } public handleNewMessages() { @@ -2383,7 +2405,7 @@ export class AppMessagesManager { } var dialog = foundDialog[0]; - dialog.index = this.generateDialogIndex(this.generateDialogPinnedDate()); + dialog.index = this.generateDialogIndex(this.generateDialogPinnedDate(dialog)); dialog.pFlags.pinned = true; break; } @@ -2428,7 +2450,7 @@ export class AppMessagesManager { } var dialog = foundDialog[0] - dialog.index = this.generateDialogIndex(this.generateDialogPinnedDate()); + dialog.index = this.generateDialogIndex(this.generateDialogPinnedDate(dialog)); dialog.pFlags.pinned = true; this.newDialogsToHandle[peerID] = dialog diff --git a/src/lib/appManagers/appSidebarRight.ts b/src/lib/appManagers/appSidebarRight.ts index b39ca7d6..c1903737 100644 --- a/src/lib/appManagers/appSidebarRight.ts +++ b/src/lib/appManagers/appSidebarRight.ts @@ -146,7 +146,7 @@ class AppSidebarRight { let prev = ids[idx + 1] || null; let next = ids[idx - 1] || null; - appMediaViewer.openMedia(message, false, target, this.mediaDivsByIDs[prev] || null, this.mediaDivsByIDs[next] || null); + appMediaViewer.openMedia(message, target, this.mediaDivsByIDs[prev] || null, this.mediaDivsByIDs[next] || null); }); this.profileElements.notificationsCheckbox.addEventListener('change', () => { diff --git a/src/lib/mtproto/apiFileManager.ts b/src/lib/mtproto/apiFileManager.ts index e6860a7e..12b116bf 100644 --- a/src/lib/mtproto/apiFileManager.ts +++ b/src/lib/mtproto/apiFileManager.ts @@ -276,7 +276,7 @@ export class ApiFileManager { var cachedPromise = this.cachedSavePromises[fileName] || this.cachedDownloadPromises[fileName]; var fileStorage = this.getFileStorage(); - this.log('downloadFile', fileStorage.name, fileName, fileName.length, location, arguments); + //this.log('downloadFile', fileStorage.name, fileName, fileName.length, location, arguments); if(cachedPromise) { if(toFileEntry) { diff --git a/src/scss/partials/_mediaViewer.scss b/src/scss/partials/_mediaViewer.scss index 9f17836f..1481dca9 100644 --- a/src/scss/partials/_mediaViewer.scss +++ b/src/scss/partials/_mediaViewer.scss @@ -184,6 +184,7 @@ left: 0; top: 0; transform-origin: top left; + overflow: hidden; .ckin__player { width: 100%; @@ -197,7 +198,7 @@ } &.active { - transition: .25s all; + transition: .2s all; } } } diff --git a/src/scss/style.scss b/src/scss/style.scss index 8abb0cb1..becac186 100644 --- a/src/scss/style.scss +++ b/src/scss/style.scss @@ -1227,16 +1227,16 @@ span.popup-close { //display: none; opacity: 0; visibility: hidden; - -webkit-transition: opacity 0.25s 0s, visibility 0s 0.25s; - -moz-transition: opacity 0.25s 0s, visibility 0s 0.25s; - transition: opacity 0.25s 0s, visibility 0s 0.25s; + -webkit-transition: opacity 0.2s 0s, visibility 0s 0.2s; + -moz-transition: opacity 0.2s 0s, visibility 0s 0.2s; + transition: opacity 0.2s 0s, visibility 0s 0.2s; &.active { opacity: 1; visibility: visible; - -webkit-transition: opacity 0.25s 0s, visibility 0s 0s; - -moz-transition: opacity 0.25s 0s, visibility 0s 0s; - transition: opacity 0.25s 0s, visibility 0s 0s; + -webkit-transition: opacity 0.2s 0s, visibility 0s 0s; + -moz-transition: opacity 0.2s 0s, visibility 0s 0s; + transition: opacity 0.2s 0s, visibility 0s 0s; } }