collection reordering changes #7301
11 changed files with 213 additions and 84 deletions
|
@ -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
|
||||||
|
|
118
ui/component/claimPreview/collection-buttons.jsx
Normal file
118
ui/component/claimPreview/collection-buttons.jsx
Normal file
|
@ -0,0 +1,118 @@
|
||||||
|
// @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
|
||||||
|
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
|
||||||
|
className={'button-collection-manage button-collection-delete-cancel top-right'}
|
||||||
|
icon={ICONS.REMOVE}
|
||||||
|
onClick={(e) => {
|
||||||
|
setConfirmDelete(false);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
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;
|
|
@ -25,8 +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 Button from 'component/button';
|
import CollectionEditButtons from './collection-buttons';
|
||||||
import * as ICONS from 'constants/icons';
|
|
||||||
|
|
||||||
import AbandonedChannelPreview from 'component/abandonedChannelPreview';
|
import AbandonedChannelPreview from 'component/abandonedChannelPreview';
|
||||||
|
|
||||||
|
@ -151,7 +150,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);
|
||||||
|
@ -347,8 +346,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,58 +405,6 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
|
||||||
{!pending && (
|
{!pending && (
|
||||||
<>
|
<>
|
||||||
{renderActions && claim && renderActions(claim)}
|
{renderActions && claim && renderActions(claim)}
|
||||||
{Boolean(isMyCollection && listId) && (
|
|
||||||
<>
|
|
||||||
<div className="collection-preview__edit-buttons">
|
|
||||||
<div className="collection-preview__edit-group">
|
|
||||||
<Button
|
|
||||||
button="alt"
|
|
||||||
className={'button-collection-order'}
|
|
||||||
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
|
|
||||||
button="alt"
|
|
||||||
className={'button-collection-order'}
|
|
||||||
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>
|
|
||||||
<div className="collection-preview__edit-group">
|
|
||||||
<Button
|
|
||||||
button="alt"
|
|
||||||
icon={ICONS.DELETE}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
// $FlowFixMe
|
|
||||||
if (editCollection) editCollection(listId, { claims: [claim], remove: true });
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
{shouldHideActions || renderActions ? null : actions !== undefined ? (
|
{shouldHideActions || renderActions ? null : actions !== undefined ? (
|
||||||
actions
|
actions
|
||||||
) : (
|
) : (
|
||||||
|
|
|
@ -358,7 +358,12 @@ function CollectionForm(props: Props) {
|
||||||
</div>
|
</div>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<ClaimList uris={collectionUrls} collectionId={collectionId} empty={__('This list has no items.')} />
|
<ClaimList
|
||||||
|
uris={collectionUrls}
|
||||||
|
collectionId={collectionId}
|
||||||
|
empty={__('This list has no items.')}
|
||||||
|
type={'listview'}
|
||||||
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel>
|
<TabPanel>
|
||||||
<Card
|
<Card
|
||||||
|
|
|
@ -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" />
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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';
|
||||||
|
|
|
@ -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>
|
||||||
);
|
);
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in a new issue