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