Browse Source

new mediaviewer animation delay & clearing empty divs in chat

master
Eduard Kuzmenko 5 years ago
parent
commit
26c95ac6f6
  1. 2
      src/components/scrollable.ts
  2. 68
      src/lib/appManagers/appImManager.ts
  3. 141
      src/lib/appManagers/appMediaViewer.ts
  4. 40
      src/lib/appManagers/appMessagesManager.ts
  5. 2
      src/lib/appManagers/appSidebarRight.ts
  6. 2
      src/lib/mtproto/apiFileManager.ts
  7. 3
      src/scss/partials/_mediaViewer.scss
  8. 12
      src/scss/style.scss

2
src/components/scrollable.ts

@ -284,6 +284,8 @@ export default class Scrollable { @@ -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);

68
src/lib/appManagers/appImManager.ts

@ -529,7 +529,6 @@ export class AppImManager { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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<void>) {
this.loadMediaQueue.push(cb);
this.loadMediaQueueProcess();
@ -1220,7 +1253,7 @@ export class AppImManager { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 ?

141
src/lib/appManagers/appMediaViewer.ts

@ -1,11 +1,7 @@ @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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);
}
}

40
src/lib/appManagers/appMessagesManager.ts

@ -974,7 +974,7 @@ export class AppMessagesManager { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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

2
src/lib/appManagers/appSidebarRight.ts

@ -146,7 +146,7 @@ class AppSidebarRight { @@ -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', () => {

2
src/lib/mtproto/apiFileManager.ts

@ -276,7 +276,7 @@ export class ApiFileManager { @@ -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) {

3
src/scss/partials/_mediaViewer.scss

@ -184,6 +184,7 @@ @@ -184,6 +184,7 @@
left: 0;
top: 0;
transform-origin: top left;
overflow: hidden;
.ckin__player {
width: 100%;
@ -197,7 +198,7 @@ @@ -197,7 +198,7 @@
}
&.active {
transition: .25s all;
transition: .2s all;
}
}
}

12
src/scss/style.scss

@ -1227,16 +1227,16 @@ span.popup-close { @@ -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;
}
}

Loading…
Cancel
Save