collection reordering changes #7301

Merged
jessopb merged 4 commits from collection-ordering into master 2021-12-02 21:08:24 +01:00
11 changed files with 247 additions and 35 deletions
Showing only changes of commit 3386880317 - Show all commits

View file

@ -2220,5 +2220,6 @@
"filtered": "filtered", "filtered": "filtered",
"View All Playlists": "View All Playlists", "View All Playlists": "View All Playlists",
"Your wallet is not currently using a cloud sync service. You are in control of backing up your wallet.": "Your wallet is not currently using a cloud sync service. You are in control of backing up your wallet.", "Your wallet is not currently using a cloud sync service. You are in control of backing up your wallet.": "Your wallet is not currently using a cloud sync service. You are in control of backing up your wallet.",
"%action% %collection%": "%action% %collection%",
"--end--": "--end--" "--end--": "--end--"
} }

View file

@ -78,8 +78,6 @@ export default function ClaimList(props: Props) {
noEmpty, noEmpty,
} = props; } = props;
console.log('noempty', noEmpty);
const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW); const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW);
// Exclude prefix uris in these results variables. We don't want to show // Exclude prefix uris in these results variables. We don't want to show

View file

@ -0,0 +1,121 @@
// @flow
import React from 'react';
import Button from 'component/button';
import * as ICONS from 'constants/icons';
type Props = {
collectionIndex?: number,
editCollection: (string, CollectionEditParams) => void,
listId?: string,
lastCollectionIndex?: number,
claim: ?Claim,
};
function CollectionButtons(props: Props) {
const { collectionIndex, editCollection, listId, lastCollectionIndex, claim } = props;
const [confirmDelete, setConfirmDelete] = React.useState(false);
return (
<div className="collection-preview__edit-buttons">
<div className="collection-preview__edit-group">
<Button
className={'button-collection-manage top-left'}
icon={ICONS.UP_TOP}
disabled={collectionIndex === 0}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (editCollection) {
// $FlowFixMe
editCollection(listId, {
order: { from: collectionIndex, to: 0 },
});
}
}}
/>
<Button
className={'button-collection-manage bottom-left'}
icon={ICONS.DOWN_BOTTOM}
disabled={collectionIndex === lastCollectionIndex}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (editCollection) {
// $FlowFixMe
editCollection(listId, {
order: { from: collectionIndex, to: lastCollectionIndex },
});
}
}}
/>
</div>
<div className="collection-preview__edit-group">
<Button
className={'button-collection-manage'}
disabled={collectionIndex === 0}
icon={ICONS.UP}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (editCollection) {
// $FlowFixMe
editCollection(listId, {
order: { from: collectionIndex, to: Number(collectionIndex) - 1 },
});
}
}}
/>
<Button
className={'button-collection-manage'}
icon={ICONS.DOWN}
disabled={collectionIndex === lastCollectionIndex}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (editCollection) {
// $FlowFixMe
editCollection(listId, {
order: { from: collectionIndex, to: Number(collectionIndex + 1) },
});
}
}}
/>
</div>
{!confirmDelete && (
<div className="collection-preview__edit-group collection-preview__delete ">
<Button
// button="alt"
className={'button-collection-manage button-collection-delete top-right bottom-right'}
icon={ICONS.DELETE}
onClick={(e) => {
setConfirmDelete(true);
}}
/>
</div>
)}
{confirmDelete && (
<div className="collection-preview__edit-group collection-preview__delete">
<Button
// button="alt"
className={'button-collection-manage button-collection-delete-cancel top-right'}
icon={ICONS.REMOVE}
onClick={(e) => {
setConfirmDelete(false);
}}
/>
<Button
// button="alt"
className={'button-collection-manage button-collection-delete-confirm bottom-right'}
icon={ICONS.DELETE}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
// $FlowFixMe
if (editCollection) editCollection(listId, { claims: [claim], remove: true });
}}
/>
</div>
)}
</div>
);
}
export default CollectionButtons;

View file

