|
|
@ -1,6 +1,6 @@ |
|
|
|
import { formatDateAccordingToToday, months } from "../helpers/date"; |
|
|
|
import { formatDateAccordingToToday, months } from "../helpers/date"; |
|
|
|
import { positionElementByIndex } from "../helpers/dom"; |
|
|
|
import { positionElementByIndex } from "../helpers/dom"; |
|
|
|
import { copy, getObjectKeysAndSort } from "../helpers/object"; |
|
|
|
import { copy, getObjectKeysAndSort, safeAssign } from "../helpers/object"; |
|
|
|
import { escapeRegExp, limitSymbols } from "../helpers/string"; |
|
|
|
import { escapeRegExp, limitSymbols } from "../helpers/string"; |
|
|
|
import appChatsManager from "../lib/appManagers/appChatsManager"; |
|
|
|
import appChatsManager from "../lib/appManagers/appChatsManager"; |
|
|
|
import appDialogsManager from "../lib/appManagers/appDialogsManager"; |
|
|
|
import appDialogsManager from "../lib/appManagers/appDialogsManager"; |
|
|
@ -25,11 +25,11 @@ import useHeavyAnimationCheck, { getHeavyAnimationPromise } from "../hooks/useHe |
|
|
|
import { isSafari } from "../helpers/userAgent"; |
|
|
|
import { isSafari } from "../helpers/userAgent"; |
|
|
|
import { LangPackKey, i18n } from "../lib/langPack"; |
|
|
|
import { LangPackKey, i18n } from "../lib/langPack"; |
|
|
|
import findUpClassName from "../helpers/dom/findUpClassName"; |
|
|
|
import findUpClassName from "../helpers/dom/findUpClassName"; |
|
|
|
import renderImageFromUrl from "../helpers/dom/renderImageFromUrl"; |
|
|
|
import { getMiddleware } from "../helpers/middleware"; |
|
|
|
|
|
|
|
|
|
|
|
//const testScroll = false;
|
|
|
|
//const testScroll = false;
|
|
|
|
|
|
|
|
|
|
|
|
export type SearchSuperType = MyInputMessagesFilter/* | 'chats' */; |
|
|
|
export type SearchSuperType = MyInputMessagesFilter/* | 'members' */; |
|
|
|
export type SearchSuperContext = { |
|
|
|
export type SearchSuperContext = { |
|
|
|
peerId: number, |
|
|
|
peerId: number, |
|
|
|
inputFilter: MyInputMessagesFilter, |
|
|
|
inputFilter: MyInputMessagesFilter, |
|
|
@ -43,10 +43,20 @@ export type SearchSuperContext = { |
|
|
|
maxDate?: number |
|
|
|
maxDate?: number |
|
|
|
}; |
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export type SearchSuperMediaType = 'members' | 'media' | 'files' | 'links' | 'music' | 'chats' | 'voice'; |
|
|
|
|
|
|
|
export type SearchSuperMediaTab = { |
|
|
|
|
|
|
|
inputFilter: SearchSuperType, |
|
|
|
|
|
|
|
name: LangPackKey, |
|
|
|
|
|
|
|
type: SearchSuperMediaType, |
|
|
|
|
|
|
|
contentTab?: HTMLElement, |
|
|
|
|
|
|
|
menuTab?: HTMLElement, |
|
|
|
|
|
|
|
scroll?: {scrollTop: number, scrollHeight: number} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
export default class AppSearchSuper { |
|
|
|
export default class AppSearchSuper { |
|
|
|
public tabs: {[t in SearchSuperType]: HTMLDivElement} = {} as any; |
|
|
|
public tabs: {[t in SearchSuperType]: HTMLDivElement} = {} as any; |
|
|
|
|
|
|
|
|
|
|
|
public type: SearchSuperType; |
|
|
|
public mediaTab: SearchSuperMediaTab; |
|
|
|
public tabSelected: HTMLElement; |
|
|
|
public tabSelected: HTMLElement; |
|
|
|
|
|
|
|
|
|
|
|
public container: HTMLElement; |
|
|
|
public container: HTMLElement; |
|
|
@ -56,7 +66,7 @@ export default class AppSearchSuper { |
|
|
|
private prevTabId = -1; |
|
|
|
private prevTabId = -1; |
|
|
|
|
|
|
|
|
|
|
|
private lazyLoadQueue = new LazyLoadQueue(); |
|
|
|
private lazyLoadQueue = new LazyLoadQueue(); |
|
|
|
private cleanupObj = {cleaned: false}; |
|
|
|
public middleware = getMiddleware(); |
|
|
|
|
|
|
|
|
|
|
|
public historyStorage: Partial<{[type in SearchSuperType]: {mid: number, peerId: number}[]}> = {}; |
|
|
|
public historyStorage: Partial<{[type in SearchSuperType]: {mid: number, peerId: number}[]}> = {}; |
|
|
|
public usedFromHistory: Partial<{[type in SearchSuperType]: number}> = {}; |
|
|
|
public usedFromHistory: Partial<{[type in SearchSuperType]: number}> = {}; |
|
|
@ -84,9 +94,19 @@ export default class AppSearchSuper { |
|
|
|
|
|
|
|
|
|
|
|
private searchGroupMedia: SearchGroup; |
|
|
|
private searchGroupMedia: SearchGroup; |
|
|
|
|
|
|
|
|
|
|
|
public goingHard: Partial<{[type in MyInputMessagesFilter]: {scrollTop: number, scrollHeight: number}}> = {}; |
|
|
|
public mediaTabsMap: Map<SearchSuperMediaType, SearchSuperMediaTab> = new Map(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// * arguments
|
|
|
|
|
|
|
|
public mediaTabs: SearchSuperMediaTab[]; |
|
|
|
|
|
|
|
public scrollable: Scrollable; |
|
|
|
|
|
|
|
public searchGroups?: {[group in SearchGroupType]: SearchGroup}; |
|
|
|
|
|
|
|
public asChatList? = false; |
|
|
|
|
|
|
|
public groupByMonth? = true; |
|
|
|
|
|
|
|
public hideEmptyTabs? = true; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor(options: Pick<AppSearchSuper, 'mediaTabs' | 'scrollable' | 'searchGroups' | 'asChatList' | 'groupByMonth' | 'hideEmptyTabs'>) { |
|
|
|
|
|
|
|
safeAssign(this, options); |
|
|
|
|
|
|
|
|
|
|
|
constructor(public types: {inputFilter: SearchSuperType, name: LangPackKey, type: string}[], public scrollable: Scrollable, public searchGroups?: {[group in SearchGroupType]: SearchGroup}, public asChatList = false, public groupByMonth = true) { |
|
|
|
|
|
|
|
this.container = document.createElement('div'); |
|
|
|
this.container = document.createElement('div'); |
|
|
|
this.container.classList.add('search-super'); |
|
|
|
this.container.classList.add('search-super'); |
|
|
|
|
|
|
|
|
|
|
@ -101,13 +121,13 @@ export default class AppSearchSuper { |
|
|
|
|
|
|
|
|
|
|
|
navScrollable.container.append(nav); |
|
|
|
navScrollable.container.append(nav); |
|
|
|
|
|
|
|
|
|
|
|
for(const type of types) { |
|
|
|
for(const mediaTab of this.mediaTabs) { |
|
|
|
const menuTab = document.createElement('div'); |
|
|
|
const menuTab = document.createElement('div'); |
|
|
|
menuTab.classList.add('menu-horizontal-div-item'); |
|
|
|
menuTab.classList.add('menu-horizontal-div-item'); |
|
|
|
const span = document.createElement('span'); |
|
|
|
const span = document.createElement('span'); |
|
|
|
const i = document.createElement('i'); |
|
|
|
const i = document.createElement('i'); |
|
|
|
|
|
|
|
|
|
|
|
span.append(i18n(type.name)); |
|
|
|
span.append(i18n(mediaTab.name)); |
|
|
|
span.append(i); |
|
|
|
span.append(i); |
|
|
|
|
|
|
|
|
|
|
|
menuTab.append(span); |
|
|
|
menuTab.append(span); |
|
|
@ -115,38 +135,29 @@ export default class AppSearchSuper { |
|
|
|
ripple(menuTab); |
|
|
|
ripple(menuTab); |
|
|
|
|
|
|
|
|
|
|
|
this.tabsMenu.append(menuTab); |
|
|
|
this.tabsMenu.append(menuTab); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.mediaTabsMap.set(mediaTab.type, mediaTab); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mediaTab.menuTab = menuTab; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.tabsContainer = document.createElement('div'); |
|
|
|
this.tabsContainer = document.createElement('div'); |
|
|
|
this.tabsContainer.classList.add('search-super-tabs-container', 'tabs-container'); |
|
|
|
this.tabsContainer.classList.add('search-super-tabs-container', 'tabs-container'); |
|
|
|
|
|
|
|
|
|
|
|
for(const type of types) { |
|
|
|
for(const mediaTab of this.mediaTabs) { |
|
|
|
const container = document.createElement('div'); |
|
|
|
const container = document.createElement('div'); |
|
|
|
container.classList.add('search-super-container-' + type.type/* , 'scrollable', 'scrollable-y' */); |
|
|
|
container.classList.add('search-super-container-' + mediaTab.type); |
|
|
|
|
|
|
|
|
|
|
|
const content = document.createElement('div'); |
|
|
|
const content = document.createElement('div'); |
|
|
|
content.classList.add('search-super-content-' + type.type/* , 'scrollable', 'scrollable-y' */); |
|
|
|
content.classList.add('search-super-content-' + mediaTab.type); |
|
|
|
|
|
|
|
|
|
|
|
//content.style.overflowY = 'hidden';
|
|
|
|
|
|
|
|
/* container.style.overflow = 'visible'; |
|
|
|
|
|
|
|
const v = 236; |
|
|
|
|
|
|
|
content.style.top = (v * -1) + 'px'; |
|
|
|
|
|
|
|
content.style.paddingTop = v + 'px'; |
|
|
|
|
|
|
|
content.style.height = `calc(100% + ${v}px)`; |
|
|
|
|
|
|
|
content.style.maxHeight = `calc(100% + ${v}px)`; |
|
|
|
|
|
|
|
content.addEventListener('scroll', (e) => { |
|
|
|
|
|
|
|
const scrollTop = content.scrollTop; |
|
|
|
|
|
|
|
if(scrollTop <= v) { |
|
|
|
|
|
|
|
//this.scrollable.scrollTop = scrollTop;
|
|
|
|
|
|
|
|
(this.container.previousElementSibling as HTMLElement).style.transform = `translateY(-${scrollTop}px)`; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
container.append(content); |
|
|
|
container.append(content); |
|
|
|
|
|
|
|
|
|
|
|
this.tabsContainer.append(container); |
|
|
|
this.tabsContainer.append(container); |
|
|
|
|
|
|
|
|
|
|
|
this.tabs[type.inputFilter] = content; |
|
|
|
this.tabs[mediaTab.inputFilter] = content; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
mediaTab.contentTab = content; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.container.append(navScrollableContainer, this.tabsContainer); |
|
|
|
this.container.append(navScrollableContainer, this.tabsContainer); |
|
|
@ -170,23 +181,23 @@ export default class AppSearchSuper { |
|
|
|
this.onTransitionStart(); |
|
|
|
this.onTransitionStart(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.goingHard[this.type] = {scrollTop: this.scrollable.scrollTop, scrollHeight: this.scrollable.scrollHeight}; |
|
|
|
this.mediaTab.scroll = {scrollTop: this.scrollable.scrollTop, scrollHeight: this.scrollable.scrollHeight}; |
|
|
|
|
|
|
|
|
|
|
|
const newType = this.types[id].inputFilter; |
|
|
|
const newMediaTab = this.mediaTabs[id]; |
|
|
|
this.tabSelected = tabContent.firstElementChild as HTMLDivElement; |
|
|
|
this.tabSelected = tabContent.firstElementChild as HTMLDivElement; |
|
|
|
|
|
|
|
|
|
|
|
if(this.goingHard[newType] === undefined) { |
|
|
|
if(newMediaTab.scroll === undefined) { |
|
|
|
const rect = this.container.getBoundingClientRect(); |
|
|
|
const rect = this.container.getBoundingClientRect(); |
|
|
|
const rect2 = this.container.parentElement.getBoundingClientRect(); |
|
|
|
const rect2 = this.container.parentElement.getBoundingClientRect(); |
|
|
|
const diff = rect.y - rect2.y; |
|
|
|
const diff = rect.y - rect2.y; |
|
|
|
|
|
|
|
|
|
|
|
if(this.scrollable.scrollTop > diff) { |
|
|
|
if(this.scrollable.scrollTop > diff) { |
|
|
|
this.goingHard[newType] = {scrollTop: diff, scrollHeight: 0}; |
|
|
|
newMediaTab.scroll = {scrollTop: diff, scrollHeight: 0}; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(this.goingHard[newType]) { |
|
|
|
if(newMediaTab.scroll) { |
|
|
|
const diff = this.goingHard[this.type].scrollTop - this.goingHard[newType].scrollTop; |
|
|
|
const diff = this.mediaTab.scroll.scrollTop - newMediaTab.scroll.scrollTop; |
|
|
|
//console.log('what you gonna do', this.goingHard, diff);
|
|
|
|
//console.log('what you gonna do', this.goingHard, diff);
|
|
|
|
|
|
|
|
|
|
|
|
if(diff/* && diff < 0 */) { |
|
|
|
if(diff/* && diff < 0 */) { |
|
|
@ -194,7 +205,7 @@ export default class AppSearchSuper { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.type = newType; |
|
|
|
this.mediaTab = newMediaTab; |
|
|
|
|
|
|
|
|
|
|
|
/* if(this.prevTabId !== -1 && nav.offsetTop) { |
|
|
|
/* if(this.prevTabId !== -1 && nav.offsetTop) { |
|
|
|
this.scrollable.scrollTop -= nav.offsetTop; |
|
|
|
this.scrollable.scrollTop -= nav.offsetTop; |
|
|
@ -213,9 +224,9 @@ export default class AppSearchSuper { |
|
|
|
this.scrollable.onScroll(); |
|
|
|
this.scrollable.onScroll(); |
|
|
|
|
|
|
|
|
|
|
|
//console.log('what y', this.tabSelected.style.transform);
|
|
|
|
//console.log('what y', this.tabSelected.style.transform);
|
|
|
|
if(this.goingHard[this.type] !== undefined) { |
|
|
|
if(this.mediaTab.scroll !== undefined) { |
|
|
|
this.tabSelected.style.transform = ''; |
|
|
|
this.tabSelected.style.transform = ''; |
|
|
|
this.scrollable.scrollTop = this.goingHard[this.type].scrollTop; |
|
|
|
this.scrollable.scrollTop = this.mediaTab.scroll.scrollTop; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
this.onTransitionEnd(); |
|
|
|
this.onTransitionEnd(); |
|
|
@ -241,11 +252,11 @@ export default class AppSearchSuper { |
|
|
|
|
|
|
|
|
|
|
|
const message = appMessagesManager.getMessageByPeer(peerId, mid); |
|
|
|
const message = appMessagesManager.getMessageByPeer(peerId, mid); |
|
|
|
new AppMediaViewer() |
|
|
|
new AppMediaViewer() |
|
|
|
.setSearchContext(this.copySearchContext(this.type)) |
|
|
|
.setSearchContext(this.copySearchContext(this.mediaTab.inputFilter)) |
|
|
|
.openMedia(message, target, 0, false, targets.slice(0, idx), targets.slice(idx + 1)); |
|
|
|
.openMedia(message, target, 0, false, targets.slice(0, idx), targets.slice(idx + 1)); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.type = this.types[0].inputFilter; |
|
|
|
this.mediaTab = this.mediaTabs[0]; |
|
|
|
|
|
|
|
|
|
|
|
useHeavyAnimationCheck(() => { |
|
|
|
useHeavyAnimationCheck(() => { |
|
|
|
this.lazyLoadQueue.lock(); |
|
|
|
this.lazyLoadQueue.lock(); |
|
|
@ -381,7 +392,7 @@ export default class AppSearchSuper { |
|
|
|
const elemsToAppend: {element: HTMLElement, message: any}[] = []; |
|
|
|
const elemsToAppend: {element: HTMLElement, message: any}[] = []; |
|
|
|
const sharedMediaDiv: HTMLElement = this.tabs[type]; |
|
|
|
const sharedMediaDiv: HTMLElement = this.tabs[type]; |
|
|
|
const promises: Promise<any>[] = []; |
|
|
|
const promises: Promise<any>[] = []; |
|
|
|
const middleware = this.getMiddleware(); |
|
|
|
const middleware = this.middleware.get(); |
|
|
|
|
|
|
|
|
|
|
|
await getHeavyAnimationPromise(); |
|
|
|
await getHeavyAnimationPromise(); |
|
|
|
|
|
|
|
|
|
|
@ -538,23 +549,22 @@ export default class AppSearchSuper { |
|
|
|
|
|
|
|
|
|
|
|
//this.log('wrapping webpage', webpage);
|
|
|
|
//this.log('wrapping webpage', webpage);
|
|
|
|
|
|
|
|
|
|
|
|
previewDiv.innerHTML = RichTextProcessor.getAbbreviation(webpage.title || webpage.display_url || webpage.description || webpage.url, true); |
|
|
|
|
|
|
|
previewDiv.classList.add('empty'); |
|
|
|
|
|
|
|
if(webpage.photo) { |
|
|
|
if(webpage.photo) { |
|
|
|
let load = () => appPhotosManager.preloadPhoto(webpage.photo.id, appPhotosManager.choosePhotoSize(webpage.photo, 60, 60)) |
|
|
|
const res = wrapPhoto({ |
|
|
|
.then(() => { |
|
|
|
container: previewDiv, |
|
|
|
if(!middleware()) { |
|
|
|
message: null, |
|
|
|
//this.log.warn('peer changed');
|
|
|
|
photo: webpage.photo, |
|
|
|
return; |
|
|
|
boxWidth: 0, |
|
|
|
} |
|
|
|
boxHeight: 0, |
|
|
|
|
|
|
|
withoutPreloader: true, |
|
|
|
previewDiv.classList.remove('empty'); |
|
|
|
lazyLoadQueue: this.lazyLoadQueue, |
|
|
|
|
|
|
|
middleware, |
|
|
|
previewDiv.innerText = ''; |
|
|
|
size: appPhotosManager.choosePhotoSize(webpage.photo, 60, 60, false), |
|
|
|
renderImageFromUrl(previewDiv, webpage.photo.url); |
|
|
|
loadPromises: promises |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
} else { |
|
|
|
this.lazyLoadQueue.push({div: previewDiv, load}); |
|
|
|
previewDiv.classList.add('empty'); |
|
|
|
|
|
|
|
previewDiv.innerHTML = RichTextProcessor.getAbbreviation(webpage.title || webpage.display_url || webpage.description || webpage.url, true); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
let title = webpage.rTitle || ''; |
|
|
|
let title = webpage.rTitle || ''; |
|
|
@ -624,16 +634,16 @@ export default class AppSearchSuper { |
|
|
|
//}
|
|
|
|
//}
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private afterPerforming(length: number, tab: HTMLElement) { |
|
|
|
private afterPerforming(length: number, contentTab: HTMLElement) { |
|
|
|
if(tab) { |
|
|
|
if(contentTab) { |
|
|
|
const parent = tab.parentElement; |
|
|
|
const parent = contentTab.parentElement; |
|
|
|
Array.from(parent.children).slice(1).forEach(child => { |
|
|
|
Array.from(parent.children).slice(1).forEach(child => { |
|
|
|
child.remove(); |
|
|
|
child.remove(); |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
//this.contentContainer.classList.add('loaded');
|
|
|
|
//this.contentContainer.classList.add('loaded');
|
|
|
|
|
|
|
|
|
|
|
|
if(!length && !tab.childElementCount) { |
|
|
|
if(!length && !contentTab.childElementCount) { |
|
|
|
const div = document.createElement('div'); |
|
|
|
const div = document.createElement('div'); |
|
|
|
div.innerText = 'Nothing interesting here yet...'; |
|
|
|
div.innerText = 'Nothing interesting here yet...'; |
|
|
|
div.classList.add('position-center', 'text-center', 'content-empty', 'no-select'); |
|
|
|
div.classList.add('position-center', 'text-center', 'content-empty', 'no-select'); |
|
|
@ -645,7 +655,7 @@ export default class AppSearchSuper { |
|
|
|
|
|
|
|
|
|
|
|
private loadChats() { |
|
|
|
private loadChats() { |
|
|
|
const renderedPeerIds: Set<number> = new Set(); |
|
|
|
const renderedPeerIds: Set<number> = new Set(); |
|
|
|
const middleware = this.getMiddleware(); |
|
|
|
const middleware = this.middleware.get(); |
|
|
|
|
|
|
|
|
|
|
|
for(let i in this.searchGroups) { |
|
|
|
for(let i in this.searchGroups) { |
|
|
|
const group = this.searchGroups[i as SearchGroupType]; |
|
|
|
const group = this.searchGroups[i as SearchGroupType]; |
|
|
@ -808,32 +818,14 @@ export default class AppSearchSuper { |
|
|
|
} else return Promise.resolve(); |
|
|
|
} else return Promise.resolve(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public load(single = false, justLoad = false) { |
|
|
|
private loadType(mediaTab: SearchSuperMediaTab, justLoad: boolean, loadCount: number, middleware: () => boolean) { |
|
|
|
// if(testScroll/* || 1 === 1 */) {
|
|
|
|
const type = mediaTab.inputFilter; |
|
|
|
// return;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const peerId = this.searchContext.peerId; |
|
|
|
|
|
|
|
this.log('load', single, peerId, this.loadPromises); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let typesToLoad = single ? [this.type] : this.types.filter(t => t.inputFilter !== this.type).map(t => t.inputFilter); |
|
|
|
if(this.loadPromises[type]) { |
|
|
|
typesToLoad = typesToLoad.filter(type => !this.loaded[type] |
|
|
|
return this.loadPromises[type]; |
|
|
|
|| (this.historyStorage[type] && this.usedFromHistory[type] < this.historyStorage[type].length)); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(!typesToLoad.length) return; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const loadCount = justLoad ? 50 : Math.round((appPhotosManager.windowH / 130 | 0) * 3 * 1.25); // that's good for all types
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const historyStorage = this.historyStorage ?? (this.historyStorage = {}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const middleware = this.getMiddleware(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const promises: Promise<any>[] = typesToLoad.map(type => { |
|
|
|
|
|
|
|
if(this.loadPromises[type]) return this.loadPromises[type]; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const history = historyStorage[type] ?? (historyStorage[type] = []); |
|
|
|
const history = this.historyStorage[type] ?? (this.historyStorage[type] = []); |
|
|
|
|
|
|
|
|
|
|
|
if(type === 'inputMessagesFilterEmpty' && !history.length) { |
|
|
|
if(type === 'inputMessagesFilterEmpty' && !history.length) { |
|
|
|
if(!this.loadedChats) { |
|
|
|
if(!this.loadedChats) { |
|
|
@ -889,7 +881,7 @@ export default class AppSearchSuper { |
|
|
|
|
|
|
|
|
|
|
|
//let loadCount = history.length ? 50 : 15;
|
|
|
|
//let loadCount = history.length ? 50 : 15;
|
|
|
|
return this.loadPromises[type] = appMessagesManager.getSearch({ |
|
|
|
return this.loadPromises[type] = appMessagesManager.getSearch({ |
|
|
|
peerId, |
|
|
|
peerId: this.searchContext.peerId, |
|
|
|
query: this.searchContext.query, |
|
|
|
query: this.searchContext.query, |
|
|
|
inputFilter: {_: type}, |
|
|
|
inputFilter: {_: type}, |
|
|
|
maxId, |
|
|
|
maxId, |
|
|
@ -929,7 +921,7 @@ export default class AppSearchSuper { |
|
|
|
setTimeout(() => { |
|
|
|
setTimeout(() => { |
|
|
|
if(!middleware()) return; |
|
|
|
if(!middleware()) return; |
|
|
|
//this.log('will preload more');
|
|
|
|
//this.log('will preload more');
|
|
|
|
if(this.type === type) { |
|
|
|
if(this.mediaTab === mediaTab) { |
|
|
|
const promise = this.load(true, true); |
|
|
|
const promise = this.load(true, true); |
|
|
|
if(promise) { |
|
|
|
if(promise) { |
|
|
|
promise.then(() => { |
|
|
|
promise.then(() => { |
|
|
@ -953,6 +945,33 @@ export default class AppSearchSuper { |
|
|
|
}).finally(() => { |
|
|
|
}).finally(() => { |
|
|
|
this.loadPromises[type] = null; |
|
|
|
this.loadPromises[type] = null; |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public load(single = false, justLoad = false) { |
|
|
|
|
|
|
|
// if(testScroll/* || 1 === 1 */) {
|
|
|
|
|
|
|
|
// return;
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const peerId = this.searchContext.peerId; |
|
|
|
|
|
|
|
this.log('load', single, peerId, this.loadPromises); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let toLoad = single ? [this.mediaTab] : this.mediaTabs.filter(t => t !== this.mediaTab); |
|
|
|
|
|
|
|
toLoad = toLoad.filter(mediaTab => { |
|
|
|
|
|
|
|
const inputFilter = mediaTab.inputFilter; |
|
|
|
|
|
|
|
return !this.loaded[inputFilter] || (this.historyStorage[inputFilter] && this.usedFromHistory[inputFilter] < this.historyStorage[inputFilter].length); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(!toLoad.length) { |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const loadCount = justLoad ? 50 : Math.round((appPhotosManager.windowH / 130 | 0) * 3 * 1.25); // that's good for all types
|
|
|
|
|
|
|
|
const middleware = this.middleware.get(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const promises: Promise<any>[] = toLoad.map(mediaTab => { |
|
|
|
|
|
|
|
return this.loadType(mediaTab, justLoad, loadCount, middleware) |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
return Promise.all(promises).catch(err => { |
|
|
|
return Promise.all(promises).catch(err => { |
|
|
@ -1006,13 +1025,18 @@ export default class AppSearchSuper { |
|
|
|
|
|
|
|
|
|
|
|
this.lazyLoadQueue.clear(); |
|
|
|
this.lazyLoadQueue.clear(); |
|
|
|
|
|
|
|
|
|
|
|
this.types.forEach(type => { |
|
|
|
this.mediaTabs.forEach(mediaTab => { |
|
|
|
this.usedFromHistory[type.inputFilter] = -1; |
|
|
|
this.usedFromHistory[mediaTab.inputFilter] = -1; |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
this.cleanupObj.cleaned = true; |
|
|
|
this.middleware.clean(); |
|
|
|
this.cleanupObj = {cleaned: false}; |
|
|
|
this.cleanScrollPositions(); |
|
|
|
this.goingHard = {}; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public cleanScrollPositions() { |
|
|
|
|
|
|
|
this.mediaTabs.forEach(mediaTab => { |
|
|
|
|
|
|
|
mediaTab.scroll = undefined; |
|
|
|
|
|
|
|
}); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public cleanupHTML() { |
|
|
|
public cleanupHTML() { |
|
|
@ -1023,15 +1047,15 @@ export default class AppSearchSuper { |
|
|
|
this.urlsToRevoke.length = 0; |
|
|
|
this.urlsToRevoke.length = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
(Object.keys(this.tabs) as SearchSuperType[]).forEach(type => { |
|
|
|
this.mediaTabs.forEach((tab) => { |
|
|
|
this.tabs[type].innerHTML = ''; |
|
|
|
tab.contentTab.innerHTML = ''; |
|
|
|
|
|
|
|
|
|
|
|
if(type === 'inputMessagesFilterEmpty') { |
|
|
|
if(tab.type === 'chats') { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(!this.historyStorage || !this.historyStorage[type]) { |
|
|
|
if(!this.historyStorage[tab.inputFilter]) { |
|
|
|
const parent = this.tabs[type].parentElement; |
|
|
|
const parent = tab.contentTab.parentElement; |
|
|
|
//if(!testScroll) {
|
|
|
|
//if(!testScroll) {
|
|
|
|
if(!parent.querySelector('.preloader')) { |
|
|
|
if(!parent.querySelector('.preloader')) { |
|
|
|
putPreloader(parent, true); |
|
|
|
putPreloader(parent, true); |
|
|
@ -1061,14 +1085,6 @@ export default class AppSearchSuper { |
|
|
|
} */ |
|
|
|
} */ |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// * will change .cleaned in cleanup() and new instance will be created
|
|
|
|
|
|
|
|
public getMiddleware() { |
|
|
|
|
|
|
|
const cleanupObj = this.cleanupObj; |
|
|
|
|
|
|
|
return () => { |
|
|
|
|
|
|
|
return !cleanupObj.cleaned; |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private copySearchContext(newInputFilter: MyInputMessagesFilter) { |
|
|
|
private copySearchContext(newInputFilter: MyInputMessagesFilter) { |
|
|
|
const context = copy(this.searchContext); |
|
|
|
const context = copy(this.searchContext); |
|
|
|
context.inputFilter = newInputFilter; |
|
|
|
context.inputFilter = newInputFilter; |
|
|
@ -1088,7 +1104,7 @@ export default class AppSearchSuper { |
|
|
|
this.searchContext = { |
|
|
|
this.searchContext = { |
|
|
|
peerId: peerId || 0, |
|
|
|
peerId: peerId || 0, |
|
|
|
query: query || '', |
|
|
|
query: query || '', |
|
|
|
inputFilter: this.type, |
|
|
|
inputFilter: this.mediaTab.inputFilter, |
|
|
|
threadId, |
|
|
|
threadId, |
|
|
|
folderId, |
|
|
|
folderId, |
|
|
|
minDate, |
|
|
|
minDate, |
|
|
|