diff --git a/ui/component/claimCollectionAdd/index.js b/ui/component/claimCollectionAdd/index.js index 8aba56b2c..3fd17c245 100644 --- a/ui/component/claimCollectionAdd/index.js +++ b/ui/component/claimCollectionAdd/index.js @@ -19,9 +19,11 @@ const select = (state, props) => { if (collectionId) { items = makeSelectUrlsForCollectionId(collectionId)(state); - items.map((uri) => { - itemsClaims.push(makeSelectClaimForUri(uri)(state)); - }); + if (items) { + items.map((uri) => { + itemsClaims.push(makeSelectClaimForUri(uri)(state)); + }); + } } return { diff --git a/ui/component/claimMenuList/index.js b/ui/component/claimMenuList/index.js index 262a356f5..e1541d540 100644 --- a/ui/component/claimMenuList/index.js +++ b/ui/component/claimMenuList/index.js @@ -9,6 +9,8 @@ import { COLLECTIONS_CONSTS, makeSelectEditedCollectionForId, makeSelectClaimIsMine, + doFetchItemsInCollection, + makeSelectUrlsForCollectionId, } from 'lbry-redux'; import { makeSelectChannelIsMuted } from 'redux/selectors/blocked'; import { doChannelMute, doChannelUnmute } from 'redux/actions/blocked'; @@ -33,6 +35,8 @@ import fs from 'fs'; const select = (state, props) => { const claim = makeSelectClaimForUri(props.uri, false)(state); + const collectionId = props.collectionId; + const resolvedList = makeSelectUrlsForCollectionId(collectionId)(state); const repostedClaim = claim && claim.reposted_claim; const contentClaim = repostedClaim || claim; const contentSigningChannel = contentClaim && contentClaim.signing_channel; @@ -60,10 +64,11 @@ const select = (state, props) => { isSubscribed: makeSelectIsSubscribed(contentChannelUri, true)(state), channelIsAdminBlocked: makeSelectChannelIsAdminBlocked(props.uri)(state), isAdmin: selectHasAdminChannel(state), - claimInCollection: makeSelectCollectionForIdHasClaimUrl(props.collectionId, contentPermanentUri)(state), - isMyCollection: makeSelectCollectionIsMine(props.collectionId)(state), - editedCollection: makeSelectEditedCollectionForId(props.collectionId)(state), + claimInCollection: makeSelectCollectionForIdHasClaimUrl(collectionId, contentPermanentUri)(state), + isMyCollection: makeSelectCollectionIsMine(collectionId)(state), + editedCollection: makeSelectEditedCollectionForId(collectionId)(state), isAuthenticated: Boolean(selectUserVerifiedEmail(state)), + resolvedList, }; }; @@ -90,6 +95,7 @@ const perform = (dispatch) => ({ doChannelSubscribe: (subscription) => dispatch(doChannelSubscribe(subscription)), doChannelUnsubscribe: (subscription) => dispatch(doChannelUnsubscribe(subscription)), doCollectionEdit: (collection, props) => dispatch(doCollectionEdit(collection, props)), + fetchCollectionItems: (collectionId) => dispatch(doFetchItemsInCollection({ collectionId })), }); export default connect(select, perform)(ClaimPreview); diff --git a/ui/component/claimMenuList/view.jsx b/ui/component/claimMenuList/view.jsx index 4ab197178..f12fba09d 100644 --- a/ui/component/claimMenuList/view.jsx +++ b/ui/component/claimMenuList/view.jsx @@ -56,6 +56,8 @@ type Props = { isChannelPage: boolean, editedCollection: Collection, isAuthenticated: boolean, + fetchCollectionItems: (string) => void, + resolvedList: boolean, }; function ClaimMenuList(props: Props) { @@ -93,6 +95,8 @@ function ClaimMenuList(props: Props) { isChannelPage = false, editedCollection, isAuthenticated, + fetchCollectionItems, + resolvedList, } = props; const incognitoClaim = contentChannelUri && !contentChannelUri.includes('@'); const isChannel = !incognitoClaim && !contentSigningChannel; @@ -106,6 +110,12 @@ function ClaimMenuList(props: Props) { ? __('Unfollow') : __('Follow'); + const fetchItems = React.useCallback(() => { + if (collectionId) { + fetchCollectionItems(collectionId); + } + }, [collectionId, fetchCollectionItems]); + const { push, replace } = useHistory(); if (!claim) { return null; @@ -251,6 +261,18 @@ function ClaimMenuList(props: Props) { {__('View List')} + { + fetchItems(); + openModal(MODALS.COLLECTION_ADD, { collectionId }); + }} + > + + + {__('Copy List')} + + {isMyCollection && ( <> { const playingUri = selectPlayingUri(state); @@ -26,4 +25,6 @@ const select = (state, props) => { }; }; -export default connect(select)(CollectionContent); +export default connect(select, { + doOpenModal, +})(CollectionContent); diff --git a/ui/component/collectionContentSidebar/view.jsx b/ui/component/collectionContentSidebar/view.jsx index 75248f3cb..555e00438 100644 --- a/ui/component/collectionContentSidebar/view.jsx +++ b/ui/component/collectionContentSidebar/view.jsx @@ -4,6 +4,7 @@ import ClaimList from 'component/claimList'; import Card from 'component/common/card'; import Button from 'component/button'; import * as PAGES from 'constants/pages'; +import * as MODALS from 'constants/modal_types'; import Icon from 'component/common/icon'; import * as ICONS from 'constants/icons'; import { COLLECTIONS_CONSTS } from 'lbry-redux'; @@ -16,28 +17,52 @@ type Props = { collectionName: string, collection: any, createUnpublishedCollection: (string, Array, ?string) => void, + doOpenModal: (id: string, { collectionId: string }) => void, }; export default function CollectionContent(props: Props) { - const { collectionUrls, collectionName, id, url } = props; + const { + collectionUrls, + collectionName, + id, + url, + doOpenModal, + } = props; + return ( - - {collectionName} - + <> + + + {collectionName} + + > } titleActions={ - - {/* TODO: BUTTON TO SAVE COLLECTION - Probably save/copy modal */} - - + <> + + + + + doOpenModal(MODALS.COLLECTION_ADD, { collectionId: id })} + /> + + > } body={ + doOpenModal(MODALS.COLLECTION_ADD, { collectionId })} + > + + + {__('Copy List')} + + push(`/$/${PAGES.LIST}/${collectionId}?view=edit`)}