From 269f1f33e337584ccb85861348abb8b4ff58b2f5 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Sep 2017 11:27:25 +0100 Subject: [PATCH 1/3] show response on copy so you don't mash it Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/TextualBody.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index 58273bee67..a0fa61ccca 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -31,6 +31,7 @@ import dis from '../../../dispatcher'; import { _t } from '../../../languageHandler'; import UserSettingsStore from "../../../UserSettingsStore"; import MatrixClientPeg from '../../../MatrixClientPeg'; +import ContextualMenu from '../../structures/ContextualMenu'; import {RoomMember} from 'matrix-js-sdk'; import classNames from 'classnames'; @@ -119,6 +120,20 @@ module.exports = React.createClass({ buttons[i].onclick = (e) => { const copyCode = buttons[i].parentNode.getElementsByTagName("code")[0]; this.copyToClipboard(copyCode.textContent); + + const GenericTextContextMenu = sdk.getComponent('context_menus.GenericTextContextMenu'); + const buttonRect = e.target.getBoundingClientRect(); + + // The window X and Y offsets are to adjust position when zoomed in to page + const x = buttonRect.right + window.pageXOffset; + const y = (buttonRect.top + (buttonRect.height / 2) + window.pageYOffset) - 19; + const {close} = ContextualMenu.createMenu(GenericTextContextMenu, { + chevronOffset: 10, + left: x, + top: y, + message: "Copied!", + }); + e.target.onmouseout = close; }; } } From b10b0e573d76909fb884bcd95649263c7c4f7117 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 6 Sep 2017 11:29:55 +0100 Subject: [PATCH 2/3] i18n and change message depending on success of copy Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/TextualBody.js | 10 +++++++--- src/i18n/strings/en_EN.json | 2 ++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index a0fa61ccca..d7d858e0c4 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -73,12 +73,16 @@ module.exports = React.createClass({ textArea.value = text; document.body.appendChild(textArea); textArea.select(); + + let successful; try { - const successful = document.execCommand('copy'); + successful = document.execCommand('copy'); } catch (err) { console.log('Unable to copy'); } + document.body.removeChild(textArea); + return successful; }, componentDidMount: function() { @@ -119,7 +123,7 @@ module.exports = React.createClass({ for (let i = 0; i < buttons.length; i++) { buttons[i].onclick = (e) => { const copyCode = buttons[i].parentNode.getElementsByTagName("code")[0]; - this.copyToClipboard(copyCode.textContent); + const successful = this.copyToClipboard(copyCode.textContent); const GenericTextContextMenu = sdk.getComponent('context_menus.GenericTextContextMenu'); const buttonRect = e.target.getBoundingClientRect(); @@ -131,7 +135,7 @@ module.exports = React.createClass({ chevronOffset: 10, left: x, top: y, - message: "Copied!", + message: successful ? _t('Copied!') : _t('Failed to copy'), }); e.target.onmouseout = close; }; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 8c0f3c8db7..de0b8e9ebb 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -620,6 +620,8 @@ "Encrypt room": "Encrypt room", "There are no visible files in this room": "There are no visible files in this room", "Room": "Room", + "Copied!": "Copied!", + "Failed to copy": "Failed to copy", "Connectivity to the server has been lost.": "Connectivity to the server has been lost.", "Sent messages will be stored until your connection has returned.": "Sent messages will be stored until your connection has returned.", "Auto-complete": "Auto-complete", From d3bfdf495c058d4f43044870e82ceb4d45fb7bfb Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 13 Sep 2017 14:18:31 +0100 Subject: [PATCH 3/3] initialize value with false to prevent undefined. Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/messages/TextualBody.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/messages/TextualBody.js b/src/components/views/messages/TextualBody.js index d7d858e0c4..17bb9f90b5 100644 --- a/src/components/views/messages/TextualBody.js +++ b/src/components/views/messages/TextualBody.js @@ -74,7 +74,7 @@ module.exports = React.createClass({ document.body.appendChild(textArea); textArea.select(); - let successful; + let successful = false; try { successful = document.execCommand('copy'); } catch (err) {