FloatingPlayer: Stay within screen when window is resized

## Issue
4741: `Pop out player disappears or is cut off`

## Approach:
- When dragging stops, determine the location of the floating player with respect to the main window in terms of percentage.
- When window is resized, roughly re-position based on the stored percentage.
This commit is contained in:
infiinte-persistence 2020-09-10 19:52:42 +08:00 committed by Sean Yesmunt
parent ddfc2a54b8
commit e784107a0b
2 changed files with 58 additions and 1 deletions

View file

@ -27,6 +27,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Fix partially untranslated text in the Upgrade Modal _community pr!_ ([#4722](https://github.com/lbryio/lbry-desktop/pull/4722))
- Fix floating player being paused after dragging _community pr!_ ([#4710](https://github.com/lbryio/lbry-desktop/pull/4710))
- Web: Fix 'Download' not triggering until second attempt _community pr!_ ([#4721](https://github.com/lbryio/lbry-desktop/pull/4721))
- Floating player: Stay within screen when window is resized _community pr!_([#4750](https://github.com/lbryio/lbry-desktop/pull/4750))
## [0.47.1] - [2020-07-23]

View file

@ -13,6 +13,9 @@ import Draggable from 'react-draggable';
import Tooltip from 'component/common/tooltip';
import { onFullscreenChange } from 'util/full-screen';
import { useIsMobile } from 'effects/use-screensize';
import debounce from 'util/debounce';
const DEBOUNCE_WINDOW_RESIZE_HANDLER_MS = 60;
type Props = {
isFloating: boolean,
@ -45,6 +48,7 @@ export default function FileRenderFloating(props: Props) {
x: -25,
y: window.innerHeight - 400,
});
const [relativePos, setRelativePos] = useState({ x: 0, y: 0 });
const isPlayable = RENDER_MODES.FLOATING_MODES.includes(renderMode);
const isReadyToPlay = isPlayable && (streamingUrl || (fileInfo && fileInfo.completed));
@ -53,6 +57,55 @@ export default function FileRenderFloating(props: Props) {
? __("It looks like you deleted or moved this file. We're rebuilding it now. It will only take a few seconds.")
: __('Loading');
function getScreenWidth() {
if (document && document.documentElement) {
return document.documentElement.clientWidth;
} else {
return window.innerWidth;
}
}
function getScreenHeight() {
if (document && document.documentElement) {
return document.documentElement.clientHeight;
} else {
return window.innerHeight;
}
}
useEffect(() => {
setRelativePos({
x: position.x / getScreenWidth(),
y: position.y / getScreenHeight(),
});
}, []);
useEffect(() => {
const handleMainWindowResize = debounce(e => {
const GAP_PX = 10;
const ESTIMATED_SCROLL_BAR_PX = 50;
const FLOATING_PLAYER_CLASS = 'content__viewer--floating';
const fpPlayerElem = document.querySelector(`.${FLOATING_PLAYER_CLASS}`);
let newX = Math.round(relativePos.x * getScreenWidth());
let newY = Math.round(relativePos.y * getScreenHeight());
if (fpPlayerElem) {
if (newX + fpPlayerElem.getBoundingClientRect().width > getScreenWidth() - ESTIMATED_SCROLL_BAR_PX) {
newX = getScreenWidth() - fpPlayerElem.getBoundingClientRect().width - ESTIMATED_SCROLL_BAR_PX - GAP_PX;
}
if (newY + fpPlayerElem.getBoundingClientRect().height > getScreenHeight()) {
newY = getScreenHeight() - fpPlayerElem.getBoundingClientRect().height - GAP_PX * 2;
}
}
setPosition({ x: newX, y: newY });
}, DEBOUNCE_WINDOW_RESIZE_HANDLER_MS);
window.addEventListener('resize', handleMainWindowResize);
return () => window.removeEventListener('resize', handleMainWindowResize);
}, [relativePos]);
useEffect(() => {
function handleResize() {
const element = document.querySelector(`.${FILE_WRAPPER_CLASS}`);
@ -97,7 +150,6 @@ export default function FileRenderFloating(props: Props) {
function handleDragMove(e, ui) {
setWasDragging(true);
const { x, y } = position;
const newX = x + ui.deltaX;
const newY = y + ui.deltaY;
@ -111,6 +163,10 @@ export default function FileRenderFloating(props: Props) {
if (wasDragging) {
e.stopPropagation();
setWasDragging(false);
setRelativePos({
x: position.x / getScreenWidth(),
y: position.y / getScreenHeight(),
});
}
}