Add Loop Control for Lists
This commit is contained in:
parent
7b70db4ea7
commit
fe01c4764c
8 changed files with 77 additions and 15 deletions
|
@ -1,7 +1,7 @@
|
|||
import { connect } from 'react-redux';
|
||||
import { makeSelectClaimForUri, SETTINGS, COLLECTIONS_CONSTS, makeSelectNextUrlForCollectionAndUrl } from 'lbry-redux';
|
||||
import { withRouter } from 'react-router';
|
||||
import { makeSelectIsPlayerFloating, makeSelectNextUnplayedRecommended } from 'redux/selectors/content';
|
||||
import { makeSelectIsPlayerFloating, makeSelectNextUnplayedRecommended, selectListLoop } from 'redux/selectors/content';
|
||||
import { makeSelectClientSetting } from 'redux/selectors/settings';
|
||||
import { doSetPlayingUri, doPlayUri } from 'redux/actions/content';
|
||||
import AutoplayCountdown from './view';
|
||||
|
@ -16,10 +16,12 @@ const select = (state, props) => {
|
|||
const { search } = location;
|
||||
const urlParams = new URLSearchParams(search);
|
||||
const collectionId = urlParams.get(COLLECTIONS_CONSTS.COLLECTION_ID);
|
||||
const loopList = selectListLoop(state);
|
||||
const loop = loopList && loopList.collectionId === collectionId && loopList.loop;
|
||||
|
||||
let nextRecommendedUri;
|
||||
if (collectionId) {
|
||||
nextRecommendedUri = makeSelectNextUrlForCollectionAndUrl(collectionId, props.uri)(state);
|
||||
nextRecommendedUri = makeSelectNextUrlForCollectionAndUrl(collectionId, props.uri, loop)(state);
|
||||
} else {
|
||||
nextRecommendedUri = makeSelectNextUnplayedRecommended(props.uri)(state);
|
||||
}
|
||||
|
|
|
@ -7,15 +7,16 @@ import {
|
|||
makeSelectClaimForUri,
|
||||
makeSelectClaimIsMine,
|
||||
} from 'lbry-redux';
|
||||
import {
|
||||
selectPlayingUri,
|
||||
} from 'redux/selectors/content';
|
||||
import { selectPlayingUri, selectListLoop } from 'redux/selectors/content';
|
||||
import { doToggleLoopList } from 'redux/actions/content';
|
||||
|
||||
const select = (state, props) => {
|
||||
const playingUri = selectPlayingUri(state);
|
||||
const playingUrl = playingUri && playingUri.uri;
|
||||
const claim = makeSelectClaimForUri(playingUrl)(state);
|
||||
const url = claim && claim.permanent_url;
|
||||
const loopList = selectListLoop(state);
|
||||
const loop = loopList && loopList.collectionId === props.id && loopList.loop;
|
||||
|
||||
return {
|
||||
url,
|
||||
|
@ -23,7 +24,10 @@ const select = (state, props) => {
|
|||
collectionUrls: makeSelectUrlsForCollectionId(props.id)(state),
|
||||
collectionName: makeSelectNameForCollectionId(props.id)(state),
|
||||
isMine: makeSelectClaimIsMine(url)(state),
|
||||
loop,
|
||||
};
|
||||
};
|
||||
|
||||
export default connect(select)(CollectionContent);
|
||||
export default connect(select, {
|
||||
doToggleLoopList,
|
||||
})(CollectionContent);
|
||||
|
|
|
@ -15,23 +15,42 @@ type Props = {
|
|||
collectionUrls: Array<Claim>,
|
||||
collectionName: string,
|
||||
collection: any,
|
||||
loop: boolean,
|
||||
doToggleLoopList: (string, boolean) => void,
|
||||
createUnpublishedCollection: (string, Array<any>, ?string) => void,
|
||||
};
|
||||
|
||||
export default function CollectionContent(props: Props) {
|
||||
const { collectionUrls, collectionName, id, url } = props;
|
||||
const { collectionUrls, collectionName, id, url, loop, doToggleLoopList } = props;
|
||||
|
||||
return (
|
||||
<Card
|
||||
isBodyList
|
||||
className="file-page__recommended"
|
||||
className="file-page__recommended-collection"
|
||||
title={
|
||||
<span>
|
||||
<Icon
|
||||
icon={(id === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
|
||||
(id === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) || ICONS.STACK}
|
||||
className="icon--margin-right" />
|
||||
{collectionName}
|
||||
</span>
|
||||
<>
|
||||
<span className="file-page__recommended-collection__row">
|
||||
<Icon
|
||||
icon={
|
||||
(id === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
|
||||
(id === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) ||
|
||||
ICONS.STACK
|
||||
}
|
||||
className="icon--margin-right"
|
||||
/>
|
||||
{collectionName}
|
||||
</span>
|
||||
<span className="file-page__recommended-collection__row">
|
||||
<Button
|
||||
button="alt"
|
||||
title="Loop"
|
||||
icon={ICONS.REPEAT}
|
||||
iconColor={loop && 'blue'}
|
||||
className="button--file-action"
|
||||
onClick={() => doToggleLoopList(id, !loop)}
|
||||
/>
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
titleActions={
|
||||
<div className="card__title-actions--link">
|
||||
|
|
|
@ -100,6 +100,7 @@ export const CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI';
|
|||
export const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL';
|
||||
export const RECOMMENDATION_UPDATED = 'RECOMMENDATION_UPDATED';
|
||||
export const RECOMMENDATION_CLICKED = 'RECOMMENDATION_CLICKED';
|
||||
export const TOGGLE_LOOP_LIST = 'TOGGLE_LOOP_LIST';
|
||||
|
||||
// Files
|
||||
export const FILE_LIST_STARTED = 'FILE_LIST_STARTED';
|
||||
|
|
|
@ -16,6 +16,7 @@ import {
|
|||
makeSelectClaimForUri,
|
||||
makeSelectClaimIsMine,
|
||||
makeSelectClaimWasPurchased,
|
||||
doToast,
|
||||
} from 'lbry-redux';
|
||||
import { makeSelectCostInfoForUri, Lbryio } from 'lbryinc';
|
||||
import { makeSelectClientSetting, selectosNotificationsEnabled, selectDaemonSettings } from 'redux/selectors/settings';
|
||||
|
@ -279,3 +280,19 @@ export const doRecommendationClicked = (claimId: string, index: number) => (disp
|
|||
});
|
||||
}
|
||||
};
|
||||
|
||||
export function doToggleLoopList(collectionId: string, loop: boolean, hideToast: boolean) {
|
||||
return (dispatch: Dispatch) => {
|
||||
dispatch({
|
||||
type: ACTIONS.TOGGLE_LOOP_LIST,
|
||||
data: { collectionId, loop },
|
||||
});
|
||||
if (loop && !hideToast) {
|
||||
dispatch(
|
||||
doToast({
|
||||
message: __('Loop is on.'),
|
||||
})
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -29,6 +29,14 @@ reducers[ACTIONS.SET_PLAYING_URI] = (state, action) =>
|
|||
},
|
||||
});
|
||||
|
||||
reducers[ACTIONS.TOGGLE_LOOP_LIST] = (state, action) =>
|
||||
Object.assign({}, state, {
|
||||
loopList: {
|
||||
collectionId: action.data.collectionId,
|
||||
loop: action.data.loop,
|
||||
},
|
||||
});
|
||||
|
||||
reducers[ACTIONS.SET_CONTENT_POSITION] = (state, action) => {
|
||||
const { claimId, outpoint, position } = action.data;
|
||||
return {
|
||||
|
|
|
@ -29,6 +29,8 @@ export const selectState = (state: any) => state.content || {};
|
|||
export const selectPlayingUri = createSelector(selectState, (state) => state.playingUri);
|
||||
export const selectPrimaryUri = createSelector(selectState, (state) => state.primaryUri);
|
||||
|
||||
export const selectListLoop = createSelector(selectState, (state) => state.loopList);
|
||||
|
||||
export const makeSelectIsPlaying = (uri: string) =>
|
||||
createSelector(selectPrimaryUri, (primaryUri) => primaryUri === uri);
|
||||
|
||||
|
|
|
@ -133,6 +133,15 @@
|
|||
}
|
||||
}
|
||||
|
||||
.file-page__recommended-collection {
|
||||
@extend .file-page__recommended;
|
||||
flex-direction: column;
|
||||
|
||||
.file-page__recommended-collection__row {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: $breakpoint-medium) {
|
||||
flex-direction: column;
|
||||
> :first-child {
|
||||
|
|
Loading…
Add table
Reference in a new issue