Browse Source

Mobile search fixes

master
morethanwords 3 years ago
parent
commit
cbd00b4816
  1. 7
      src/components/appNavigationController.ts
  2. 7
      src/components/chat/chat.ts
  3. 87
      src/components/chat/search.ts
  4. 2
      src/scss/partials/_chatSearch.scss
  5. 10
      src/scss/partials/_chatTopbar.scss

7
src/components/appNavigationController.ts

@ -15,7 +15,8 @@ import isSwipingBackSafari from "../helpers/dom/isSwipingBackSafari"; @@ -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 { @@ -187,6 +188,10 @@ export class AppNavigationController {
}
public removeItem(item: NavigationItem) {
if(!item) {
return;
}
indexOfAndSplice(this.navigations, item);
}

7
src/components/chat/chat.ts

@ -55,6 +55,7 @@ export default class Chat extends EventListenerBase<{ @@ -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<{ @@ -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) {

87
src/components/chat/search.ts

@ -15,6 +15,10 @@ import { cancelEvent } from "../../helpers/dom/cancelEvent"; @@ -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,8 +40,10 @@ export default class ChatSearch { @@ -36,8 +40,10 @@ 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');
@ -45,19 +51,15 @@ export default class ChatSearch { @@ -45,19 +51,15 @@ export default class ChatSearch {
this.backBtn.classList.add('btn-icon', 'tgico-left', 'sidebar-close-button');
ripple(this.backBtn);
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});
const listenerSetter = this.listenerSetter = new ListenerSetter();
const attachClick = (element: HTMLElement, callback: (e: MouseEvent) => void) => {
attachClickEvent(element, callback, {listenerSetter});
};
attachClick(this.backBtn, () => {
this.destroy();
});
this.inputSearch = new InputSearch('Search');
@ -66,7 +68,7 @@ export default class ChatSearch { @@ -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 { @@ -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 { @@ -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 { @@ -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 { @@ -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);
}
}
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;
}
onDateClick = (e: MouseEvent) => {
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,28 +203,28 @@ export default class ChatSearch { @@ -172,28 +203,28 @@ 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);
};

2
src/scss/partials/_chatSearch.scss

@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
.chat-search {
position: absolute !important;
top: 0;
right: 0;
left: 0;
z-index: 2;
&-footer {

10
src/scss/partials/_chatTopbar.scss

@ -299,10 +299,18 @@ body.is-right-column-shown { @@ -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 {
margin-bottom: .25rem;
}
}
}
.chat:not(.type-chat) & {

Loading…
Cancel
Save