Add Copy List functionality
This commit is contained in:
parent
975b6a3b01
commit
34913e33fc
4 changed files with 120 additions and 19 deletions
|
@ -2,22 +2,42 @@ import { connect } from 'react-redux';
|
|||
import ClaimCollectionAdd from './view';
|
||||
import { withRouter } from 'react-router';
|
||||
import {
|
||||
doResolveUris,
|
||||
makeSelectClaimForUri,
|
||||
doLocalCollectionCreate,
|
||||
selectBuiltinCollections,
|
||||
selectMyPublishedCollections,
|
||||
selectMyUnpublishedCollections,
|
||||
doCollectionEdit,
|
||||
makeSelectUrlsForCollectionId,
|
||||
} from 'lbry-redux';
|
||||
|
||||
const select = (state, props) => ({
|
||||
claim: makeSelectClaimForUri(props.uri)(state),
|
||||
builtin: selectBuiltinCollections(state),
|
||||
published: selectMyPublishedCollections(state),
|
||||
unpublished: selectMyUnpublishedCollections(state),
|
||||
});
|
||||
const select = (state, props) => {
|
||||
const collectionId = props.collectionId;
|
||||
let items;
|
||||
let itemsClaims = [];
|
||||
|
||||
if (collectionId) {
|
||||
items = makeSelectUrlsForCollectionId(collectionId)(state);
|
||||
items.map((uri) => {
|
||||
itemsClaims.push(makeSelectClaimForUri(uri)(state));
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
claim: makeSelectClaimForUri(props.uri)(state),
|
||||
builtin: selectBuiltinCollections(state),
|
||||
published: selectMyPublishedCollections(state),
|
||||
unpublished: selectMyUnpublishedCollections(state),
|
||||
items,
|
||||
itemsClaims,
|
||||
};
|
||||
};
|
||||
|
||||
const perform = (dispatch) => ({
|
||||
addCollection: (name, items, type) => dispatch(doLocalCollectionCreate(name, items, type)),
|
||||
editCollection: (id, params) => dispatch(doCollectionEdit(id, params)),
|
||||
doResolveUris: (uris) => dispatch(doResolveUris(uris)),
|
||||
});
|
||||
|
||||
export default withRouter(connect(select, perform)(ClaimCollectionAdd));
|
||||
|
|
|
@ -13,16 +13,33 @@ type Props = {
|
|||
published: any,
|
||||
unpublished: any,
|
||||
addCollection: (string, Array<string>, string) => void,
|
||||
editCollection: (string, {}) => void,
|
||||
closeModal: () => void,
|
||||
uri: string,
|
||||
collectionId: string,
|
||||
doResolveUris: (Array<string>) => void,
|
||||
items: Array<string>,
|
||||
itemsClaims: Array<string>,
|
||||
};
|
||||
|
||||
const ClaimCollectionAdd = (props: Props) => {
|
||||
const { builtin, published, unpublished, addCollection, claim, closeModal, uri } = props;
|
||||
const {
|
||||
builtin,
|
||||
published,
|
||||
unpublished,
|
||||
addCollection,
|
||||
editCollection,
|
||||
claim,
|
||||
closeModal,
|
||||
uri,
|
||||
doResolveUris,
|
||||
items,
|
||||
itemsClaims,
|
||||
} = props;
|
||||
const buttonref: ElementRef<any> = React.useRef();
|
||||
const permanentUrl = claim && claim.permanent_url;
|
||||
const isChannel = claim && claim.value_type === 'channel';
|
||||
|
||||
const [selectedCollections, setSelectedCollections] = React.useState([]);
|
||||
const [addNewCollection, setAddNewCollection] = React.useState(false);
|
||||
const [newCollectionName, setNewCollectionName] = React.useState('');
|
||||
|
||||
|
@ -34,17 +51,32 @@ const ClaimCollectionAdd = (props: Props) => {
|
|||
// claim.value.stream_type &&
|
||||
// (claim.value.stream_type === 'audio' || claim.value.stream_type === 'video');
|
||||
|
||||
React.useEffect(() => {
|
||||
if (items) {
|
||||
doResolveUris(items);
|
||||
}
|
||||
}, [doResolveUris, items]);
|
||||
|
||||
function handleNameInput(e) {
|
||||
const { value } = e.target;
|
||||
setNewCollectionName(value);
|
||||
}
|
||||
|
||||
function handleAddCollection() {
|
||||
addCollection(newCollectionName, [permanentUrl], isChannel ? 'collection' : 'playlist');
|
||||
addCollection(newCollectionName, items || [permanentUrl], isChannel ? 'collection' : 'playlist');
|
||||
if (items) setSelectedCollections([...selectedCollections, newCollectionName]);
|
||||
setNewCollectionName('');
|
||||
setAddNewCollection(false);
|
||||
}
|
||||
|
||||
function handleEditCollection() {
|
||||
if (selectedCollections) {
|
||||
selectedCollections.map((id) => {
|
||||
editCollection(id, { claims: itemsClaims, remove: false });
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function altEnterListener(e: SyntheticKeyboardEvent<*>) {
|
||||
const KEYCODE_ENTER = 13;
|
||||
if (e.keyCode === KEYCODE_ENTER) {
|
||||
|
@ -71,7 +103,7 @@ const ClaimCollectionAdd = (props: Props) => {
|
|||
title={__('Add To...')}
|
||||
actions={
|
||||
<div className="card__body">
|
||||
{uri && (
|
||||
{(uri || items) && (
|
||||
<fieldset-section>
|
||||
<div className={'card__body-scrollable'}>
|
||||
{(Object.values(builtin): any)
|
||||
|
@ -86,6 +118,9 @@ const ClaimCollectionAdd = (props: Props) => {
|
|||
uri={permanentUrl}
|
||||
key={id}
|
||||
category={'builtin'}
|
||||
setSelectedCollections={setSelectedCollections}
|
||||
selectedCollections={selectedCollections}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@ -102,6 +137,9 @@ const ClaimCollectionAdd = (props: Props) => {
|
|||
uri={permanentUrl}
|
||||
key={id}
|
||||
category={'unpublished'}
|
||||
setSelectedCollections={setSelectedCollections}
|
||||
selectedCollections={selectedCollections}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@ -116,6 +154,9 @@ const ClaimCollectionAdd = (props: Props) => {
|
|||
uri={permanentUrl}
|
||||
key={id}
|
||||
category={'published'}
|
||||
setSelectedCollections={setSelectedCollections}
|
||||
selectedCollections={selectedCollections}
|
||||
items={items}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
|
@ -158,7 +199,17 @@ const ClaimCollectionAdd = (props: Props) => {
|
|||
)}
|
||||
</fieldset-section>
|
||||
<div className="card__actions">
|
||||
<Button button="secondary" label={__('Done')} disabled={addNewCollection} onClick={closeModal} />
|
||||
<Button
|
||||
button="secondary"
|
||||
label={__('Done')}
|
||||
disabled={addNewCollection}
|
||||
onClick={() => {
|
||||
if (items) {
|
||||
handleEditCollection();
|
||||
}
|
||||
closeModal();
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -13,19 +13,48 @@ type Props = {
|
|||
editCollection: (string, CollectionEditParams) => void,
|
||||
claim: Claim,
|
||||
collectionPending: Collection,
|
||||
setSelectedCollections: (any) => void,
|
||||
selectedCollections: Array<string>,
|
||||
items: Array<string>,
|
||||
};
|
||||
|
||||
function CollectionSelectItem(props: Props) {
|
||||
const { collection, hasClaim, category, editCollection, claim, collectionPending } = props;
|
||||
const {
|
||||
collection,
|
||||
hasClaim,
|
||||
category,
|
||||
editCollection,
|
||||
claim,
|
||||
collectionPending,
|
||||
setSelectedCollections,
|
||||
selectedCollections,
|
||||
items,
|
||||
} = props;
|
||||
const { name, id } = collection;
|
||||
const handleChange = (e) => {
|
||||
editCollection(id, { claims: [claim], remove: hasClaim });
|
||||
const justAdded = selectedCollections.includes(name);
|
||||
const [active, setActive] = React.useState(justAdded);
|
||||
|
||||
const handleChange = () => {
|
||||
if (items) {
|
||||
if (active) {
|
||||
selectedCollections.splice(selectedCollections.indexOf(id), 1);
|
||||
setSelectedCollections([...selectedCollections]);
|
||||
} else {
|
||||
setSelectedCollections([...selectedCollections, id]);
|
||||
}
|
||||
setActive(!active);
|
||||
} else {
|
||||
editCollection(id, { claims: [claim], remove: hasClaim });
|
||||
}
|
||||
};
|
||||
|
||||
let icon;
|
||||
switch (category) {
|
||||
case 'builtin':
|
||||
icon = (id === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) || (id === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) || ICONS.STACK;
|
||||
icon =
|
||||
(id === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
|
||||
(id === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) ||
|
||||
ICONS.STACK;
|
||||
break;
|
||||
case 'published':
|
||||
icon = ICONS.STACK;
|
||||
|
@ -39,12 +68,12 @@ function CollectionSelectItem(props: Props) {
|
|||
return (
|
||||
<div className={'collection-select__item'}>
|
||||
<FormField
|
||||
checked={hasClaim}
|
||||
checked={items ? active : hasClaim}
|
||||
disabled={collectionPending}
|
||||
icon={icon}
|
||||
type="checkbox"
|
||||
name={`select-${id}`}
|
||||
onChange={handleChange} // edit the collection
|
||||
onChange={!justAdded && handleChange} // edit the collection
|
||||
label={
|
||||
<span>
|
||||
<Icon icon={icon} className={'icon-collection-select'} />
|
||||
|
|
|
@ -6,13 +6,14 @@ import { Modal } from 'modal/modal';
|
|||
type Props = {
|
||||
doHideModal: () => void,
|
||||
uri: string,
|
||||
collectionId: string,
|
||||
};
|
||||
|
||||
const ModalClaimCollectionAdd = (props: Props) => {
|
||||
const { doHideModal, uri } = props;
|
||||
const { doHideModal, uri, collectionId } = props;
|
||||
return (
|
||||
<Modal isOpen type="card" onAborted={doHideModal}>
|
||||
<ClaimCollectionAdd uri={uri} closeModal={doHideModal} />
|
||||
<ClaimCollectionAdd uri={uri} closeModal={doHideModal} collectionId={collectionId} />
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue