From a982b6765f9e2da14213f36061fe3bafec00d701 Mon Sep 17 00:00:00 2001 From: Joffrey JAFFEUX Date: Mon, 17 Jul 2023 15:11:51 +0200 Subject: [PATCH] FIX: allows to resize panels on tablets (#22640) On tablets like iPad where we allow channel and thread to be on the same screen, it was not possible to resize the panels due to code being thought for mouse events. This commit should now correctly allow for this. The "resizer" has also been made larger to simplify touching. No test as it's hard to test on iPad and dragging events are also complex. --- .../modifiers/chat/resizable-node.js | 88 ++++++++++++++----- .../common/chat-side-panel-resizer.scss | 26 ++++-- 2 files changed, 85 insertions(+), 29 deletions(-) diff --git a/plugins/chat/assets/javascripts/discourse/modifiers/chat/resizable-node.js b/plugins/chat/assets/javascripts/discourse/modifiers/chat/resizable-node.js index a7c965f6475d55..42abed17975391 100644 --- a/plugins/chat/assets/javascripts/discourse/modifiers/chat/resizable-node.js +++ b/plugins/chat/assets/javascripts/discourse/modifiers/chat/resizable-node.js @@ -1,10 +1,13 @@ import Modifier from "ember-modifier"; import { registerDestructor } from "@ember/destroyable"; import { bind } from "discourse-common/utils/decorators"; +import { inject as service } from "@ember/service"; const MINIMUM_SIZE = 20; export default class ResizableNode extends Modifier { + @service capabilities; + element = null; resizerSelector = null; didResizeContainer = null; @@ -14,8 +17,8 @@ export default class ResizableNode extends Modifier { _originalHeight = 0; _originalX = 0; _originalY = 0; - _originalMouseX = 0; - _originalMouseY = 0; + _originalPageX = 0; + _originalPageY = 0; constructor(owner, args) { super(owner, args); @@ -31,15 +34,27 @@ export default class ResizableNode extends Modifier { options ); - this.element - .querySelector(this.resizerSelector) - ?.addEventListener("mousedown", this._startResize); + if (this.capabilities.touch) { + this.element + .querySelector(this.resizerSelector) + ?.addEventListener("touchstart", this._startResize); + } else { + this.element + .querySelector(this.resizerSelector) + ?.addEventListener("mousedown", this._startResize); + } } cleanup() { - this.element - .querySelector(this.resizerSelector) - ?.removeEventListener("mousedown", this._startResize); + if (this.capabilities.touch) { + this.element + .querySelector(this.resizerSelector) + ?.addEventListener("touchstart", this._startResize); + } else { + this.element + .querySelector(this.resizerSelector) + ?.removeEventListener("mousedown", this._startResize); + } } @bind @@ -58,19 +73,25 @@ export default class ResizableNode extends Modifier { ); this._originalX = this.element.getBoundingClientRect().left; this._originalY = this.element.getBoundingClientRect().top; - this._originalMouseX = event.pageX; - this._originalMouseY = event.pageY; - window.addEventListener("mousemove", this._resize); - window.addEventListener("mouseup", this._stopResize); + this._originalPageX = this._eventValueForProperty(event, "pageX"); + this._originalPageY = this._eventValueForProperty(event, "pageY"); + + if (this.capabilities.touch) { + window.addEventListener("touchmove", this._resize); + window.addEventListener("touchend", this._stopResize); + } else { + window.addEventListener("mousemove", this._resize); + window.addEventListener("mouseup", this._stopResize); + } } /* The bulk of the logic is to calculate the new width and height of the element - based on the current mouse position: width is calculated by subtracting - the difference between the current event.pageX and the original this._originalMouseX + based on the current position on page: width is calculated by subtracting + the difference between the current pageX and the original this._originalPageX from the original this._originalWidth, and rounding up to the nearest integer. - height is calculated in a similar way using event.pageY and this._originalMouseY. + height is calculated in a similar way using pageY and this._originalPageY. In this example (B) is the current element top/left and (A) is x/y of the mouse after dragging: @@ -83,7 +104,8 @@ export default class ResizableNode extends Modifier { @bind _resize(event) { let width = this._originalWidth; - let diffWidth = event.pageX - this._originalMouseX; + let diffWidth = + this._eventValueForProperty(event, "pageX") - this._originalPageX; if (document.documentElement.classList.contains("rtl")) { width = Math.ceil(width + diffWidth); } else { @@ -91,7 +113,8 @@ export default class ResizableNode extends Modifier { } const height = Math.ceil( - this._originalHeight - (event.pageY - this._originalMouseY) + this._originalHeight - + (this._eventValueForProperty(event, "pageY") - this._originalPageY) ); const newStyle = {}; @@ -101,8 +124,11 @@ export default class ResizableNode extends Modifier { if (this.options.position) { newStyle.left = - Math.ceil(this._originalX + (event.pageX - this._originalMouseX)) + - "px"; + Math.ceil( + this._originalX + + (this._eventValueForProperty(event, "pageX") - + this._originalPageX) + ) + "px"; } } @@ -111,8 +137,11 @@ export default class ResizableNode extends Modifier { if (this.options.position) { newStyle.top = - Math.ceil(this._originalY + (event.pageY - this._originalMouseY)) + - "px"; + Math.ceil( + this._originalY + + (this._eventValueForProperty(event, "pageY") - + this._originalPageY) + ) + "px"; } } @@ -125,7 +154,20 @@ export default class ResizableNode extends Modifier { @bind _stopResize() { - window.removeEventListener("mousemove", this._resize); - window.removeEventListener("mouseup", this._stopResize); + if (this.capabilities.touch) { + window.removeEventListener("touchmove", this._resize); + window.removeEventListener("touchend", this._stopResize); + } else { + window.removeEventListener("mousemove", this._resize); + window.removeEventListener("mouseup", this._stopResize); + } + } + + _eventValueForProperty(event, property) { + if (this.capabilities.touch) { + return event.changedTouches[0][property]; + } else { + return event[property]; + } } } diff --git a/plugins/chat/assets/stylesheets/common/chat-side-panel-resizer.scss b/plugins/chat/assets/stylesheets/common/chat-side-panel-resizer.scss index 17a1de45085885..61186aea2646cb 100644 --- a/plugins/chat/assets/stylesheets/common/chat-side-panel-resizer.scss +++ b/plugins/chat/assets/stylesheets/common/chat-side-panel-resizer.scss @@ -1,16 +1,30 @@ .chat-side-panel-resizer { top: 0; bottom: 0; - left: -3px; - width: 5px; + position: absolute; z-index: calc(z("header") - 1); transition: background-color 0.15s 0.15s; background-color: transparent; - &:hover, - &:active { - cursor: col-resize; - background: var(--tertiary); + .touch & { + left: -6px; + width: 10px; + + &:active { + cursor: col-resize; + background: var(--tertiary); + } + } + + .no-touch & { + left: -3px; + width: 5px; + + &:hover, + &:active { + cursor: col-resize; + background: var(--tertiary); + } } }