Browse Source

Shared media handle new & deleted messages

master
morethanwords 4 years ago
parent
commit
77ea3e2f01
  1. 109
      src/components/sidebarRight/tabs/sharedMedia.ts
  2. 9
      src/lib/appManagers/appImManager.ts

109
src/components/sidebarRight/tabs/sharedMedia.ts

@ -33,19 +33,9 @@ let setText = (text: string, el: HTMLDivElement) => {
}); });
}; };
type ContentType = /* 'contentMembers' | */'contentMedia' | 'contentDocuments' | 'contentLinks' | 'contentAudio';
type SharedMediaType = /* 'inputMessagesFilterContacts' | */'inputMessagesFilterEmpty' | 'inputMessagesFilterPhotoVideo' | 'inputMessagesFilterDocument' | 'inputMessagesFilterUrl' | 'inputMessagesFilterMusic'; type SharedMediaType = /* 'inputMessagesFilterContacts' | */'inputMessagesFilterEmpty' | 'inputMessagesFilterPhotoVideo' | 'inputMessagesFilterDocument' | 'inputMessagesFilterUrl' | 'inputMessagesFilterMusic';
const contentToSharedMap: {[contentType in ContentType]: SharedMediaType} = { // TODO: отредактированное сообщение не изменится
//contentMembers: 'inputMessagesFilterContacts',
contentMedia: 'inputMessagesFilterPhotoVideo',
contentDocuments: 'inputMessagesFilterDocument',
contentLinks: 'inputMessagesFilterUrl',
contentAudio: 'inputMessagesFilterMusic'
};
// TODO: отправленное сообщение с картинкой, или же новое полученное апдейтом сообщение не отобразится в медии
// TODO: по-хорошему, нужно просто сделать апдейты для всего сайдбара
export default class AppSharedMediaTab implements SliderTab { export default class AppSharedMediaTab implements SliderTab {
public container: HTMLElement; public container: HTMLElement;
@ -67,7 +57,7 @@ export default class AppSharedMediaTab implements SliderTab {
notificationsStatus: HTMLParagraphElement notificationsStatus: HTMLParagraphElement
} = {} as any; } = {} as any;
public sharedMedia: { public sharedMedia: {
[t in ContentType]: HTMLDivElement [t in SharedMediaType]: HTMLDivElement
} = {} as any; } = {} as any;
private loadSidebarMediaPromises: {[type: string]: Promise<void>} = {}; private loadSidebarMediaPromises: {[type: string]: Promise<void>} = {};
@ -131,11 +121,12 @@ export default class AppSharedMediaTab implements SliderTab {
this.sharedMedia = { this.sharedMedia = {
//contentMembers: this.profileContentEl.querySelector('#content-members'), //contentMembers: this.profileContentEl.querySelector('#content-members'),
contentMedia: this.profileContentEl.querySelector('#content-media'), //inputMessagesFilterEmpty: null,
contentDocuments: this.profileContentEl.querySelector('#content-docs'), inputMessagesFilterPhotoVideo: this.profileContentEl.querySelector('#content-media'),
contentLinks: this.profileContentEl.querySelector('#content-links'), inputMessagesFilterDocument: this.profileContentEl.querySelector('#content-docs'),
contentAudio: this.profileContentEl.querySelector('#content-audio'), inputMessagesFilterUrl: this.profileContentEl.querySelector('#content-links'),
}; inputMessagesFilterMusic: this.profileContentEl.querySelector('#content-audio'),
} as any;
let container = this.profileContentEl.querySelector('.content-container .tabs-container') as HTMLDivElement; let container = this.profileContentEl.querySelector('.content-container .tabs-container') as HTMLDivElement;
this.profileTabs = this.profileContentEl.querySelector('.profile-tabs'); this.profileTabs = this.profileContentEl.querySelector('.profile-tabs');
@ -177,7 +168,7 @@ export default class AppSharedMediaTab implements SliderTab {
this.onTransitionEnd(); this.onTransitionEnd();
}); });
this.sharedMedia.contentMedia.addEventListener('click', (e) => { this.sharedMedia.inputMessagesFilterPhotoVideo.addEventListener('click', (e) => {
const target = e.target as HTMLDivElement; const target = e.target as HTMLDivElement;
const messageID = +target.dataset.mid; const messageID = +target.dataset.mid;
@ -210,6 +201,52 @@ export default class AppSharedMediaTab implements SliderTab {
}); */ }); */
} }
public renderNewMessages(mids: number[]) {
mids = mids.slice().reverse(); // ! because it will be ascend sorted array
for(const sharedMediaType of this.sharedMediaTypes) {
const filtered = this.filterMessagesByType(mids, sharedMediaType);
if(filtered.length) {
if(this.usedFromHistory[sharedMediaType] !== -1) {
this.historiesStorage[this.peerID][sharedMediaType].unshift(...mids);
this.usedFromHistory[sharedMediaType] += filtered.length;
this.performSearchResult(filtered, sharedMediaType, false);
}
break;
}
}
}
public deleteDeletedMessages(mids: number[]) {
for(const mid of mids) {
for(const sharedMediaType of this.sharedMediaTypes) {
if(!this.historiesStorage[this.peerID] || !this.historiesStorage[this.peerID][sharedMediaType]) continue;
const history = this.historiesStorage[this.peerID][sharedMediaType];
const idx = history.findIndex(m => m == mid);
if(idx !== -1) {
history.splice(idx, 1);
const container = this.sharedMedia[sharedMediaType];
const div = container.querySelector(`div[data-mid="${mid}"]`);
if(div) {
if(sharedMediaType == 'inputMessagesFilterPhotoVideo') {
delete this.mediaDivsByIDs[mid];
}
div.remove();
}
if(this.usedFromHistory[sharedMediaType] >= (idx + 1)) {
this.usedFromHistory[sharedMediaType]--;
}
break;
}
}
}
}
private onTransitionStart = () => { private onTransitionStart = () => {
// Jolly Cobra's // Workaround for scrollable content flickering during animation. // Jolly Cobra's // Workaround for scrollable content flickering during animation.
const container = this.scroll.container; const container = this.scroll.container;
@ -302,28 +339,27 @@ export default class AppSharedMediaTab implements SliderTab {
return filtered; return filtered;
} }
public async performSearchResult(messages: any[], type: SharedMediaType) { public async performSearchResult(messages: any[], type: SharedMediaType, append = true) {
const peerID = this.peerID; const peerID = this.peerID;
const elemsToAppend: HTMLElement[] = []; const elemsToAppend: HTMLElement[] = [];
const promises: Promise<any>[] = []; const promises: Promise<any>[] = [];
let sharedMediaDiv: HTMLDivElement; const sharedMediaDiv = this.sharedMedia[type];
/* for(let contentType in contentToSharedMap) { /* for(let contentType in contentToSharedMap) {
if(contentToSharedMap[contentType as ContentType] == type) { if(contentToSharedMap[contentType as ContentType] == type) {
sharedMediaDiv = this.sharedMedia[contentType as ContentType]; sharedMediaDiv = this.sharedMedia[contentType as ContentType];
} }
} */ } */
// https://core.telegram.org/type/MessagesFilter // https://core.telegram.org/type/MessagesFilter
switch(type) { switch(type) {
case 'inputMessagesFilterPhotoVideo': { case 'inputMessagesFilterPhotoVideo': {
sharedMediaDiv = this.sharedMedia.contentMedia;
for(const message of messages) { for(const message of messages) {
const media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document); const media = message.media.photo || message.media.document || (message.media.webpage && message.media.webpage.document);
const div = document.createElement('div'); const div = document.createElement('div');
div.classList.add('grid-item'); div.classList.add('grid-item');
div.dataset.mid = '' + message.mid;
//console.log(message, photo); //console.log(message, photo);
const isPhoto = media._ == 'photo'; const isPhoto = media._ == 'photo';
@ -428,18 +464,15 @@ export default class AppSharedMediaTab implements SliderTab {
} }
case 'inputMessagesFilterDocument': { case 'inputMessagesFilterDocument': {
sharedMediaDiv = this.sharedMedia.contentDocuments;
for(let message of messages) { for(let message of messages) {
let div = wrapDocument(message.media.document, true, false, message.mid); let div = wrapDocument(message.media.document, true, false, message.mid);
div.dataset.mid = '' + message.mid;
elemsToAppend.push(div); elemsToAppend.push(div);
} }
break; break;
} }
case 'inputMessagesFilterUrl': { case 'inputMessagesFilterUrl': {
sharedMediaDiv = this.sharedMedia.contentLinks;
for(let message of messages) { for(let message of messages) {
let webpage: any; let webpage: any;
@ -546,17 +579,16 @@ export default class AppSharedMediaTab implements SliderTab {
} }
case 'inputMessagesFilterMusic': { case 'inputMessagesFilterMusic': {
sharedMediaDiv = this.sharedMedia.contentAudio;
for(let message of messages) { for(let message of messages) {
let div = wrapAudio(message.media.document, true, message.mid); let div = wrapAudio(message.media.document, true, message.mid);
div.dataset.mid = '' + message.mid;
elemsToAppend.push(div); elemsToAppend.push(div);
} }
break; break;
} }
default: default:
console.warn('death is my friend', messages); //console.warn('death is my friend', messages);
break; break;
} }
@ -573,7 +605,7 @@ export default class AppSharedMediaTab implements SliderTab {
} }
if(elemsToAppend.length) { if(elemsToAppend.length) {
sharedMediaDiv.append(...elemsToAppend); sharedMediaDiv[append ? 'append' : 'prepend'](...elemsToAppend);
} }
if(sharedMediaDiv) { if(sharedMediaDiv) {
@ -621,7 +653,7 @@ export default class AppSharedMediaTab implements SliderTab {
// render from cache // render from cache
if(history.length && this.usedFromHistory[type] < history.length) { if(history.length && this.usedFromHistory[type] < history.length) {
let messages: any[] = []; let messages: any[] = [];
let used = this.usedFromHistory[type]; let used = Math.max(0, this.usedFromHistory[type]);
do { do {
let ids = history.slice(used, used + loadCount); let ids = history.slice(used, used + loadCount);
@ -694,7 +726,7 @@ export default class AppSharedMediaTab implements SliderTab {
this.lazyLoadQueue.clear(); this.lazyLoadQueue.clear();
this.sharedMediaTypes.forEach(type => { this.sharedMediaTypes.forEach(type => {
this.usedFromHistory[type] = 0; this.usedFromHistory[type] = -1;
}); });
this.sharedMediaType = 'inputMessagesFilterPhotoVideo'; this.sharedMediaType = 'inputMessagesFilterPhotoVideo';
@ -718,12 +750,11 @@ export default class AppSharedMediaTab implements SliderTab {
this.urlsToRevoke.length = 0; this.urlsToRevoke.length = 0;
} }
(Object.keys(this.sharedMedia) as ContentType[]).forEach(key => { (Object.keys(this.sharedMedia) as SharedMediaType[]).forEach(sharedMediaType => {
this.sharedMedia[key].innerHTML = ''; this.sharedMedia[sharedMediaType].innerHTML = '';
const inputFilter = contentToSharedMap[key]; if(!this.historiesStorage[this.peerID] || !this.historiesStorage[this.peerID][sharedMediaType]) {
if(!this.historiesStorage[this.peerID] || !this.historiesStorage[this.peerID][inputFilter]) { const parent = this.sharedMedia[sharedMediaType].parentElement;
const parent = this.sharedMedia[key].parentElement;
if(!testScroll) { if(!testScroll) {
if(!parent.querySelector('.preloader')) { if(!parent.querySelector('.preloader')) {
putPreloader(parent, true); putPreloader(parent, true);
@ -744,7 +775,7 @@ export default class AppSharedMediaTab implements SliderTab {
div.classList.add('grid-item'); div.classList.add('grid-item');
div.dataset.id = '' + (i / 3 | 0); div.dataset.id = '' + (i / 3 | 0);
//div.innerText = '' + (i / 3 | 0); //div.innerText = '' + (i / 3 | 0);
this.sharedMedia.contentMedia.append(div); this.sharedMedia.inputMessagesFilterPhotoVideo.append(div);
} }
} }

9
src/lib/appManagers/appImManager.ts

@ -221,12 +221,15 @@ export class AppImManager {
let msgIDs = msgIDsByPeer[this.peerID]; let msgIDs = msgIDsByPeer[this.peerID];
this.renderNewMessagesByIDs(msgIDs); this.renderNewMessagesByIDs(msgIDs);
appSidebarRight.sharedMediaTab.renderNewMessages(msgIDs);
}); });
$rootScope.$on('history_delete', (e) => { $rootScope.$on('history_delete', (e) => {
let detail = e.detail; const detail = e.detail;
this.deleteMessagesByIDs(Object.keys(detail.msgs).map(s => +s)); const mids = Object.keys(detail.msgs).map(s => +s);
this.deleteMessagesByIDs(mids);
appSidebarRight.sharedMediaTab.deleteDeletedMessages(mids);
}); });
$rootScope.$on('dialog_flush', (e) => { $rootScope.$on('dialog_flush', (e) => {
@ -272,6 +275,8 @@ export class AppImManager {
} }
} }
} }
appSidebarRight.sharedMediaTab.renderNewMessages([mid]);
let bubble = this.bubbles[tempID]; let bubble = this.bubbles[tempID];
if(bubble) { if(bubble) {

Loading…
Cancel
Save