Browse Source

scroll try #11 & sidebar safari fix

master
Eduard Kuzmenko 5 years ago
parent
commit
05d90d8a2b
  1. 18
      src/components/scrollable.ts
  2. 4
      src/components/wrappers.ts
  3. 33
      src/lib/appManagers/appDialogsManager.ts
  4. 42
      src/lib/appManagers/appImManager.ts
  5. 4
      src/lib/appManagers/appMediaViewer.ts
  6. 21
      src/lib/appManagers/appSidebarRight.ts
  7. 19
      src/scss/partials/_chat.scss
  8. 16
      src/scss/partials/_rightSIdebar.scss

18
src/components/scrollable.ts

@ -86,7 +86,7 @@ export default class Scrollable {
public scrollTopOffset: number = 0; public scrollTopOffset: number = 0;
private log: ReturnType<typeof logger>; private log: ReturnType<typeof logger>;
private debug = false; private debug = true;
constructor(public el: HTMLDivElement, x = false, y = true, public splitOffset = 300, logPrefix = '', public appendTo = el, public onScrollOffset = splitOffset) { constructor(public el: HTMLDivElement, x = false, y = true, public splitOffset = 300, logPrefix = '', public appendTo = el, public onScrollOffset = splitOffset) {
this.container = document.createElement('div'); this.container = document.createElement('div');
@ -333,6 +333,8 @@ export default class Scrollable {
} }
public onScroll() { public onScroll() {
this.log('onScroll call');
if(this.onScrollMeasure) fastdom.clear(this.onScrollMeasure); if(this.onScrollMeasure) fastdom.clear(this.onScrollMeasure);
this.onScrollMeasure = fastdom.measure(() => { this.onScrollMeasure = fastdom.measure(() => {
// @ts-ignore quick brown fix // @ts-ignore quick brown fix
@ -467,6 +469,10 @@ export default class Scrollable {
this.onManualScrollBottom(scrollTop, needHeight); this.onManualScrollBottom(scrollTop, needHeight);
}); });
} else if(this.paddings.down) { // scrolled manually or safari } 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); this.onManualScrollBottom(scrollTop, needHeight);
} }
} else { // scrolling top } else { // scrolling top
@ -496,6 +502,10 @@ export default class Scrollable {
this.onManualScrollTop(scrollTop, needHeight, maxScrollTop); this.onManualScrollTop(scrollTop, needHeight, maxScrollTop);
}); });
} else if(this.paddings.up) { } 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); this.onManualScrollTop(scrollTop, needHeight, maxScrollTop);
} }
} }
@ -510,11 +520,11 @@ export default class Scrollable {
}); });
this.onScrollMeasure.then(({value, maxValue}) => { this.onScrollMeasure.then(({value, maxValue}) => {
fastdom.mutate(() => { //fastdom.mutate(() => {
// @ts-ignore // @ts-ignore
//this.thumb.style[this.side] = (value >= maxValue ? maxValue : value) + '%'; //this.thumb.style[this.side] = (value >= maxValue ? maxValue : value) + '%';
this.thumb.style.transform = this.translate + '(' + (value >= maxValue ? maxValue : value) + 'px)'; this.thumb.style.transform = this.translate + '(' + (value >= maxValue ? maxValue : value) + 'px)';
}); //});
}); });
//console.timeEnd('scroll onScroll'); //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.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.paddingBottomDiv.style.height = this.paddings.down + 'px';
this.onTopIntersection((this.size * 2) + (needHeight * 2)); this.onTopIntersection((this.size * 2) + (needHeight * 2));
}); });
@ -558,6 +569,7 @@ export default class Scrollable {
} }
this.paddingTopDiv.style.height = this.paddings.up + 'px'; this.paddingTopDiv.style.height = this.paddings.up + 'px';
this.paddingBottomDiv.style.height = this.paddings.down + 'px';
this.onBottomIntersection(this.size + (needHeight * 2)); this.onBottomIntersection(this.size + (needHeight * 2));
}); });
} }

4
src/components/wrappers.ts

