improve fullscreen mode of the viewer

This commit is contained in:
btzr-io 2019-05-26 00:18:47 -06:00
parent d15a85eaaa
commit 934f3b271a
6 changed files with 84 additions and 10 deletions

View file

@ -15,15 +15,34 @@ type Props = {
openModal: (id: string, { uri: string }) => void, openModal: (id: string, { uri: string }) => void,
claimIsMine: boolean, claimIsMine: boolean,
fileInfo: FileInfo, fileInfo: FileInfo,
showFullscreen: boolean,
}; };
class FileActions extends React.PureComponent<Props> { class FileActions extends React.PureComponent<Props> {
MaximizeViewer() {
// Get viewer container
const viewer = document.getElementsByClassName('content__embedded')[0];
viewer.webkitRequestFullscreen();
}
render() { render() {
const { fileInfo, uri, openModal, claimIsMine, claimId } = this.props; const { fileInfo, uri, openModal, claimIsMine, claimId, showFullscreen } = this.props;
const showDelete = claimIsMine || (fileInfo && Object.keys(fileInfo).length > 0); const showDelete = claimIsMine || (fileInfo && Object.keys(fileInfo).length > 0);
return ( return (
<React.Fragment> <React.Fragment>
{showFullscreen && (
<Tooltip onComponent body={__('Full screen (f)')}>
<Button
button="alt"
description={__('Fullscreen')}
icon={ICONS.FULLSCREEN}
onClick={() => {
this.MaximizeViewer();
}}
/>
</Tooltip>
)}
{showDelete && ( {showDelete && (
<Tooltip onComponent body={__('Delete this file')}> <Tooltip onComponent body={__('Delete this file')}>
<Button <Button

View file

@ -7,10 +7,13 @@ import LoadingScreen from 'component/common/loading-screen';
import PlayButton from './internal/play-button'; import PlayButton from './internal/play-button';
const Player = React.lazy(() => const Player = React.lazy(() =>
import(/* webpackChunkName: "player-legacy" */ import(
'./internal/player') /* webpackChunkName: "player-legacy" */
'./internal/player'
)
); );
const F_KEYCODE = 70;
const SPACE_BAR_KEYCODE = 32; const SPACE_BAR_KEYCODE = 32;
type Props = { type Props = {
@ -49,6 +52,7 @@ type Props = {
insufficientCredits: boolean, insufficientCredits: boolean,
nsfw: boolean, nsfw: boolean,
thumbnail: ?string, thumbnail: ?string,
isPlayableType: boolean,
}; };
class FileViewer extends React.PureComponent<Props> { class FileViewer extends React.PureComponent<Props> {
@ -63,6 +67,8 @@ class FileViewer extends React.PureComponent<Props> {
// Don't add these variables to state because we don't need to re-render when their values change // Don't add these variables to state because we don't need to re-render when their values change
(this: any).startTime = undefined; (this: any).startTime = undefined;
(this: any).playTime = undefined; (this: any).playTime = undefined;
(this: any).container = React.createRef();
} }
componentDidMount() { componentDidMount() {
@ -125,9 +131,40 @@ class FileViewer extends React.PureComponent<Props> {
handleKeyDown(event: SyntheticKeyboardEvent<*>) { handleKeyDown(event: SyntheticKeyboardEvent<*>) {
const { searchBarFocused } = this.props; const { searchBarFocused } = this.props;
if (!searchBarFocused && event.keyCode === SPACE_BAR_KEYCODE) {
event.preventDefault(); // prevent page scroll if (!searchBarFocused) {
this.playContent(); if (event.keyCode === SPACE_BAR_KEYCODE) {
event.preventDefault(); // prevent page scroll
this.playContent();
}
// Handle fullscreen shortcut key (f)
if (event.keyCode === F_KEYCODE) {
this.toggleFullscreen();
}
}
}
toggleFullscreen() {
const { isPlayableType } = this.props;
if (!document.webkitFullscreenElement) {
// Enter fullscreen mode if content is not playable
// Otherwise it should be handle internally on the video player
// or it will break the toggle fullscreen button
if (!isPlayableType) {
this.container.current.webkitRequestFullScreen();
}
// Request fullscreen mode for the video player
// Don't use this with the new player
// @if TARGET='app'
else {
const video = document.getElementsByTagName('video')[0];
video && video.webkitRequestFullscreen();
}
// @endif
} else {
document.webkitExitFullscreen();
} }
} }
@ -257,7 +294,7 @@ class FileViewer extends React.PureComponent<Props> {
const layoverStyle = !shouldObscureNsfw && thumbnail ? { backgroundImage: `url("${thumbnail}")` } : {}; const layoverStyle = !shouldObscureNsfw && thumbnail ? { backgroundImage: `url("${thumbnail}")` } : {};
return ( return (
<div className={classnames('video', {}, className)}> <div className={classnames('video', {}, className)} ref={this.container}>
{isPlaying && ( {isPlaying && (
<div className="content__view"> <div className="content__view">
{!isReadyToPlay ? ( {!isReadyToPlay ? (

View file

@ -41,6 +41,7 @@ export const ACCOUNT = 'User';
export const SETTINGS = 'Settings'; export const SETTINGS = 'Settings';
export const INVITE = 'Users'; export const INVITE = 'Users';
export const FILE = 'File'; export const FILE = 'File';
export const FULLSCREEN = 'Maximize';
export const OPTIONS = 'Sliders'; export const OPTIONS = 'Sliders';
export const YES = 'ThumbsUp'; export const YES = 'ThumbsUp';
export const NO = 'ThumbsDown'; export const NO = 'ThumbsDown';

View file

@ -157,6 +157,13 @@ ipcRenderer.on('window-is-focused', () => {
ipcRenderer.on('devtools-is-opened', () => { ipcRenderer.on('devtools-is-opened', () => {
doLogWarningConsoleMessage(); doLogWarningConsoleMessage();
}); });
// Force exit mode for html5 fullscreen api
// See: https://github.com/electron/electron/issues/18188
remote.getCurrentWindow().on('leave-full-screen', event => {
document.webkitExitFullscreen();
});
// @endif // @endif
document.addEventListener('dragover', event => { document.addEventListener('dragover', event => {

View file

@ -92,7 +92,9 @@ class FilePage extends React.Component<Props> {
setViewed(uri); setViewed(uri);
} }
componentWillReceiveProps(nextProps: Props) { // This is now marked as a react lecacy method:
// https://reactjs.org/docs/react-component.html#unsafe_componentwillmount
UNSAFE_componentWillReceiveProps(nextProps: Props) {
const { fetchFileInfo, uri, setViewed } = this.props; const { fetchFileInfo, uri, setViewed } = this.props;
// @if TARGET='app' // @if TARGET='app'
if (nextProps.fileInfo === undefined) { if (nextProps.fileInfo === undefined) {
@ -152,7 +154,9 @@ class FilePage extends React.Component<Props> {
const shouldObscureThumbnail = obscureNsfw && nsfw; const shouldObscureThumbnail = obscureNsfw && nsfw;
const fileName = fileInfo ? fileInfo.file_name : null; const fileName = fileInfo ? fileInfo.file_name : null;
const mediaType = getMediaType(contentType, fileName); const mediaType = getMediaType(contentType, fileName);
const showFile = PLAYABLE_MEDIA_TYPES.includes(mediaType) || PREVIEW_MEDIA_TYPES.includes(mediaType); const isPreviewType = PREVIEW_MEDIA_TYPES.includes(mediaType);
const isPlayableType = PLAYABLE_MEDIA_TYPES.includes(mediaType);
const showFile = isPlayableType || isPreviewType;
const speechShareable = const speechShareable =
costInfo && costInfo.cost === 0 && contentType && ['video', 'image'].includes(contentType.split('/')[0]); costInfo && costInfo.cost === 0 && contentType && ['video', 'image'].includes(contentType.split('/')[0]);
@ -203,6 +207,7 @@ class FilePage extends React.Component<Props> {
className="content__embedded" className="content__embedded"
uri={uri} uri={uri}
mediaType={mediaType} mediaType={mediaType}
isPlayableType={isPlayableType}
/> />
)} )}
{!showFile && {!showFile &&
@ -288,7 +293,7 @@ class FilePage extends React.Component<Props> {
<div className="media__action-group--large"> <div className="media__action-group--large">
<FileDownloadLink uri={uri} /> <FileDownloadLink uri={uri} />
<FileActions uri={uri} claimId={claim.claim_id} /> <FileActions uri={uri} claimId={claim.claim_id} showFullscreen={isPreviewType} />
</div> </div>
</div> </div>

View file

@ -43,6 +43,11 @@
cursor: pointer; cursor: pointer;
} }
} }
&:-webkit-full-screen {
width: 100%;
height: 100%;
}
} }
.content__empty { .content__empty {