improve fullscreen mode of the viewer
This commit is contained in:
parent
d15a85eaaa
commit
934f3b271a
6 changed files with 84 additions and 10 deletions
|
@ -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
|
||||||
|
|
|
@ -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 ? (
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
|
@ -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>
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,11 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:-webkit-full-screen {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.content__empty {
|
.content__empty {
|
||||||
|
|
Loading…
Add table
Reference in a new issue