Allow users to rename private/unpublished lists.
This commit is contained in:
parent
2aeb419969
commit
1369fbb064
6 changed files with 93 additions and 9 deletions
|
@ -16,10 +16,19 @@ type Props = {
|
|||
collectionId: string,
|
||||
playNextUri: string,
|
||||
doToggleShuffleList: (string) => void,
|
||||
onRenameList: () => void,
|
||||
};
|
||||
|
||||
function CollectionMenuList(props: Props) {
|
||||
const { inline = false, collectionId, collectionName, doOpenModal, playNextUri, doToggleShuffleList } = props;
|
||||
const {
|
||||
inline = false,
|
||||
collectionId,
|
||||
collectionName,
|
||||
doOpenModal,
|
||||
playNextUri,
|
||||
doToggleShuffleList,
|
||||
onRenameList,
|
||||
} = props;
|
||||
const [doShuffle, setDoShuffle] = React.useState(false);
|
||||
|
||||
const { push } = useHistory();
|
||||
|
@ -86,6 +95,12 @@ function CollectionMenuList(props: Props) {
|
|||
{__('Delete List')}
|
||||
</div>
|
||||
</MenuItem>
|
||||
<MenuItem onSelect={onRenameList}>
|
||||
<div className="menu__link">
|
||||
<Icon aria-hidden icon={ICONS.EDIT} />
|
||||
{__('Rename List')}
|
||||
</div>
|
||||
</MenuItem>
|
||||
</>
|
||||
)}
|
||||
</MenuList>
|
||||
|
|
|
@ -16,7 +16,7 @@ import {
|
|||
makeSelectCountForCollectionId,
|
||||
makeSelectIsResolvingCollectionForId,
|
||||
} from 'redux/selectors/collections';
|
||||
import { doFetchItemsInCollection, doCollectionDelete } from 'redux/actions/collections';
|
||||
import { doFetchItemsInCollection, doCollectionDelete, doCollectionRename } from 'redux/actions/collections';
|
||||
import { doResolveUri } from 'redux/actions/claims';
|
||||
import { selectMutedChannels } from 'redux/selectors/blocked';
|
||||
import { selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc';
|
||||
|
@ -54,6 +54,7 @@ const perform = (dispatch) => ({
|
|||
resolveUri: (uri) => dispatch(doResolveUri(uri)),
|
||||
resolveCollectionItems: (options) => doFetchItemsInCollection(options),
|
||||
deleteCollection: (id) => dispatch(doCollectionDelete(id)),
|
||||
renameCollection: (id, name) => dispatch(doCollectionRename(id, name)),
|
||||
});
|
||||
|
||||
export default connect(select, perform)(CollectionPreviewTile);
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
// @flow
|
||||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import { NavLink, useHistory } from 'react-router-dom';
|
||||
import { FormField } from 'component/common/form';
|
||||
import Button from 'component/button';
|
||||
import ClaimPreviewTile from 'component/claimPreviewTile';
|
||||
import TruncatedText from 'component/common/truncated-text';
|
||||
import CollectionCount from './collectionCount';
|
||||
|
@ -40,6 +43,7 @@ type Props = {
|
|||
deleteCollection: (string) => void,
|
||||
resolveCollectionItems: (any) => void,
|
||||
isResolvingCollectionClaims: boolean,
|
||||
renameCollection: (string, string) => void,
|
||||
};
|
||||
|
||||
function CollectionPreviewTile(props: Props) {
|
||||
|
@ -53,10 +57,15 @@ function CollectionPreviewTile(props: Props) {
|
|||
collectionItemUrls,
|
||||
claim,
|
||||
resolveCollectionItems,
|
||||
renameCollection,
|
||||
} = props;
|
||||
|
||||
const { push } = useHistory();
|
||||
const hasClaim = Boolean(claim);
|
||||
|
||||
const [isRenamingList, setIsRenamingList] = React.useState(false);
|
||||
const [newName, setNewName] = React.useState(collectionName);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (collectionId && hasClaim && resolveCollectionItems) {
|
||||
resolveCollectionItems({ collectionId, page_size: 5 });
|
||||
|
@ -69,11 +78,16 @@ function CollectionPreviewTile(props: Props) {
|
|||
formatLbryUrlForWeb(collectionItemUrls[0] || '/') + (collectionId ? generateListSearchUrlParams(collectionId) : '');
|
||||
|
||||
function handleClick(e) {
|
||||
if (navigateUrl) {
|
||||
if (navigateUrl && !isRenamingList) {
|
||||
push(navigateUrl);
|
||||
}
|
||||
}
|
||||
|
||||
function handleRenameCollection() {
|
||||
renameCollection(collectionId, newName);
|
||||
setIsRenamingList(false);
|
||||
}
|
||||
|
||||
const navLinkProps = {
|
||||
to: navigateUrl,
|
||||
onClick: (e) => e.stopPropagation(),
|
||||
|
@ -144,12 +158,44 @@ function CollectionPreviewTile(props: Props) {
|
|||
</React.Fragment>
|
||||
</FileThumbnail>
|
||||
</NavLink>
|
||||
<NavLink {...navLinkProps}>
|
||||
<h2 className="claim-tile__title">
|
||||
<TruncatedText text={collectionName} lines={1} />
|
||||
<CollectionMenuList collectionId={collectionId} />
|
||||
</h2>
|
||||
</NavLink>
|
||||
{isRenamingList && (
|
||||
<FormField
|
||||
autoFocus
|
||||
type="text"
|
||||
name="rename_collection"
|
||||
value={newName}
|
||||
label={__('New Name')}
|
||||
inputButton={
|
||||
<>
|
||||
<Button
|
||||
button={'alt'}
|
||||
icon={ICONS.COMPLETE}
|
||||
className={'button-toggle'}
|
||||
disabled={collectionName === newName}
|
||||
onClick={handleRenameCollection}
|
||||
/>
|
||||
<Button
|
||||
button={'alt'}
|
||||
className={'button-toggle'}
|
||||
icon={ICONS.REMOVE}
|
||||
onClick={() => {
|
||||
setIsRenamingList(false);
|
||||
setNewName(collectionName);
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
}
|
||||
onChange={(e) => setNewName(e.target.value)}
|
||||
/>
|
||||
)}
|
||||
{!isRenamingList && (
|
||||
<NavLink {...navLinkProps}>
|
||||
<h2 className="claim-tile__title">
|
||||
<TruncatedText text={collectionName} lines={1} />
|
||||
<CollectionMenuList collectionId={collectionId} onRenameList={() => setIsRenamingList(true)} />
|
||||
</h2>
|
||||
</NavLink>
|
||||
)}
|
||||
<div>
|
||||
<div className="claim-tile__info">
|
||||
<React.Fragment>
|
||||
|
|
|
@ -195,6 +195,7 @@ export const COLLECTION_ITEMS_RESOLVE_STARTED = 'COLLECTION_ITEMS_RESOLVE_STARTE
|
|||
export const COLLECTION_ITEMS_RESOLVE_COMPLETED = 'COLLECTION_ITEMS_RESOLVE_COMPLETED';
|
||||
export const COLLECTION_ITEMS_RESOLVE_FAILED = 'COLLECTION_ITEMS_RESOLVE_FAILED';
|
||||
export const COLLECTION_NEW = 'COLLECTION_NEW';
|
||||
export const COLLECTION_RENAME = 'COLLECTION_RENAME';
|
||||
export const COLLECTION_DELETE = 'COLLECTION_DELETE';
|
||||
export const COLLECTION_PENDING = 'COLLECTION_PENDING';
|
||||
export const COLLECTION_EDIT = 'COLLECTION_EDIT';
|
||||
|
|
|
@ -40,6 +40,14 @@ export const doLocalCollectionCreate = (
|
|||
});
|
||||
};
|
||||
|
||||
export const doCollectionRename = (id: string, newName: string) => ({
|
||||
type: ACTIONS.COLLECTION_RENAME,
|
||||
data: {
|
||||
id,
|
||||
newName,
|
||||
},
|
||||
});
|
||||
|
||||
export const doCollectionDelete = (id: string, colKey: ?string = undefined) => (
|
||||
dispatch: Dispatch,
|
||||
getState: GetState
|
||||
|
|
|
@ -58,6 +58,19 @@ const collectionsReducer = handleActions(
|
|||
};
|
||||
},
|
||||
|
||||
[ACTIONS.COLLECTION_RENAME]: (state, action) => {
|
||||
const { unpublished } = state;
|
||||
const { id, newName } = action.data;
|
||||
const newUnpublished = { ...unpublished };
|
||||
if (newUnpublished[id]) {
|
||||
newUnpublished[id].name = newName;
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
unpublished: newUnpublished,
|
||||
};
|
||||
},
|
||||
|
||||
[ACTIONS.COLLECTION_DELETE]: (state, action) => {
|
||||
const { lastUsedCollection } = state;
|
||||
const { id, collectionKey } = action.data;
|
||||
|
|
Loading…
Reference in a new issue