@ -25,6 +25,7 @@ import ClaimMenuList from 'component/claimMenuList';
import ClaimPreviewLoading from './claim-preview-loading'; import ClaimPreviewLoading from './claim-preview-loading';
import ClaimPreviewHidden from './claim-preview-no-mature'; import ClaimPreviewHidden from './claim-preview-no-mature';
import ClaimPreviewNoContent from './claim-preview-no-content'; import ClaimPreviewNoContent from './claim-preview-no-content';
import CollectionEditButtons from './collection-buttons';
import Button from 'component/button'; import Button from 'component/button';
import * as ICONS from 'constants/icons'; import * as ICONS from 'constants/icons';
@ -151,7 +152,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
} = props; } = props;
const isCollection = claim && claim.value_type === 'collection'; const isCollection = claim && claim.value_type === 'collection';
const collectionClaimId = isCollection && claim && claim.claim_id; const collectionClaimId = isCollection && claim && claim.claim_id;
const listId = collectionId || collectionClaimId; const listId = collectionId || collectionClaimId || null;
const WrapperElement = wrapperElement || 'li'; const WrapperElement = wrapperElement || 'li';
const shouldFetch = const shouldFetch =
claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending); claim === undefined || (claim !== null && claim.value_type === 'channel' && isEmpty(claim.meta) && !pending);
@ -160,6 +161,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
const shouldHideActions = hideActions || isMyCollection || type === 'small' || type === 'tooltip'; const shouldHideActions = hideActions || isMyCollection || type === 'small' || type === 'tooltip';
const canonicalUrl = claim && claim.canonical_url; const canonicalUrl = claim && claim.canonical_url;
const lastCollectionIndex = collectionUris ? collectionUris.length - 1 : 0; const lastCollectionIndex = collectionUris ? collectionUris.length - 1 : 0;
console.log('type', type);
const channelSubscribers = React.useMemo(() => { const channelSubscribers = React.useMemo(() => {
if (channelSubCount === undefined) { if (channelSubCount === undefined) {
return <span />; return <span />;
@ -347,8 +349,18 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
'claim-preview--channel': isChannelUri, 'claim-preview--channel': isChannelUri,
'claim-preview--visited': !isChannelUri && !claimIsMine && hasVisitedUri, 'claim-preview--visited': !isChannelUri && !claimIsMine && hasVisitedUri,
'claim-preview--pending': pending, 'claim-preview--pending': pending,
'claim-preview--collection-mine': isMyCollection && listId && type === 'listview',
})} })}
> >
{isMyCollection && listId && type === 'listview' && (
<CollectionEditButtons
collectionIndex={collectionIndex}
editCollection={editCollection}
listId={listId}
lastCollectionIndex={lastCollectionIndex}
claim={claim}
/>
)}
{isChannelUri && claim ? ( {isChannelUri && claim ? (
<UriIndicator focusable={false} uri={uri} link> <UriIndicator focusable={false} uri={uri} link>
<ChannelThumbnail uri={uri} small={type === 'inline'} /> <ChannelThumbnail uri={uri} small={type === 'inline'} />
@ -396,13 +408,27 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
{!pending && ( {!pending && (
<> <>
{renderActions && claim && renderActions(claim)} {renderActions && claim && renderActions(claim)}
{Boolean(isMyCollection && listId) && ( {false && Boolean(isMyCollection && listId) && (
<> <>
<div className="collection-preview__edit-buttons"> <div className="collection-preview__edit-buttons">
<div className="collection-preview__edit-group"> <div className="collection-preview__edit-group">
<Button <Button
button="alt" className={'button-collection-manage'}
className={'button-collection-order'} icon={ICONS.UP_TOP}
disabled={collectionIndex === 0}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (editCollection) {
// $FlowFixMe
editCollection(listId, {
order: { from: collectionIndex, to: 0 },
});
}
}}
/>
<Button
className={'button-collection-manage'}
disabled={collectionIndex === 0} disabled={collectionIndex === 0}
icon={ICONS.UP} icon={ICONS.UP}
onClick={(e) => { onClick={(e) => {
@ -417,8 +443,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
}} }}
/> />
<Button <Button
button="alt" className={'button-collection-manage'}
className={'button-collection-order'}
icon={ICONS.DOWN} icon={ICONS.DOWN}
disabled={collectionIndex === lastCollectionIndex} disabled={collectionIndex === lastCollectionIndex}
onClick={(e) => { onClick={(e) => {
@ -432,10 +457,26 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
} }
}} }}
/> />
<Button
className={'button-collection-manage'}
icon={ICONS.DOWN_BOTTOM}
disabled={collectionIndex === lastCollectionIndex}
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
if (editCollection) {
// $FlowFixMe
editCollection(listId, {
order: { from: collectionIndex, to: lastCollectionIndex },
});
}
}}
/>
</div> </div>
<div className="collection-preview__edit-group"> <div className="collection-preview__edit-group">
<Button <Button
button="alt" // button="alt"
className={'button-collection-manage'}
icon={ICONS.DELETE} icon={ICONS.DELETE}
onClick={(e) => { onClick={(e) => {
e.preventDefault(); e.preventDefault();

View file

@ -382,7 +382,21 @@ export const icons = {
[ICONS.NO]: buildIcon( [ICONS.NO]: buildIcon(
<path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17" /> <path d="M10 15v4a3 3 0 0 0 3 3l4-9V2H5.72a2 2 0 0 0-2 1.7l-1.38 9a2 2 0 0 0 2 2.3zm7-13h2.67A2.31 2.31 0 0 1 22 4v7a2.31 2.31 0 0 1-2.33 2H17" />
), ),
[ICONS.UP]: buildIcon(<polyline transform="matrix(1,0,0,-1,0,24.707107)" points="6 9 12 15 18 9" />), [ICONS.UP]: buildIcon(
<g>
<polyline transform="matrix(1,0,0,-1,0,24.707107)" points="6 9 12 15 18 9" />
</g>
),
[ICONS.UP_TOP]: buildIcon(
<g>
<path d="m6 16 6-6 6 6M6 8h12" />
</g>
),
[ICONS.DOWN_BOTTOM]: buildIcon(
<g>
<path d="m6 8 6 6 6-6M6 16h12" />
</g>
),
[ICONS.DOWN]: buildIcon(<polyline points="6 9 12 15 18 9" />), [ICONS.DOWN]: buildIcon(<polyline points="6 9 12 15 18 9" />),
[ICONS.FULLSCREEN]: buildIcon( [ICONS.FULLSCREEN]: buildIcon(
<path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" /> <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" />

View file

@ -27,7 +27,7 @@ function FileDescription(props: Props) {
const { uri, claim, metadata, pendingAmount, doOpenModal, claimIsMine, expandOverride } = props; const { uri, claim, metadata, pendingAmount, doOpenModal, claimIsMine, expandOverride } = props;
const [expanded, setExpanded] = React.useState(false); const [expanded, setExpanded] = React.useState(false);
const [showCreditDetails, setShowCreditDetails] = React.useState(false); const [showCreditDetails, setShowCreditDetails] = React.useState(false);
const amount = parseFloat(claim.amount) + parseFloat(pendingAmount || claim.meta.support_amount); const amount = claim ? parseFloat(claim.amount) + parseFloat(pendingAmount || claim.meta.support_amount) : undefined;
const formattedAmount = formatCredits(amount, 2, true); const formattedAmount = formatCredits(amount, 2, true);
const hasSupport = claim && claim.meta && claim.meta.support_amount && Number(claim.meta.support_amount) > 0; const hasSupport = claim && claim.meta && claim.meta.support_amount && Number(claim.meta.support_amount) > 0;

View file

@ -65,7 +65,9 @@ export const OPTIONS = 'Sliders';
export const YES = 'ThumbsUp'; export const YES = 'ThumbsUp';
export const NO = 'ThumbsDown'; export const NO = 'ThumbsDown';
export const UP = 'ChevronUp'; export const UP = 'ChevronUp';
export const UP_TOP = 'ChevronUpTop';
export const DOWN = 'ChevronDown'; export const DOWN = 'ChevronDown';
export const DOWN_BOTTOM = 'ChevronDownBottom';
export const SECURE = 'Lock'; export const SECURE = 'Lock';
export const MENU = 'Menu'; export const MENU = 'Menu';
export const BACKUP = 'Database'; export const BACKUP = 'Database';

View file

@ -188,7 +188,7 @@ export default function CollectionPage(props: Props) {
<Page> <Page>
<div className={classnames('section card-stack')}> <div className={classnames('section card-stack')}>
{info} {info}
<ClaimList uris={collectionUrls} collectionId={collectionId} /> <ClaimList uris={collectionUrls} collectionId={collectionId} type={'listview'} />
</div> </div>
</Page> </Page>
); );

View file

@ -604,30 +604,55 @@ svg + .button__label {
} }
} }
.button-collection-order { .button-collection-manage {
height: 100%;
font-size: var(--font-base); font-size: var(--font-base);
border-left-width: 0; border-left-width: 0;
border-radius: 0;
margin: 0; margin: 0;
color: var(--color-text); width: 100%;
button { button {
padding: var(--spacing-xs); padding: var(--spacing-xxs);
}
.button__content {
display: unset;
}
line-height: 1.2;
font-weight: var(--font-weight-bold);
height: 100%;
background-color: var(--color-button-alt-bg);
color: var(--color-button-alt-text);
text-align: center;
&:hover {
background-color: var(--color-button-alt-bg-hover);
}
@media (max-width: $breakpoint-small) {
font-size: var(--font-small);
} }
@media (max-width: $breakpoint-small) { @media (max-width: $breakpoint-small) {
padding: var(--spacing-s) var(--spacing-s); padding: var(--spacing-s) var(--spacing-s);
} }
&:first-of-type { &.top-right {
border-left-width: 1px; border-top-right-radius: var(--border-radius);
}
&.top-left {
border-top-left-radius: var(--border-radius); border-top-left-radius: var(--border-radius);
}
&.bottom-right {
border-bottom-right-radius: var(--border-radius);
}
&.bottom-left {
border-bottom-left-radius: var(--border-radius); border-bottom-left-radius: var(--border-radius);
} }
&:last-of-type { &.button-collection-delete-confirm {
border-top-right-radius: var(--border-radius); background-color: green;
border-bottom-right-radius: var(--border-radius); }
&.button-collection-delete-cancel {
background-color: red;
} }
} }

View file

@ -215,6 +215,11 @@
} }
} }
.claim-preview--collection-mine {
padding-left: 7rem;
position: relative;
}
.claim-preview--pending { .claim-preview--pending {
opacity: 0.6; opacity: 0.6;
} }

View file

@ -86,22 +86,27 @@
} }
.collection-preview__edit-buttons { .collection-preview__edit-buttons {
display: flex; position: absolute;
flex-direction: row; left: 0;
margin-top: var(--spacing-xs); top: calc(-1 * var(--spacing-m));
margin-bottom: var(--spacing-xs); bottom: calc(-1 * var(--spacing-m));
padding-left: 0;
padding-top: var(--spacing-m);
padding-bottom: var(--spacing-m);
display: grid;
grid-template-columns: 1fr 1fr 1fr;
align-items: center;
} }
.collection-preview__edit-group { .collection-preview__edit-group {
&:not(:last-of-type) { height: 100%;
margin-right: var(--spacing-s); display: flex;
} flex-direction: column;
margin-right: var(--spacing-s); width: 2rem;
button { align-items: center;
@media (max-width: $breakpoint-small) { justify-content: center;
padding: var(--spacing-s) var(--spacing-s); align-items: stretch;
} flex-grow: 4;
}
} }
.collection-edit__header { .collection-edit__header {