From c36e5df589cd5f7046ba816afbc8b05580f3bc3e Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Sat, 12 Dec 2020 18:30:01 +0200 Subject: [PATCH] Fix touch events --- src/components/buttonMenu.ts | 2 +- src/components/buttonMenuToggle.ts | 1 + src/components/chat/bubbles.ts | 4 +-- src/components/chat/input.ts | 30 ++++++++++++++----- src/components/poll.ts | 12 ++++---- src/components/sidebarLeft/index.ts | 14 ++++----- src/components/sidebarLeft/tabs/editFolder.ts | 4 +-- src/components/sidebarLeft/tabs/settings.ts | 4 +-- src/components/wrappers.ts | 6 ++-- src/helpers/dom.ts | 1 + 10 files changed, 48 insertions(+), 30 deletions(-) diff --git a/src/components/buttonMenu.ts b/src/components/buttonMenu.ts index 521797e1..3e759d98 100644 --- a/src/components/buttonMenu.ts +++ b/src/components/buttonMenu.ts @@ -23,7 +23,7 @@ const ButtonMenuItem = (options: ButtonMenuItemOptions) => { ripple(el); // * cancel keyboard close - attachClickEvent(el, CLICK_EVENT_NAME == 'touchend' ? (e) => { + attachClickEvent(el, CLICK_EVENT_NAME !== 'click' ? (e) => { cancelEvent(e); onClick(e); closeBtnMenu(); diff --git a/src/components/buttonMenuToggle.ts b/src/components/buttonMenuToggle.ts index 40e36dca..8ca5fea9 100644 --- a/src/components/buttonMenuToggle.ts +++ b/src/components/buttonMenuToggle.ts @@ -14,6 +14,7 @@ const ButtonMenuToggle = (options: Partial<{noRipple: true, onlyMobile: true, li return button; }; +// TODO: refactor for attachClickEvent, because if move finger after touchstart, it will start anyway const ButtonMenuToggleHandler = (el: HTMLElement, onOpen?: () => void, options?: AttachClickOptions) => { const add = options?.listenerSetter ? options.listenerSetter.add.bind(options.listenerSetter, el) : el.addEventListener.bind(el); diff --git a/src/components/chat/bubbles.ts b/src/components/chat/bubbles.ts index 8b2059a8..4a938c55 100644 --- a/src/components/chat/bubbles.ts +++ b/src/components/chat/bubbles.ts @@ -7,7 +7,7 @@ import type { AppInlineBotsManager } from "../../lib/appManagers/AppInlineBotsMa import type { AppPhotosManager } from "../../lib/appManagers/appPhotosManager"; import type { AppDocsManager } from "../../lib/appManagers/appDocsManager"; import type { AppPeersManager } from "../../lib/appManagers/appPeersManager"; -import { findUpClassName, cancelEvent, findUpTag, CLICK_EVENT_NAME, whichChild, getElementByPoint } from "../../helpers/dom"; +import { findUpClassName, cancelEvent, findUpTag, whichChild, getElementByPoint, attachClickEvent } from "../../helpers/dom"; import { getObjectKeysAndSort } from "../../helpers/object"; import { isTouchSupported } from "../../helpers/touchSupport"; import { logger } from "../../lib/logger"; @@ -1480,7 +1480,7 @@ export default class ChatBubbles { containerDiv.append(rowDiv); }); - containerDiv.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(containerDiv, (e) => { cancelEvent(e); let target = e.target as HTMLElement; diff --git a/src/components/chat/input.ts b/src/components/chat/input.ts index db7c4695..d511ba4a 100644 --- a/src/components/chat/input.ts +++ b/src/components/chat/input.ts @@ -11,7 +11,7 @@ import apiManager from "../../lib/mtproto/mtprotoworker"; //import Recorder from '../opus-recorder/dist/recorder.min'; import opusDecodeController from "../../lib/opusDecodeController"; import RichTextProcessor from "../../lib/richtextprocessor"; -import { blurActiveElement, cancelEvent, cancelSelection, CLICK_EVENT_NAME, findUpClassName, getRichValue, getSelectedNodes, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd, serializeNodes } from "../../helpers/dom"; +import { attachClickEvent, blurActiveElement, cancelEvent, cancelSelection, findUpClassName, getRichValue, getSelectedNodes, isInputEmpty, markdownTags, MarkdownType, placeCaretAtEnd, serializeNodes } from "../../helpers/dom"; import { ButtonMenuItemOptions } from '../buttonMenu'; import emoticonsDropdown from "../emoticonsDropdown"; import PopupCreatePoll from "../popupCreatePoll"; @@ -123,10 +123,10 @@ export default class ChatInput { this.goDownBtn.append(this.goDownUnreadBadge); this.chatInput.append(this.goDownBtn); - this.listenerSetter.add(this.goDownBtn, CLICK_EVENT_NAME, (e) => { + attachClickEvent(this.goDownBtn, (e) => { cancelEvent(e); this.chat.bubbles.onGoDownClick(); - }); + }, {listenerSetter: this.listenerSetter}); // * constructor end } @@ -260,7 +260,23 @@ export default class ChatInput { this.fileInput.value = ''; }, false); - this.listenerSetter.add(this.btnSend, CLICK_EVENT_NAME, this.onBtnSendClick); + /* let time = Date.now(); + this.btnSend.addEventListener('touchstart', (e) => { + time = Date.now(); + }); + + let eventName1 = 'touchend'; + this.btnSend.addEventListener(eventName1, (e: Event) => { + //cancelEvent(e); + console.log(eventName1 + ', time: ' + (Date.now() - time)); + }); + + let eventName = 'mousedown'; + this.btnSend.addEventListener(eventName, (e: Event) => { + cancelEvent(e); + console.log(eventName + ', time: ' + (Date.now() - time)); + }); */ + attachClickEvent(this.btnSend, this.onBtnSendClick, {listenerSetter: this.listenerSetter}); if(this.recorder) { const onCancelRecordClick = (e: Event) => { @@ -269,7 +285,7 @@ export default class ChatInput { this.recorder.stop(); opusDecodeController.setKeepAlive(false); }; - this.listenerSetter.add(this.btnCancelRecord, CLICK_EVENT_NAME, onCancelRecordClick); + attachClickEvent(this.btnCancelRecord, onCancelRecordClick, {listenerSetter: this.listenerSetter}); this.recorder.onstop = () => { this.recording = false; @@ -308,8 +324,8 @@ export default class ChatInput { }; } - this.listenerSetter.add(this.replyElements.cancelBtn, CLICK_EVENT_NAME, this.onHelperCancel); - this.listenerSetter.add(this.replyElements.container, CLICK_EVENT_NAME, this.onHelperClick); + attachClickEvent(this.replyElements.cancelBtn, this.onHelperCancel, {listenerSetter: this.listenerSetter}); + attachClickEvent(this.replyElements.container, this.onHelperClick, {listenerSetter: this.listenerSetter}); } public constructPinnedHelpers() { diff --git a/src/components/poll.ts b/src/components/poll.ts index 99b7c935..716ac48a 100644 --- a/src/components/poll.ts +++ b/src/components/poll.ts @@ -5,7 +5,7 @@ import appPollsManager, { Poll, PollResults } from "../lib/appManagers/appPollsM import serverTimeManager from "../lib/mtproto/serverTimeManager"; import { RichTextProcessor } from "../lib/richtextprocessor"; import rootScope from "../lib/rootScope"; -import { cancelEvent, CLICK_EVENT_NAME, findUpClassName } from "../helpers/dom"; +import { attachClickEvent, cancelEvent, detachClickEvent, findUpClassName } from "../helpers/dom"; import { ripple } from "./ripple"; import appSidebarRight from "./sidebarRight"; @@ -338,7 +338,7 @@ export default class PollElement extends HTMLElement { this.votersCountDiv.classList.add('hide'); } - this.sendVoteBtn.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(this.sendVoteBtn, (e) => { cancelEvent(e); /* const indexes = this.answerDivs.filter(el => el.classList.contains('is-chosing')).map(el => +el.dataset.index); if(indexes.length) { @@ -364,7 +364,7 @@ export default class PollElement extends HTMLElement { this.performResults(results, poll.chosenIndexes); } else if(!this.isClosed) { this.setVotersCount(results); - this.addEventListener(CLICK_EVENT_NAME, this.clickHandler); + attachClickEvent(this, this.clickHandler); } } @@ -406,7 +406,7 @@ export default class PollElement extends HTMLElement { this.descDiv.append(toggleHint); //let active = false; - toggleHint.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(toggleHint, (e) => { cancelEvent(e); //active = true; @@ -514,9 +514,9 @@ export default class PollElement extends HTMLElement { this.chosenIndexes = chosenIndexes.slice(); if(this.isRetracted) { - this.addEventListener(CLICK_EVENT_NAME, this.clickHandler); + attachClickEvent(this, this.clickHandler); } else { - this.removeEventListener(CLICK_EVENT_NAME, this.clickHandler); + detachClickEvent(this, this.clickHandler); } } diff --git a/src/components/sidebarLeft/index.ts b/src/components/sidebarLeft/index.ts index 7a5e97e4..973fd2d4 100644 --- a/src/components/sidebarLeft/index.ts +++ b/src/components/sidebarLeft/index.ts @@ -8,7 +8,7 @@ import appStateManager from "../../lib/appManagers/appStateManager"; import appUsersManager from "../../lib/appManagers/appUsersManager"; import { MOUNT_CLASS_TO } from "../../lib/mtproto/mtproto_config"; import rootScope from "../../lib/rootScope"; -import { CLICK_EVENT_NAME, findUpClassName, findUpTag } from "../../helpers/dom"; +import { attachClickEvent, findUpClassName, findUpTag } from "../../helpers/dom"; import AppSearch, { SearchGroup } from "../appSearch"; import "../avatar"; import { parseMenuButtonsTo } from "../misc"; @@ -292,32 +292,32 @@ export class AppSidebarLeft extends SidebarSlider { this.archivedCount = this.buttons.archived.querySelector('.archived-count') as HTMLSpanElement; - this.buttons.saved.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(this.buttons.saved, (e) => { ///////this.log('savedbtn click'); setTimeout(() => { // menu doesn't close if no timeout (lol) appImManager.setPeer(appImManager.myId); }, 0); }); - this.buttons.archived.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(this.buttons.archived, (e) => { this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.archived); }); - this.buttons.contacts.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(this.buttons.contacts, (e) => { this.contactsTab.openContacts(); }); - this.buttons.settings.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(this.buttons.settings, (e) => { this.settingsTab.fillElements(); this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.settings); }); - this.newButtons.channel.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(this.newButtons.channel, (e) => { this.selectTab(AppSidebarLeft.SLIDERITEMSIDS.newChannel); }); [this.newButtons.group, this.buttons.newGroup].forEach(btn => { - btn.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(btn, (e) => { this.addMembersTab.init(0, 'chat', false, (peerIds) => { this.newGroupTab.init(peerIds); }); diff --git a/src/components/sidebarLeft/tabs/editFolder.ts b/src/components/sidebarLeft/tabs/editFolder.ts index b6649d16..46f2776e 100644 --- a/src/components/sidebarLeft/tabs/editFolder.ts +++ b/src/components/sidebarLeft/tabs/editFolder.ts @@ -8,7 +8,7 @@ import { ripple } from "../../ripple"; import { SliderTab } from "../../slider"; import { toast } from "../../toast"; import appMessagesManager from "../../../lib/appManagers/appMessagesManager"; -import { CLICK_EVENT_NAME } from "../../../helpers/dom"; +import { attachClickEvent } from "../../../helpers/dom"; const MAX_FOLDER_NAME_LENGTH = 12; @@ -72,7 +72,7 @@ export default class AppEditFolderTab implements SliderTab { this.animation = player; }); - this.deleteFolderBtn.addEventListener(CLICK_EVENT_NAME, () => { + attachClickEvent(this.deleteFolderBtn, () => { this.deleteFolderBtn.setAttribute('disabled', 'true'); appMessagesManager.filtersStorage.updateDialogFilter(this.filter, true).then(bool => { if(bool) { diff --git a/src/components/sidebarLeft/tabs/settings.ts b/src/components/sidebarLeft/tabs/settings.ts index 7ed1e242..b2f519e0 100644 --- a/src/components/sidebarLeft/tabs/settings.ts +++ b/src/components/sidebarLeft/tabs/settings.ts @@ -5,7 +5,7 @@ import { parseMenuButtonsTo } from "../../misc"; import apiManager from "../../../lib/mtproto/mtprotoworker"; import appSidebarLeft, { AppSidebarLeft } from ".."; import appUsersManager from "../../../lib/appManagers/appUsersManager"; -import { CLICK_EVENT_NAME } from "../../../helpers/dom"; +import { attachClickEvent } from "../../../helpers/dom"; export default class AppSettingsTab implements SliderTab { private container = document.querySelector('.settings-container') as HTMLDivElement; @@ -31,7 +31,7 @@ export default class AppSettingsTab implements SliderTab { this.fillElements(); }); */ - this.logOutBtn.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(this.logOutBtn, (e) => { apiManager.logOut(); }); diff --git a/src/components/wrappers.ts b/src/components/wrappers.ts index e5c04fea..c2915261 100644 --- a/src/components/wrappers.ts +++ b/src/components/wrappers.ts @@ -12,7 +12,7 @@ import appMessagesManager from '../lib/appManagers/appMessagesManager'; import appPhotosManager, { MyPhoto } from '../lib/appManagers/appPhotosManager'; import LottieLoader from '../lib/lottieLoader'; import VideoPlayer from '../lib/mediaPlayer'; -import { cancelEvent, CLICK_EVENT_NAME, isInDOM } from "../helpers/dom"; +import { attachClickEvent, cancelEvent, isInDOM } from "../helpers/dom"; import webpWorkerController from '../lib/webp/webpWorkerController'; import animationIntersector from './animationIntersector'; import appMediaPlaybackController from './appMediaPlaybackController'; @@ -402,7 +402,7 @@ export function wrapDocument(doc: MyDocument, withTime = false, uploading = fals let preloader: ProgressivePreloader; let download: DownloadBlob; - docDiv.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(docDiv, (e) => { cancelEvent(e); if(!download) { if(downloadDiv.classList.contains('downloading')) { @@ -757,7 +757,7 @@ export function wrapSticker({doc, div, middleware, lazyLoadQueue, group, play, o }, true); if(emoji) { - div.addEventListener(CLICK_EVENT_NAME, (e) => { + attachClickEvent(div, (e) => { cancelEvent(e); let animation = LottieLoader.getAnimation(div); diff --git a/src/helpers/dom.ts b/src/helpers/dom.ts index e9762d76..cf40dec7 100644 --- a/src/helpers/dom.ts +++ b/src/helpers/dom.ts @@ -477,6 +477,7 @@ export const attachClickEvent = (elem: HTMLElement, callback: (e: TouchEvent | M const onTouchStart = (e: TouchEvent) => { const onTouchMove = (e: TouchEvent) => { + remove('touchmove', onTouchMove, o); remove('touchend', onTouchEnd, o); };