Add Copy List functionality

This commit is contained in:
saltrafael 2021-08-20 10:07:10 -03:00
parent 975b6a3b01
commit 34913e33fc
No known key found for this signature in database
GPG key ID: 9C7F1DC0B0F54515
4 changed files with 120 additions and 19 deletions

View file

@ -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));

View file

@ -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>
}

View file

@ -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'} />

View file

@ -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>
);
};