diff --git a/static/app-strings.json b/static/app-strings.json index 357f52efe..712de9a86 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -2327,5 +2327,7 @@ "* Note that as\n peer-to-peer software, your IP address and potentially other system information can be sent to other\n users, though this information is not stored permanently.": "* Note that as\n peer-to-peer software, your IP address and potentially other system information can be sent to other\n users, though this information is not stored permanently.", "Persist watch time": "Persist watch time", "Persist the watch time of the videos you have watched.": "Persist the watch time of the videos you have watched.", + "Clearing...": "Clearing...", + "Cache cleared": "Cache cleared", "--end--": "--end--" } diff --git a/ui/component/fileThumbnail/index.js b/ui/component/fileThumbnail/index.js index f657b7e66..c817b8193 100644 --- a/ui/component/fileThumbnail/index.js +++ b/ui/component/fileThumbnail/index.js @@ -1,12 +1,12 @@ import { connect } from 'react-redux'; import { doResolveUri } from 'redux/actions/claims'; import { makeSelectClaimForUri } from 'redux/selectors/claims'; -import { makeSelectContentPositionForUri } from 'redux/selectors/content'; +import { makeSelectContentWatchedPercentageForUri } from 'redux/selectors/content'; import CardMedia from './view'; const select = (state, props) => { return { - position: makeSelectContentPositionForUri(props.uri)(state), + watchedPercentage: makeSelectContentWatchedPercentageForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state), }; }; diff --git a/ui/component/fileThumbnail/view.jsx b/ui/component/fileThumbnail/view.jsx index 1e16cadd1..3a9124950 100644 --- a/ui/component/fileThumbnail/view.jsx +++ b/ui/component/fileThumbnail/view.jsx @@ -16,11 +16,20 @@ type Props = { claim: ?StreamClaim, doResolveUri: (string) => void, className?: string, - position: number | null, + watchedPercentage: number, }; function FileThumbnail(props: Props) { - const { claim, uri, doResolveUri, thumbnail: rawThumbnail, children, allowGifs = false, className, position } = props; + const { + claim, + uri, + doResolveUri, + thumbnail: rawThumbnail, + children, + allowGifs = false, + className, + watchedPercentage, + } = props; const passedThumbnail = rawThumbnail && rawThumbnail.trim().replace(/^http:\/\//i, 'https://'); const thumbnailFromClaim = @@ -30,12 +39,7 @@ function FileThumbnail(props: Props) { const hasResolvedClaim = claim !== undefined; const isGif = thumbnail && thumbnail.endsWith('gif'); - const media = claim && claim.value && (claim.value.video || claim.value.audio); - const duration = media && media.duration; - // When the position is -1, it means the user has watched the entire - // video and he/she is using the persist watch setting. - const watchedPercentage = position === -1 ? 100 : ((position || 0) / (duration || 1)) * 100 || 0; - const viewedBar = position && ( + const viewedBar = watchedPercentage && (
diff --git a/ui/component/settingContent/view.jsx b/ui/component/settingContent/view.jsx index 114c6c3ba..dead73189 100644 --- a/ui/component/settingContent/view.jsx +++ b/ui/component/settingContent/view.jsx @@ -52,6 +52,18 @@ export default function SettingContent(props: Props) { clearPlayingUri, clearContentCache, } = props; + const [contentCacheCleared, setContentCacheCleared] = React.useState(false); + const [clearingContentCache, setClearingContentCache] = React.useState(false); + const onClearContentCache = React.useCallback(() => { + setClearingContentCache(true); + clearContentCache(); + // Just a small timer to give the user a visual effect + // that the content is being cleared. + setTimeout(() => { + setClearingContentCache(false); + setContentCacheCleared(true); + }, 2000); + }, [setClearingContentCache, clearContentCache, setContentCacheCleared]); return ( <> @@ -119,9 +131,15 @@ export default function SettingContent(props: Props) {
diff --git a/ui/redux/actions/content.js b/ui/redux/actions/content.js index a37962c6c..11f0be3fa 100644 --- a/ui/redux/actions/content.js +++ b/ui/redux/actions/content.js @@ -246,7 +246,7 @@ export function clearPosition(uri: string) { if (persistWatchTime) { dispatch({ type: ACTIONS.SET_CONTENT_POSITION, - data: { claimId, outpoint, position: -1 }, + data: { claimId, outpoint, position: null }, }); return; } diff --git a/ui/redux/selectors/content.js b/ui/redux/selectors/content.js index f3d4e9784..6ec055e4a 100644 --- a/ui/redux/selectors/content.js +++ b/ui/redux/selectors/content.js @@ -63,6 +63,31 @@ export const makeSelectContentPositionForUri = (uri: string) => return state.positions[id] ? state.positions[id][outpoint] : null; }); +export const makeSelectContentWatchedPercentageForUri = (uri: string) => + createSelector(selectState, makeSelectClaimForUri(uri), (state, claim) => { + if (!claim) { + return 0; + } + const media = claim.value && (claim.value.video || claim.value.audio); + if (!media) { + return 0; + } + const id = claim.claim_id; + if (!state.positions[id]) { + return 0; + } + const outpoint = `${claim.txid}:${claim.nout}`; + const watched = state.positions[id][outpoint]; + // If the user turns on the persist watch setting, + // clearing the position will set it to null, + // which means the entire video has been watched. + if (watched === null) { + return 100; + } + const duration = media.duration; + return (watched / duration) * 100; + }); + export const selectHistory = createSelector(selectState, (state) => state.history || []); export const selectHistoryPageCount = createSelector(selectHistory, (history) =>