diff --git a/ui/component/fileThumbnail/index.js b/ui/component/fileThumbnail/index.js index 9dfd3400b..f657b7e66 100644 --- a/ui/component/fileThumbnail/index.js +++ b/ui/component/fileThumbnail/index.js @@ -1,17 +1,12 @@ import { connect } from 'react-redux'; -import * as SETTINGS from 'constants/settings'; import { doResolveUri } from 'redux/actions/claims'; -import { makeSelectClientSetting } from 'redux/selectors/settings'; import { makeSelectClaimForUri } from 'redux/selectors/claims'; -import { makeSelectContentPositionForUri, makeSelectContentPositionPersistedForUri } from 'redux/selectors/content'; +import { makeSelectContentPositionForUri } from 'redux/selectors/content'; import CardMedia from './view'; const select = (state, props) => { - const persistWatchTime = makeSelectClientSetting(SETTINGS.PERSIST_WATCH_TIME)(state); return { - position: persistWatchTime - ? makeSelectContentPositionPersistedForUri(props.uri)(state) - : makeSelectContentPositionForUri(props.uri)(state), + position: makeSelectContentPositionForUri(props.uri)(state), claim: makeSelectClaimForUri(props.uri)(state), }; }; diff --git a/ui/component/fileThumbnail/view.jsx b/ui/component/fileThumbnail/view.jsx index b658ac215..1e16cadd1 100644 --- a/ui/component/fileThumbnail/view.jsx +++ b/ui/component/fileThumbnail/view.jsx @@ -16,7 +16,7 @@ type Props = { claim: ?StreamClaim, doResolveUri: (string) => void, className?: string, - position?: number, + position: number | null, }; function FileThumbnail(props: Props) { @@ -32,9 +32,12 @@ function FileThumbnail(props: Props) { const media = claim && claim.value && (claim.value.video || claim.value.audio); const duration = media && media.duration; - const viewedBar = position && 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 && (
-
+
); diff --git a/ui/component/settingContent/index.js b/ui/component/settingContent/index.js index bfa054385..a934aa76b 100644 --- a/ui/component/settingContent/index.js +++ b/ui/component/settingContent/index.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; import { selectMyChannelUrls } from 'redux/selectors/claims'; import * as SETTINGS from 'constants/settings'; -import { doSetPlayingUri } from 'redux/actions/content'; +import { doSetPlayingUri, clearContentCache } from 'redux/actions/content'; import { doSetClientSetting } from 'redux/actions/settings'; import { selectShowMatureContent, makeSelectClientSetting } from 'redux/selectors/settings'; import { selectUserVerifiedEmail } from 'redux/selectors/user'; @@ -25,6 +25,7 @@ const select = (state) => ({ const perform = (dispatch) => ({ setClientSetting: (key, value) => dispatch(doSetClientSetting(key, value)), clearPlayingUri: () => dispatch(doSetPlayingUri({ uri: null })), + clearContentCache: () => dispatch(clearContentCache()), }); export default connect(select, perform)(SettingContent); diff --git a/ui/component/settingContent/view.jsx b/ui/component/settingContent/view.jsx index a388c345d..114c6c3ba 100644 --- a/ui/component/settingContent/view.jsx +++ b/ui/component/settingContent/view.jsx @@ -32,6 +32,7 @@ type Props = { // --- perform --- setClientSetting: (string, boolean | string | number) => void, clearPlayingUri: () => void, + clearContentCache: () => void, }; export default function SettingContent(props: Props) { @@ -49,6 +50,7 @@ export default function SettingContent(props: Props) { enablePublishPreview, setClientSetting, clearPlayingUri, + clearContentCache, } = props; return ( @@ -105,12 +107,23 @@ export default function SettingContent(props: Props) { /> - setClientSetting(SETTINGS.PERSIST_WATCH_TIME, !persistWatchTime)} - checked={persistWatchTime} - /> +
+ setClientSetting(SETTINGS.PERSIST_WATCH_TIME, !persistWatchTime)} + checked={persistWatchTime} + /> +
+
+
any) => { const state = getState(); const claim = makeSelectClaimForUri(uri)(state); + const persistWatchTime = makeSelectClientSetting(SETTINGS.PERSIST_WATCH_TIME)(state); const { claim_id: claimId, txid, nout } = claim; const outpoint = `${txid}:${nout}`; + if (persistWatchTime) { + dispatch({ + type: ACTIONS.SET_CONTENT_POSITION, + data: { claimId, outpoint, position: -1 }, + }); + return; + } + dispatch({ type: ACTIONS.CLEAR_CONTENT_POSITION, data: { claimId, outpoint }, @@ -249,6 +258,12 @@ export function clearPosition(uri: string) { }; } +export function clearContentCache() { + return { + type: ACTIONS.CLEAR_CONTENT_CACHE, + }; +} + export function doSetContentHistoryItem(uri: string) { return (dispatch: Dispatch) => { dispatch({ diff --git a/ui/redux/reducers/content.js b/ui/redux/reducers/content.js index 9596d5365..72ef10562 100644 --- a/ui/redux/reducers/content.js +++ b/ui/redux/reducers/content.js @@ -55,7 +55,6 @@ reducers[ACTIONS.SET_CONTENT_POSITION] = (state, action) => { [claimId]: { ...state.positions[claimId], [outpoint]: position, - [`${outpoint}:persisted`]: position, }, }, }; @@ -91,6 +90,13 @@ reducers[ACTIONS.CLEAR_CONTENT_POSITION] = (state, action) => { } }; +reducers[ACTIONS.CLEAR_CONTENT_CACHE] = (state, action) => { + return { + ...state, + positions: {}, + }; +}; + reducers[ACTIONS.SET_CONTENT_LAST_VIEWED] = (state, action) => { const { uri, lastViewed } = action.data; const { history } = state; diff --git a/ui/redux/reducers/settings.js b/ui/redux/reducers/settings.js index 3a868b8ab..5eb440a8c 100644 --- a/ui/redux/reducers/settings.js +++ b/ui/redux/reducers/settings.js @@ -67,6 +67,7 @@ const defaultState = { [SETTINGS.FLOATING_PLAYER]: true, [SETTINGS.AUTO_DOWNLOAD]: true, [SETTINGS.HIDE_REPOSTS]: false, + [SETTINGS.PERSIST_WATCH_TIME]: false, // OS [SETTINGS.AUTO_LAUNCH]: true, diff --git a/ui/redux/selectors/content.js b/ui/redux/selectors/content.js index 298f8988f..f3d4e9784 100644 --- a/ui/redux/selectors/content.js +++ b/ui/redux/selectors/content.js @@ -63,16 +63,6 @@ export const makeSelectContentPositionForUri = (uri: string) => return state.positions[id] ? state.positions[id][outpoint] : null; }); -export const makeSelectContentPositionPersistedForUri = (uri: string) => - createSelector(selectState, makeSelectClaimForUri(uri), (state, claim) => { - if (!claim) { - return null; - } - const outpoint = `${claim.txid}:${claim.nout}:persisted`; - const id = claim.claim_id; - return state.positions[id] ? state.positions[id][outpoint] : null; - }); - export const selectHistory = createSelector(selectState, (state) => state.history || []); export const selectHistoryPageCount = createSelector(selectHistory, (history) => diff --git a/ui/scss/component/_settings.scss b/ui/scss/component/_settings.scss index 631e0e606..c5d7241da 100644 --- a/ui/scss/component/_settings.scss +++ b/ui/scss/component/_settings.scss @@ -18,3 +18,13 @@ margin-left: 2.2rem; } } + +.settings { + &__persistWatchTimeCheckbox { + display: flex; + justify-content: end; + } + &__persistWatchTimeClearCache { + text-align: right; + } +}