From 6685cbcb25e76abd9304319e6f2f16dfc53e58f8 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 29 Apr 2017 06:13:03 +0100 Subject: [PATCH 1/6] make MessageComposerInput (new and old) warn on unload new needs binding due to class this ref being softer couldn't do this nicely in MessageComposer/Input as isTyping wasn't propagated. Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposerInput.js | 10 ++++++++++ src/components/views/rooms/MessageComposerInputOld.js | 9 +++++++++ 2 files changed, 19 insertions(+) diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 8efd2fa579..672279ef54 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -93,6 +93,7 @@ export default class MessageComposerInput extends React.Component { this.onEscape = this.onEscape.bind(this); this.setDisplayedCompletion = this.setDisplayedCompletion.bind(this); this.onMarkdownToggleClicked = this.onMarkdownToggleClicked.bind(this); + this.onPageUnload = this.onPageUnload.bind(this); const isRichtextEnabled = UserSettingsStore.getSyncedSetting('MessageComposerInput.isRichTextEnabled', false); @@ -233,11 +234,13 @@ export default class MessageComposerInput extends React.Component { this.refs.editor, this.props.room.roomId ); + window.addEventListener('beforeunload', this.onPageUnload); } componentWillUnmount() { dis.unregister(this.dispatcherRef); this.sentHistory.saveLastTextEntry(); + window.removeEventListener('beforeunload', this.onPageUnload); } componentWillUpdate(nextProps, nextState) { @@ -249,6 +252,13 @@ export default class MessageComposerInput extends React.Component { } } + onPageUnload(event) { + if (this.isTyping) { + return event.returnValue = + 'You seem to be typing a message, are you sure you want to quit?'; + } + } + onAction(payload) { let editor = this.refs.editor; let contentState = this.state.editorState.getCurrentContent(); diff --git a/src/components/views/rooms/MessageComposerInputOld.js b/src/components/views/rooms/MessageComposerInputOld.js index 378644478c..2a992cdf5f 100644 --- a/src/components/views/rooms/MessageComposerInputOld.js +++ b/src/components/views/rooms/MessageComposerInputOld.js @@ -177,11 +177,20 @@ export default React.createClass({ if (this.props.tabComplete) { this.props.tabComplete.setTextArea(this.refs.textarea); } + window.addEventListener('beforeunload', this.onPageUnload); }, componentWillUnmount: function() { dis.unregister(this.dispatcherRef); this.sentHistory.saveLastTextEntry(); + window.removeEventListener('beforeunload', this.onPageUnload); + }, + + onPageUnload(event) { + if (this.isTyping) { + return event.returnValue = + 'You seem to be typing a message, are you sure you want to quit?'; + } }, onAction: function(payload) { From daae3bd1ecfae565ff1ed7958c564ff73fb0eae0 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sat, 29 Apr 2017 06:25:30 +0100 Subject: [PATCH 2/6] warn on unload when uploading file(s) Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomView.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index a0c36374b6..9414a59e01 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -271,6 +271,7 @@ module.exports = React.createClass({ this._updateConfCallNotification(); + window.addEventListener('beforeunload', this.onPageUnload); window.addEventListener('resize', this.onResize); this.onResize(); @@ -353,6 +354,7 @@ module.exports = React.createClass({ MatrixClientPeg.get().removeListener("accountData", this.onAccountData); } + window.removeEventListener('beforeunload', this.onPageUnload); window.removeEventListener('resize', this.onResize); document.removeEventListener("keydown", this.onKeyDown); @@ -365,6 +367,14 @@ module.exports = React.createClass({ // Tinter.tint(); // reset colourscheme }, + onPageUnload(event) { + if (ContentMessages.getCurrentUploads().length > 0) { + return event.returnValue = + 'You seem to be uploading files, are you sure you want to quit?'; + } + }, + + onKeyDown: function(ev) { let handled = false; const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0; From b6fd771b9aaba669ef1b567c6d937f026533c2b4 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 3 May 2017 16:21:35 +0100 Subject: [PATCH 3/6] move implementation to MessageComposer to it applies to any future composers Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposer.js | 11 +++++++++++ src/components/views/rooms/MessageComposerInput.js | 10 ---------- src/components/views/rooms/MessageComposerInputOld.js | 9 --------- 3 files changed, 11 insertions(+), 19 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 88230062fe..2161198142 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -43,6 +43,7 @@ export default class MessageComposer extends React.Component { this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this); this.onInputStateChanged = this.onInputStateChanged.bind(this); this.onEvent = this.onEvent.bind(this); + this.onPageUnload = this.onPageUnload.bind(this); this.state = { autocompleteQuery: '', @@ -64,12 +65,22 @@ export default class MessageComposer extends React.Component { // marked as encrypted. // XXX: fragile as all hell - fixme somehow, perhaps with a dedicated Room.encryption event or something. MatrixClientPeg.get().on("event", this.onEvent); + + window.addEventListener('beforeunload', this.onPageUnload); } componentWillUnmount() { if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener("event", this.onEvent); } + window.removeEventListener('beforeunload', this.onPageUnload); + } + + onPageUnload(event) { + if (this.messageComposerInput && this.messageComposerInput.isTyping) { + return event.returnValue = + 'You seem to be typing a message, are you sure you want to quit?'; + } } onEvent(event) { diff --git a/src/components/views/rooms/MessageComposerInput.js b/src/components/views/rooms/MessageComposerInput.js index 672279ef54..8efd2fa579 100644 --- a/src/components/views/rooms/MessageComposerInput.js +++ b/src/components/views/rooms/MessageComposerInput.js @@ -93,7 +93,6 @@ export default class MessageComposerInput extends React.Component { this.onEscape = this.onEscape.bind(this); this.setDisplayedCompletion = this.setDisplayedCompletion.bind(this); this.onMarkdownToggleClicked = this.onMarkdownToggleClicked.bind(this); - this.onPageUnload = this.onPageUnload.bind(this); const isRichtextEnabled = UserSettingsStore.getSyncedSetting('MessageComposerInput.isRichTextEnabled', false); @@ -234,13 +233,11 @@ export default class MessageComposerInput extends React.Component { this.refs.editor, this.props.room.roomId ); - window.addEventListener('beforeunload', this.onPageUnload); } componentWillUnmount() { dis.unregister(this.dispatcherRef); this.sentHistory.saveLastTextEntry(); - window.removeEventListener('beforeunload', this.onPageUnload); } componentWillUpdate(nextProps, nextState) { @@ -252,13 +249,6 @@ export default class MessageComposerInput extends React.Component { } } - onPageUnload(event) { - if (this.isTyping) { - return event.returnValue = - 'You seem to be typing a message, are you sure you want to quit?'; - } - } - onAction(payload) { let editor = this.refs.editor; let contentState = this.state.editorState.getCurrentContent(); diff --git a/src/components/views/rooms/MessageComposerInputOld.js b/src/components/views/rooms/MessageComposerInputOld.js index 2a992cdf5f..378644478c 100644 --- a/src/components/views/rooms/MessageComposerInputOld.js +++ b/src/components/views/rooms/MessageComposerInputOld.js @@ -177,20 +177,11 @@ export default React.createClass({ if (this.props.tabComplete) { this.props.tabComplete.setTextArea(this.refs.textarea); } - window.addEventListener('beforeunload', this.onPageUnload); }, componentWillUnmount: function() { dis.unregister(this.dispatcherRef); this.sentHistory.saveLastTextEntry(); - window.removeEventListener('beforeunload', this.onPageUnload); - }, - - onPageUnload(event) { - if (this.isTyping) { - return event.returnValue = - 'You seem to be typing a message, are you sure you want to quit?'; - } }, onAction: function(payload) { From 356d29939c1deb2ce07694e653e0ee3c6d581d09 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 3 May 2017 16:25:27 +0100 Subject: [PATCH 4/6] also warn when quitting mid-call Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomStatusBar.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 0389b606aa..0cb246973b 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -100,6 +100,10 @@ module.exports = React.createClass({ this._checkSize(); }, + componentDidMount: function() { + window.addEventListener('beforeunload', this.onPageUnload); + }, + componentDidUpdate: function() { this._checkSize(); }, @@ -111,6 +115,7 @@ module.exports = React.createClass({ client.removeListener("sync", this.onSyncStateChange); client.removeListener("RoomMember.typing", this.onRoomMemberTyping); } + window.removeEventListener('beforeunload', this.onPageUnload); }, onSyncStateChange: function(state, prevState) { @@ -128,6 +133,13 @@ module.exports = React.createClass({ }); }, + onPageUnload(event) { + if (this.props.hasActiveCall) { + return event.returnValue = + 'You seem to be in a call, are you sure you want to quit?'; + } + }, + // Check whether current size is greater than 0, if yes call props.onVisible _checkSize: function () { if (this.props.onVisible && this._getSize()) { From 9d92f93fcbf7208bc2ee37f3bf2fcb8e15629e07 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 3 May 2017 16:36:57 +0100 Subject: [PATCH 5/6] consolidate call onPageUnload handler into RoomView Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/structures/RoomStatusBar.js | 12 ------------ src/components/structures/RoomView.js | 3 +++ 2 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js index 0cb246973b..0389b606aa 100644 --- a/src/components/structures/RoomStatusBar.js +++ b/src/components/structures/RoomStatusBar.js @@ -100,10 +100,6 @@ module.exports = React.createClass({ this._checkSize(); }, - componentDidMount: function() { - window.addEventListener('beforeunload', this.onPageUnload); - }, - componentDidUpdate: function() { this._checkSize(); }, @@ -115,7 +111,6 @@ module.exports = React.createClass({ client.removeListener("sync", this.onSyncStateChange); client.removeListener("RoomMember.typing", this.onRoomMemberTyping); } - window.removeEventListener('beforeunload', this.onPageUnload); }, onSyncStateChange: function(state, prevState) { @@ -133,13 +128,6 @@ module.exports = React.createClass({ }); }, - onPageUnload(event) { - if (this.props.hasActiveCall) { - return event.returnValue = - 'You seem to be in a call, are you sure you want to quit?'; - } - }, - // Check whether current size is greater than 0, if yes call props.onVisible _checkSize: function () { if (this.props.onVisible && this._getSize()) { diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 9414a59e01..1b3ed6e80d 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -371,6 +371,9 @@ module.exports = React.createClass({ if (ContentMessages.getCurrentUploads().length > 0) { return event.returnValue = 'You seem to be uploading files, are you sure you want to quit?'; + } else if (this._getCallForRoom() && this.state.callState !== 'ended') { + return event.returnValue = + 'You seem to be in a call, are you sure you want to quit?'; } }, From 2b2b43a7f3d57dcbf53a70817b31d6287974e517 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Sun, 7 May 2017 18:15:37 +0100 Subject: [PATCH 6/6] Content in Composer is not lost on unload so it should be fine to scare the user thinking they have lost all of their content even though when they come back they can cry with joy :D Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/components/views/rooms/MessageComposer.js | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/components/views/rooms/MessageComposer.js b/src/components/views/rooms/MessageComposer.js index 2161198142..88230062fe 100644 --- a/src/components/views/rooms/MessageComposer.js +++ b/src/components/views/rooms/MessageComposer.js @@ -43,7 +43,6 @@ export default class MessageComposer extends React.Component { this.onToggleMarkdownClicked = this.onToggleMarkdownClicked.bind(this); this.onInputStateChanged = this.onInputStateChanged.bind(this); this.onEvent = this.onEvent.bind(this); - this.onPageUnload = this.onPageUnload.bind(this); this.state = { autocompleteQuery: '', @@ -65,22 +64,12 @@ export default class MessageComposer extends React.Component { // marked as encrypted. // XXX: fragile as all hell - fixme somehow, perhaps with a dedicated Room.encryption event or something. MatrixClientPeg.get().on("event", this.onEvent); - - window.addEventListener('beforeunload', this.onPageUnload); } componentWillUnmount() { if (MatrixClientPeg.get()) { MatrixClientPeg.get().removeListener("event", this.onEvent); } - window.removeEventListener('beforeunload', this.onPageUnload); - } - - onPageUnload(event) { - if (this.messageComposerInput && this.messageComposerInput.isTyping) { - return event.returnValue = - 'You seem to be typing a message, are you sure you want to quit?'; - } } onEvent(event) {