From cd6c6936b05e87c6ff42fcfe742734043825da1c Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Mon, 23 Nov 2020 12:03:53 +0200 Subject: [PATCH] Fix keyboard close on message input for mobiles --- src/components/buttonMenu.ts | 24 ++++++++++++++++--- src/components/chat/contextMenu.ts | 25 +++++++------------- src/components/chat/input.ts | 16 ++++++++----- src/helpers/clipboard.ts | 38 ++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 26 deletions(-) create mode 100644 src/helpers/clipboard.ts diff --git a/src/components/buttonMenu.ts b/src/components/buttonMenu.ts index cc157b05..f0fffb4b 100644 --- a/src/components/buttonMenu.ts +++ b/src/components/buttonMenu.ts @@ -1,7 +1,8 @@ -import { CLICK_EVENT_NAME } from "../helpers/dom"; +import { cancelEvent, CLICK_EVENT_NAME } from "../helpers/dom"; +import { closeBtnMenu } from "./misc"; import { ripple } from "./ripple"; -export type ButtonMenuItemOptions = {icon: string, text: string, onClick: (e: MouseEvent | TouchEvent) => void, element?: HTMLElement}; +export type ButtonMenuItemOptions = {icon: string, text: string, onClick: (e: MouseEvent | TouchEvent) => void, element?: HTMLElement/* , cancelEvent?: true */}; const ButtonMenuItem = (options: ButtonMenuItemOptions) => { if(options.element) return options.element; @@ -12,7 +13,24 @@ const ButtonMenuItem = (options: ButtonMenuItemOptions) => { el.innerText = text; ripple(el); - el.addEventListener(CLICK_EVENT_NAME, onClick); + /* if(options.cancelEvent) { + el.addEventListener(CLICK_EVENT_NAME, (e) => { + cancelEvent(e); + closeBtnMenu(); + options.onClick(e); + }); + } else { + el.addEventListener(CLICK_EVENT_NAME, onClick); + } */ + if(CLICK_EVENT_NAME == 'touchend') { // * cancel keyboard close + el.addEventListener(CLICK_EVENT_NAME, (e) => { + cancelEvent(e); + options.onClick(e); + closeBtnMenu(); + }); + } else { + el.addEventListener(CLICK_EVENT_NAME, onClick); + } return options.element = el; }; diff --git a/src/components/chat/contextMenu.ts b/src/components/chat/contextMenu.ts index 8d07b0f0..e2ba0a43 100644 --- a/src/components/chat/contextMenu.ts +++ b/src/components/chat/contextMenu.ts @@ -11,6 +11,7 @@ import { attachContextMenuListener, openBtnMenu, positionMenu } from "../misc"; import PopupDeleteMessages from "../popupDeleteMessages"; import PopupForward from "../popupForward"; import PopupPinMessage from "../popupUnpinMessage"; +import { copyTextToClipboard } from "../../helpers/clipboard"; export default class ChatContextMenu { private buttons: (ButtonMenuItemOptions & {verify: () => boolean, notDirect?: () => boolean, withSelection?: true})[]; @@ -153,7 +154,8 @@ export default class ChatContextMenu { icon: 'reply', text: 'Reply', onClick: this.onReplyClick, - verify: () => (this.peerID > 0 || appChatsManager.hasRights(-this.peerID, 'send')) && this.msgID > 0 + verify: () => (this.peerID > 0 || appChatsManager.hasRights(-this.peerID, 'send')) && this.msgID > 0/* , + cancelEvent: true */ }, { icon: 'edit', text: 'Edit', @@ -194,7 +196,8 @@ export default class ChatContextMenu { const message = appMessagesManager.getMessage(this.msgID); const poll = message.media?.poll as Poll; return poll && poll.chosenIndexes.length && !poll.pFlags.closed && !poll.pFlags.quiz; - } + }/* , + cancelEvent: true */ }, { icon: 'stop', text: 'Stop poll', @@ -203,7 +206,8 @@ export default class ChatContextMenu { const message = appMessagesManager.getMessage(this.msgID); const poll = message.media?.poll; return appMessagesManager.canEditMessage(this.msgID, 'poll') && poll && !poll.pFlags.closed && this.msgID > 0; - } + }/* , + cancelEvent: true */ }, { icon: 'forward', text: 'Forward', @@ -273,20 +277,7 @@ export default class ChatContextMenu { return acc + (message?.message ? message.message + '\n' : ''); }, '').trim(); - const textArea = document.createElement('textarea'); - textArea.value = str; - textArea.style.position = 'fixed'; //avoid scrolling to bottom - document.body.appendChild(textArea); - textArea.focus(); - textArea.select(); - - try { - document.execCommand('copy'); - } catch (err) { - console.error('Oops, unable to copy', err); - } - - document.body.removeChild(textArea); + copyTextToClipboard(str); }; private onPinClick = () => { diff --git a/src/components/chat/input.ts b/src/components/chat/input.ts index 35aed7e6..02dae7c1 100644 --- a/src/components/chat/input.ts +++ b/src/components/chat/input.ts @@ -723,13 +723,17 @@ export class ChatInput { }; public clearInput() { - this.attachMessageInputField(); + if(isTouchSupported) { + this.messageInput.innerText = ''; + } else { + this.attachMessageInputField(); - // clear executions - this.canRedoFromHTML = ''; - this.undoHistory.length = 0; - this.executedHistory.length = 0; - this.canUndoFromHTML = ''; + // clear executions + this.canRedoFromHTML = ''; + this.undoHistory.length = 0; + this.executedHistory.length = 0; + this.canUndoFromHTML = ''; + } } public isInputEmpty() { diff --git a/src/helpers/clipboard.ts b/src/helpers/clipboard.ts new file mode 100644 index 00000000..9296b34c --- /dev/null +++ b/src/helpers/clipboard.ts @@ -0,0 +1,38 @@ +// https://stackoverflow.com/a/30810322 +function fallbackCopyTextToClipboard(text: string) { + var textArea = document.createElement("textarea"); + textArea.value = text; + + // Avoid scrolling to bottom + textArea.style.top = "0"; + textArea.style.left = "0"; + textArea.style.position = "fixed"; + + document.body.appendChild(textArea); + textArea.focus(); + textArea.select(); + + try { + document.execCommand('copy'); + //const successful = document.execCommand('copy'); + //const msg = successful ? 'successful' : 'unsuccessful'; + //console.log('Fallback: Copying text command was ' + msg); + } catch(err) { + //console.error('Fallback: Oops, unable to copy', err); + } + + document.body.removeChild(textArea); +} + +export function copyTextToClipboard(text: string) { + if(!navigator.clipboard) { + fallbackCopyTextToClipboard(text); + return; + } + + navigator.clipboard.writeText(text);/* .then(function() { + console.log('Async: Copying to clipboard was successful!'); + }, function(err) { + console.error('Async: Could not copy text: ', err); + }); */ +} \ No newline at end of file