From d74efd09abd4a260ca36956279580e3b6af7b134 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Thu, 27 Sep 2018 16:11:57 -0600 Subject: [PATCH] Track how far the user travels before dismissing their user settings Fixes https://github.com/vector-im/riot-web/issues/7158 Because the onClick was on a fullpage div, the browser was firing it regardless of how far the mouse moved. The onClick event itself doesn't give us any sort of travel distance, or a start point we can use to determine if they clicked a scrollbar or something. This means we have to rely on good ol' fashioned mouse down and up events to see if the user moved their mouse during their click. If the user's click starts in a valid container, we record the coordinates. This is so we can easily identify when the user clicks inside something like the settings container itself. When the user releases their mouse, we determine how far they moved their mouse - if the distance is within some threshold (~5 pixels in this case) then we can count it as a click. Because we've already filtered on the component they started their click in, we can safely rely on the presence of coordinates as a flag that they are in the right container, combined with the fact that they can't stray too far before their click not counting anyways. --- src/components/structures/LoggedInView.js | 32 ++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js index 0c4688a411..180a348434 100644 --- a/src/components/structures/LoggedInView.js +++ b/src/components/structures/LoggedInView.js @@ -319,7 +319,7 @@ const LoggedInView = React.createClass({ ), true); }, - _onClick: function(ev) { + _onMouseDown: function(ev) { // When the panels are disabled, clicking on them results in a mouse event // which bubbles to certain elements in the tree. When this happens, close // any settings page that is currently open (user/room/group). @@ -330,11 +330,37 @@ const LoggedInView = React.createClass({ targetClasses.has('mx_MatrixChat_middlePanel') || targetClasses.has('mx_RoomView') ) { - dis.dispatch({ action: 'close_settings' }); + this.setState({ + mouseDown: { + x: ev.pageX, + y: ev.pageY, + }, + }); } } }, + _onMouseUp: function(ev) { + if (!this.state.mouseDown) return; + + const deltaX = ev.pageX - this.state.mouseDown.x; + const deltaY = ev.pageY - this.state.mouseDown.y; + const distance = Math.sqrt((deltaX * deltaX) + (deltaY + deltaY)); + const maxRadius = 5; // People shouldn't be straying too far, hopefully + + // Note: we track how far the user moved their mouse to help + // combat against https://github.com/vector-im/riot-web/issues/7158 + + if (distance < maxRadius) { + // This is probably a real click, and not a drag + dis.dispatch({ action: 'close_settings' }); + } + + // Always clear the mouseDown state to ensure we don't accidentally + // use stale values due to the mouseDown checks. + this.setState({mouseDown: null}); + }, + render: function() { const LeftPanel = sdk.getComponent('structures.LeftPanel'); const RightPanel = sdk.getComponent('structures.RightPanel'); @@ -478,7 +504,7 @@ const LoggedInView = React.createClass({ } return ( -
+
{ topBar }