@ -431,12 +431,12 @@ export function wrapAudio(doc: MTDocument, withTime = false): HTMLDivElement {
return div; 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'); //container.classList.add('photo');
let peerID = this.peerID; 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 image = container.firstElementChild as HTMLImageElement || new Image();
//let size = appPhotosManager.setAttachmentSize(photo.id, image); //let size = appPhotosManager.setAttachmentSize(photo.id, image);
image.setAttribute('message-id', message.mid); image.setAttribute('message-id', message.mid);

33
src/lib/appManagers/appDialogsManager.ts

@ -34,6 +34,8 @@ export class AppDialogsManager {
public domsArchived: {[peerID: number]: DialogDom} = {}; public domsArchived: {[peerID: number]: DialogDom} = {};
public lastActiveListElement: HTMLElement = null; public lastActiveListElement: HTMLElement = null;
public savedAvatarURLs: {[peerID: number]: string} = {};
constructor() { constructor() {
this.pinnedDelimiter = document.createElement('div'); this.pinnedDelimiter = document.createElement('div');
this.pinnedDelimiter.classList.add('pinned-delimiter'); this.pinnedDelimiter.classList.add('pinned-delimiter');
@ -86,10 +88,11 @@ export class AppDialogsManager {
}); });
} }
public async loadDialogPhoto(div: HTMLDivElement, peerID: number | string, isDialog = false): Promise<boolean> { // peerID == peerID || title
public async loadDialogPhoto(div: HTMLDivElement, peerID: number, isDialog = false, title = ''): Promise<boolean> {
let inputPeer: any; let inputPeer: any;
let location: any; let location: any;
if(typeof(peerID) != 'string') { if(peerID) {
inputPeer = appPeersManager.getInputPeerByID(peerID); inputPeer = appPeersManager.getInputPeerByID(peerID);
location = appPeersManager.getPeerPhoto(peerID); location = appPeersManager.getPeerPhoto(peerID);
} }
@ -113,7 +116,7 @@ export class AppDialogsManager {
} }
let color = ''; let color = '';
if(typeof(peerID) != 'string' && peerID != this.myID) { if(peerID && peerID != this.myID) {
color = appPeersManager.getPeerColorByID(peerID); color = appPeersManager.getPeerColorByID(peerID);
} }
@ -121,7 +124,7 @@ export class AppDialogsManager {
div.style.fontSize = ''; div.style.fontSize = '';
div.style.backgroundColor = color; 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 ? let abbr = (abbrSplitted.length == 2 ?
abbrSplitted[0][0] + abbrSplitted[1][0] : abbrSplitted[0][0] + abbrSplitted[1][0] :
abbrSplitted[0][0]).toUpperCase(); abbrSplitted[0][0]).toUpperCase();
@ -135,17 +138,21 @@ export class AppDialogsManager {
return true; return true;
} }
let res = await apiFileManager.downloadSmallFile({ if(!this.savedAvatarURLs[peerID]) {
_: 'inputPeerPhotoFileLocation', let res = await apiFileManager.downloadSmallFile({
dc_id: location.dc_id, _: 'inputPeerPhotoFileLocation',
flags: 0, dc_id: location.dc_id,
peer: inputPeer, flags: 0,
volume_id: location.photo_small.volume_id, peer: inputPeer,
local_id: location.photo_small.local_id volume_id: location.photo_small.volume_id,
}); local_id: location.photo_small.local_id
});
this.savedAvatarURLs[peerID] = URL.createObjectURL(res);
}
let img = new Image(); let img = new Image();
img.src = URL.createObjectURL(res); img.src = this.savedAvatarURLs[peerID];
div.innerHTML = ''; div.innerHTML = '';
div.style.fontSize = '0'; // need div.style.fontSize = '0'; // need
div.append(img); div.append(img);

42
src/lib/appManagers/appImManager.ts

