Mobile file page, comments and player improvements for rotated landscape view

undo plugin changes
This commit is contained in:
Rafael 2022-04-06 09:01:29 -03:00 committed by Thomas Zarebczan
parent 35c933e7e4
commit 800e735115
7 changed files with 78 additions and 17 deletions

View file

@ -85,3 +85,20 @@ export function getPossiblePlayerHeight(height: number, isMobile: boolean) {
return forceMinHeight; return forceMinHeight;
} }
export function getWindowAngle(cb?: () => void) {
// iOS
if (typeof window.orientation === 'number') {
return window.orientation;
}
// Android
if (screen && screen.orientation && screen.orientation.angle) {
return window.orientation;
}
if (cb) cb();
return 0;
}
export function isWindowLandscapeForAngle(angle: number) {
return angle === 90 || angle === 270 || angle === -90;
}

View file

@ -17,7 +17,7 @@ import { PRIMARY_PLAYER_WRAPPER_CLASS } from 'page/file/view';
import Draggable from 'react-draggable'; import Draggable from 'react-draggable';
import { onFullscreenChange } from 'util/full-screen'; import { onFullscreenChange } from 'util/full-screen';
import { generateListSearchUrlParams, formatLbryChannelName } from 'util/url'; import { generateListSearchUrlParams, formatLbryChannelName } from 'util/url';
import { useIsMobile } from 'effects/use-screensize'; import { useIsMobile, useIsMobileLandscape } from 'effects/use-screensize';
import debounce from 'util/debounce'; import debounce from 'util/debounce';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';
import { isURIEqual } from 'util/lbryURI'; import { isURIEqual } from 'util/lbryURI';
@ -111,6 +111,7 @@ export default function FileRenderFloating(props: Props) {
} = props; } = props;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isLandscapeRotated = useIsMobileLandscape();
const initialMobileState = React.useRef(isMobile); const initialMobileState = React.useRef(isMobile);
const initialPlayerHeight = React.useRef(); const initialPlayerHeight = React.useRef();
@ -368,7 +369,7 @@ export default function FileRenderFloating(props: Props) {
'content__viewer--secondary': isComment, 'content__viewer--secondary': isComment,
'content__viewer--theater-mode': videoTheaterMode && mainFilePlaying && !isCurrentClaimLive && !isMobile, 'content__viewer--theater-mode': videoTheaterMode && mainFilePlaying && !isCurrentClaimLive && !isMobile,
'content__viewer--disable-click': wasDragging, 'content__viewer--disable-click': wasDragging,
'content__viewer--mobile': isMobile && !playingUriSource, 'content__viewer--mobile': isMobile && !isLandscapeRotated && !playingUriSource,
})} })}
style={ style={
!isFloating && fileViewerRect !isFloating && fileViewerRect
@ -388,11 +389,12 @@ export default function FileRenderFloating(props: Props) {
<PlayerGlobalStyles <PlayerGlobalStyles
videoAspectRatio={videoAspectRatio} videoAspectRatio={videoAspectRatio}
videoTheaterMode={videoTheaterMode} videoTheaterMode={videoTheaterMode}
appDrawerOpen={appDrawerOpen} appDrawerOpen={appDrawerOpen && !isLandscapeRotated}
initialPlayerHeight={initialPlayerHeight} initialPlayerHeight={initialPlayerHeight}
isFloating={isFloating} isFloating={isFloating}
fileViewerRect={fileViewerRect} fileViewerRect={fileViewerRect}
mainFilePlaying={mainFilePlaying} mainFilePlaying={mainFilePlaying}
isLandscapeRotated={isLandscapeRotated}
/> />
) : null} ) : null}
@ -450,6 +452,7 @@ type GlobalStylesProps = {
isFloating: boolean, isFloating: boolean,
fileViewerRect: any, fileViewerRect: any,
mainFilePlaying: boolean, mainFilePlaying: boolean,
isLandscapeRotated: boolean,
}; };
const PlayerGlobalStyles = (props: GlobalStylesProps) => { const PlayerGlobalStyles = (props: GlobalStylesProps) => {
@ -461,6 +464,7 @@ const PlayerGlobalStyles = (props: GlobalStylesProps) => {
isFloating, isFloating,
fileViewerRect, fileViewerRect,
mainFilePlaying, mainFilePlaying,
isLandscapeRotated,
} = props; } = props;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@ -481,7 +485,7 @@ const PlayerGlobalStyles = (props: GlobalStylesProps) => {
// Handles video shrink + center on mobile view // Handles video shrink + center on mobile view
// direct DOM manipulation due to performance for every scroll // direct DOM manipulation due to performance for every scroll
React.useEffect(() => { React.useEffect(() => {
if (!isMobilePlayer || !mainFilePlaying || appDrawerOpen) return; if (!isMobilePlayer || !mainFilePlaying || appDrawerOpen || isLandscapeRotated) return;
const viewer = document.querySelector(`.${CONTENT_VIEWER_CLASS}`); const viewer = document.querySelector(`.${CONTENT_VIEWER_CLASS}`);
if (viewer) viewer.style.height = `${heightForViewer}px`; if (viewer) viewer.style.height = `${heightForViewer}px`;
@ -527,7 +531,15 @@ const PlayerGlobalStyles = (props: GlobalStylesProps) => {
window.removeEventListener('scroll', handleScroll); window.removeEventListener('scroll', handleScroll);
}; };
}, [appDrawerOpen, heightForViewer, isMobilePlayer, mainFilePlaying, maxLandscapeHeight, initialPlayerHeight]); }, [
appDrawerOpen,
heightForViewer,
isMobilePlayer,
mainFilePlaying,
maxLandscapeHeight,
initialPlayerHeight,
isLandscapeRotated,
]);
React.useEffect(() => { React.useEffect(() => {
if (appDrawerOpen && videoGreaterThanLandscape && isMobilePlayer) { if (appDrawerOpen && videoGreaterThanLandscape && isMobilePlayer) {
@ -594,7 +606,10 @@ const PlayerGlobalStyles = (props: GlobalStylesProps) => {
}, },
[`.${CONTENT_VIEWER_CLASS}`]: { [`.${CONTENT_VIEWER_CLASS}`]: {
height: !forceDefaults && (!isMobile || isMobilePlayer) ? `${heightResult} !important` : undefined, height:
(!forceDefaults || isLandscapeRotated) && (!isMobile || isMobilePlayer)
? `${heightResult} !important`
: undefined,
...maxHeight, ...maxHeight,
}, },
}} }}

View file

@ -2,7 +2,7 @@
import 'scss/component/_swipeable-drawer.scss'; import 'scss/component/_swipeable-drawer.scss';
import { lazyImport } from 'util/lazyImport'; import { lazyImport } from 'util/lazyImport';
import { useIsMobile } from 'effects/use-screensize'; import { useIsMobile, useIsMobileLandscape } from 'effects/use-screensize';
import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button'; import { Menu, MenuList, MenuButton, MenuItem } from '@reach/menu-button';
import FileTitleSection from 'component/fileTitleSection'; import FileTitleSection from 'component/fileTitleSection';
import LivestreamLink from 'component/livestreamLink'; import LivestreamLink from 'component/livestreamLink';
@ -53,6 +53,7 @@ export default function LivestreamLayout(props: Props) {
} = props; } = props;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isLandscapeRotated = useIsMobileLandscape();
const [superchatsHidden, setSuperchatsHidden] = React.useState(false); const [superchatsHidden, setSuperchatsHidden] = React.useState(false);
const [chatViewMode, setChatViewMode] = React.useState(VIEW_MODES.CHAT); const [chatViewMode, setChatViewMode] = React.useState(VIEW_MODES.CHAT);
@ -100,7 +101,7 @@ export default function LivestreamLayout(props: Props) {
/> />
)} )}
{isMobile && !hideComments && ( {isMobile && !isLandscapeRotated && !hideComments && (
<React.Suspense fallback={null}> <React.Suspense fallback={null}>
<SwipeableDrawer <SwipeableDrawer
title={ title={

View file

@ -3,7 +3,7 @@ import { lazyImport } from 'util/lazyImport';
import { MAIN_CLASS } from 'constants/classnames'; import { MAIN_CLASS } from 'constants/classnames';
import { parseURI } from 'util/lbryURI'; import { parseURI } from 'util/lbryURI';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';
import { useIsMobile, useIsMediumScreen } from 'effects/use-screensize'; import { useIsMobile, useIsMediumScreen, useIsMobileLandscape } from 'effects/use-screensize';
import classnames from 'classnames'; import classnames from 'classnames';
import Header from 'component/header'; import Header from 'component/header';
import React from 'react'; import React from 'react';
@ -65,6 +65,7 @@ function Page(props: Props) {
const isMediumScreen = useIsMediumScreen(); const isMediumScreen = useIsMediumScreen();
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isLandscapeRotated = useIsMobileLandscape();
const [sidebarOpen, setSidebarOpen] = usePersistedState('sidebar', false); const [sidebarOpen, setSidebarOpen] = usePersistedState('sidebar', false);
const url = pathname.slice(1).replace(/:/g, '#'); const url = pathname.slice(1).replace(/:/g, '#');
@ -143,7 +144,7 @@ function Page(props: Props) {
> >
{children} {children}
{!isMobile && (!livestream || !chatDisabled) && rightSide} {(!isMobile || isLandscapeRotated) && (!livestream || !chatDisabled) && rightSide}
</main> </main>
{!noFooter && ( {!noFooter && (

View file

@ -115,7 +115,7 @@ const onPlayerReady = (player, options) => {
screen.orientation.onchange = rotationHandler; screen.orientation.onchange = rotationHandler;
} }
player.on('ended', _ => { player.on('ended', (_) => {
if (locked === true) { if (locked === true) {
screen.orientation.unlock(); screen.orientation.unlock();
locked = false; locked = false;

View file

@ -1,6 +1,7 @@
// @flow // @flow
// Widths are taken from "ui/scss/init/vars.scss" // Widths are taken from "ui/scss/init/vars.scss"
import React, { useRef } from 'react'; import React, { useRef } from 'react';
import { getWindowAngle, isWindowLandscapeForAngle } from 'component/fileRenderFloating/helper-functions';
const DEFAULT_SCREEN_SIZE = 1080; const DEFAULT_SCREEN_SIZE = 1080;
export function useWindowSize() { export function useWindowSize() {
@ -51,6 +52,33 @@ export function useIsMobile() {
return useHasWindowWidthChangedEnough((windowSize) => windowSize < 901); return useHasWindowWidthChangedEnough((windowSize) => windowSize < 901);
} }
export function useIsMobileLandscape() {
const isWindowClient = typeof window === 'object';
const isMobile = useIsMobile();
const windowAngle = getWindowAngle();
const isLandscape = isMobile && isWindowLandscapeForAngle(windowAngle);
const [landscape, setLandscape] = React.useState<boolean>(isLandscape);
React.useEffect(() => {
function handleResize() {
const currAngle = getWindowAngle();
const isCurrLandscape = isMobile && isWindowLandscapeForAngle(currAngle);
if (landscape !== isCurrLandscape) {
setLandscape(isCurrLandscape);
}
}
if (isWindowClient) {
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}
}, [isWindowClient, landscape]);
return landscape;
}
export function useIsMediumScreen() { export function useIsMediumScreen() {
return useHasWindowWidthChangedEnough((windowSize) => windowSize < 1151); return useHasWindowWidthChangedEnough((windowSize) => windowSize < 1151);
} }

View file

@ -16,7 +16,7 @@ import Button from 'component/button';
import Empty from 'component/common/empty'; import Empty from 'component/common/empty';
import SwipeableDrawer from 'component/swipeableDrawer'; import SwipeableDrawer from 'component/swipeableDrawer';
import DrawerExpandButton from 'component/swipeableDrawerExpand'; import DrawerExpandButton from 'component/swipeableDrawerExpand';
import { useIsMobile } from 'effects/use-screensize'; import { useIsMobile, useIsMobileLandscape } from 'effects/use-screensize';
const CommentsList = lazyImport(() => import('component/commentsList' /* webpackChunkName: "comments" */)); const CommentsList = lazyImport(() => import('component/commentsList' /* webpackChunkName: "comments" */));
const PostViewer = lazyImport(() => import('component/postViewer' /* webpackChunkName: "postViewer" */)); const PostViewer = lazyImport(() => import('component/postViewer' /* webpackChunkName: "postViewer" */));
@ -81,8 +81,7 @@ export default function FilePage(props: Props) {
} = props; } = props;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isLandscapeRotated = useIsMobileLandscape();
// Auto-open the drawer on Mobile view if there is a linked comment
const channelSettings = channelId ? settingsByChannelId[channelId] : undefined; const channelSettings = channelId ? settingsByChannelId[channelId] : undefined;
const commentSettingDisabled = channelSettings && !channelSettings.comments_enabled; const commentSettingDisabled = channelSettings && !channelSettings.comments_enabled;
@ -239,7 +238,7 @@ export default function FilePage(props: Props) {
<Empty {...emptyMsgProps} text={__('The creator of this content has disabled comments.')} /> <Empty {...emptyMsgProps} text={__('The creator of this content has disabled comments.')} />
) : commentSettingDisabled ? ( ) : commentSettingDisabled ? (
<Empty {...emptyMsgProps} text={__('This channel has disabled comments on their page.')} /> <Empty {...emptyMsgProps} text={__('This channel has disabled comments on their page.')} />
) : isMobile ? ( ) : isMobile && !isLandscapeRotated ? (
<> <>
<SwipeableDrawer title={commentsListTitle}> <SwipeableDrawer title={commentsListTitle}>
<CommentsList {...commentsListProps} /> <CommentsList {...commentsListProps} />