Replace local sorage with redux

This commit is contained in:
Raphael Wickihalder 2022-05-04 12:24:13 +02:00 committed by Thomas Zarebczan
parent f3fd0ba08f
commit d3fc96d961
7 changed files with 41 additions and 28 deletions

View file

@ -141,7 +141,6 @@ 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);

View file

@ -21,6 +21,7 @@ import { selectIsSubscribedForUri } from 'redux/selectors/subscriptions';
import { isClaimNsfw, isStreamPlaceholderClaim } from 'util/claim'; import { isClaimNsfw, isStreamPlaceholderClaim } from 'util/claim';
import ClaimPreview from './view'; import ClaimPreview from './view';
import formatMediaDuration from 'util/formatMediaDuration'; import formatMediaDuration from 'util/formatMediaDuration';
import { doClearContentHistoryUri } from 'redux/actions/content';
const select = (state, props) => { const select = (state, props) => {
const claim = props.uri && selectClaimForUri(state, props.uri); const claim = props.uri && selectClaimForUri(state, props.uri);
@ -55,6 +56,7 @@ const select = (state, props) => {
const perform = (dispatch) => ({ const perform = (dispatch) => ({
resolveUri: (uri) => dispatch(doResolveUri(uri)), resolveUri: (uri) => dispatch(doResolveUri(uri)),
getFile: (uri) => dispatch(doFileGet(uri, false)), getFile: (uri) => dispatch(doFileGet(uri, false)),
doClearContentHistoryUri: (uri) => dispatch(doClearContentHistoryUri(uri)),
}); });
export default connect(select, perform)(ClaimPreview); export default connect(select, perform)(ClaimPreview);

View file

@ -37,7 +37,6 @@ import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import CollectionEditButtons from 'component/collectionEditButtons'; import CollectionEditButtons from 'component/collectionEditButtons';
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import { useIsMobile } from 'effects/use-screensize'; import { useIsMobile } from 'effects/use-screensize';
import usePersistedState from 'effects/use-persisted-state';
const AbandonedChannelPreview = lazyImport(() => const AbandonedChannelPreview = lazyImport(() =>
import('component/abandonedChannelPreview' /* webpackChunkName: "abandonedChannelPreview" */) import('component/abandonedChannelPreview' /* webpackChunkName: "abandonedChannelPreview" */)
@ -98,6 +97,7 @@ type Props = {
unavailableUris?: Array<string>, unavailableUris?: Array<string>,
showMemberBadge?: boolean, showMemberBadge?: boolean,
inWatchHistory?: boolean, inWatchHistory?: boolean,
doClearContentHistoryUri: (uri: string) => void,
}; };
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => { const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
@ -164,6 +164,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
unavailableUris, unavailableUris,
showMemberBadge, showMemberBadge,
inWatchHistory, inWatchHistory,
doClearContentHistoryUri,
} = props; } = props;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@ -214,7 +215,6 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
? claim.permanent_url || claim.canonical_url ? claim.permanent_url || claim.canonical_url
: undefined; : undefined;
const repostedContentUri = claim && (claim.reposted_claim ? claim.reposted_claim.permanent_url : claim.permanent_url); const repostedContentUri = claim && (claim.reposted_claim ? claim.reposted_claim.permanent_url : claim.permanent_url);
const [watchHistory, setWatchHistory] = usePersistedState('watch-history', []);
// Get channel title ( use name as fallback ) // Get channel title ( use name as fallback )
let channelTitle = null; let channelTitle = null;
@ -298,10 +298,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
function removeFromHistory(e, uri) { function removeFromHistory(e, uri) {
e.stopPropagation(); e.stopPropagation();
if (watchHistory.find((entry) => entry === uri)) { doClearContentHistoryUri(uri);
watchHistory.splice(watchHistory.indexOf(uri), 1);
setWatchHistory(watchHistory);
}
} }
useEffect(() => { useEffect(() => {

View file

@ -16,7 +16,13 @@ import {
doAnalyticsView, doAnalyticsView,
} from 'redux/actions/app'; } from 'redux/actions/app';
import { selectVolume, selectMute } from 'redux/selectors/app'; import { selectVolume, selectMute } from 'redux/selectors/app';
import { savePosition, clearPosition, doPlayUri, doSetPlayingUri } from 'redux/actions/content'; import {
savePosition,
clearPosition,
doPlayUri,
doSetPlayingUri,
doSetContentHistoryItem,
} from 'redux/actions/content';
import { makeSelectIsPlayerFloating, selectContentPositionForUri, selectPlayingUri } from 'redux/selectors/content'; import { makeSelectIsPlayerFloating, selectContentPositionForUri, selectPlayingUri } from 'redux/selectors/content';
import { selectRecommendedContentForUri } from 'redux/selectors/search'; import { selectRecommendedContentForUri } from 'redux/selectors/search';
import VideoViewer from './view'; import VideoViewer from './view';
@ -104,6 +110,7 @@ const perform = (dispatch) => ({
doAnalyticsView: (uri, timeToStart) => dispatch(doAnalyticsView(uri, timeToStart)), doAnalyticsView: (uri, timeToStart) => dispatch(doAnalyticsView(uri, timeToStart)),
claimRewards: () => dispatch(doClaimEligiblePurchaseRewards()), claimRewards: () => dispatch(doClaimEligiblePurchaseRewards()),
doToast: (props) => dispatch(doToast(props)), doToast: (props) => dispatch(doToast(props)),
doSetContentHistoryItem: (uri) => dispatch(doSetContentHistoryItem(uri)),
}); });
export default withRouter(connect(select, perform)(VideoViewer)); export default withRouter(connect(select, perform)(VideoViewer));

View file

@ -29,7 +29,6 @@ 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;
@ -73,6 +72,9 @@ type Props = {
activeLivestreamForChannel: any, activeLivestreamForChannel: any,
defaultQuality: ?string, defaultQuality: ?string,
doToast: ({ message: string, linkText: string, linkTarget: string }) => void, doToast: ({ message: string, linkText: string, linkTarget: string }) => void,
selectHistory: Array<string>,
doSetContentHistoryItem: (uri: string) => void,
doClearContentHistoryUri: (uri: string) => void,
}; };
/* /*
@ -119,6 +121,7 @@ function VideoViewer(props: Props) {
activeLivestreamForChannel, activeLivestreamForChannel,
defaultQuality, defaultQuality,
doToast, doToast,
doSetContentHistoryItem,
} = props; } = props;
const permanentUrl = claim && claim.permanent_url; const permanentUrl = claim && claim.permanent_url;
@ -152,21 +155,9 @@ 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 [watchHistory, setWatchHistory] = usePersistedState('watch-history', []);
React.useEffect(() => { React.useEffect(() => {
if (!watchHistory[0] || !watchHistory[0].indexOf(claim.permanent_url) !== -1) { if (isPlaying) {
if (!watchHistory || !watchHistory.length) { doSetContentHistoryItem(claim.permanent_url);
setWatchHistory([claim.permanent_url]);
} else {
let newWatchHistory = watchHistory;
if (newWatchHistory.find((entry) => entry === claim.permanent_url)) {
newWatchHistory.splice(newWatchHistory.indexOf(claim.permanent_url), 1);
newWatchHistory.unshift(claim.permanent_url);
} else {
newWatchHistory.unshift(claim.permanent_url);
}
setWatchHistory(newWatchHistory);
}
} }
}, [isPlaying]); }, [isPlaying]);

View file

@ -10,6 +10,10 @@ import {
makeSelectChannelForClaimUri, makeSelectChannelForClaimUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { selectHistory } from 'redux/selectors/content';
import { doClearContentHistoryAll } from 'redux/actions/content';
import { import {
makeSelectCollectionForId, makeSelectCollectionForId,
makeSelectUrlsForCollectionId, makeSelectUrlsForCollectionId,
@ -38,6 +42,7 @@ const select = (state, props) => {
collectionUrls: makeSelectUrlsForCollectionId(collectionId)(state), collectionUrls: makeSelectUrlsForCollectionId(collectionId)(state),
collectionCount: makeSelectCountForCollectionId(collectionId)(state), collectionCount: makeSelectCountForCollectionId(collectionId)(state),
isResolvingCollection: makeSelectIsResolvingCollectionForId(collectionId)(state), isResolvingCollection: makeSelectIsResolvingCollectionForId(collectionId)(state),
selectHistory: selectHistory(state, uri),
title: selectTitleForUri(state, uri), title: selectTitleForUri(state, uri),
thumbnail: getThumbnailFromClaim(claim), thumbnail: getThumbnailFromClaim(claim),
isMyClaim: selectClaimIsMine(state, claim), // or collection is mine? isMyClaim: selectClaimIsMine(state, claim), // or collection is mine?
@ -51,6 +56,7 @@ const select = (state, props) => {
}; };
const perform = (dispatch) => ({ const perform = (dispatch) => ({
doClearContentHistoryAll: () => dispatch(doClearContentHistoryAll()),
fetchCollectionItems: (claimId, cb) => dispatch(doFetchItemsInCollection({ collectionId: claimId }, cb)), // if this collection is not resolved, resolve it fetchCollectionItems: (claimId, cb) => dispatch(doFetchItemsInCollection({ collectionId: claimId }, cb)), // if this collection is not resolved, resolve it
deleteCollection: (id, colKey) => dispatch(doCollectionDelete(id, colKey)), deleteCollection: (id, colKey) => dispatch(doCollectionDelete(id, colKey)),
editCollection: (id, params) => dispatch(doCollectionEdit(id, params)), editCollection: (id, params) => dispatch(doCollectionEdit(id, params)),

View file

@ -1,5 +1,5 @@
// @flow // @flow
import React from 'react'; import React, { useState } from 'react';
import ClaimList from 'component/claimList'; import ClaimList from 'component/claimList';
import Page from 'component/page'; import Page from 'component/page';
import Button from 'component/button'; import Button from 'component/button';
@ -8,7 +8,6 @@ import Icon from 'component/common/icon';
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
import { YRBL_SAD_IMG_URL } from 'config'; import { YRBL_SAD_IMG_URL } from 'config';
import Tooltip from 'component/common/tooltip'; import Tooltip from 'component/common/tooltip';
import usePersistedState from 'effects/use-persisted-state';
export const PAGE_VIEW_QUERY = 'view'; export const PAGE_VIEW_QUERY = 'view';
@ -19,20 +18,32 @@ type Props = {
thumbnail: string, thumbnail: string,
collectionUrls: Array<string>, collectionUrls: Array<string>,
isResolvingCollection: boolean, isResolvingCollection: boolean,
selectHistory: Array<any>,
doClearContentHistoryAll: () => void,
fetchCollectionItems: (string, () => void) => void, fetchCollectionItems: (string, () => void) => void,
resolveUris: (string) => void, resolveUris: (string) => void,
user: ?User, user: ?User,
}; };
export default function WatchHistoryPage(props: Props) { export default function WatchHistoryPage(props: Props) {
const { collectionId } = props; const { collectionId, selectHistory, doClearContentHistoryAll } = props;
const [watchHistory, setWatchHistory] = usePersistedState('watch-history', []); const [watchHistory, setWatchHistory] = useState([]);
const [unavailableUris] = React.useState([]); const [unavailableUris] = React.useState([]);
function clearHistory() { function clearHistory() {
setWatchHistory([]); doClearContentHistoryAll();
} }
React.useEffect(() => {
let newWatchHistory = [];
for (let entry of selectHistory) {
if (entry.uri.indexOf('@') !== -1) {
newWatchHistory.push(entry.uri);
}
}
setWatchHistory(newWatchHistory);
}, [selectHistory]);
return ( return (
<Page className="historyPage-wrapper"> <Page className="historyPage-wrapper">
<div className={classnames('section card-stack')}> <div className={classnames('section card-stack')}>