Browse Source

Search messages pagination

master
Eduard Kuzmenko 5 years ago
parent
commit
70324b96ad
  1. BIN
      .DS_Store
  2. 1
      .gitignore
  3. 91
      src/components/misc.ts
  4. 18
      src/lib/appManagers/appDialogsManager.ts
  5. 88
      src/lib/appManagers/appImManager.ts
  6. 32
      src/lib/appManagers/appMediaViewer.ts
  7. 16
      src/lib/appManagers/appMessagesManager.ts
  8. 12
      src/lib/appManagers/appPhotosManager.ts
  9. 117
      src/lib/appManagers/appSidebarLeft.ts
  10. 1
      src/lib/appManagers/appSidebarRight.ts
  11. 12
      src/lib/services.ts
  12. 11
      src/scss/partials/_chat.scss
  13. 130
      src/scss/style.scss
  14. 9665
      stats.json

BIN
.DS_Store vendored

Binary file not shown.

1
.gitignore vendored

@ -2,3 +2,4 @@ node_modules
coverage coverage
__pycache__ __pycache__
dist dist
.DS_Store

91
src/components/misc.ts

@ -5,6 +5,8 @@ import CryptoWorker from '../lib/crypto/cryptoworker';
import LottieLoader from '../lib/lottieLoader'; import LottieLoader from '../lib/lottieLoader';
import appStickersManager from "../lib/appManagers/appStickersManager"; import appStickersManager from "../lib/appManagers/appStickersManager";
import appDocsManager from "../lib/appManagers/appDocsManager"; import appDocsManager from "../lib/appManagers/appDocsManager";
import {AppImManager} from "../lib/appManagers/appImManager";
import {AppMediaViewer} from '../lib/appManagers/appMediaViewer';
export type MTDocument = { export type MTDocument = {
_: 'document', _: 'document',
@ -213,9 +215,20 @@ export class LazyLoadQueue {
} }
} }
export function wrapVideo(doc: MTDocument, container: HTMLDivElement, middleware: () => boolean, messageID: number, justLoader = true, preloader?: ProgressivePreloader) { export function wrapVideo(this: any, doc: MTDocument, container: HTMLDivElement, message: any, justLoader = true, preloader?: ProgressivePreloader) {
if(!container.firstElementChild || container.firstElementChild.tagName != 'IMG') { //if(!container.firstElementChild || container.firstElementChild.tagName != 'IMG') {
let size = appPhotosManager.setAttachmentSize(doc, container); let size = appPhotosManager.setAttachmentSize(doc, container);
//}
let peerID = this.peerID ? this.peerID : this.currentMessageID;
//container.classList.add('video');
let img = container.firstElementChild as HTMLImageElement || new Image();
img.setAttribute('message-id', '' + message.id);
if(!container.contains(img)) {
container.append(img);
} }
//return Promise.resolve(); //return Promise.resolve();
@ -227,17 +240,18 @@ export function wrapVideo(doc: MTDocument, container: HTMLDivElement, middleware
let loadVideo = () => { let loadVideo = () => {
let promise = appDocsManager.downloadDoc(doc); let promise = appDocsManager.downloadDoc(doc);
promise.notify = (details: {done: number, total: number}) => { /* promise.notify = (details: {done: number, total: number}) => {
console.log('doc download', promise, details); console.log('doc download', promise, details);
preloader.setProgress(details.done); preloader.setProgress(details.done);
}; }; */
return promise.then(blob => { return promise.then(blob => {
if(!middleware()) { if((this.peerID ? this.peerID : this.currentMessageID) != peerID) {
this.log.warn('peer changed');
return; return;
} }
console.log('loaded doc:', doc, blob, container.firstElementChild); console.log('loaded doc:', doc, blob, container);
let video = document.createElement('video'); let video = document.createElement('video');
video.loop = true; video.loop = true;
@ -245,52 +259,50 @@ export function wrapVideo(doc: MTDocument, container: HTMLDivElement, middleware
if(!justLoader) { if(!justLoader) {
video.controls = true; video.controls = true;
} else {
video.volume = 0;
} }
video.setAttribute('message-id', '' + messageID); video.setAttribute('message-id', '' + message.id);
let source = document.createElement('source'); let source = document.createElement('source');
//source.src = doc.url; //source.src = doc.url;
source.src = URL.createObjectURL(blob); source.src = URL.createObjectURL(blob);
source.type = doc.mime_type; source.type = doc.mime_type;
if(img && container.contains(img)) {
container.removeChild(img);
}
video.append(source); video.append(source);
container.append(video); container.append(video);
if(container.firstElementChild) {
container.firstElementChild.remove();
}
preloader.detach(); preloader.detach();
}); });
}; };
if(doc.type == 'gif') { if(doc.type == 'gif') {
return loadVideo(); return this.peerID ? this.loadMediaQueuePush(loadVideo) : loadVideo();
} else { // if video } else { // if video
return appPhotosManager.preloadPhoto(doc).then((blob) => { let load = () => appPhotosManager.preloadPhoto(doc).then((blob) => {
if(!middleware()) { if((this.peerID ? this.peerID : this.currentMessageID) != peerID) {
this.log.warn('peer changed');
return; return;
} }
if(container.firstElementChild) { img.src = URL.createObjectURL(blob);
container.firstElementChild.remove();
}
let image = new Image();
image.src = URL.createObjectURL(blob);
/* image.style.height = doc.h + 'px'; /* image.style.height = doc.h + 'px';
image.style.width = doc.w + 'px'; */ image.style.width = doc.w + 'px'; */
image.setAttribute('message-id', '' + messageID);
container.append(image);
if(!justLoader) { if(!justLoader) {
return loadVideo(); return loadVideo();
} else {
preloader.detach();
} }
}); });
return this.peerID ? this.loadMediaQueuePush(load) : load();
} }
} }
@ -350,6 +362,37 @@ export function scrollable(el: HTMLDivElement, x = false, y = true) {
return container; return container;
} }
export function wrapPhoto(this: AppImManager, photo: any, message: any, container: HTMLDivElement) {
//container.classList.add('photo');
let peerID = this.peerID;
let size = appPhotosManager.setAttachmentSize(photo.id, container);
let image = container.firstElementChild as HTMLImageElement || new Image();
image.setAttribute('message-id', message.mid);
if(!container.contains(image)) {
container.append(image);
}
let preloader = new ProgressivePreloader(container, false);
let load = () => appPhotosManager.preloadPhoto(photo.id, size).then((blob) => {
if(this.peerID != peerID) {
this.log.warn('peer changed');
return;
}
image.src = URL.createObjectURL(blob);
preloader.detach();
});
console.log('wrapPhoto', load, container, image);
return this.loadMediaQueue ? this.loadMediaQueuePush(load) : load();
}
export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: () => boolean, lazyLoadQueue?: LazyLoadQueue, group?: string, canvas?: boolean) { export function wrapSticker(doc: MTDocument, div: HTMLDivElement, middleware?: () => boolean, lazyLoadQueue?: LazyLoadQueue, group?: string, canvas?: boolean) {
let stickerType = doc.mime_type == "application/x-tgsticker" ? 2 : (doc.mime_type == "image/webp" ? 1 : 0); let stickerType = doc.mime_type == "application/x-tgsticker" ? 2 : (doc.mime_type == "image/webp" ? 1 : 0);

18
src/lib/appManagers/appDialogsManager.ts

@ -2,13 +2,23 @@ import { MTProto } from "../mtproto/mtproto";
import { $rootScope, findUpTag } from "../utils"; import { $rootScope, findUpTag } from "../utils";
import appImManager from "./appImManager"; import appImManager from "./appImManager";
import appPeersManager from './appPeersManager'; import appPeersManager from './appPeersManager';
import { DialogDom } from "../services";
import appMessagesManager from "./appMessagesManager"; import appMessagesManager from "./appMessagesManager";
import appUsersManager from "./appUsersManager"; import appUsersManager from "./appUsersManager";
import appSidebarRight from "./appSidebarRight"; import appSidebarRight from "./appSidebarRight";
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
import { ripple } from "../../components/misc"; import { ripple } from "../../components/misc";
type DialogDom = {
avatarDiv: HTMLDivElement,
captionDiv: HTMLDivElement,
titleSpan: HTMLSpanElement,
statusSpan: HTMLSpanElement,
lastTimeSpan: HTMLSpanElement,
unreadMessagesSpan: HTMLSpanElement,
lastMessageSpan: HTMLSpanElement,
listEl: HTMLLIElement
};
export class AppDialogsManager { export class AppDialogsManager {
public pinnedChatList = document.getElementById('dialogs-pinned') as HTMLUListElement; public pinnedChatList = document.getElementById('dialogs-pinned') as HTMLUListElement;
public chatList = document.getElementById('dialogs') as HTMLUListElement; public chatList = document.getElementById('dialogs') as HTMLUListElement;
@ -190,13 +200,13 @@ export class AppDialogsManager {
} }
if(document.type == 'video') { if(document.type == 'video') {
lastMessageText += '<i>Video</i>'; lastMessageText = '<i>Video' + (lastMessage.message ? ', ' : '') + '</i>';
found = true; found = true;
} else if(document.type == 'voice') { } else if(document.type == 'voice') {
lastMessageText += '<i>Voice message</i>'; lastMessageText = '<i>Voice message</i>';
found = true; found = true;
} else if(document.type == 'gif') { } else if(document.type == 'gif') {
lastMessageText += '<i>GIF</i>'; lastMessageText = '<i>GIF' + (lastMessage.message ? ', ' : '') + '</i>';
found = true; found = true;
} }

88
src/lib/appManagers/appImManager.ts

@ -4,7 +4,7 @@ import appUsersManager from "./appUsersManager";
import appMessagesManager from "./appMessagesManager"; import appMessagesManager from "./appMessagesManager";
import appPeersManager from "./appPeersManager"; import appPeersManager from "./appPeersManager";
import appProfileManager from "./appProfileManager"; import appProfileManager from "./appProfileManager";
import { ProgressivePreloader, wrapDocument, wrapSticker, wrapVideo } from "../../components/misc"; import { ProgressivePreloader, wrapDocument, wrapSticker, wrapVideo, wrapPhoto } from "../../components/misc";
import appDialogsManager from "./appDialogsManager"; import appDialogsManager from "./appDialogsManager";
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
import appPhotosManager from "./appPhotosManager"; import appPhotosManager from "./appPhotosManager";
@ -121,7 +121,7 @@ export class AppImManager {
public scroll: HTMLDivElement = null; public scroll: HTMLDivElement = null;
public scrollPosition: ScrollPosition = null; public scrollPosition: ScrollPosition = null;
private log: ReturnType<typeof logger>; public log: ReturnType<typeof logger>;
private preloader: ProgressivePreloader = null; private preloader: ProgressivePreloader = null;
@ -763,28 +763,9 @@ export class AppImManager {
let photo = message.media.photo; let photo = message.media.photo;
this.log('messageMediaPhoto', photo); this.log('messageMediaPhoto', photo);
bubble.classList.add('photo'); bubble.classList.add('hide-name', 'photo');
let size = appPhotosManager.setAttachmentSize(photo.id, attachmentDiv); wrapPhoto.call(this, photo, message, attachmentDiv);
let load = () => appPhotosManager.preloadPhoto(photo.id, size).then((blob) => {
if(this.peerID != peerID) {
this.log.warn('peer changed');
return;
}
if(attachmentDiv.firstElementChild) {
attachmentDiv.firstElementChild.remove();
}
let image = new Image();
image.src = URL.createObjectURL(blob);
image.setAttribute('message-id', message.mid);
attachmentDiv.append(image);
});
bubble.classList.add('hide-name');
this.loadMediaQueuePush(load);
break; break;
} }
@ -827,58 +808,18 @@ export class AppImManager {
doc = webpage.document; doc = webpage.document;
if(doc.type == 'gif' || doc.type == 'video') { if(doc.type == 'gif' || doc.type == 'video') {
appPhotosManager.setAttachmentSize(doc, preview);
bubble.classList.add('video'); bubble.classList.add('video');
wrapVideo.call(this, doc, preview, message);
let load = () => wrapVideo(doc, preview, () => {
if(this.peerID != peerID) {
this.log.warn('peer changed');
return false;
}
loadedVideo = true;
return true;
}, message.mid);
this.loadMediaQueuePush(load);
} else { } else {
doc = null; doc = null;
} }
} }
if(webpage.photo && !doc) { if(webpage.photo && !doc) {
appPhotosManager.savePhoto(webpage.photo); // hot-fix because no webpage manager
bubble.classList.add('photo'); bubble.classList.add('photo');
appPhotosManager.savePhoto(webpage.photo); // hot-fix because no webpage manager
let size = appPhotosManager.setAttachmentSize(webpage.photo.id, preview); wrapPhoto.call(this, webpage.photo, message, preview);
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, size).then((blob) => {
if(this.peerID != peerID) {
this.log.warn('peer changed');
return;
}
if(loadedVideo) {
return;
}
let img = preview.firstElementChild as HTMLImageElement || new Image();
this.log('night running 1', bubble, bubble.scrollHeight, img.src);
//setTimeout(() => {
img.src = URL.createObjectURL(blob);
///}, 5e3);
if(!preview.contains(img)) {
preview.append(img);
}
this.log('night running 2', bubble, bubble.scrollHeight);
});
this.loadMediaQueuePush(load);
} }
if(preview) { if(preview) {
@ -943,18 +884,7 @@ export class AppImManager {
this.log('never get free 2', doc); this.log('never get free 2', doc);
bubble.classList.add('video'); bubble.classList.add('video');
wrapVideo.call(this, doc, attachmentDiv, message);
appPhotosManager.setAttachmentSize(doc, attachmentDiv);
let load = () => wrapVideo(doc, attachmentDiv, () => {
if(this.peerID != peerID) {
this.log.warn('peer changed');
return false;
}
return true;
}, message.mid);
this.loadMediaQueuePush(load);
break; break;
} else { } else {
@ -1055,6 +985,7 @@ export class AppImManager {
//} //}
} }
if(!our && this.peerID < 0) {
let avatarDiv = document.createElement('div'); let avatarDiv = document.createElement('div');
avatarDiv.classList.add('user-avatar'); avatarDiv.classList.add('user-avatar');
@ -1069,6 +1000,7 @@ export class AppImManager {
bubble.append(avatarDiv); bubble.append(avatarDiv);
} }
}
let type = our ? 'out' : 'in'; let type = our ? 'out' : 'in';

32
src/lib/appManagers/appMediaViewer.ts

@ -7,8 +7,9 @@ import { $rootScope } from "../utils";
import appMessagesManager from "./appMessagesManager"; import appMessagesManager from "./appMessagesManager";
import { CancellablePromise } from "../mtproto/apiFileManager"; import { CancellablePromise } from "../mtproto/apiFileManager";
import { RichTextProcessor } from "../richtextprocessor"; import { RichTextProcessor } from "../richtextprocessor";
import { logger } from "../polyfill";
class AppMediaViewer { export class AppMediaViewer {
private overlaysDiv = document.querySelector('.overlays') as HTMLDivElement; private overlaysDiv = document.querySelector('.overlays') as HTMLDivElement;
private author = { private author = {
avatarEl: this.overlaysDiv.querySelector('.user-avatar') as HTMLDivElement, avatarEl: this.overlaysDiv.querySelector('.user-avatar') as HTMLDivElement,
@ -29,17 +30,21 @@ class AppMediaViewer {
}; };
private reverse = false; private reverse = false;
private currentMessageID = 0; public currentMessageID = 0;
private higherMsgID: number | undefined = 0; private higherMsgID: number | undefined = 0;
private lowerMsgID: number | undefined = 0; private lowerMsgID: number | undefined = 0;
private preloader: ProgressivePreloader = null; private preloader: ProgressivePreloader = null;
public log: ReturnType<typeof logger>;
constructor() { constructor() {
this.log = logger('AMV');
this.preloader = new ProgressivePreloader(); this.preloader = new ProgressivePreloader();
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 = '';
this.currentMessageID = 0;
}); });
this.buttons.prev.addEventListener('click', () => { this.buttons.prev.addEventListener('click', () => {
@ -127,7 +132,7 @@ class AppMediaViewer {
} }
public openMedia(message: any, reverse = false) { public openMedia(message: any, reverse = false) {
console.log('openMedia doc:', message); this.log('openMedia doc:', message);
let media = message.media.photo || message.media.document || message.media.webpage.document; let media = message.media.photo || message.media.document || message.media.webpage.document;
let isVideo = media.mime_type == 'video/mp4'; let isVideo = media.mime_type == 'video/mp4';
@ -138,7 +143,7 @@ class AppMediaViewer {
let container = this.content.container; let container = this.content.container;
if(container.firstElementChild) { if(container.firstElementChild) {
container.firstElementChild.remove(); container.innerHTML = '';
} }
let date = new Date(media.date * 1000); let date = new Date(media.date * 1000);
@ -163,21 +168,12 @@ class AppMediaViewer {
this.overlaysDiv.classList.add('active'); this.overlaysDiv.classList.add('active');
if(isVideo) { if(isVideo) {
appPhotosManager.setAttachmentSize(media, container); //this.preloader.attach(container);
this.preloader.attach(container);
//this.preloader.setProgress(75); //this.preloader.setProgress(75);
console.log('will wrap video'); this.log('will wrap video');
wrapVideo(media, container, () => {
if(this.currentMessageID != message.mid) {
console.warn('media viewer changed photo');
return false;
}
return true; wrapVideo.call(this, media, container, message, false, this.preloader);
}, message.mid, false, this.preloader);
} else { } else {
let size = appPhotosManager.setAttachmentSize(media.id, container, appPhotosManager.windowW, appPhotosManager.windowH); let size = appPhotosManager.setAttachmentSize(media.id, container, appPhotosManager.windowW, appPhotosManager.windowH);
@ -187,11 +183,11 @@ class AppMediaViewer {
let cancellablePromise = appPhotosManager.preloadPhoto(media.id, size); let cancellablePromise = appPhotosManager.preloadPhoto(media.id, size);
cancellablePromise.then((blob) => { cancellablePromise.then((blob) => {
if(this.currentMessageID != message.mid) { if(this.currentMessageID != message.mid) {
console.warn('media viewer changed photo'); this.log.warn('media viewer changed photo');
return; return;
} }
console.log('indochina', blob); this.log('indochina', blob);
if(container.firstElementChild) { if(container.firstElementChild) {
container.firstElementChild.remove(); container.firstElementChild.remove();
} }

16
src/lib/appManagers/appMessagesManager.ts

@ -1639,7 +1639,11 @@ export class AppMessagesManager {
public getSearch(peerID = 0, query: string = '', inputFilter: { public getSearch(peerID = 0, query: string = '', inputFilter: {
_?: string _?: string
} = {_: 'inputMessagesFilterEmpty'}, maxID: number, limit: number) { } = {_: 'inputMessagesFilterEmpty'}, maxID: number, limit: number, offsetRate = 0): Promise<{
count: number,
next_rate: number,
history: number[]
}> {
//peerID = peerID ? parseInt(peerID) : 0; //peerID = peerID ? parseInt(peerID) : 0;
var foundMsgs: number[] = []; var foundMsgs: number[] = [];
var useSearchCache = !query; var useSearchCache = !query;
@ -1713,6 +1717,7 @@ export class AppMessagesManager {
default: default:
return Promise.resolve({ return Promise.resolve({
count: 0, count: 0,
next_rate: 0,
history: [] as number[] history: [] as number[]
}); });
} }
@ -1756,6 +1761,7 @@ export class AppMessagesManager {
return Promise.resolve({ return Promise.resolve({
count: 0, count: 0,
next_rate: 0,
history: foundMsgs history: foundMsgs
}); });
} }
@ -1793,7 +1799,7 @@ export class AppMessagesManager {
apiPromise = MTProto.apiManager.invokeApi('messages.searchGlobal', { apiPromise = MTProto.apiManager.invokeApi('messages.searchGlobal', {
q: query, q: query,
offset_date: offsetDate, offset_rate: offsetRate,
offset_peer: AppPeersManager.getInputPeerByID(offsetPeerID), offset_peer: AppPeersManager.getInputPeerByID(offsetPeerID),
offset_id: appMessagesIDsManager.getMessageLocalID(offsetID), offset_id: appMessagesIDsManager.getMessageLocalID(offsetID),
limit: limit || 20 limit: limit || 20
@ -1808,6 +1814,8 @@ export class AppMessagesManager {
appChatsManager.saveApiChats(searchResult.chats); appChatsManager.saveApiChats(searchResult.chats);
this.saveMessages(searchResult.messages); this.saveMessages(searchResult.messages);
console.log('messages.search result:', searchResult);
var foundCount: number = searchResult.count || searchResult.messages.length; var foundCount: number = searchResult.count || searchResult.messages.length;
foundMsgs = []; foundMsgs = [];
@ -1830,12 +1838,14 @@ export class AppMessagesManager {
return { return {
count: foundCount, count: foundCount,
next_rate: searchResult.next_rate,
history: foundMsgs history: foundMsgs
} };
}, (error) => { }, (error) => {
if(error.code == 400) { if(error.code == 400) {
error.handled = true; error.handled = true;
} }
return Promise.reject(error); return Promise.reject(error);
}); });
} }

12
src/lib/appManagers/appPhotosManager.ts

@ -151,13 +151,13 @@ export class AppPhotosManager {
let image = new Image(); let image = new Image();
image.src = URL.createObjectURL(blob); image.src = URL.createObjectURL(blob);
image.style.width = '100%'; // image.style.width = '100%';
image.style.height = '100%'; // image.style.height = '100%';
div.append(image); div.append(image);
} }
} }
public setAttachmentSize(photoID: any, div: HTMLDivElement, w = 380, h = 0) { public setAttachmentSize(photoID: any, div: HTMLDivElement, w = 380, h = 0/* 380 */) {
let photo: /* MTDocument | MTPhoto */any = null; let photo: /* MTDocument | MTPhoto */any = null;
if(typeof(photoID) === 'string') { if(typeof(photoID) === 'string') {
@ -170,11 +170,9 @@ export class AppPhotosManager {
let photoSize = this.choosePhotoSize(photo, w, h); let photoSize = this.choosePhotoSize(photo, w, h);
//console.log('setAttachmentSize', photo, photo.sizes[0].bytes, div); //console.log('setAttachmentSize', photo, photo.sizes[0].bytes, div);
let thumb: any;
let sizes = photo.sizes || photo.thumbs; let sizes = photo.sizes || photo.thumbs;
if(sizes && (sizes[0]._ == 'photoStrippedSize' || sizes[0]._ == 'photoCachedSize' && sizes[0].bytes)) { if(sizes && sizes[0].bytes) {
thumb = sizes[0]; this.setAttachmentPreview(sizes[0].bytes, div);
this.setAttachmentPreview(thumb.bytes, div);
} }
if(photo._ == 'document' /* && photo.type != 'video' */ && photo.type != 'gif') { if(photo._ == 'document' /* && photo.type != 'video' */ && photo.type != 'gif') {

117
src/lib/appManagers/appSidebarLeft.ts

@ -2,6 +2,8 @@ import { logger } from "../polyfill";
import { scrollable } from "../../components/misc"; import { scrollable } from "../../components/misc";
import appMessagesManager from "./appMessagesManager"; import appMessagesManager from "./appMessagesManager";
import appDialogsManager from "./appDialogsManager"; import appDialogsManager from "./appDialogsManager";
import { isElementInViewport } from "../utils";
import appMessagesIDsManager from "./appMessagesIDsManager";
class AppSidebarLeft { class AppSidebarLeft {
private sidebarEl = document.querySelector('.page-chats .chats-container') as HTMLDivElement; private sidebarEl = document.querySelector('.page-chats .chats-container') as HTMLDivElement;
@ -15,13 +17,22 @@ class AppSidebarLeft {
private log = logger('SL'); private log = logger('SL');
private peerID = 0; private peerID = 0;
private minMsgID = 0;
private loadedCount = 0;
private foundCount = 0;
private offsetRate = 0;
private searchPromise: Promise<void> = null; private searchPromise: Promise<void> = null;
private searchTimeout: number = 0;
private query = '';
constructor() { constructor() {
this.listsContainer = scrollable(this.searchContainer); this.listsContainer = scrollable(this.searchContainer);
this.searchMessagesList = document.createElement('ul'); this.searchMessagesList = document.createElement('ul');
this.listsContainer.onscroll = this.onSidebarScroll.bind(this);
this.searchContainer.append(this.listsContainer); this.searchContainer.append(this.listsContainer);
appDialogsManager.setListClickListener(this.searchMessagesList); appDialogsManager.setListClickListener(this.searchMessagesList);
@ -42,7 +53,9 @@ class AppSidebarLeft {
this.searchContainer.classList.remove('active'); this.searchContainer.classList.remove('active');
} }
this.peerID = 0; /* this.peerID = 0;
this.loadedCount = 0;
this.minMsgID = 0; */
}, {once: true}); }, {once: true});
}); });
@ -59,16 +72,83 @@ class AppSidebarLeft {
return; return;
} }
appMessagesManager.getSearch(this.peerID, value, null, 0, 20).then(res => { this.query = value;
if(this.searchInput.value != value) { this.minMsgID = 0;
this.loadedCount = 0;
this.foundCount = 0;
this.offsetRate = 0;
this.searchMessagesList.innerHTML = '';
this.searchPromise = null;
this.searchMore().then(() => {
this.listsContainer.append(this.searchMessagesList);
});
});
this.toolsBtn.addEventListener('click', () => {
if(this.toolsBtn.classList.contains('tgico-back')) {
this.searchInput.value = '';
this.toolsBtn.classList.add('tgico-menu');
this.toolsBtn.classList.remove('tgico-back');
this.searchContainer.classList.remove('active');
}
});
window.addEventListener('resize', () => {
setTimeout(() => this.onSidebarScroll(), 0);
});
}
public onSidebarScroll() {
let elements = Array.from(this.searchMessagesList.childNodes).slice(-5);
for(let li of elements) {
if(isElementInViewport(li)) {
this.log('Will load more search');
if(!this.searchTimeout) {
this.searchTimeout = setTimeout(() => {
this.searchMore();
this.searchTimeout = 0;
}, 0);
}
break;
}
}
}
public beginSearch(peerID?: number) {
if(peerID) {
this.peerID = peerID;
}
this.searchInput.focus();
}
private searchMore() {
if(this.searchPromise) return this.searchPromise;
let query = this.query;
if(this.loadedCount != 0 && this.loadedCount >= this.foundCount) {
return Promise.resolve();
}
let maxID = 0;//appMessagesIDsManager.getMessageIDInfo(this.minMsgID)[0] - 1;
return this.searchPromise = appMessagesManager.getSearch(this.peerID, query, null, maxID, 20, this.offsetRate).then(res => {
this.searchPromise = null;
if(this.searchInput.value != query) {
return; return;
} }
this.log('input search result:', res); this.log('input search result:', this.peerID, query, null, maxID, 20, res);
let {count, history} = res; let {count, history, next_rate} = res;
this.searchMessagesList.innerHTML = ''; if(history[0] == this.minMsgID) {
history.shift();
}
history.forEach((msgID: number) => { history.forEach((msgID: number) => {
let message = appMessagesManager.getMessage(msgID); let message = appMessagesManager.getMessage(msgID);
@ -83,27 +163,18 @@ class AppSidebarLeft {
appDialogsManager.setLastMessage(dialog, message, dom); appDialogsManager.setLastMessage(dialog, message, dom);
}); });
this.listsContainer.append(this.searchMessagesList); this.minMsgID = history[history.length - 1];
}); this.offsetRate = next_rate;
}); this.loadedCount += history.length;
this.toolsBtn.addEventListener('click', () => { if(!this.foundCount) {
if(this.toolsBtn.classList.contains('tgico-back')) { this.foundCount = count;
this.searchInput.value = '';
this.toolsBtn.classList.add('tgico-menu');
this.toolsBtn.classList.remove('tgico-back');
this.searchContainer.classList.remove('active');
} }
}).catch(err => {
this.log.error('search error', err);
this.searchPromise = null;
}); });
} }
public beginSearch(peerID?: number) {
if(peerID) {
this.peerID = peerID;
}
this.searchInput.focus();
}
} }
export default new AppSidebarLeft(); export default new AppSidebarLeft();

1
src/lib/appManagers/appSidebarRight.ts

@ -9,7 +9,6 @@ import { RichTextProcessor } from "../richtextprocessor";
import { logger } from "../polyfill"; import { logger } from "../polyfill";
import appImManager from "./appImManager"; import appImManager from "./appImManager";
import appMediaViewer from "./appMediaViewer"; import appMediaViewer from "./appMediaViewer";
import appDocsManager from "./appDocsManager";
class AppSidebarRight { class AppSidebarRight {
public sidebarEl = document.querySelector('.profile-container') as HTMLDivElement; public sidebarEl = document.querySelector('.profile-container') as HTMLDivElement;

12
src/lib/services.ts

@ -30,18 +30,6 @@ export const appStickersManager = AppStickersManager;
export const appSidebarRight = AppSidebarRight; export const appSidebarRight = AppSidebarRight;
export const appSidebarLeft = AppSidebarLeft; export const appSidebarLeft = AppSidebarLeft;
export type DialogDom = {
avatarDiv: HTMLDivElement,
captionDiv: HTMLDivElement,
titleSpan: HTMLSpanElement,
statusSpan: HTMLSpanElement,
lastTimeSpan: HTMLSpanElement,
unreadMessagesSpan: HTMLSpanElement,
lastMessageSpan: HTMLSpanElement,
listEl: HTMLLIElement
};
(window as any).Services = { (window as any).Services = {
appUsersManager, appUsersManager,
appChatsManager, appChatsManager,

11
src/scss/partials/_chat.scss

@ -237,7 +237,8 @@
.box.web { .box.web {
width: min-content; width: min-content;
max-width: min-content; /* max-width: min-content; */
max-width: 100%;
} }
} }
@ -248,7 +249,8 @@
} }
img, video { img, video {
object-fit: contain; /* object-fit: contain; */
object-fit: cover;
} }
.emoji { .emoji {
@ -361,14 +363,17 @@
&:not(.sticker) { &:not(.sticker) {
.attachment { .attachment {
max-width: 380px; max-width: 380px;
max-height: 380px;
} }
} }
&.video { &.video {
.attachment { .attachment {
//max-height: fit-content;
img { img {
width: 100%; width: 100%;
height: 100%; /* height: 100%; */
} }
} }
} }

130
src/scss/style.scss

@ -32,6 +32,7 @@ $time-size: 12px;
@import "partials/chat"; @import "partials/chat";
@import "partials/sidebar"; @import "partials/sidebar";
@import "partials/leftSidebar"; @import "partials/leftSidebar";
@import "partials/mediaViewer";
html, body { html, body {
height: 100%; height: 100%;
@ -1077,136 +1078,7 @@ $width: 100px;
} }
} }
.media-viewer {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, .9);
/* color: $darkgrey; */
display: flex;
align-items: center;
justify-content: center;
.media-viewer-author {
position: absolute;
top: 0;
left: 0;
height: 60px;
padding: 8px 8px 8px 80px;
display: flex;
flex-direction: column;
justify-content: center;
color: #8b8b8b;
.user-avatar {
width: 44px;
height: 44px;
position: absolute;
top: 8px;
left: 20px;
}
.media-viewer-name {
font-weight: 500;
}
.media-viewer-date {
font-size: 15px;
}
}
.media-viewer-buttons {
position: absolute;
top: 0;
right: 0;
display: flex;
flex-flow: row nowrap;
padding: 8px;
.btn-icon {
margin: 0 .25rem;
}
}
.media-viewer-content {
display: flex;
flex-direction: column;
justify-content: center;
height: 100%;
.media-viewer-stub {
flex: 1;
}
.media-viewer-container {
align-self: center;
position: relative;
}
.media-viewer-media {
display: flex;
align-items: center;
justify-content: center;
> img, > video {
max-height: calc(100vh - 100px);
max-width: calc(100vw - 16px);
}
}
.media-viewer-switcher-left, .media-viewer-switcher-right {
position: absolute;
left: 0;
top: 0;
width: 10rem;
height: 100%;
cursor: pointer;
&:hover {
> span {
opacity: 1;
}
}
}
.media-viewer-switcher-right {
left: auto;
right: 0;
}
.media-viewer-prev-button, .media-viewer-next-button {
cursor: pointer;
position: absolute;
color: #fff;
font-size: 3rem;
left: 2rem;
top: 50%;
transform: translateY(-50%) rotate(90deg);
opacity: 0;
transition: .2s opacity;
z-index: 3;
/* box-shadow: 0 1px 2px 0 rgba(16, 35, 47, 0.07); */
}
.media-viewer-next-button {
left: auto;
right: 2rem;
transform: translateY(-50%) rotate(-90deg);
}
.media-viewer-caption {
flex: 1;
text-align: center;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: $darkgrey;
}
}
}
div.scrollable-y::-webkit-scrollbar { div.scrollable-y::-webkit-scrollbar {
/* width: 4px; */ /* width: 4px; */

9665
stats.json

File diff suppressed because one or more lines are too long
Loading…
Cancel
Save