Patch to restore position upon returning to video until more fully fleshed out fix can be introduced (#817)
* Patch to restore position upon returning to video until more fully fleshed out fix can be introduced * Add code to notify other open tabs of position saving * Fix typo * Wrap localStorage access in try/catch in event browser settings make it unavailable * Remove formatting changes * Move constant from 'pages' to 'player' * Move dispatch out of try/catch * Fixed typo
This commit is contained in:
parent
65ad2df643
commit
ce903c9280
6 changed files with 36 additions and 4 deletions
|
@ -32,6 +32,7 @@ export type Player = {
|
|||
chromecast: (any) => void,
|
||||
currentTime: (?number) => number,
|
||||
dispose: () => void,
|
||||
duration: () => number,
|
||||
ended: () => boolean,
|
||||
error: () => any,
|
||||
exitFullscreen: () => boolean,
|
||||
|
@ -292,7 +293,7 @@ export default React.memo<Props>(function VideoJs(props: Props) {
|
|||
/** instantiate videoJS and dispose of it when done with code **/
|
||||
// This lifecycle hook is only called once (on mount), or when `isAudio` or `source` changes.
|
||||
useEffect(() => {
|
||||
(async function() {
|
||||
(async function () {
|
||||
// test if perms to play video are available
|
||||
let canAutoplayVideo = await canAutoplay.video({ timeout: 2000, inline: true });
|
||||
|
||||
|
@ -351,7 +352,7 @@ export default React.memo<Props>(function VideoJs(props: Props) {
|
|||
const adsClaimParentDiv = adsClaimDiv.parentNode;
|
||||
|
||||
// watch parent div for when it is on viewport
|
||||
const observer = new IntersectionObserver(function(entries) {
|
||||
const observer = new IntersectionObserver(function (entries) {
|
||||
// when ad div parent becomes visible by 1px, show the ad video
|
||||
if (entries[0].isIntersecting === true) {
|
||||
adsClaimDiv.style.display = 'block';
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
// @flow
|
||||
import { ENABLE_PREROLL_ADS } from 'config';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import { VIDEO_ALMOST_FINISHED_THRESHOLD } from 'constants/player';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import React, { useEffect, useState, useContext, useCallback } from 'react';
|
||||
import { stopContextMenu } from 'util/context-menu';
|
||||
|
@ -265,6 +266,12 @@ function VideoViewer(props: Props) {
|
|||
function onDispose(event, player) {
|
||||
handlePosition(player);
|
||||
analytics.videoIsPlaying(false, player);
|
||||
|
||||
const almostFinished = player.currentTime() / player.duration() >= VIDEO_ALMOST_FINISHED_THRESHOLD;
|
||||
|
||||
if (player.ended() || almostFinished) {
|
||||
clearPosition(permanentUrl);
|
||||
}
|
||||
}
|
||||
|
||||
function handlePosition(player) {
|
||||
|
|
1
ui/constants/player.js
Normal file
1
ui/constants/player.js
Normal file
|
@ -0,0 +1 @@
|
|||
export const VIDEO_ALMOST_FINISHED_THRESHOLD = 0.8;
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import * as PAGES from 'constants/pages';
|
||||
import { VIDEO_ALMOST_FINISHED_THRESHOLD } from 'constants/player';
|
||||
import * as React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { lazyImport } from 'util/lazyImport';
|
||||
|
@ -72,9 +73,9 @@ function FilePage(props: Props) {
|
|||
const durationInSecs =
|
||||
fileInfo && fileInfo.metadata && fileInfo.metadata.video ? fileInfo.metadata.video.duration : 0;
|
||||
const isVideoTooShort = durationInSecs <= 45;
|
||||
const almostFinishedPlaying = position / durationInSecs >= 0.8;
|
||||
const almostFinishedPlaying = position / durationInSecs >= VIDEO_ALMOST_FINISHED_THRESHOLD;
|
||||
|
||||
return isVideoTooShort || almostFinishedPlaying;
|
||||
return durationInSecs ? isVideoTooShort || almostFinishedPlaying : false;
|
||||
}, [fileInfo, position]);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
|
|
@ -220,6 +220,19 @@ export function savePosition(uri: string, position: number) {
|
|||
const { claim_id: claimId, txid, nout } = claim;
|
||||
const outpoint = `${txid}:${nout}`;
|
||||
|
||||
try {
|
||||
localStorage.setItem(
|
||||
ACTIONS.SET_CONTENT_POSITION,
|
||||
JSON.stringify({
|
||||
claimId,
|
||||
outpoint,
|
||||
position,
|
||||
})
|
||||
);
|
||||
} catch (e) {
|
||||
console.error('localStorage not available');
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: ACTIONS.SET_CONTENT_POSITION,
|
||||
data: { claimId, outpoint, position },
|
||||
|
|
|
@ -230,4 +230,13 @@ const store = createStore(
|
|||
const persistor = persistStore(store);
|
||||
window.persistor = persistor;
|
||||
|
||||
window.addEventListener('storage', (e) => {
|
||||
if (e.key === ACTIONS.SET_CONTENT_POSITION) {
|
||||
store.dispatch({
|
||||
type: ACTIONS.SET_CONTENT_POSITION,
|
||||
data: JSON.parse(e.newValue),
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
export { store, persistor, history, whiteListedReducers };
|
||||
|
|
Loading…
Reference in a new issue