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:
David Granado 2022-02-07 11:51:26 -06:00 committed by GitHub
parent 65ad2df643
commit ce903c9280
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 36 additions and 4 deletions

View file

@ -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';

View file

@ -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
View file

@ -0,0 +1 @@
export const VIDEO_ALMOST_FINISHED_THRESHOLD = 0.8;

View file

@ -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(() => {

View file

@ -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 },

View file

@ -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 };