diff --git a/src/components/scrollable.ts b/src/components/scrollable.ts
index 208d40449..cfb0a9937 100644
--- a/src/components/scrollable.ts
+++ b/src/components/scrollable.ts
@@ -86,7 +86,7 @@ export default class Scrollable {
public scrollTopOffset: number = 0;
private log: ReturnType
;
- private debug = false;
+ private debug = true;
constructor(public el: HTMLDivElement, x = false, y = true, public splitOffset = 300, logPrefix = '', public appendTo = el, public onScrollOffset = splitOffset) {
this.container = document.createElement('div');
@@ -333,6 +333,8 @@ export default class Scrollable {
}
public onScroll() {
+ this.log('onScroll call');
+
if(this.onScrollMeasure) fastdom.clear(this.onScrollMeasure);
this.onScrollMeasure = fastdom.measure(() => {
// @ts-ignore quick brown fix
@@ -467,6 +469,10 @@ export default class Scrollable {
this.onManualScrollBottom(scrollTop, needHeight);
});
} else if(this.paddings.down) { // scrolled manually or safari
+ if(this.debug) {
+ this.log.warn('seems manually scrolled bottom', this.paddings.up, this.lastScrollTop);
+ }
+
this.onManualScrollBottom(scrollTop, needHeight);
}
} else { // scrolling top
@@ -496,6 +502,10 @@ export default class Scrollable {
this.onManualScrollTop(scrollTop, needHeight, maxScrollTop);
});
} else if(this.paddings.up) {
+ if(this.debug) {
+ this.log.warn('seems manually scrolled top', this.paddings.down, this.lastScrollTop);
+ }
+
this.onManualScrollTop(scrollTop, needHeight, maxScrollTop);
}
}
@@ -510,11 +520,11 @@ export default class Scrollable {
});
this.onScrollMeasure.then(({value, maxValue}) => {
- fastdom.mutate(() => {
+ //fastdom.mutate(() => {
// @ts-ignore
//this.thumb.style[this.side] = (value >= maxValue ? maxValue : value) + '%';
this.thumb.style.transform = this.translate + '(' + (value >= maxValue ? maxValue : value) + 'px)';
- });
+ //});
});
//console.timeEnd('scroll onScroll');
@@ -536,6 +546,7 @@ export default class Scrollable {
this.log.warn('bait it off now', this, length, this.splitUp.childElementCount, scrollTop, this.paddings.up, h);
}
+ this.paddingTopDiv.style.height = this.paddings.up + 'px';
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
this.onTopIntersection((this.size * 2) + (needHeight * 2));
});
@@ -558,6 +569,7 @@ export default class Scrollable {
}
this.paddingTopDiv.style.height = this.paddings.up + 'px';
+ this.paddingBottomDiv.style.height = this.paddings.down + 'px';
this.onBottomIntersection(this.size + (needHeight * 2));
});
}
diff --git a/src/components/wrappers.ts b/src/components/wrappers.ts
index fb31d3806..ec41d0e08 100644
--- a/src/components/wrappers.ts
+++ b/src/components/wrappers.ts
@@ -431,12 +431,12 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
return div;
}
-export function wrapPhoto(this: AppImManager, photo: any, message: any, container: HTMLDivElement) {
+export function wrapPhoto(this: AppImManager, photo: any, message: any, container: HTMLDivElement, boxWidth = 380, boxHeight = 380) {
//container.classList.add('photo');
let peerID = this.peerID;
- let size = appPhotosManager.setAttachmentSize(photo.id, container);
+ let size = appPhotosManager.setAttachmentSize(photo.id, container, boxWidth, boxHeight);
let image = container.firstElementChild as HTMLImageElement || new Image();
//let size = appPhotosManager.setAttachmentSize(photo.id, image);
image.setAttribute('message-id', message.mid);
diff --git a/src/lib/appManagers/appDialogsManager.ts b/src/lib/appManagers/appDialogsManager.ts
index df4f54346..623c51b18 100644
--- a/src/lib/appManagers/appDialogsManager.ts
+++ b/src/lib/appManagers/appDialogsManager.ts
@@ -34,6 +34,8 @@ export class AppDialogsManager {
public domsArchived: {[peerID: number]: DialogDom} = {};
public lastActiveListElement: HTMLElement = null;
+ public savedAvatarURLs: {[peerID: number]: string} = {};
+
constructor() {
this.pinnedDelimiter = document.createElement('div');
this.pinnedDelimiter.classList.add('pinned-delimiter');
@@ -86,10 +88,11 @@ export class AppDialogsManager {
});
}
- public async loadDialogPhoto(div: HTMLDivElement, peerID: number | string, isDialog = false): Promise {
+ // peerID == peerID || title
+ public async loadDialogPhoto(div: HTMLDivElement, peerID: number, isDialog = false, title = ''): Promise {
let inputPeer: any;
let location: any;
- if(typeof(peerID) != 'string') {
+ if(peerID) {
inputPeer = appPeersManager.getInputPeerByID(peerID);
location = appPeersManager.getPeerPhoto(peerID);
}
@@ -113,7 +116,7 @@ export class AppDialogsManager {
}
let color = '';
- if(typeof(peerID) != 'string' && peerID != this.myID) {
+ if(peerID && peerID != this.myID) {
color = appPeersManager.getPeerColorByID(peerID);
}
@@ -121,7 +124,7 @@ export class AppDialogsManager {
div.style.fontSize = '';
div.style.backgroundColor = color;
- let abbrSplitted = (typeof(peerID) != 'string' ? appPeersManager.getPeerTitle(peerID, true) : peerID).split(' ');
+ let abbrSplitted = (!title && peerID ? appPeersManager.getPeerTitle(peerID, true) : title).split(' ');
let abbr = (abbrSplitted.length == 2 ?
abbrSplitted[0][0] + abbrSplitted[1][0] :
abbrSplitted[0][0]).toUpperCase();
@@ -135,17 +138,21 @@ export class AppDialogsManager {
return true;
}
- let res = await apiFileManager.downloadSmallFile({
- _: 'inputPeerPhotoFileLocation',
- dc_id: location.dc_id,
- flags: 0,
- peer: inputPeer,
- volume_id: location.photo_small.volume_id,
- local_id: location.photo_small.local_id
- });
+ if(!this.savedAvatarURLs[peerID]) {
+ let res = await apiFileManager.downloadSmallFile({
+ _: 'inputPeerPhotoFileLocation',
+ dc_id: location.dc_id,
+ flags: 0,
+ peer: inputPeer,
+ volume_id: location.photo_small.volume_id,
+ local_id: location.photo_small.local_id
+ });
+
+ this.savedAvatarURLs[peerID] = URL.createObjectURL(res);
+ }
let img = new Image();
- img.src = URL.createObjectURL(res);
+ img.src = this.savedAvatarURLs[peerID];
div.innerHTML = '';
div.style.fontSize = '0'; // need
div.append(img);
diff --git a/src/lib/appManagers/appImManager.ts b/src/lib/appManagers/appImManager.ts
index 407b076f2..2f71d104f 100644
--- a/src/lib/appManagers/appImManager.ts
+++ b/src/lib/appManagers/appImManager.ts
@@ -132,7 +132,7 @@ class BubbleGroups {
this.groups.push(group = [bubble]);
}
- console.log('addBubble', bubble, message.mid, fromID, reverse, group);
+ //console.log('addBubble', bubble, message.mid, fromID, reverse, group);
this.bubblesByGroups[reverse ? 'unshift' : 'push']({timestamp, fromID, mid: message.mid, group});
this.updateGroup(group);
@@ -153,7 +153,7 @@ class BubbleGroups {
let first = group[0];
- console.log('updateGroup', group, first);
+ //console.log('updateGroup', group, first);
if(group.length == 1) {
first.classList.add('is-group-first', 'is-group-last');
@@ -705,6 +705,7 @@ export class AppImManager {
if(dialog) {
this.setPeer(this.peerID, dialog.top_message);
} else {
+ this.log('will scroll down 3');
this.scroll.scrollTop = this.scroll.scrollHeight;
}
});
@@ -877,7 +878,7 @@ export class AppImManager {
}
});
- lottieLoader.checkAnimations();
+ lottieLoader.checkAnimations(false, 'chat');
if(readed.length) {
let max = Math.max(...readed);
@@ -903,8 +904,10 @@ export class AppImManager {
}
public setScroll() {
- this.scrollable = new Scrollable(this.bubblesContainer, false, true, 750, 'IM', this.chatInner/* 1500 */, 300);
+ this.scrollable = new Scrollable(this.bubblesContainer, false, true, 750, 'IM', this.chatInner/* 1500 */, 450);
this.scroll = this.scrollable.container;
+
+ this.bubblesContainer.append(this.goDownBtn);
this.scrollable.setVirtualContainer(this.chatInner);
this.scrollable.onScrolledTop = () => this.loadMoreHistory(true);
@@ -1062,6 +1065,7 @@ export class AppImManager {
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
if(dialog && lastMsgID == dialog.top_message) {
+ this.log('will scroll down', this.scroll.scrollTop, this.scroll.scrollHeight);
this.scroll.scrollTop = this.scroll.scrollHeight;
} else {
//this.bubbles[lastMsgID].scrollIntoView();
@@ -1086,7 +1090,7 @@ export class AppImManager {
this.pinnedMessageContainer.style.display = 'none';
- this.preloader.attach(this.chatInner);
+ this.preloader.attach(this.bubblesContainer);
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null;
//////this.log('setPeer peerID:', this.peerID, dialog, lastMsgID);
@@ -1119,7 +1123,7 @@ export class AppImManager {
this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = title;
this.topbar.style.display = this.goDownBtn.style.display = '';
- appSidebarRight.toggleSidebar(true);
+ //appSidebarRight.toggleSidebar(true);
this.chatInput.style.display = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID) ? 'none' : '';
@@ -1148,6 +1152,7 @@ export class AppImManager {
if(bubble) this.bubbles[lastMsgID].scrollIntoView();
else this.log.warn('no bubble by lastMsgID:', lastMsgID);
} else {
+ this.log('will scroll down 2');
this.scroll.scrollTop = this.scroll.scrollHeight;
}
} else if(dialog && dialog.top_message) { // add last message, bc in getHistory will load < max_id
@@ -1183,6 +1188,7 @@ export class AppImManager {
}
this.log.error('setPeer promises error:', err);
+ this.preloader.detach();
return false;
});
}
@@ -1497,7 +1503,7 @@ export class AppImManager {
bubble.classList.add('photo');
//appPhotosManager.savePhoto(webpage.photo); // hot-fix because no webpage manager
- wrapPhoto.call(this, webpage.photo, message, preview);
+ wrapPhoto.call(this, webpage.photo, message, preview, 380, 300);
}
if(preview) {
@@ -1688,7 +1694,7 @@ export class AppImManager {
} else if(!title && message.fwd_from && message.fwd_from.from_name) {
title = message.fwd_from.from_name;
- appDialogsManager.loadDialogPhoto(avatarDiv, title);
+ appDialogsManager.loadDialogPhoto(avatarDiv, 0, false, title);
}
avatarDiv.dataset.peerID = message.fromID;
@@ -1824,12 +1830,20 @@ export class AppImManager {
if(!isBackLimit) {
this.scrollPosition.prepareFor(reverse ? 'up' : 'down');
}
-
- /* for(let i = 0; i < 25; ++i) */ history.forEachReverse((msgID: number) => {
- let message = appMessagesManager.getMessage(msgID);
-
- this.renderMessage(message, reverse, true);
- });
+
+ if(testScroll) {
+ for(let i = 0; i < 25; ++i) history.forEachReverse((msgID: number) => {
+ let message = appMessagesManager.getMessage(msgID);
+
+ this.renderMessage(message, reverse, true);
+ });
+ } else {
+ history.forEachReverse((msgID: number) => {
+ let message = appMessagesManager.getMessage(msgID);
+
+ this.renderMessage(message, reverse, true);
+ });
+ }
if(!isBackLimit) {
this.scrollPosition.restore();
diff --git a/src/lib/appManagers/appMediaViewer.ts b/src/lib/appManagers/appMediaViewer.ts
index 0fd8a2e57..9b7c1e923 100644
--- a/src/lib/appManagers/appMediaViewer.ts
+++ b/src/lib/appManagers/appMediaViewer.ts
@@ -52,6 +52,10 @@ export class AppMediaViewer {
this.buttons.close.addEventListener('click', () => {
//this.overlaysDiv.classList.remove('active');
this.content.container.innerHTML = '';
+ if(this.content.container.firstElementChild) {
+ URL.revokeObjectURL((this.content.container.firstElementChild as HTMLImageElement).src);
+ }
+
this.currentMessageID = 0;
this.setMoverToTarget(this.lastTarget, true);
diff --git a/src/lib/appManagers/appSidebarRight.ts b/src/lib/appManagers/appSidebarRight.ts
index 79c850230..af646e26b 100644
--- a/src/lib/appManagers/appSidebarRight.ts
+++ b/src/lib/appManagers/appSidebarRight.ts
@@ -87,6 +87,8 @@ class AppSidebarRight {
private mediaDivsByIDs: {
[mid: number]: HTMLDivElement
} = {};
+
+ public urlsToRevoke: string[] = [];
constructor() {
let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement;
@@ -212,7 +214,7 @@ class AppSidebarRight {
}
public loadSidebarMedia(single = false) {
- if(testScroll /* || 1 == 1 */) {
+ if(testScroll/* || 1 == 1 */) {
return;
}
@@ -298,14 +300,17 @@ class AppSidebarRight {
//this.log('inputMessagesFilterPhotoVideo', message, media);
- let load = () => appPhotosManager.preloadPhoto(media, appPhotosManager.choosePhotoSize(media, 380, 0))
+ let load = () => appPhotosManager.preloadPhoto(media, appPhotosManager.choosePhotoSize(media, 200, 200))
.then((blob) => {
if($rootScope.selectedPeerID != peerID) {
this.log.warn('peer changed');
return;
}
+
+ let url = URL.createObjectURL(blob);
+ this.urlsToRevoke.push(url);
- div.style.backgroundImage = 'url(' + URL.createObjectURL(blob) + ')';
+ div.style.backgroundImage = 'url(' + url + ')';
});
div.setAttribute('message-id', '' + message.mid);
@@ -372,8 +377,11 @@ class AppSidebarRight {
this.log.warn('peer changed');
return;
}
+
+ let url = URL.createObjectURL(blob);
+ this.urlsToRevoke.push(url);
- previewDiv.style.backgroundImage = 'url(' + URL.createObjectURL(blob) + ')';
+ previewDiv.style.backgroundImage = 'url(' + url + ')';
});
this.lazyLoadQueueSidebar.push({div: previewDiv, load});
@@ -475,6 +483,11 @@ class AppSidebarRight {
putPreloader(parent, true);
}
});
+
+ this.urlsToRevoke.forEach(url => {
+ URL.revokeObjectURL(url);
+ });
+ this.urlsToRevoke.length = 0;
this.sharedMediaTypes.forEach(type => {
//this.minMediaID[type] = 0;
diff --git a/src/scss/partials/_chat.scss b/src/scss/partials/_chat.scss
index 165d64390..7f6fcebc8 100644
--- a/src/scss/partials/_chat.scss
+++ b/src/scss/partials/_chat.scss
@@ -113,7 +113,16 @@
position: relative;
> .scrollable {
- position: unset;
+ //position: unset;
+
+ height: auto;
+ position: absolute;
+ bottom: 0;
+ left: 0;
+
+ /* display: flex;
+ flex-direction: column;
+ justify-content: flex-end; */
}
&:not(.scrolled-down) {
@@ -141,10 +150,10 @@
display: flex;
flex-direction: column;
flex-shrink: 1;
- padding-top: 9px;
+ //padding-top: 9px;
margin: 0 auto;
box-sizing: border-box;
- min-height: 100%;
+ /* min-height: 100%; */
justify-content: flex-end;
&.is-chat {
@@ -469,7 +478,8 @@
font-size: .95rem;
// margin: .25rem;
margin: 4px 4px 4px 6px;
- padding: .25rem;
+ //padding: .25rem;
+ padding: 4px;
margin-bottom: -5px;
border-radius: 4px;
//transition: anim(background-color);
@@ -592,6 +602,7 @@
max-width: 100%;
color: #000;
line-height: 21px;
+ word-break: break-word;
* {
overflow: hidden;
diff --git a/src/scss/partials/_rightSIdebar.scss b/src/scss/partials/_rightSIdebar.scss
index 3293c30d8..be3a0c548 100644
--- a/src/scss/partials/_rightSIdebar.scss
+++ b/src/scss/partials/_rightSIdebar.scss
@@ -33,6 +33,7 @@
flex: 1 1 auto;
display: flex;
flex-direction: column;
+ height: 100%;
.profile-name {
text-align: center;
@@ -106,11 +107,17 @@
margin-left: -54px;
}
+ &-wrapper {
+ flex: 0 0 auto;
+ }
+
.content-container {
width: 100%;
max-width: 100%;
- overflow: hidden;
- flex: 1;
+ //overflow: hidden;
+ flex: 1 1 auto;
+ position: relative;
+ //height: 1%; // fix safari
}
.profile-tabs {
@@ -118,7 +125,8 @@
}
.profile-tabs-content {
- height: 100%;
+ min-height: 100%;
+ position: absolute; // FIX THE SAFARI!
/* width: 500%;
margin-left: -100%;
*/
@@ -131,7 +139,7 @@
} */
> div {
- height: 100%;
+ //height: 100%;
position: relative;
}