Save and load watch history
This commit is contained in:
parent
6d4c15f72c
commit
1a7b92c4fa
6 changed files with 41 additions and 76 deletions
|
@ -141,6 +141,7 @@ function App(props: Props) {
|
||||||
const [localeSwitchDismissed] = usePersistedState('locale-switch-dismissed', false);
|
const [localeSwitchDismissed] = usePersistedState('locale-switch-dismissed', false);
|
||||||
const [showAnalyticsNag, setShowAnalyticsNag] = usePersistedState('analytics-nag', true);
|
const [showAnalyticsNag, setShowAnalyticsNag] = usePersistedState('analytics-nag', true);
|
||||||
const [lbryTvApiStatus, setLbryTvApiStatus] = useState(STATUS_OK);
|
const [lbryTvApiStatus, setLbryTvApiStatus] = useState(STATUS_OK);
|
||||||
|
usePersistedState('watch-history', []);
|
||||||
|
|
||||||
const { pathname, hash, search } = props.location;
|
const { pathname, hash, search } = props.location;
|
||||||
const [upgradeNagClosed, setUpgradeNagClosed] = useState(false);
|
const [upgradeNagClosed, setUpgradeNagClosed] = useState(false);
|
||||||
|
|
|
@ -90,7 +90,7 @@ const PLAYLISTS: SideNavLink = {
|
||||||
const HISTORY: SideNavLink = {
|
const HISTORY: SideNavLink = {
|
||||||
title: 'History',
|
title: 'History',
|
||||||
link: `/$/${PAGES.HISTORY}`,
|
link: `/$/${PAGES.HISTORY}`,
|
||||||
icon: ICONS.STACK,
|
icon: ICONS.TIME,
|
||||||
hideForUnauth: true,
|
hideForUnauth: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import debounce from 'util/debounce';
|
||||||
import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
|
import { formatLbryUrlForWeb, generateListSearchUrlParams } from 'util/url';
|
||||||
import useInterval from 'effects/use-interval';
|
import useInterval from 'effects/use-interval';
|
||||||
import { lastBandwidthSelector } from './internal/plugins/videojs-http-streaming--override/playlist-selectors';
|
import { lastBandwidthSelector } from './internal/plugins/videojs-http-streaming--override/playlist-selectors';
|
||||||
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
|
|
||||||
// const PLAY_TIMEOUT_ERROR = 'play_timeout_error';
|
// const PLAY_TIMEOUT_ERROR = 'play_timeout_error';
|
||||||
// const PLAY_TIMEOUT_LIMIT = 2000;
|
// const PLAY_TIMEOUT_LIMIT = 2000;
|
||||||
|
@ -151,6 +152,23 @@ function VideoViewer(props: Props) {
|
||||||
const isFirstRender = React.useRef(true);
|
const isFirstRender = React.useRef(true);
|
||||||
const playerRef = React.useRef(null);
|
const playerRef = React.useRef(null);
|
||||||
|
|
||||||
|
const [history, setHistory] = usePersistedState('watch-history', []);
|
||||||
|
React.useEffect(() => {
|
||||||
|
if (!history[0].indexOf(claim.permanent_url) !== -1) {
|
||||||
|
if (!history || !history.length) {
|
||||||
|
setHistory([claim.permanent_url]);
|
||||||
|
} else {
|
||||||
|
if (history.find((entry) => entry === claim.permanent_url)) {
|
||||||
|
history.splice(history.indexOf(claim.permanent_url), 1);
|
||||||
|
history.unshift(claim.permanent_url);
|
||||||
|
} else {
|
||||||
|
history.unshift(claim.permanent_url);
|
||||||
|
}
|
||||||
|
setHistory(history);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [isPlaying]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isFirstRender.current) {
|
if (isFirstRender.current) {
|
||||||
isFirstRender.current = false;
|
isFirstRender.current = false;
|
||||||
|
@ -288,6 +306,7 @@ function VideoViewer(props: Props) {
|
||||||
setIsEndedEmbed(false);
|
setIsEndedEmbed(false);
|
||||||
setReplay(false);
|
setReplay(false);
|
||||||
setDoNavigate(false);
|
setDoNavigate(false);
|
||||||
|
// setWatchHistory()
|
||||||
analytics.videoIsPlaying(true, player);
|
analytics.videoIsPlaying(true, player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -64,6 +64,9 @@ export default function CollectionPage(props: Props) {
|
||||||
deleteCollection,
|
deleteCollection,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
console.log('collection: ', props.collection);
|
||||||
|
console.log('collectionUrls: ', props.collectionUrls);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
replace,
|
replace,
|
||||||
location: { search },
|
location: { search },
|
||||||
|
|
|
@ -2,20 +2,17 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ClaimList from 'component/claimList';
|
import ClaimList from 'component/claimList';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import * as PAGES from 'constants/pages';
|
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import CollectionEdit from 'component/collectionEdit';
|
|
||||||
import Card from 'component/common/card';
|
import Card from 'component/common/card';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import CollectionActions from 'component/collectionActions';
|
|
||||||
import classnames from 'classnames';
|
import classnames from 'classnames';
|
||||||
import ClaimAuthor from 'component/claimAuthor';
|
|
||||||
import FileDescription from 'component/fileDescription';
|
|
||||||
import * as COLLECTIONS_CONSTS from 'constants/collections';
|
import * as COLLECTIONS_CONSTS from 'constants/collections';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
|
|
||||||
|
import usePersistedState from 'effects/use-persisted-state';
|
||||||
|
|
||||||
// prettier-ignore
|
// prettier-ignore
|
||||||
const Lazy = {
|
const Lazy = {
|
||||||
// $FlowFixMe
|
// $FlowFixMe
|
||||||
|
@ -29,13 +26,10 @@ export const EDIT_PAGE = 'edit';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
collectionId: string,
|
collectionId: string,
|
||||||
uri: string,
|
|
||||||
claim: Claim,
|
claim: Claim,
|
||||||
title: string,
|
title: string,
|
||||||
thumbnail: string,
|
thumbnail: string,
|
||||||
collection: Collection,
|
|
||||||
collectionUrls: Array<string>,
|
collectionUrls: Array<string>,
|
||||||
collectionCount: number,
|
|
||||||
isResolvingCollection: boolean,
|
isResolvingCollection: boolean,
|
||||||
isMyClaim: boolean,
|
isMyClaim: boolean,
|
||||||
isMyCollection: boolean,
|
isMyCollection: boolean,
|
||||||
|
@ -51,11 +45,7 @@ type Props = {
|
||||||
export default function HistoryPage(props: Props) {
|
export default function HistoryPage(props: Props) {
|
||||||
const {
|
const {
|
||||||
collectionId,
|
collectionId,
|
||||||
uri,
|
|
||||||
claim,
|
claim,
|
||||||
collection,
|
|
||||||
collectionUrls,
|
|
||||||
collectionCount,
|
|
||||||
collectionHasEdits,
|
collectionHasEdits,
|
||||||
claimIsPending,
|
claimIsPending,
|
||||||
isResolvingCollection,
|
isResolvingCollection,
|
||||||
|
@ -64,17 +54,21 @@ export default function HistoryPage(props: Props) {
|
||||||
deleteCollection,
|
deleteCollection,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const collection = {
|
||||||
|
id: 'watchhistory',
|
||||||
|
name: __('Watch History'),
|
||||||
|
type: 'playlist',
|
||||||
|
};
|
||||||
|
const collectionUrls = [];
|
||||||
|
|
||||||
|
const [history] = usePersistedState('watch-history', []);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
replace,
|
|
||||||
location: { search },
|
location: { search },
|
||||||
} = useHistory();
|
} = useHistory();
|
||||||
|
|
||||||
const [didTryResolve, setDidTryResolve] = React.useState(false);
|
const [didTryResolve, setDidTryResolve] = React.useState(false);
|
||||||
const [showInfo, setShowInfo] = React.useState(false);
|
|
||||||
const [showEdit, setShowEdit] = React.useState(false);
|
|
||||||
const [unavailableUris, setUnavailable] = React.useState([]);
|
const [unavailableUris, setUnavailable] = React.useState([]);
|
||||||
|
|
||||||
const { name, totalItems } = collection || {};
|
|
||||||
const isBuiltin = COLLECTIONS_CONSTS.BUILTIN_LISTS.includes(collectionId);
|
const isBuiltin = COLLECTIONS_CONSTS.BUILTIN_LISTS.includes(collectionId);
|
||||||
|
|
||||||
function handleOnDragEnd(result) {
|
function handleOnDragEnd(result) {
|
||||||
|
@ -91,8 +85,7 @@ export default function HistoryPage(props: Props) {
|
||||||
const urlParams = new URLSearchParams(search);
|
const urlParams = new URLSearchParams(search);
|
||||||
const editing = urlParams.get(PAGE_VIEW_QUERY) === EDIT_PAGE;
|
const editing = urlParams.get(PAGE_VIEW_QUERY) === EDIT_PAGE;
|
||||||
|
|
||||||
const urlsReady =
|
const urlsReady = collectionUrls && history.length;
|
||||||
collectionUrls && (totalItems === undefined || (totalItems && totalItems === collectionUrls.length));
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (collectionId && !urlsReady && !didTryResolve && !collection) {
|
if (collectionId && !urlsReady && !didTryResolve && !collection) {
|
||||||
|
@ -135,15 +128,6 @@ export default function HistoryPage(props: Props) {
|
||||||
titleActions = pending;
|
titleActions = pending;
|
||||||
}
|
}
|
||||||
|
|
||||||
const subTitle = (
|
|
||||||
<div>
|
|
||||||
<span className="collection__subtitle">
|
|
||||||
{collectionCount === 1 ? __('1 item') : __('%collectionCount% items', { collectionCount })}
|
|
||||||
</span>
|
|
||||||
{uri && <ClaimAuthor uri={uri} />}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
const listName = claim ? claim.value.title || claim.name : collection && collection.name;
|
const listName = claim ? claim.value.title || claim.name : collection && collection.name;
|
||||||
|
|
||||||
const info = (
|
const info = (
|
||||||
|
@ -154,7 +138,7 @@ export default function HistoryPage(props: Props) {
|
||||||
icon={
|
icon={
|
||||||
(collectionId === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
|
(collectionId === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
|
||||||
(collectionId === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) ||
|
(collectionId === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) ||
|
||||||
ICONS.STACK
|
ICONS.TIME
|
||||||
}
|
}
|
||||||
className="icon--margin-right"
|
className="icon--margin-right"
|
||||||
/>
|
/>
|
||||||
|
@ -162,27 +146,6 @@ export default function HistoryPage(props: Props) {
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
titleActions={unavailableUris.length > 0 ? removeUnavailable : titleActions}
|
titleActions={unavailableUris.length > 0 ? removeUnavailable : titleActions}
|
||||||
subtitle={subTitle}
|
|
||||||
body={
|
|
||||||
<CollectionActions
|
|
||||||
uri={uri}
|
|
||||||
collectionId={collectionId}
|
|
||||||
setShowInfo={setShowInfo}
|
|
||||||
showInfo={showInfo}
|
|
||||||
isBuiltin={isBuiltin}
|
|
||||||
collectionUrls={collectionUrls}
|
|
||||||
setShowEdit={setShowEdit}
|
|
||||||
showEdit={showEdit}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
actions={
|
|
||||||
showInfo &&
|
|
||||||
uri && (
|
|
||||||
<div className="section">
|
|
||||||
<FileDescription uri={uri} expandOverride />
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -202,27 +165,6 @@ export default function HistoryPage(props: Props) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (editing) {
|
|
||||||
return (
|
|
||||||
<Page
|
|
||||||
noFooter
|
|
||||||
noSideNavigation={editing}
|
|
||||||
backout={{
|
|
||||||
title: __('%action% %collection%', { collection: name, action: uri ? __('Editing') : __('Publishing') }),
|
|
||||||
simpleTitle: uri ? __('Editing') : __('Publishing'),
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<CollectionEdit
|
|
||||||
uri={uri}
|
|
||||||
collectionId={collectionId}
|
|
||||||
onDone={(id) => {
|
|
||||||
replace(`/$/${PAGES.LIST}/${id}`);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Page>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (urlsReady) {
|
if (urlsReady) {
|
||||||
return (
|
return (
|
||||||
<Page className="playlistPage-wrapper">
|
<Page className="playlistPage-wrapper">
|
||||||
|
@ -234,9 +176,9 @@ export default function HistoryPage(props: Props) {
|
||||||
<Lazy.Droppable droppableId="list__ordering">
|
<Lazy.Droppable droppableId="list__ordering">
|
||||||
{(DroppableProvided) => (
|
{(DroppableProvided) => (
|
||||||
<ClaimList
|
<ClaimList
|
||||||
uris={collectionUrls}
|
uris={history}
|
||||||
collectionId={collectionId}
|
collectionId={collectionId}
|
||||||
showEdit={showEdit}
|
// showEdit={showEdit}
|
||||||
droppableProvided={DroppableProvided}
|
droppableProvided={DroppableProvided}
|
||||||
unavailableUris={unavailableUris}
|
unavailableUris={unavailableUris}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -41,7 +41,7 @@ $nag-error-z-index: 999;
|
||||||
background-color: var(--color-primary);
|
background-color: var(--color-primary);
|
||||||
color: var(--color-white);
|
color: var(--color-white);
|
||||||
z-index: $nag-helpful-z-index;
|
z-index: $nag-helpful-z-index;
|
||||||
border-radius: var(--border-radius);
|
// border-radius: var(--border-radius);
|
||||||
margin-top: var(--spacing-s);
|
margin-top: var(--spacing-s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ $nag-error-z-index: 999;
|
||||||
|
|
||||||
.nag__button--helpful {
|
.nag__button--helpful {
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--color-secondary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue