Swipe animation for profile avatars
Search refactor Fix dialogs slicing
This commit is contained in:
parent
cd37d44db1
commit
3119e7788a
@ -194,39 +194,43 @@ class AppMediaViewerBase<ContentAdditionType extends string, ButtonsAdditionType
|
|||||||
this.wholeDiv.addEventListener('click', this.onClick);
|
this.wholeDiv.addEventListener('click', this.onClick);
|
||||||
|
|
||||||
if(isTouchSupported) {
|
if(isTouchSupported) {
|
||||||
const swipeHandler = new SwipeHandler(this.wholeDiv, (xDiff, yDiff) => {
|
const swipeHandler = new SwipeHandler({
|
||||||
if(VideoPlayer.isFullScreen()) {
|
element: this.wholeDiv,
|
||||||
return;
|
onSwipe: (xDiff, yDiff) => {
|
||||||
}
|
if(VideoPlayer.isFullScreen()) {
|
||||||
//console.log(xDiff, yDiff);
|
return;
|
||||||
|
}
|
||||||
|
//console.log(xDiff, yDiff);
|
||||||
|
|
||||||
const percents = Math.abs(xDiff) / appPhotosManager.windowW;
|
const percents = Math.abs(xDiff) / appPhotosManager.windowW;
|
||||||
if(percents > .2 || xDiff > 125) {
|
if(percents > .2 || xDiff > 125) {
|
||||||
//console.log('will swipe', xDiff);
|
//console.log('will swipe', xDiff);
|
||||||
|
|
||||||
if(xDiff < 0) {
|
if(xDiff < 0) {
|
||||||
this.buttons.prev.click();
|
this.buttons.prev.click();
|
||||||
} else {
|
} else {
|
||||||
this.buttons.next.click();
|
this.buttons.next.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const percentsY = Math.abs(yDiff) / appPhotosManager.windowH;
|
||||||
|
if(percentsY > .2 || yDiff > 125) {
|
||||||
|
this.buttons.close.click();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
verifyTouchTarget: (evt) => {
|
||||||
|
// * Fix for seek input
|
||||||
|
if((evt.target as HTMLElement).tagName === 'INPUT' || findUpClassName(evt.target, 'media-viewer-caption')) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const percentsY = Math.abs(yDiff) / appPhotosManager.windowH;
|
|
||||||
if(percentsY > .2 || yDiff > 125) {
|
|
||||||
this.buttons.close.click();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}, (evt) => {
|
|
||||||
// * Fix for seek input
|
|
||||||
if((evt.target as HTMLElement).tagName === 'INPUT' || findUpClassName(evt.target, 'media-viewer-caption')) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -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);
|
||||||
@ -169,24 +180,24 @@ export default class AppSearchSuper {
|
|||||||
if(this.prevTabId !== -1) {
|
if(this.prevTabId !== -1) {
|
||||||
this.onTransitionStart();
|
this.onTransitionStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.mediaTab.scroll = {scrollTop: this.scrollable.scrollTop, scrollHeight: this.scrollable.scrollHeight};
|
||||||
|
|
||||||
this.goingHard[this.type] = {scrollTop: this.scrollable.scrollTop, scrollHeight: this.scrollable.scrollHeight};
|
const newMediaTab = this.mediaTabs[id];
|
||||||
|
|
||||||
const newType = this.types[id].inputFilter;
|
|
||||||
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];
|
||||||
@ -807,6 +817,135 @@ export default class AppSearchSuper {
|
|||||||
]);
|
]);
|
||||||
} else return Promise.resolve();
|
} else return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private loadType(mediaTab: SearchSuperMediaTab, justLoad: boolean, loadCount: number, middleware: () => boolean) {
|
||||||
|
const type = mediaTab.inputFilter;
|
||||||
|
|
||||||
|
if(this.loadPromises[type]) {
|
||||||
|
return this.loadPromises[type];
|
||||||
|
}
|
||||||
|
|
||||||
|
const history = this.historyStorage[type] ?? (this.historyStorage[type] = []);
|
||||||
|
|
||||||
|
if(type === 'inputMessagesFilterEmpty' && !history.length) {
|
||||||
|
if(!this.loadedChats) {
|
||||||
|
this.loadChats();
|
||||||
|
this.loadedChats = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.searchContext.query.trim() && !this.searchContext.peerId && !this.searchContext.minDate) {
|
||||||
|
this.loaded[type] = true;
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const logStr = 'load [' + type + ']: ';
|
||||||
|
|
||||||
|
// render from cache
|
||||||
|
if(history.length && this.usedFromHistory[type] < history.length && !justLoad) {
|
||||||
|
let messages: any[] = [];
|
||||||
|
let used = Math.max(0, this.usedFromHistory[type]);
|
||||||
|
let slicedLength = 0;
|
||||||
|
|
||||||
|
do {
|
||||||
|
let ids = history.slice(used, used + loadCount);
|
||||||
|
//this.log(logStr + 'will render from cache', used, history, ids, loadCount);
|
||||||
|
used += ids.length;
|
||||||
|
slicedLength += ids.length;
|
||||||
|
|
||||||
|
messages.push(...this.filterMessagesByType(ids.map(m => appMessagesManager.getMessageByPeer(m.peerId, m.mid)), type));
|
||||||
|
} while(slicedLength < loadCount && used < history.length);
|
||||||
|
|
||||||
|
// если перебор
|
||||||
|
/* if(slicedLength > loadCount) {
|
||||||
|
let diff = messages.length - loadCount;
|
||||||
|
messages = messages.slice(0, messages.length - diff);
|
||||||
|
used -= diff;
|
||||||
|
} */
|
||||||
|
|
||||||
|
this.usedFromHistory[type] = used;
|
||||||
|
//if(messages.length) {
|
||||||
|
return this.performSearchResult(messages, type).finally(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.scrollable.checkForTriggers();
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
//}
|
||||||
|
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
let maxId = history.length ? history[history.length - 1].mid : 0;
|
||||||
|
|
||||||
|
//this.log(logStr + 'search house of glass pre', type, maxId);
|
||||||
|
|
||||||
|
//let loadCount = history.length ? 50 : 15;
|
||||||
|
return this.loadPromises[type] = appMessagesManager.getSearch({
|
||||||
|
peerId: this.searchContext.peerId,
|
||||||
|
query: this.searchContext.query,
|
||||||
|
inputFilter: {_: type},
|
||||||
|
maxId,
|
||||||
|
limit: loadCount,
|
||||||
|
nextRate: this.nextRates[type] ?? (this.nextRates[type] = 0),
|
||||||
|
threadId: this.searchContext.threadId,
|
||||||
|
folderId: this.searchContext.folderId,
|
||||||
|
minDate: this.searchContext.minDate,
|
||||||
|
maxDate: this.searchContext.maxDate
|
||||||
|
}).then(value => {
|
||||||
|
history.push(...value.history.map(m => ({mid: m.mid, peerId: m.peerId})));
|
||||||
|
|
||||||
|
this.log(logStr + 'search house of glass', type, value);
|
||||||
|
|
||||||
|
if(!middleware()) {
|
||||||
|
//this.log.warn('peer changed');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ! Фикс случая, когда не загружаются документы при открытой панели разработчиков (происходит из-за того, что не совпадают критерии отбора документов в getSearch)
|
||||||
|
if(value.history.length < loadCount) {
|
||||||
|
//if((value.count || history.length === value.count) && history.length >= value.count) {
|
||||||
|
//this.log(logStr + 'loaded all media', value, loadCount);
|
||||||
|
this.loaded[type] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.nextRates[type] = value.next_rate;
|
||||||
|
|
||||||
|
if(justLoad) {
|
||||||
|
return Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.usedFromHistory[type] = history.length;
|
||||||
|
|
||||||
|
if(!this.loaded[type]) {
|
||||||
|
(this.loadPromises[type] || Promise.resolve()).then(() => {
|
||||||
|
setTimeout(() => {
|
||||||
|
if(!middleware()) return;
|
||||||
|
//this.log('will preload more');
|
||||||
|
if(this.mediaTab === mediaTab) {
|
||||||
|
const promise = this.load(true, true);
|
||||||
|
if(promise) {
|
||||||
|
promise.then(() => {
|
||||||
|
if(!middleware()) return;
|
||||||
|
//this.log('preloaded more');
|
||||||
|
setTimeout(() => {
|
||||||
|
this.scrollable.checkForTriggers();
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, 0);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//if(value.history.length) {
|
||||||
|
return this.performSearchResult(this.filterMessagesByType(value.history, type), type);
|
||||||
|
//}
|
||||||
|
}).catch(err => {
|
||||||
|
this.log.error('load error:', err);
|
||||||
|
}).finally(() => {
|
||||||
|
this.loadPromises[type] = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public load(single = false, justLoad = false) {
|
public load(single = false, justLoad = false) {
|
||||||
// if(testScroll/* || 1 === 1 */) {
|
// if(testScroll/* || 1 === 1 */) {
|
||||||
@ -818,141 +957,21 @@ export default class AppSearchSuper {
|
|||||||
const peerId = this.searchContext.peerId;
|
const peerId = this.searchContext.peerId;
|
||||||
this.log('load', single, peerId, this.loadPromises);
|
this.log('load', single, peerId, this.loadPromises);
|
||||||
|
|
||||||
let typesToLoad = single ? [this.type] : this.types.filter(t => t.inputFilter !== this.type).map(t => t.inputFilter);
|
let toLoad = single ? [this.mediaTab] : this.mediaTabs.filter(t => t !== this.mediaTab);
|
||||||
typesToLoad = typesToLoad.filter(type => !this.loaded[type]
|
toLoad = toLoad.filter(mediaTab => {
|
||||||
|| (this.historyStorage[type] && this.usedFromHistory[type] < this.historyStorage[type].length));
|
const inputFilter = mediaTab.inputFilter;
|
||||||
|
return !this.loaded[inputFilter] || (this.historyStorage[inputFilter] && this.usedFromHistory[inputFilter] < this.historyStorage[inputFilter].length);
|
||||||
|
});
|
||||||
|
|
||||||
if(!typesToLoad.length) return;
|
if(!toLoad.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const loadCount = justLoad ? 50 : Math.round((appPhotosManager.windowH / 130 | 0) * 3 * 1.25); // that's good for all types
|
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 historyStorage = this.historyStorage ?? (this.historyStorage = {});
|
|
||||||
|
|
||||||
const middleware = this.getMiddleware();
|
const promises: Promise<any>[] = toLoad.map(mediaTab => {
|
||||||
|
return this.loadType(mediaTab, justLoad, loadCount, middleware)
|
||||||
const promises: Promise<any>[] = typesToLoad.map(type => {
|
|
||||||
if(this.loadPromises[type]) return this.loadPromises[type];
|
|
||||||
|
|
||||||
const history = historyStorage[type] ?? (historyStorage[type] = []);
|
|
||||||
|
|
||||||
if(type === 'inputMessagesFilterEmpty' && !history.length) {
|
|
||||||
if(!this.loadedChats) {
|
|
||||||
this.loadChats();
|
|
||||||
this.loadedChats = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!this.searchContext.query.trim() && !this.searchContext.peerId && !this.searchContext.minDate) {
|
|
||||||
this.loaded[type] = true;
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const logStr = 'load [' + type + ']: ';
|
|
||||||
|
|
||||||
// render from cache
|
|
||||||
if(history.length && this.usedFromHistory[type] < history.length && !justLoad) {
|
|
||||||
let messages: any[] = [];
|
|
||||||
let used = Math.max(0, this.usedFromHistory[type]);
|
|
||||||
let slicedLength = 0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
let ids = history.slice(used, used + loadCount);
|
|
||||||
//this.log(logStr + 'will render from cache', used, history, ids, loadCount);
|
|
||||||
used += ids.length;
|
|
||||||
slicedLength += ids.length;
|
|
||||||
|
|
||||||
messages.push(...this.filterMessagesByType(ids.map(m => appMessagesManager.getMessageByPeer(m.peerId, m.mid)), type));
|
|
||||||
} while(slicedLength < loadCount && used < history.length);
|
|
||||||
|
|
||||||
// если перебор
|
|
||||||
/* if(slicedLength > loadCount) {
|
|
||||||
let diff = messages.length - loadCount;
|
|
||||||
messages = messages.slice(0, messages.length - diff);
|
|
||||||
used -= diff;
|
|
||||||
} */
|
|
||||||
|
|
||||||
this.usedFromHistory[type] = used;
|
|
||||||
//if(messages.length) {
|
|
||||||
return this.performSearchResult(messages, type).finally(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.scrollable.checkForTriggers();
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
//}
|
|
||||||
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
let maxId = history.length ? history[history.length - 1].mid : 0;
|
|
||||||
|
|
||||||
//this.log(logStr + 'search house of glass pre', type, maxId);
|
|
||||||
|
|
||||||
//let loadCount = history.length ? 50 : 15;
|
|
||||||
return this.loadPromises[type] = appMessagesManager.getSearch({
|
|
||||||
peerId,
|
|
||||||
query: this.searchContext.query,
|
|
||||||
inputFilter: {_: type},
|
|
||||||
maxId,
|
|
||||||
limit: loadCount,
|
|
||||||
nextRate: this.nextRates[type] ?? (this.nextRates[type] = 0),
|
|
||||||
threadId: this.searchContext.threadId,
|
|
||||||
folderId: this.searchContext.folderId,
|
|
||||||
minDate: this.searchContext.minDate,
|
|
||||||
maxDate: this.searchContext.maxDate
|
|
||||||
}).then(value => {
|
|
||||||
history.push(...value.history.map(m => ({mid: m.mid, peerId: m.peerId})));
|
|
||||||
|
|
||||||
this.log(logStr + 'search house of glass', type, value);
|
|
||||||
|
|
||||||
if(!middleware()) {
|
|
||||||
//this.log.warn('peer changed');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ! Фикс случая, когда не загружаются документы при открытой панели разработчиков (происходит из-за того, что не совпадают критерии отбора документов в getSearch)
|
|
||||||
if(value.history.length < loadCount) {
|
|
||||||
//if((value.count || history.length === value.count) && history.length >= value.count) {
|
|
||||||
//this.log(logStr + 'loaded all media', value, loadCount);
|
|
||||||
this.loaded[type] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.nextRates[type] = value.next_rate;
|
|
||||||
|
|
||||||
if(justLoad) {
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.usedFromHistory[type] = history.length;
|
|
||||||
|
|
||||||
if(!this.loaded[type]) {
|
|
||||||
(this.loadPromises[type] || Promise.resolve()).then(() => {
|
|
||||||
setTimeout(() => {
|
|
||||||
if(!middleware()) return;
|
|
||||||
//this.log('will preload more');
|
|
||||||
if(this.type === type) {
|
|
||||||
const promise = this.load(true, true);
|
|
||||||
if(promise) {
|
|
||||||
promise.then(() => {
|
|
||||||
if(!middleware()) return;
|
|
||||||
//this.log('preloaded more');
|
|
||||||
setTimeout(() => {
|
|
||||||
this.scrollable.checkForTriggers();
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
//if(value.history.length) {
|
|
||||||
return this.performSearchResult(this.filterMessagesByType(value.history, type), type);
|
|
||||||
//}
|
|
||||||
}).catch(err => {
|
|
||||||
this.log.error('load error:', err);
|
|
||||||
}).finally(() => {
|
|
||||||
this.loadPromises[type] = null;
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
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);
|
||||||
@ -1044,7 +1068,7 @@ export default class AppSearchSuper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
this.monthContainers = {};
|
this.monthContainers = {};
|
||||||
this.searchGroupMedia.clear();
|
this.searchGroupMedia.clear();
|
||||||
this.scrollable.scrollTop = 0;
|
this.scrollable.scrollTop = 0;
|
||||||
@ -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,
|
||||||
|
@ -829,7 +829,7 @@ export default class ChatBubbles {
|
|||||||
//appSidebarRight.forwardTab.open([mid]);
|
//appSidebarRight.forwardTab.open([mid]);
|
||||||
return;
|
return;
|
||||||
} else if(target.classList.contains('peer-title') || target.classList.contains('name')) {
|
} else if(target.classList.contains('peer-title') || target.classList.contains('name')) {
|
||||||
target = findUpClassName(target, 'name');
|
target = findUpClassName(target, 'name') || target;
|
||||||
const peerId = +target.dataset.peerId;
|
const peerId = +target.dataset.peerId;
|
||||||
const savedFrom = target.dataset.savedFrom;
|
const savedFrom = target.dataset.savedFrom;
|
||||||
if(savedFrom) {
|
if(savedFrom) {
|
||||||
|
@ -193,31 +193,37 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
recent: new SearchGroup('Recent', 'contacts', true, 'search-group-recent', true, true, close)
|
recent: new SearchGroup('Recent', 'contacts', true, 'search-group-recent', true, true, close)
|
||||||
};
|
};
|
||||||
|
|
||||||
const searchSuper = this.searchSuper = new AppSearchSuper([{
|
const searchSuper = this.searchSuper = new AppSearchSuper({
|
||||||
inputFilter: 'inputMessagesFilterEmpty',
|
mediaTabs: [{
|
||||||
name: 'FilterChats',
|
inputFilter: 'inputMessagesFilterEmpty',
|
||||||
type: 'chats'
|
name: 'FilterChats',
|
||||||
}, {
|
type: 'chats'
|
||||||
inputFilter: 'inputMessagesFilterPhotoVideo',
|
}, {
|
||||||
name: 'SharedMediaTab2',
|
inputFilter: 'inputMessagesFilterPhotoVideo',
|
||||||
type: 'media'
|
name: 'SharedMediaTab2',
|
||||||
}, {
|
type: 'media'
|
||||||
inputFilter: 'inputMessagesFilterUrl',
|
}, {
|
||||||
name: 'SharedLinksTab2',
|
inputFilter: 'inputMessagesFilterUrl',
|
||||||
type: 'links'
|
name: 'SharedLinksTab2',
|
||||||
}, {
|
type: 'links'
|
||||||
inputFilter: 'inputMessagesFilterDocument',
|
}, {
|
||||||
name: 'SharedFilesTab2',
|
inputFilter: 'inputMessagesFilterDocument',
|
||||||
type: 'files'
|
name: 'SharedFilesTab2',
|
||||||
}, {
|
type: 'files'
|
||||||
inputFilter: 'inputMessagesFilterMusic',
|
}, {
|
||||||
name: 'SharedMusicTab2',
|
inputFilter: 'inputMessagesFilterMusic',
|
||||||
type: 'music'
|
name: 'SharedMusicTab2',
|
||||||
}, {
|
type: 'music'
|
||||||
inputFilter: 'inputMessagesFilterVoice',
|
}, {
|
||||||
name: 'SharedVoiceTab2',
|
inputFilter: 'inputMessagesFilterVoice',
|
||||||
type: 'voice'
|
name: 'SharedVoiceTab2',
|
||||||
}], scrollable, this.searchGroups, true);
|
type: 'voice'
|
||||||
|
}],
|
||||||
|
scrollable,
|
||||||
|
searchGroups: this.searchGroups,
|
||||||
|
asChatList: true,
|
||||||
|
hideEmptyTabs: false
|
||||||
|
});
|
||||||
|
|
||||||
searchContainer.prepend(searchSuper.nav.parentElement.parentElement);
|
searchContainer.prepend(searchSuper.nav.parentElement.parentElement);
|
||||||
scrollable.container.append(searchSuper.container);
|
scrollable.container.append(searchSuper.container);
|
||||||
@ -347,7 +353,7 @@ export class AppSidebarLeft extends SidebarSlider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!selectedPeerId && value.trim()) {
|
if(!selectedPeerId && value.trim()) {
|
||||||
const middleware = searchSuper.getMiddleware();
|
const middleware = searchSuper.middleware.get();
|
||||||
Promise.all([
|
Promise.all([
|
||||||
appMessagesManager.getConversationsAll(value).then(dialogs => dialogs.map(d => d.peerId)),
|
appMessagesManager.getConversationsAll(value).then(dialogs => dialogs.map(d => d.peerId)),
|
||||||
appUsersManager.getContacts(value, true)
|
appUsersManager.getContacts(value, true)
|
||||||
|
@ -10,7 +10,7 @@ import AppSearchSuper, { SearchSuperType } from "../../appSearchSuper.";
|
|||||||
import AvatarElement from "../../avatar";
|
import AvatarElement from "../../avatar";
|
||||||
import SidebarSlider, { SliderSuperTab } from "../../slider";
|
import SidebarSlider, { SliderSuperTab } from "../../slider";
|
||||||
import CheckboxField from "../../checkboxField";
|
import CheckboxField from "../../checkboxField";
|
||||||
import { attachClickEvent, replaceContent } from "../../../helpers/dom";
|
import { attachClickEvent, replaceContent, whichChild } from "../../../helpers/dom";
|
||||||
import appSidebarRight from "..";
|
import appSidebarRight from "..";
|
||||||
import { TransitionSlider } from "../../transition";
|
import { TransitionSlider } from "../../transition";
|
||||||
import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager";
|
import appNotificationsManager from "../../../lib/appManagers/appNotificationsManager";
|
||||||
@ -32,6 +32,7 @@ import { safeAssign } from "../../../helpers/object";
|
|||||||
import { forEachReverse } from "../../../helpers/array";
|
import { forEachReverse } from "../../../helpers/array";
|
||||||
import appPhotosManager from "../../../lib/appManagers/appPhotosManager";
|
import appPhotosManager from "../../../lib/appManagers/appPhotosManager";
|
||||||
import renderImageFromUrl from "../../../helpers/dom/renderImageFromUrl";
|
import renderImageFromUrl from "../../../helpers/dom/renderImageFromUrl";
|
||||||
|
import SwipeHandler from "../../swipeHandler";
|
||||||
|
|
||||||
let setText = (text: string, row: Row) => {
|
let setText = (text: string, row: Row) => {
|
||||||
fastRaf(() => {
|
fastRaf(() => {
|
||||||
@ -175,7 +176,13 @@ class PeerProfileAvatars {
|
|||||||
|
|
||||||
this.container.append(this.avatars, this.info, this.tabs);
|
this.container.append(this.avatars, this.info, this.tabs);
|
||||||
|
|
||||||
|
let cancel = false;
|
||||||
attachClickEvent(this.container, (_e) => {
|
attachClickEvent(this.container, (_e) => {
|
||||||
|
if(cancel) {
|
||||||
|
cancel = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const rect = this.container.getBoundingClientRect();
|
const rect = this.container.getBoundingClientRect();
|
||||||
|
|
||||||
const e = (_e as TouchEvent).touches ? (_e as TouchEvent).touches[0] : _e as MouseEvent;
|
const e = (_e as TouchEvent).touches ? (_e as TouchEvent).touches[0] : _e as MouseEvent;
|
||||||
@ -184,7 +191,57 @@ class PeerProfileAvatars {
|
|||||||
const centerX = rect.right - (rect.width / 2);
|
const centerX = rect.right - (rect.width / 2);
|
||||||
const toRight = x > centerX;
|
const toRight = x > centerX;
|
||||||
|
|
||||||
this.listLoader.go(toRight ? 1 : -1);
|
// this.avatars.classList.remove('no-transition');
|
||||||
|
// fastRaf(() => {
|
||||||
|
this.listLoader.go(toRight ? 1 : -1);
|
||||||
|
// });
|
||||||
|
});
|
||||||
|
|
||||||
|
let width = 0, x = 0, lastDiffX = 0, lastIndex = 0, minX = 0;
|
||||||
|
const swipeHandler = new SwipeHandler({
|
||||||
|
element: this.avatars,
|
||||||
|
onSwipe: (xDiff, yDiff) => {
|
||||||
|
lastDiffX = xDiff;
|
||||||
|
let lastX = x + xDiff * -2;
|
||||||
|
if(lastX > 0) lastX = 0;
|
||||||
|
else if(lastX < minX) lastX = minX;
|
||||||
|
|
||||||
|
this.avatars.style.transform = `translate3d(${lastX}px, 0, -1px) scale(2)`;
|
||||||
|
//console.log(xDiff, yDiff);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
verifyTouchTarget: (e) => {
|
||||||
|
if(this.tabs.classList.contains('hide')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
onFirstSwipe: () => {
|
||||||
|
const rect = this.avatars.getBoundingClientRect();
|
||||||
|
width = rect.width;
|
||||||
|
minX = -width * (this.tabs.childElementCount - 1);
|
||||||
|
|
||||||
|
/* lastIndex = whichChild(this.tabs.querySelector('.active'));
|
||||||
|
x = -width * lastIndex; */
|
||||||
|
x = rect.left - this.container.getBoundingClientRect().left;
|
||||||
|
|
||||||
|
this.avatars.style.transform = `translate3d(${x}px, 0, -1px) scale(2)`;
|
||||||
|
|
||||||
|
this.avatars.classList.add('no-transition');
|
||||||
|
void this.avatars.offsetLeft; // reflow
|
||||||
|
},
|
||||||
|
onReset: () => {
|
||||||
|
const addIndex = Math.ceil(Math.abs(lastDiffX) / (width / 2)) * (lastDiffX >= 0 ? 1 : -1);
|
||||||
|
cancel = true;
|
||||||
|
|
||||||
|
//console.log(addIndex);
|
||||||
|
|
||||||
|
this.avatars.classList.remove('no-transition');
|
||||||
|
fastRaf(() => {
|
||||||
|
this.listLoader.go(addIndex);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,7 +268,7 @@ class PeerProfileAvatars {
|
|||||||
onJump: (item, older) => {
|
onJump: (item, older) => {
|
||||||
const id = this.listLoader.index;
|
const id = this.listLoader.index;
|
||||||
//const nextId = Math.max(0, id);
|
//const nextId = Math.max(0, id);
|
||||||
this.avatars.style.transform = `translateX(-${100 * id}%)`;
|
this.avatars.style.transform = `translate3d(-${200 * id}%, 0, -1px) scale(2)`;
|
||||||
|
|
||||||
const activeTab = this.tabs.querySelector('.active');
|
const activeTab = this.tabs.querySelector('.active');
|
||||||
if(activeTab) activeTab.classList.remove('active');
|
if(activeTab) activeTab.classList.remove('active');
|
||||||
@ -235,6 +292,8 @@ class PeerProfileAvatars {
|
|||||||
if(this.tabs.childElementCount === 1) {
|
if(this.tabs.childElementCount === 1) {
|
||||||
tab.classList.add('active');
|
tab.classList.add('active');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.tabs.classList.toggle('hide', this.tabs.childElementCount <= 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public processItem = (photoId: string) => {
|
public processItem = (photoId: string) => {
|
||||||
@ -242,16 +301,19 @@ class PeerProfileAvatars {
|
|||||||
avatar.classList.add(PeerProfileAvatars.BASE_CLASS + '-avatar');
|
avatar.classList.add(PeerProfileAvatars.BASE_CLASS + '-avatar');
|
||||||
|
|
||||||
const photo = appPhotosManager.getPhoto(photoId);
|
const photo = appPhotosManager.getPhoto(photoId);
|
||||||
|
const img = new Image();
|
||||||
|
img.classList.add(PeerProfileAvatars.BASE_CLASS + '-avatar-image');
|
||||||
|
img.draggable = false;
|
||||||
|
|
||||||
if(photo) {
|
if(photo) {
|
||||||
appPhotosManager.preloadPhoto(photo, appPhotosManager.choosePhotoSize(photo, 420, 420, false)).then(() => {
|
appPhotosManager.preloadPhoto(photo, appPhotosManager.choosePhotoSize(photo, 420, 420, false)).then(() => {
|
||||||
const img = new Image();
|
|
||||||
renderImageFromUrl(img, photo.url, () => {
|
renderImageFromUrl(img, photo.url, () => {
|
||||||
avatar.append(img);
|
avatar.append(img);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
const photo = appPeersManager.getPeerPhoto(this.peerId);
|
const photo = appPeersManager.getPeerPhoto(this.peerId);
|
||||||
appProfileManager.putAvatar(avatar, this.peerId, photo, 'photo_big');
|
appProfileManager.putAvatar(avatar, this.peerId, photo, 'photo_big', img);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.avatars.append(avatar);
|
this.avatars.append(avatar);
|
||||||
@ -636,19 +698,10 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
transition(+isSharedMedia);
|
transition(+isSharedMedia);
|
||||||
|
|
||||||
if(!isSharedMedia) {
|
if(!isSharedMedia) {
|
||||||
this.searchSuper.goingHard = {};
|
this.searchSuper.cleanScrollPositions();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
this.scrollable.container.addEventListener('scroll', () => {
|
|
||||||
if(this.profile.avatars) {
|
|
||||||
const scrollTop = this.scrollable.scrollTop;
|
|
||||||
const y = scrollTop / 2;
|
|
||||||
this.profile.avatars.avatars.style.transform = `translateY(${y}px)`;
|
|
||||||
//this.profile.avatars.tabs.style.transform = `translateY(${scrollTop}px)`;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const transition = TransitionSlider(transitionContainer, 'slide-fade', 400, null, false);
|
const transition = TransitionSlider(transitionContainer, 'slide-fade', 400, null, false);
|
||||||
|
|
||||||
transition(0);
|
transition(0);
|
||||||
@ -686,25 +739,30 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
|
|
||||||
//this.container.prepend(this.closeBtn.parentElement);
|
//this.container.prepend(this.closeBtn.parentElement);
|
||||||
|
|
||||||
this.searchSuper = new AppSearchSuper([{
|
this.searchSuper = new AppSearchSuper({
|
||||||
inputFilter: 'inputMessagesFilterPhotoVideo',
|
mediaTabs: [{
|
||||||
name: 'SharedMediaTab2',
|
inputFilter: 'inputMessagesFilterEmpty',
|
||||||
type: 'media'
|
name: 'PeerMedia.Members',
|
||||||
}, {
|
type: 'members'
|
||||||
inputFilter: 'inputMessagesFilterDocument',
|
}, {
|
||||||
name: 'SharedFilesTab2',
|
inputFilter: 'inputMessagesFilterPhotoVideo',
|
||||||
type: 'files'
|
name: 'SharedMediaTab2',
|
||||||
}, {
|
type: 'media'
|
||||||
inputFilter: 'inputMessagesFilterUrl',
|
}, {
|
||||||
name: 'SharedLinksTab2',
|
inputFilter: 'inputMessagesFilterDocument',
|
||||||
type: 'links'
|
name: 'SharedFilesTab2',
|
||||||
}, {
|
type: 'files'
|
||||||
inputFilter: 'inputMessagesFilterMusic',
|
}, {
|
||||||
name: 'SharedMusicTab2',
|
inputFilter: 'inputMessagesFilterUrl',
|
||||||
type: 'music'
|
name: 'SharedLinksTab2',
|
||||||
}], this.scrollable/* , undefined, undefined, false */);
|
type: 'links'
|
||||||
|
}, {
|
||||||
this.profile.element.append(this.searchSuper.container);
|
inputFilter: 'inputMessagesFilterMusic',
|
||||||
|
name: 'SharedMusicTab2',
|
||||||
|
type: 'music'
|
||||||
|
}],
|
||||||
|
scrollable: this.scrollable
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public renderNewMessages(peerId: number, mids: number[]) {
|
public renderNewMessages(peerId: number, mids: number[]) {
|
||||||
@ -713,7 +771,7 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
if(!this.historiesStorage[peerId]) return;
|
if(!this.historiesStorage[peerId]) return;
|
||||||
|
|
||||||
mids = mids.slice().reverse(); // ! because it will be ascend sorted array
|
mids = mids.slice().reverse(); // ! because it will be ascend sorted array
|
||||||
for(const type of this.searchSuper.types) {
|
for(const type of this.searchSuper.mediaTabs) {
|
||||||
const inputFilter = type.inputFilter;
|
const inputFilter = type.inputFilter;
|
||||||
const filtered = this.searchSuper.filterMessagesByType(mids.map(mid => appMessagesManager.getMessageByPeer(peerId, mid)), inputFilter);
|
const filtered = this.searchSuper.filterMessagesByType(mids.map(mid => appMessagesManager.getMessageByPeer(peerId, mid)), inputFilter);
|
||||||
if(filtered.length) {
|
if(filtered.length) {
|
||||||
@ -737,7 +795,7 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
if(!this.historiesStorage[peerId]) return;
|
if(!this.historiesStorage[peerId]) return;
|
||||||
|
|
||||||
for(const mid of mids) {
|
for(const mid of mids) {
|
||||||
for(const type of this.searchSuper.types) {
|
for(const type of this.searchSuper.mediaTabs) {
|
||||||
const inputFilter = type.inputFilter;
|
const inputFilter = type.inputFilter;
|
||||||
|
|
||||||
if(!this.historiesStorage[peerId][inputFilter]) continue;
|
if(!this.historiesStorage[peerId][inputFilter]) continue;
|
||||||
@ -773,6 +831,10 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
this.editBtn.style.display = 'none';
|
this.editBtn.style.display = 'none';
|
||||||
this.searchSuper.cleanupHTML();
|
this.searchSuper.cleanupHTML();
|
||||||
this.searchSuper.selectTab(0, false);
|
this.searchSuper.selectTab(0, false);
|
||||||
|
|
||||||
|
if(!this.searchSuper.container.parentElement) {
|
||||||
|
this.profile.element.append(this.searchSuper.container);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public setLoadMutex(promise: Promise<any>) {
|
public setLoadMutex(promise: Promise<any>) {
|
||||||
@ -800,6 +862,8 @@ export default class AppSharedMediaTab extends SliderSuperTab {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fillProfileElements() {
|
public fillProfileElements() {
|
||||||
|
this.cleanupHTML();
|
||||||
|
|
||||||
this.profile.fillProfileElements();
|
this.profile.fillProfileElements();
|
||||||
|
|
||||||
if(this.peerId > 0) {
|
if(this.peerId > 0) {
|
||||||
|
@ -112,6 +112,7 @@ export default class SidebarSlider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.removeTabFromHistory(tab);
|
this.removeTabFromHistory(tab);
|
||||||
|
appNavigationController.removeByType(this.navigationType, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,34 +1,108 @@
|
|||||||
export default class SwipeHandler {
|
import { cancelEvent } from "../helpers/dom";
|
||||||
private xDown: number;
|
import { safeAssign } from "../helpers/object";
|
||||||
private yDown: number;
|
import { isTouchSupported } from "../helpers/touchSupport";
|
||||||
|
|
||||||
constructor(element: HTMLElement, private onSwipe: (xDiff: number, yDiff: number) => boolean, private verifyTouchTarget?: (evt: TouchEvent) => boolean) {
|
const getEvent = (e: TouchEvent | MouseEvent) => {
|
||||||
element.addEventListener('touchstart', this.handleTouchStart, false);
|
return (e as TouchEvent).touches ? (e as TouchEvent).touches[0] : e as MouseEvent;
|
||||||
element.addEventListener('touchmove', this.handleTouchMove, false);
|
};
|
||||||
|
|
||||||
|
const attachGlobalListenerTo = window;
|
||||||
|
|
||||||
|
export default class SwipeHandler {
|
||||||
|
private element: HTMLElement;
|
||||||
|
private onSwipe: (xDiff: number, yDiff: number) => boolean;
|
||||||
|
private verifyTouchTarget: (evt: Touch | MouseEvent) => boolean;
|
||||||
|
private onFirstSwipe: () => void;
|
||||||
|
private onReset: () => void;
|
||||||
|
|
||||||
|
private hadMove = false;
|
||||||
|
private xDown: number = null;
|
||||||
|
private yDown: number = null;
|
||||||
|
|
||||||
|
constructor(options: {
|
||||||
|
element: SwipeHandler['element'],
|
||||||
|
onSwipe: SwipeHandler['onSwipe'],
|
||||||
|
verifyTouchTarget?: SwipeHandler['verifyTouchTarget'],
|
||||||
|
onFirstSwipe?: SwipeHandler['onFirstSwipe'],
|
||||||
|
onReset?: SwipeHandler['onReset'],
|
||||||
|
}) {
|
||||||
|
safeAssign(this, options);
|
||||||
|
|
||||||
|
if(!isTouchSupported) {
|
||||||
|
this.element.addEventListener('mousedown', this.handleStart, false);
|
||||||
|
attachGlobalListenerTo.addEventListener('mouseup', this.reset);
|
||||||
|
} else {
|
||||||
|
this.element.addEventListener('touchstart', this.handleStart, false);
|
||||||
|
attachGlobalListenerTo.addEventListener('touchend', this.reset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleTouchStart = (evt: TouchEvent) => {
|
reset = (e?: Event) => {
|
||||||
if(this.verifyTouchTarget && !this.verifyTouchTarget(evt)) {
|
/* if(e) {
|
||||||
this.xDown = this.yDown = null;
|
cancelEvent(e);
|
||||||
return;
|
} */
|
||||||
|
|
||||||
|
if(isTouchSupported) {
|
||||||
|
attachGlobalListenerTo.removeEventListener('touchmove', this.handleMove, {capture: true});
|
||||||
|
} else {
|
||||||
|
attachGlobalListenerTo.removeEventListener('mousemove', this.handleMove);
|
||||||
|
this.element.style.cursor = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const firstTouch = evt.touches[0];
|
if(this.onReset && this.hadMove) {
|
||||||
this.xDown = firstTouch.clientX;
|
this.onReset();
|
||||||
this.yDown = firstTouch.clientY;
|
}
|
||||||
|
|
||||||
|
this.xDown = this.yDown = null;
|
||||||
|
this.hadMove = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
handleTouchMove = (evt: TouchEvent) => {
|
handleStart = (_e: TouchEvent | MouseEvent) => {
|
||||||
if(this.xDown === null || this.yDown === null) {
|
const e = getEvent(_e);
|
||||||
return;
|
if(this.verifyTouchTarget && !this.verifyTouchTarget(e)) {
|
||||||
|
return this.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
const xUp = evt.touches[0].clientX;
|
this.xDown = e.clientX;
|
||||||
const yUp = evt.touches[0].clientY;
|
this.yDown = e.clientY;
|
||||||
|
|
||||||
|
if(isTouchSupported) {
|
||||||
|
attachGlobalListenerTo.addEventListener('touchmove', this.handleMove, {passive: false, capture: true});
|
||||||
|
} else {
|
||||||
|
attachGlobalListenerTo.addEventListener('mousemove', this.handleMove, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
handleMove = (_e: TouchEvent | MouseEvent) => {
|
||||||
|
if(this.xDown === null || this.yDown === null) {
|
||||||
|
return this.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
cancelEvent(_e);
|
||||||
|
|
||||||
|
const e = getEvent(_e);
|
||||||
|
const xUp = e.clientX;
|
||||||
|
const yUp = e.clientY;
|
||||||
|
|
||||||
const xDiff = this.xDown - xUp;
|
const xDiff = this.xDown - xUp;
|
||||||
const yDiff = this.yDown - yUp;
|
const yDiff = this.yDown - yUp;
|
||||||
|
|
||||||
|
if(!this.hadMove) {
|
||||||
|
if(!xDiff && !yDiff) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.hadMove = true;
|
||||||
|
|
||||||
|
if(!isTouchSupported) {
|
||||||
|
this.element.style.cursor = 'grabbing';
|
||||||
|
}
|
||||||
|
|
||||||
|
if(this.onFirstSwipe) {
|
||||||
|
this.onFirstSwipe();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// if(Math.abs(xDiff) > Math.abs(yDiff)) { /*most significant*/
|
// if(Math.abs(xDiff) > Math.abs(yDiff)) { /*most significant*/
|
||||||
// if(xDiff > 0) { /* left swipe */
|
// if(xDiff > 0) { /* left swipe */
|
||||||
|
|
||||||
@ -45,8 +119,7 @@ export default class SwipeHandler {
|
|||||||
|
|
||||||
/* reset values */
|
/* reset values */
|
||||||
if(this.onSwipe(xDiff, yDiff)) {
|
if(this.onSwipe(xDiff, yDiff)) {
|
||||||
this.xDown = null;
|
this.reset();
|
||||||
this.yDown = null;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,7 @@ const App = {
|
|||||||
id: 1025907,
|
id: 1025907,
|
||||||
hash: '452b0359b988148995f22ff0f4229750',
|
hash: '452b0359b988148995f22ff0f4229750',
|
||||||
version: '0.4.0',
|
version: '0.4.0',
|
||||||
langPackVersion: '0.0.9',
|
langPackVersion: '0.1.0',
|
||||||
langPack: 'macos',
|
langPack: 'macos',
|
||||||
langPackCode: 'en',
|
langPackCode: 'en',
|
||||||
domains: [] as string[],
|
domains: [] as string[],
|
||||||
|
16
src/helpers/middleware.ts
Normal file
16
src/helpers/middleware.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// * will change .cleaned and new instance will be created
|
||||||
|
export const getMiddleware = () => {
|
||||||
|
let cleanupObj = {cleaned: false};
|
||||||
|
return {
|
||||||
|
clean: () => {
|
||||||
|
cleanupObj.cleaned = true;
|
||||||
|
cleanupObj = {cleaned: false};
|
||||||
|
},
|
||||||
|
get: () => {
|
||||||
|
const _cleanupObj = cleanupObj;
|
||||||
|
return () => {
|
||||||
|
return !_cleanupObj.cleaned;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
@ -82,7 +82,7 @@
|
|||||||
<div class="sidebar-header__btn-container">
|
<div class="sidebar-header__btn-container">
|
||||||
<div class="animated-menu-icon"></div>
|
<div class="animated-menu-icon"></div>
|
||||||
<div class="btn-icon btn-menu-toggle rp sidebar-tools-button is-visible"></div>
|
<div class="btn-icon btn-menu-toggle rp sidebar-tools-button is-visible"></div>
|
||||||
<div class="btn-icon rp sidebar-back-button"></div>
|
<div class="btn-icon sidebar-back-button"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-content transition zoom-fade">
|
<div class="sidebar-content transition zoom-fade">
|
||||||
|
@ -529,6 +529,7 @@ const lang = {
|
|||||||
"PeerInfo.SharedMedia": "Shared Media",
|
"PeerInfo.SharedMedia": "Shared Media",
|
||||||
"PeerInfo.Subscribers": "Subscribers",
|
"PeerInfo.Subscribers": "Subscribers",
|
||||||
"PeerInfo.DeleteContact": "Delete Contact",
|
"PeerInfo.DeleteContact": "Delete Contact",
|
||||||
|
"PeerMedia.Members": "Members",
|
||||||
"PollResults.Title.Poll": "Poll Results",
|
"PollResults.Title.Poll": "Poll Results",
|
||||||
"PollResults.Title.Quiz": "Quiz Results",
|
"PollResults.Title.Quiz": "Quiz Results",
|
||||||
"PollResults.LoadMore": {
|
"PollResults.LoadMore": {
|
||||||
|
@ -6,7 +6,6 @@ import { ripple } from "../../components/ripple";
|
|||||||
//import Scrollable from "../../components/scrollable";
|
//import Scrollable from "../../components/scrollable";
|
||||||
import Scrollable, { ScrollableX, SliceSides } from "../../components/scrollable";
|
import Scrollable, { ScrollableX, SliceSides } from "../../components/scrollable";
|
||||||
import { formatDateAccordingToTodayNew } from "../../helpers/date";
|
import { formatDateAccordingToTodayNew } from "../../helpers/date";
|
||||||
import { escapeRegExp } from "../../helpers/string";
|
|
||||||
import { isSafari } from "../../helpers/userAgent";
|
import { isSafari } from "../../helpers/userAgent";
|
||||||
import { logger, LogLevels } from "../logger";
|
import { logger, LogLevels } from "../logger";
|
||||||
import { RichTextProcessor } from "../richtextprocessor";
|
import { RichTextProcessor } from "../richtextprocessor";
|
||||||
@ -830,11 +829,17 @@ export class AppDialogsManager {
|
|||||||
|
|
||||||
//const scrollTopWas = this.scroll.scrollTop;
|
//const scrollTopWas = this.scroll.scrollTop;
|
||||||
|
|
||||||
const rect = this.scroll.container.getBoundingClientRect();
|
const firstElementChild = this.chatList.firstElementChild;
|
||||||
const rectX = this.chatList.firstElementChild.getBoundingClientRect();
|
const rectContainer = this.scroll.container.getBoundingClientRect();
|
||||||
|
const rectTarget = firstElementChild.getBoundingClientRect();
|
||||||
const children = Array.from(this.scroll.splitUp.children) as HTMLElement[];
|
const children = Array.from(this.scroll.splitUp.children) as HTMLElement[];
|
||||||
const firstElement = findUpTag(document.elementFromPoint(Math.ceil(rectX.x), Math.ceil(rect.y + 1)), 'LI') as HTMLElement;
|
|
||||||
const lastElement = findUpTag(document.elementFromPoint(Math.ceil(rectX.x), Math.floor(rect.y + rect.height - 1)), 'LI') as HTMLElement;
|
const offsetTop = this.folders.container.offsetTop;
|
||||||
|
const firstY = rectContainer.y + offsetTop;
|
||||||
|
const lastY = rectContainer.y;
|
||||||
|
|
||||||
|
const firstElement = findUpTag(document.elementFromPoint(Math.ceil(rectTarget.x), Math.ceil(firstY + 1)), firstElementChild.tagName) as HTMLElement;
|
||||||
|
const lastElement = findUpTag(document.elementFromPoint(Math.ceil(rectTarget.x), Math.floor(lastY + rectContainer.height - 1)), firstElementChild.tagName) as HTMLElement;
|
||||||
|
|
||||||
//alert('got element:' + rect.y);
|
//alert('got element:' + rect.y);
|
||||||
|
|
||||||
@ -845,7 +850,7 @@ export class AppDialogsManager {
|
|||||||
//alert('got element:' + !!firstElement);
|
//alert('got element:' + !!firstElement);
|
||||||
|
|
||||||
const firstElementRect = firstElement.getBoundingClientRect();
|
const firstElementRect = firstElement.getBoundingClientRect();
|
||||||
const elementOverflow = firstElementRect.y - rect.y;
|
const elementOverflow = firstElementRect.y - firstY;
|
||||||
|
|
||||||
const sliced: HTMLElement[] = [];
|
const sliced: HTMLElement[] = [];
|
||||||
const firstIndex = children.indexOf(firstElement);
|
const firstIndex = children.indexOf(firstElement);
|
||||||
|
@ -105,13 +105,7 @@
|
|||||||
height: calc(100% - 44px);
|
height: calc(100% - 44px);
|
||||||
|
|
||||||
#folders-container {
|
#folders-container {
|
||||||
li:first-child {
|
margin-top: .5rem;
|
||||||
margin-top: .5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
> div {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,6 +199,10 @@
|
|||||||
|
|
||||||
#folders-container {
|
#folders-container {
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
|
|
||||||
|
> div {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-slider {
|
.sidebar-slider {
|
||||||
|
@ -3,9 +3,10 @@
|
|||||||
&-container {
|
&-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 26.25rem;
|
height: 26.25rem;
|
||||||
overflow: hidden;
|
//overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
/* &:before, &:after {
|
/* &:before, &:after {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@ -20,8 +21,18 @@
|
|||||||
height: inherit;
|
height: inherit;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: nowrap;
|
flex-wrap: nowrap;
|
||||||
transform: translateX(0);
|
transform: translateZ(-1px) scale(2);
|
||||||
//transition: transform .2s ease-in-out;
|
transform-origin: left top;
|
||||||
|
transition: transform .2s ease-in-out;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
content: " ";
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-avatar {
|
&-avatar {
|
||||||
@ -32,11 +43,12 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
background-color: #000;
|
background-color: #000;
|
||||||
|
|
||||||
/* img, video {
|
&-image {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
} */
|
pointer-events: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-info {
|
&-info {
|
||||||
@ -60,6 +72,10 @@
|
|||||||
.profile-subtitle {
|
.profile-subtitle {
|
||||||
opacity: .7;
|
opacity: .7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.online {
|
||||||
|
color: inherit !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&-tabs {
|
&-tabs {
|
||||||
@ -118,6 +134,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-left-section {
|
.sidebar-left-section {
|
||||||
|
position: relative;
|
||||||
|
background-color: var(--surface-color);
|
||||||
//padding-top: .5625rem;
|
//padding-top: .5625rem;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,11 @@
|
|||||||
max-height: calc((var(--vh, 1vh) * 100) - 100% - 56px);
|
max-height: calc((var(--vh, 1vh) * 100) - 100% - 56px);
|
||||||
}
|
}
|
||||||
} */
|
} */
|
||||||
|
.scrollable {
|
||||||
|
perspective: 1px;
|
||||||
|
perspective-origin: left top;
|
||||||
|
}
|
||||||
|
|
||||||
.search-super {
|
.search-super {
|
||||||
top: 100%;
|
top: 100%;
|
||||||
min-height: calc((var(--vh, 1vh) * 100) - 56px);
|
min-height: calc((var(--vh, 1vh) * 100) - 56px);
|
||||||
@ -124,6 +129,7 @@
|
|||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
background-color: var(--surface-color);
|
||||||
|
|
||||||
.search-group__show-more {
|
.search-group__show-more {
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
@ -344,16 +350,13 @@
|
|||||||
min-height: 58px;
|
min-height: 58px;
|
||||||
|
|
||||||
.preview {
|
.preview {
|
||||||
height: 48px;
|
height: 3rem;
|
||||||
width: 48px;
|
width: 3rem;
|
||||||
border-radius: 5px;
|
border-radius: .375rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0;
|
top: 0;
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-size: cover;
|
|
||||||
background-position: center center;
|
|
||||||
|
|
||||||
&.empty {
|
&.empty {
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -364,6 +367,12 @@
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
background-color: var(--primary-color);
|
background-color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.media-photo {
|
||||||
|
object-fit: cover;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.url {
|
.url {
|
||||||
|
@ -999,7 +999,7 @@ middle-ellipsis-element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.row {
|
.row {
|
||||||
min-height: 3rem;
|
min-height: 3.5rem;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: .6875rem 1rem;
|
padding: .6875rem 1rem;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user