Mobile search fixes
This commit is contained in:
parent
8b04630124
commit
cbd00b4816
@ -15,7 +15,8 @@ import isSwipingBackSafari from "../helpers/dom/isSwipingBackSafari";
|
||||
|
||||
export type NavigationItem = {
|
||||
type: 'left' | 'right' | 'im' | 'chat' | 'popup' | 'media' | 'menu' |
|
||||
'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' | 'global-search' | 'voice',
|
||||
'esg' | 'multiselect' | 'input-helper' | 'autocomplete-helper' | 'markup' |
|
||||
'global-search' | 'voice' | 'mobile-search',
|
||||
onPop: (canAnimate: boolean) => boolean | void,
|
||||
onEscape?: () => boolean,
|
||||
noHistory?: boolean,
|
||||
@ -187,6 +188,10 @@ export class AppNavigationController {
|
||||
}
|
||||
|
||||
public removeItem(item: NavigationItem) {
|
||||
if(!item) {
|
||||
return;
|
||||
}
|
||||
|
||||
indexOfAndSplice(this.navigations, item);
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,7 @@ export default class Chat extends EventListenerBase<{
|
||||
public input: ChatInput;
|
||||
public selection: ChatSelection;
|
||||
public contextMenu: ChatContextMenu;
|
||||
public search: ChatSearch;
|
||||
|
||||
public wasAlreadyUsed = false;
|
||||
// public initPeerId = 0;
|
||||
@ -396,7 +397,11 @@ export default class Chat extends EventListenerBase<{
|
||||
if(!this.peerId) return;
|
||||
|
||||
if(mediaSizes.isMobile) {
|
||||
new ChatSearch(this.topbar, this, query);
|
||||
if(!this.search) {
|
||||
this.search = new ChatSearch(this.topbar, this, query);
|
||||
} else {
|
||||
this.search.setQuery(query);
|
||||
}
|
||||
} else {
|
||||
let tab = appSidebarRight.getTab(AppPrivateSearchTab);
|
||||
if(!tab) {
|
||||
|
@ -15,6 +15,10 @@ import { cancelEvent } from "../../helpers/dom/cancelEvent";
|
||||
import whichChild from "../../helpers/dom/whichChild";
|
||||
import replaceContent from "../../helpers/dom/replaceContent";
|
||||
import { i18n } from "../../lib/langPack";
|
||||
import ListenerSetter from "../../helpers/listenerSetter";
|
||||
import { attachClickEvent } from "../../helpers/dom/clickEvent";
|
||||
import appNavigationController, { NavigationItem } from "../appNavigationController";
|
||||
import { IS_MOBILE_SAFARI } from "../../environment/userAgent";
|
||||
|
||||
export default class ChatSearch {
|
||||
private element: HTMLElement;
|
||||
@ -36,28 +40,26 @@ export default class ChatSearch {
|
||||
private foundCount = 0;
|
||||
private selectedIndex = 0;
|
||||
private setPeerPromise: Promise<any>;
|
||||
private listenerSetter: ListenerSetter;
|
||||
private navigationItem: NavigationItem;
|
||||
|
||||
constructor(private topbar: ChatTopbar, private chat: Chat, private query?: string) {
|
||||
constructor(private topbar: ChatTopbar, private chat: Chat, query?: string) {
|
||||
this.element = document.createElement('div');
|
||||
this.element.classList.add('sidebar-header', 'chat-search', 'chatlist-container');
|
||||
|
||||
this.backBtn = document.createElement('button');
|
||||
this.backBtn.classList.add('btn-icon', 'tgico-left', 'sidebar-close-button');
|
||||
ripple(this.backBtn);
|
||||
|
||||
const listenerSetter = this.listenerSetter = new ListenerSetter();
|
||||
|
||||
const attachClick = (element: HTMLElement, callback: (e: MouseEvent) => void) => {
|
||||
attachClickEvent(element, callback, {listenerSetter});
|
||||
};
|
||||
|
||||
this.backBtn.addEventListener('click', () => {
|
||||
this.topbar.container.classList.remove('hide-pinned');
|
||||
this.element.remove();
|
||||
this.inputSearch.remove();
|
||||
this.results.remove();
|
||||
this.footer.remove();
|
||||
this.footer.removeEventListener('click', this.onFooterClick);
|
||||
this.dateBtn.removeEventListener('click', this.onDateClick);
|
||||
this.upBtn.removeEventListener('click', this.onUpClick);
|
||||
this.downBtn.removeEventListener('click', this.onDownClick);
|
||||
this.searchGroup.list.removeEventListener('click', this.onResultsClick);
|
||||
this.chat.bubbles.bubblesContainer.classList.remove('search-results-active');
|
||||
}, {once: true});
|
||||
attachClick(this.backBtn, () => {
|
||||
this.destroy();
|
||||
});
|
||||
|
||||
this.inputSearch = new InputSearch('Search');
|
||||
|
||||
@ -66,7 +68,7 @@ export default class ChatSearch {
|
||||
this.results.classList.add('chat-search-results', 'chatlist-container');
|
||||
|
||||
this.searchGroup = new SearchGroup(false, 'messages', undefined, '', false);
|
||||
this.searchGroup.list.addEventListener('click', this.onResultsClick);
|
||||
attachClick(this.searchGroup.list, this.onResultsClick);
|
||||
|
||||
this.appSearch = new AppSearch(this.results, this.inputSearch, {
|
||||
messages: this.searchGroup
|
||||
@ -74,7 +76,7 @@ export default class ChatSearch {
|
||||
this.foundCount = count;
|
||||
|
||||
if(!this.foundCount) {
|
||||
this.foundCountEl.replaceWith(this.inputSearch.value ? i18n('NoResult') : '');
|
||||
replaceContent(this.foundCountEl, this.inputSearch.value ? i18n('NoResult') : '');
|
||||
this.results.classList.remove('active');
|
||||
this.chat.bubbles.bubblesContainer.classList.remove('search-results-active');
|
||||
this.upBtn.setAttribute('disabled', 'true');
|
||||
@ -92,7 +94,7 @@ export default class ChatSearch {
|
||||
this.footer = document.createElement('div');
|
||||
this.footer.classList.add('chat-search-footer');
|
||||
|
||||
this.footer.addEventListener('click', this.onFooterClick);
|
||||
attachClick(this.footer, this.onFooterClick);
|
||||
ripple(this.footer);
|
||||
|
||||
this.foundCountEl = document.createElement('span');
|
||||
@ -112,9 +114,9 @@ export default class ChatSearch {
|
||||
this.upBtn.setAttribute('disabled', 'true');
|
||||
this.downBtn.setAttribute('disabled', 'true');
|
||||
|
||||
this.dateBtn.addEventListener('click', this.onDateClick);
|
||||
this.upBtn.addEventListener('click', this.onUpClick);
|
||||
this.downBtn.addEventListener('click', this.onDownClick);
|
||||
attachClick(this.dateBtn, this.onDateClick);
|
||||
attachClick(this.upBtn, this.onUpClick);
|
||||
attachClick(this.downBtn, this.onDownClick);
|
||||
this.controls.append(this.upBtn, this.downBtn);
|
||||
|
||||
this.footer.append(this.foundCountEl, this.dateBtn, this.controls);
|
||||
@ -129,15 +131,44 @@ export default class ChatSearch {
|
||||
|
||||
this.inputSearch.input.focus();
|
||||
|
||||
query && (this.inputSearch.inputField.value = query);
|
||||
if(query) {
|
||||
this.setQuery(query);
|
||||
}
|
||||
|
||||
if(!IS_MOBILE_SAFARI) {
|
||||
this.navigationItem = {
|
||||
type: 'mobile-search',
|
||||
onPop: () => {
|
||||
this.destroy();
|
||||
}
|
||||
};
|
||||
|
||||
appNavigationController.pushItem(this.navigationItem);
|
||||
}
|
||||
}
|
||||
|
||||
onDateClick = (e: MouseEvent) => {
|
||||
public destroy() {
|
||||
this.topbar.container.classList.remove('hide-pinned');
|
||||
this.element.remove();
|
||||
this.inputSearch.remove();
|
||||
this.results.remove();
|
||||
this.footer.remove();
|
||||
this.listenerSetter.removeAll();
|
||||
this.chat.bubbles.bubblesContainer.classList.remove('search-results-active');
|
||||
this.chat.search = undefined;
|
||||
appNavigationController.removeItem(this.navigationItem);
|
||||
}
|
||||
|
||||
public setQuery(query: string) {
|
||||
this.inputSearch.inputField.value = query;
|
||||
}
|
||||
|
||||
private onDateClick = (e: MouseEvent) => {
|
||||
cancelEvent(e);
|
||||
new PopupDatePicker(new Date(), this.chat.bubbles.onDatePick).show();
|
||||
};
|
||||
|
||||
selectResult = (elem: HTMLElement) => {
|
||||
private selectResult(elem: HTMLElement) {
|
||||
if(this.setPeerPromise) return this.setPeerPromise;
|
||||
|
||||
const peerId = elem.dataset.peerId.toPeerId();
|
||||
@ -172,29 +203,29 @@ export default class ChatSearch {
|
||||
}).finally(() => {
|
||||
this.setPeerPromise = null;
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
onResultsClick = (e: MouseEvent) => {
|
||||
private onResultsClick = (e: MouseEvent) => {
|
||||
const target = findUpTag(e.target, 'LI');
|
||||
if(target) {
|
||||
this.selectResult(target);
|
||||
}
|
||||
};
|
||||
|
||||
onFooterClick = (e: MouseEvent) => {
|
||||
private onFooterClick = (e: MouseEvent) => {
|
||||
if(this.foundCount) {
|
||||
this.chat.bubbles.bubblesContainer.classList.toggle('search-results-active');
|
||||
this.results.classList.toggle('active');
|
||||
}
|
||||
};
|
||||
|
||||
onUpClick = (e: MouseEvent) => {
|
||||
private onUpClick = (e: MouseEvent) => {
|
||||
cancelEvent(e);
|
||||
this.selectResult(this.searchGroup.list.children[this.selectedIndex + 1] as HTMLElement);
|
||||
};
|
||||
|
||||
onDownClick = (e: MouseEvent) => {
|
||||
private onDownClick = (e: MouseEvent) => {
|
||||
cancelEvent(e);
|
||||
this.selectResult(this.searchGroup.list.children[this.selectedIndex - 1] as HTMLElement);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@
|
||||
.chat-search {
|
||||
position: absolute !important;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
z-index: 2;
|
||||
|
||||
&-footer {
|
||||
|
@ -299,11 +299,19 @@ body.is-right-column-shown {
|
||||
}
|
||||
}
|
||||
|
||||
&.hide-pinned + .bubbles {
|
||||
.bubbles-inner {
|
||||
margin-bottom: .25rem;
|
||||
}
|
||||
}
|
||||
&.hide-pinned {
|
||||
--pinned-floating-height: 0px;
|
||||
|
||||
.pinned-container {
|
||||
display: none;
|
||||
}
|
||||
|
||||
& + .bubbles {
|
||||
.bubbles-inner {
|
||||
margin-bottom: .25rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.chat:not(.type-chat) & {
|
||||
.content {
|
||||
|
Loading…
Reference in New Issue
Block a user