@ -132,7 +132,7 @@ class BubbleGroups {
this.groups.push(group = [bubble]); 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.bubblesByGroups[reverse ? 'unshift' : 'push']({timestamp, fromID, mid: message.mid, group});
this.updateGroup(group); this.updateGroup(group);
@ -153,7 +153,7 @@ class BubbleGroups {
let first = group[0]; let first = group[0];
console.log('updateGroup', group, first); //console.log('updateGroup', group, first);
if(group.length == 1) { if(group.length == 1) {
first.classList.add('is-group-first', 'is-group-last'); first.classList.add('is-group-first', 'is-group-last');
@ -705,6 +705,7 @@ export class AppImManager {
if(dialog) { if(dialog) {
this.setPeer(this.peerID, dialog.top_message); this.setPeer(this.peerID, dialog.top_message);
} else { } else {
this.log('will scroll down 3');
this.scroll.scrollTop = this.scroll.scrollHeight; this.scroll.scrollTop = this.scroll.scrollHeight;
} }
}); });
@ -877,7 +878,7 @@ export class AppImManager {
} }
}); });
lottieLoader.checkAnimations(); lottieLoader.checkAnimations(false, 'chat');
if(readed.length) { if(readed.length) {
let max = Math.max(...readed); let max = Math.max(...readed);
@ -903,8 +904,10 @@ export class AppImManager {
} }
public setScroll() { 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.scroll = this.scrollable.container;
this.bubblesContainer.append(this.goDownBtn);
this.scrollable.setVirtualContainer(this.chatInner); this.scrollable.setVirtualContainer(this.chatInner);
this.scrollable.onScrolledTop = () => this.loadMoreHistory(true); this.scrollable.onScrolledTop = () => this.loadMoreHistory(true);
@ -1062,6 +1065,7 @@ export class AppImManager {
let dialog = appMessagesManager.getDialogByPeerID(peerID)[0]; let dialog = appMessagesManager.getDialogByPeerID(peerID)[0];
if(dialog && lastMsgID == dialog.top_message) { if(dialog && lastMsgID == dialog.top_message) {
this.log('will scroll down', this.scroll.scrollTop, this.scroll.scrollHeight);
this.scroll.scrollTop = this.scroll.scrollHeight; this.scroll.scrollTop = this.scroll.scrollHeight;
} else { } else {
//this.bubbles[lastMsgID].scrollIntoView(); //this.bubbles[lastMsgID].scrollIntoView();
@ -1086,7 +1090,7 @@ export class AppImManager {
this.pinnedMessageContainer.style.display = 'none'; this.pinnedMessageContainer.style.display = 'none';
this.preloader.attach(this.chatInner); this.preloader.attach(this.bubblesContainer);
let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null; let dialog = appMessagesManager.getDialogByPeerID(this.peerID)[0] || null;
//////this.log('setPeer peerID:', this.peerID, dialog, lastMsgID); //////this.log('setPeer peerID:', this.peerID, dialog, lastMsgID);
@ -1119,7 +1123,7 @@ export class AppImManager {
this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = title; this.titleEl.innerHTML = appSidebarRight.profileElements.name.innerHTML = title;
this.topbar.style.display = this.goDownBtn.style.display = ''; 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' : ''; this.chatInput.style.display = appPeersManager.isChannel(peerID) && !appPeersManager.isMegagroup(peerID) ? 'none' : '';
@ -1148,6 +1152,7 @@ export class AppImManager {
if(bubble) this.bubbles[lastMsgID].scrollIntoView(); if(bubble) this.bubbles[lastMsgID].scrollIntoView();
else this.log.warn('no bubble by lastMsgID:', lastMsgID); else this.log.warn('no bubble by lastMsgID:', lastMsgID);
} else { } else {
this.log('will scroll down 2');
this.scroll.scrollTop = this.scroll.scrollHeight; this.scroll.scrollTop = this.scroll.scrollHeight;
} }
} else if(dialog && dialog.top_message) { // add last message, bc in getHistory will load < max_id } 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.log.error('setPeer promises error:', err);
this.preloader.detach();
return false; return false;
}); });
} }
@ -1497,7 +1503,7 @@ export class AppImManager {
bubble.classList.add('photo'); bubble.classList.add('photo');
//appPhotosManager.savePhoto(webpage.photo); // hot-fix because no webpage manager //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) { if(preview) {
@ -1688,7 +1694,7 @@ export class AppImManager {
} else if(!title && message.fwd_from && message.fwd_from.from_name) { } else if(!title && message.fwd_from && message.fwd_from.from_name) {
title = 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; avatarDiv.dataset.peerID = message.fromID;
@ -1824,12 +1830,20 @@ export class AppImManager {
if(!isBackLimit) { if(!isBackLimit) {
this.scrollPosition.prepareFor(reverse ? 'up' : 'down'); this.scrollPosition.prepareFor(reverse ? 'up' : 'down');
} }
/* for(let i = 0; i < 25; ++i) */ history.forEachReverse((msgID: number) => { if(testScroll) {
let message = appMessagesManager.getMessage(msgID); for(let i = 0; i < 25; ++i) history.forEachReverse((msgID: number) => {
let message = appMessagesManager.getMessage(msgID);
this.renderMessage(message, reverse, true);
}); this.renderMessage(message, reverse, true);
});
} else {
history.forEachReverse((msgID: number) => {
let message = appMessagesManager.getMessage(msgID);
this.renderMessage(message, reverse, true);
});
}
if(!isBackLimit) { if(!isBackLimit) {
this.scrollPosition.restore(); this.scrollPosition.restore();

4
src/lib/appManagers/appMediaViewer.ts

@ -52,6 +52,10 @@ export class AppMediaViewer {
this.buttons.close.addEventListener('click', () => { this.buttons.close.addEventListener('click', () => {
//this.overlaysDiv.classList.remove('active'); //this.overlaysDiv.classList.remove('active');
this.content.container.innerHTML = ''; this.content.container.innerHTML = '';
if(this.content.container.firstElementChild) {
URL.revokeObjectURL((this.content.container.firstElementChild as HTMLImageElement).src);
}
this.currentMessageID = 0; this.currentMessageID = 0;
this.setMoverToTarget(this.lastTarget, true); this.setMoverToTarget(this.lastTarget, true);

21
src/lib/appManagers/appSidebarRight.ts

@ -87,6 +87,8 @@ class AppSidebarRight {
private mediaDivsByIDs: { private mediaDivsByIDs: {
[mid: number]: HTMLDivElement [mid: number]: HTMLDivElement
} = {}; } = {};
public urlsToRevoke: string[] = [];
constructor() { constructor() {
let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement; let container = this.profileContentEl.querySelector('.profile-tabs-content') as HTMLDivElement;
@ -212,7 +214,7 @@ class AppSidebarRight {
} }
public loadSidebarMedia(single = false) { public loadSidebarMedia(single = false) {
if(testScroll /* || 1 == 1 */) { if(testScroll/* || 1 == 1 */) {
return; return;
} }
@ -298,14 +300,17 @@ class AppSidebarRight {
//this.log('inputMessagesFilterPhotoVideo', message, media); //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) => { .then((blob) => {
if($rootScope.selectedPeerID != peerID) { if($rootScope.selectedPeerID != peerID) {
this.log.warn('peer changed'); this.log.warn('peer changed');
return; 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); div.setAttribute('message-id', '' + message.mid);
@ -372,8 +377,11 @@ class AppSidebarRight {
this.log.warn('peer changed'); this.log.warn('peer changed');
return; 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}); this.lazyLoadQueueSidebar.push({div: previewDiv, load});
@ -475,6 +483,11 @@ class AppSidebarRight {
putPreloader(parent, true); putPreloader(parent, true);
} }
}); });
this.urlsToRevoke.forEach(url => {
URL.revokeObjectURL(url);
});
this.urlsToRevoke.length = 0;
this.sharedMediaTypes.forEach(type => { this.sharedMediaTypes.forEach(type => {
//this.minMediaID[type] = 0; //this.minMediaID[type] = 0;

19
src/scss/partials/_chat.scss

@ -113,7 +113,16 @@
position: relative; position: relative;
> .scrollable { > .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) { &:not(.scrolled-down) {
@ -141,10 +150,10 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
flex-shrink: 1; flex-shrink: 1;
padding-top: 9px; //padding-top: 9px;
margin: 0 auto; margin: 0 auto;
box-sizing: border-box; box-sizing: border-box;
min-height: 100%; /* min-height: 100%; */
justify-content: flex-end; justify-content: flex-end;
&.is-chat { &.is-chat {
@ -469,7 +478,8 @@
font-size: .95rem; font-size: .95rem;
// margin: .25rem; // margin: .25rem;
margin: 4px 4px 4px 6px; margin: 4px 4px 4px 6px;
padding: .25rem; //padding: .25rem;
padding: 4px;
margin-bottom: -5px; margin-bottom: -5px;
border-radius: 4px; border-radius: 4px;
//transition: anim(background-color); //transition: anim(background-color);
@ -592,6 +602,7 @@
max-width: 100%; max-width: 100%;
color: #000; color: #000;
line-height: 21px; line-height: 21px;
word-break: break-word;
* { * {
overflow: hidden; overflow: hidden;

16
src/scss/partials/_rightSIdebar.scss

@ -33,6 +33,7 @@
flex: 1 1 auto; flex: 1 1 auto;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
height: 100%;
.profile-name { .profile-name {
text-align: center; text-align: center;
@ -106,11 +107,17 @@
margin-left: -54px; margin-left: -54px;
} }
&-wrapper {
flex: 0 0 auto;
}
.content-container { .content-container {
width: 100%; width: 100%;
max-width: 100%; max-width: 100%;
overflow: hidden; //overflow: hidden;
flex: 1; flex: 1 1 auto;
position: relative;
//height: 1%; // fix safari
} }
.profile-tabs { .profile-tabs {
@ -118,7 +125,8 @@
} }
.profile-tabs-content { .profile-tabs-content {
height: 100%; min-height: 100%;
position: absolute; // FIX THE SAFARI!
/* width: 500%; /* width: 500%;
margin-left: -100%; margin-left: -100%;
*/ */
@ -131,7 +139,7 @@
} */ } */
> div { > div {
height: 100%; //height: 100%;
position: relative; position: relative;
} }

Loading…
Cancel
Save