Browse Source

Close reply keyboard by touch on mobiles

Fix reply keyboard max width on mobiles
master
Eduard Kuzmenko 3 years ago
parent
commit
5f003e82db
  1. 21
      src/components/chat/replyKeyboard.ts
  2. 24
      src/helpers/listenerSetter.ts
  3. 1
      src/scss/partials/_replyKeyboard.scss

21
src/components/chat/replyKeyboard.ts

@ -10,8 +10,11 @@ import { ReplyMarkup } from "../../layer";
import RichTextProcessor from "../../lib/richtextprocessor"; import RichTextProcessor from "../../lib/richtextprocessor";
import rootScope from "../../lib/rootScope"; import rootScope from "../../lib/rootScope";
import { safeAssign } from "../../helpers/object"; import { safeAssign } from "../../helpers/object";
import ListenerSetter from "../../helpers/listenerSetter"; import ListenerSetter, { Listener } from "../../helpers/listenerSetter";
import findUpClassName from "../../helpers/dom/findUpClassName"; import findUpClassName from "../../helpers/dom/findUpClassName";
import { isTouchSupported } from "../../helpers/touchSupport";
import findUpAsChild from "../../helpers/dom/findUpAsChild";
import { cancelEvent } from "../../helpers/dom/cancelEvent";
export default class ReplyKeyboard extends DropdownHover { export default class ReplyKeyboard extends DropdownHover {
private static BASE_CLASS = 'reply-keyboard'; private static BASE_CLASS = 'reply-keyboard';
@ -20,6 +23,7 @@ export default class ReplyKeyboard extends DropdownHover {
private appMessagesManager: AppMessagesManager; private appMessagesManager: AppMessagesManager;
private btnHover: HTMLElement; private btnHover: HTMLElement;
private peerId: number; private peerId: number;
private touchListener: Listener<HTMLElement>;
constructor(options: { constructor(options: {
listenerSetter: ListenerSetter, listenerSetter: ListenerSetter,
@ -49,6 +53,13 @@ export default class ReplyKeyboard extends DropdownHover {
this.listenerSetter.add(this, 'open', () => { this.listenerSetter.add(this, 'open', () => {
this.render(); this.render();
if(isTouchSupported) {
this.touchListener = this.listenerSetter.add(document.body, 'touchstart', this.onBodyTouchStart, {passive: false, capture: true});
this.listenerSetter.add(this, 'close', () => {
this.listenerSetter.remove(this.touchListener);
}, {once: true});
}
}); });
this.listenerSetter.add(this.element, 'click', (e) => { this.listenerSetter.add(this.element, 'click', (e) => {
@ -64,6 +75,14 @@ export default class ReplyKeyboard extends DropdownHover {
return super.init(); return super.init();
} }
private onBodyTouchStart = (e: TouchEvent) => {
const target = e.touches[0].target as HTMLElement;
if(!findUpAsChild(target, this.element) && target !== this.btnHover) {
cancelEvent(e);
this.toggle(false);
}
};
private getReplyMarkup(): ReplyMarkup { private getReplyMarkup(): ReplyMarkup {
return this.appMessagesManager.getHistoryStorage(this.peerId).reply_markup ?? { return this.appMessagesManager.getHistoryStorage(this.peerId).reply_markup ?? {
_: 'replyKeyboardHide' _: 'replyKeyboardHide'

24
src/helpers/listenerSetter.ts

@ -22,7 +22,10 @@ export type Listener<T extends ListenerElement> = {
element: ListenerElement, element: ListenerElement,
event: ListenerEvent<T>, event: ListenerEvent<T>,
callback: ListenerCallback, callback: ListenerCallback,
options?: ListenerOptions options?: ListenerOptions,
onceFired?: true, // will be set only when options.once is set
onceCallback?: () => void,
}; };
export type ListenerElement = Window | Document | HTMLElement | Element | RootScope | any; export type ListenerElement = Window | Document | HTMLElement | Element | RootScope | any;
@ -43,12 +46,31 @@ export default class ListenerSetter {
public addManual<T extends ListenerElement>(listener: Listener<T>) { public addManual<T extends ListenerElement>(listener: Listener<T>) {
// @ts-ignore // @ts-ignore
listener.element.addEventListener(listener.event, listener.callback, listener.options); listener.element.addEventListener(listener.event, listener.callback, listener.options);
if(listener.options?.once) { // remove listener when its called
listener.onceCallback = () => {
this.remove(listener);
listener.onceFired = true;
};
// @ts-ignore
listener.element.addEventListener(listener.event, listener.onceCallback, listener.options);
}
this.listeners.add(listener); this.listeners.add(listener);
} }
public remove<T extends ListenerElement>(listener: Listener<T>) { public remove<T extends ListenerElement>(listener: Listener<T>) {
if(!listener.onceFired) {
// @ts-ignore // @ts-ignore
listener.element.removeEventListener(listener.event, listener.callback, listener.options); listener.element.removeEventListener(listener.event, listener.callback, listener.options);
if(listener.onceCallback) {
// @ts-ignore
listener.element.removeEventListener(listener.event, listener.onceCallback, listener.options);
}
}
this.listeners.delete(listener); this.listeners.delete(listener);
} }

1
src/scss/partials/_replyKeyboard.scss

@ -4,6 +4,7 @@
right: 0; right: 0;
bottom: calc(100% + .625rem); bottom: calc(100% + .625rem);
width: 26.25rem !important; width: 26.25rem !important;
max-width: 100%;
//height: 26.25rem; //height: 26.25rem;
max-height: 26.25rem; max-height: 26.25rem;
box-shadow: 0px 5px 10px 5px rgba(16, 35, 47, .14); box-shadow: 0px 5px 10px 5px rgba(16, 35, 47, .14);

Loading…
Cancel
Save