diff --git a/src/widgets/call-panel.jsx b/src/widgets/call-panel.jsx index 4f3762be..55fef792 100644 --- a/src/widgets/call-panel.jsx +++ b/src/widgets/call-panel.jsx @@ -175,6 +175,23 @@ class CallPanel extends React.PureComponent { this.containerRef.current.style.cursor = 'grab'; } }; + // dragStart's inline left/top/right (set the first time the minimized bubble is dragged, see + // above) always win over base.css's #video-container.minimized:not(.audio-minimized) mobile + // rule -- inline style beats any stylesheet selector regardless of media query. A desktop user + // who drags the bubble somewhere and then narrows the window below 640px (a real everyday + // action -- snapping the browser to half the screen, say) would otherwise be stuck with the + // bubble pinned at its old desktop-width position/size instead of docking as the intended + // mobile full-width strip. Clearing the manual offsets once the mobile breakpoint applies lets + // the stylesheet rule take back over; harmless (a no-op) whenever nothing was ever dragged. + this.handleWindowResize = () => { + if (this.props.minimized && this.containerRef && this.containerRef.current && + window.matchMedia('(width<=640px)').matches) { + const el = this.containerRef.current; + el.style.removeProperty('left'); + el.style.removeProperty('right'); + el.style.removeProperty('top'); + } + }; } componentDidMount() { @@ -191,6 +208,7 @@ class CallPanel extends React.PureComponent { this.containerRef.current.addEventListener('pointermove', this.drag); this.containerRef.current.addEventListener('pointerup', this.dragEnd); } + window.addEventListener('resize', this.handleWindowResize); } componentWillUnmount() { @@ -199,6 +217,7 @@ class CallPanel extends React.PureComponent { topic.onInfo = this.previousOnInfo; this.stop(); + window.removeEventListener('resize', this.handleWindowResize); if (this.containerRef) { this.containerRef.current.removeEventListener('pointerdown', this.dragStart); this.containerRef.current.removeEventListener('pointermove', this.drag);