Remove individual entries

This commit is contained in:
Raphael Wickihalder 2022-04-26 16:59:40 +02:00 committed by Thomas Zarebczan
parent 1a7b92c4fa
commit ea686474fc
6 changed files with 92 additions and 166 deletions

View file

@ -60,6 +60,7 @@ type Props = {
droppableProvided?: any,
unavailableUris?: Array<string>,
showMemberBadge?: boolean,
inHistory?: boolean,
};
export default function ClaimList(props: Props) {
@ -100,6 +101,7 @@ export default function ClaimList(props: Props) {
droppableProvided,
unavailableUris,
showMemberBadge,
inHistory,
} = props;
const [currentSort, setCurrentSort] = usePersistedState(persistedStorageKey, SORT_NEW);
@ -202,6 +204,7 @@ export default function ClaimList(props: Props) {
dragHandleProps={draggableProvided && draggableProvided.dragHandleProps}
unavailableUris={unavailableUris}
showMemberBadge={showMemberBadge}
inHistory={inHistory}
/>
);

View file

@ -37,6 +37,7 @@ import { ENABLE_NO_SOURCE_CLAIMS } from 'config';
import CollectionEditButtons from 'component/collectionEditButtons';
import * as ICONS from 'constants/icons';
import { useIsMobile } from 'effects/use-screensize';
import usePersistedState from 'effects/use-persisted-state';
const AbandonedChannelPreview = lazyImport(() =>
import('component/abandonedChannelPreview' /* webpackChunkName: "abandonedChannelPreview" */)
@ -96,6 +97,7 @@ type Props = {
dragHandleProps?: any,
unavailableUris?: Array<string>,
showMemberBadge?: boolean,
inHistory?: boolean,
};
const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
@ -161,6 +163,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
dragHandleProps,
unavailableUris,
showMemberBadge,
inHistory,
} = props;
const isMobile = useIsMobile();
@ -211,6 +214,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
? claim.permanent_url || claim.canonical_url
: undefined;
const repostedContentUri = claim && (claim.reposted_claim ? claim.reposted_claim.permanent_url : claim.permanent_url);
const [watchHistory, setHistory] = usePersistedState('watch-history', []);
// Get channel title ( use name as fallback )
let channelTitle = null;
@ -281,6 +285,7 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
function handleOnClick(e) {
if (onClick) {
console.log('click: ', e);
onClick(e, claim, indexInContainer);
}
@ -292,6 +297,14 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
}
}
function removeFromHistory(e, uri) {
e.stopPropagation();
if (watchHistory.find((entry) => entry === uri)) {
watchHistory.splice(watchHistory.indexOf(uri), 1);
setHistory(watchHistory);
}
}
useEffect(() => {
if (isValid && !isResolvingUri && shouldFetch && uri) {
resolveUri(uri);
@ -364,7 +377,6 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
>
<>
{!hideRepostLabel && <ClaimRepostAuthor uri={uri} />}
<div
className={classnames('claim-preview', {
'claim-preview--small': type === 'small' || type === 'tooltip',
@ -487,7 +499,11 @@ const ClaimPreview = forwardRef<any, {}>((props: Props, ref: any) => {
)}
</div>
</div>
{inHistory && (
<div onClick={(e) => removeFromHistory(e, uri)} className="claim-preview__history-remove">
<Icon icon={ICONS.REMOVE} />
</div>
)}
{/* Todo: check isLivestreamActive once we have that data consistently everywhere. */}
{claim && isLivestream && <ClaimPreviewReset uri={uri} />}

View file

@ -90,7 +90,7 @@ const PLAYLISTS: SideNavLink = {
const HISTORY: SideNavLink = {
title: 'History',
link: `/$/${PAGES.HISTORY}`,
icon: ICONS.TIME,
icon: ICONS.EYE,
hideForUnauth: true,
};

View file

@ -154,7 +154,7 @@ function VideoViewer(props: Props) {
const [history, setHistory] = usePersistedState('watch-history', []);
React.useEffect(() => {
if (!history[0].indexOf(claim.permanent_url) !== -1) {
if (!history[0] || !history[0].indexOf(claim.permanent_url) !== -1) {
if (!history || !history.length) {
setHistory([claim.permanent_url]);
} else {
@ -306,7 +306,6 @@ function VideoViewer(props: Props) {
setIsEndedEmbed(false);
setReplay(false);
setDoNavigate(false);
// setWatchHistory()
analytics.videoIsPlaying(true, player);
}

View file

@ -2,27 +2,15 @@
import React from 'react';
import ClaimList from 'component/claimList';
import Page from 'component/page';
import { useHistory } from 'react-router-dom';
import Card from 'component/common/card';
import Button from 'component/button';
import classnames from 'classnames';
import * as COLLECTIONS_CONSTS from 'constants/collections';
import Icon from 'component/common/icon';
import * as ICONS from 'constants/icons';
import Spinner from 'component/spinner';
import usePersistedState from 'effects/use-persisted-state';
// prettier-ignore
const Lazy = {
// $FlowFixMe
DragDropContext: React.lazy(() => import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.DragDropContext }))),
// $FlowFixMe
Droppable: React.lazy(() => import('react-beautiful-dnd' /* webpackChunkName: "dnd" */).then((module) => ({ default: module.Droppable }))),
};
export const PAGE_VIEW_QUERY = 'view';
export const EDIT_PAGE = 'edit';
// export const EDIT_PAGE = 'edit';
type Props = {
collectionId: string,
@ -31,163 +19,51 @@ type Props = {
thumbnail: string,
collectionUrls: Array<string>,
isResolvingCollection: boolean,
isMyClaim: boolean,
isMyCollection: boolean,
claimIsPending: boolean,
collectionHasEdits: boolean,
deleteCollection: (string, string) => void,
editCollection: (string, CollectionEditParams) => void,
// isMyClaim: boolean,
// isMyCollection: boolean,
// claimIsPending: boolean,
// collectionHasEdits: boolean,
// deleteCollection: (string, string) => void,
// editCollection: (string, CollectionEditParams) => void,
fetchCollectionItems: (string, () => void) => void,
resolveUris: (string) => void,
user: ?User,
};
export default function HistoryPage(props: Props) {
const {
collectionId,
claim,
collectionHasEdits,
claimIsPending,
isResolvingCollection,
editCollection,
fetchCollectionItems,
deleteCollection,
} = props;
const { collectionId } = props;
const [history, setHistory] = usePersistedState('watch-history', []);
const [unavailableUris] = React.useState([]);
const collection = {
id: 'watchhistory',
name: __('Watch History'),
type: 'playlist',
};
const collectionUrls = [];
const [history] = usePersistedState('watch-history', []);
const {
location: { search },
} = useHistory();
const [didTryResolve, setDidTryResolve] = React.useState(false);
const [unavailableUris, setUnavailable] = React.useState([]);
const isBuiltin = COLLECTIONS_CONSTS.BUILTIN_LISTS.includes(collectionId);
function handleOnDragEnd(result) {
const { source, destination } = result;
if (!destination) return;
const { index: from } = source;
const { index: to } = destination;
editCollection(collectionId, { order: { from, to } });
function clearHistory() {
setHistory([]);
}
const urlParams = new URLSearchParams(search);
const editing = urlParams.get(PAGE_VIEW_QUERY) === EDIT_PAGE;
const urlsReady = collectionUrls && history.length;
React.useEffect(() => {
if (collectionId && !urlsReady && !didTryResolve && !collection) {
fetchCollectionItems(collectionId, () => setDidTryResolve(true));
}
}, [collectionId, urlsReady, didTryResolve, setDidTryResolve, fetchCollectionItems, collection]);
const pending = (
<div className="help card__title--help">
<Spinner type={'small'} />
{__('Your publish is being confirmed and will be live soon')}
</div>
);
const unpublished = (
<Button
button="close"
icon={ICONS.REFRESH}
label={__('Clear Edits')}
onClick={() => deleteCollection(collectionId, COLLECTIONS_CONSTS.COL_KEY_EDITED)}
/>
);
const removeUnavailable = (
<Button
button="close"
icon={ICONS.DELETE}
label={__('Remove all unavailable claims')}
onClick={() => {
editCollection(collectionId, { uris: unavailableUris, remove: true });
setUnavailable([]);
}}
/>
);
let titleActions;
if (collectionHasEdits) {
titleActions = unpublished;
} else if (claimIsPending) {
titleActions = pending;
}
const listName = claim ? claim.value.title || claim.name : collection && collection.name;
const info = (
<Card
title={
<span>
<Icon
icon={
(collectionId === COLLECTIONS_CONSTS.WATCH_LATER_ID && ICONS.TIME) ||
(collectionId === COLLECTIONS_CONSTS.FAVORITES_ID && ICONS.STAR) ||
ICONS.TIME
}
className="icon--margin-right"
/>
{isBuiltin ? __(listName) : listName}
</span>
}
titleActions={unavailableUris.length > 0 ? removeUnavailable : titleActions}
/>
);
if (!collection && (isResolvingCollection || !didTryResolve)) {
return (
<Page>
<h2 className="main--empty empty">{__('Loading...')}</h2>
</Page>
);
}
if (!collection && !isResolvingCollection && didTryResolve) {
return (
<Page>
<h2 className="main--empty empty">{__('Nothing here')}</h2>
</Page>
);
}
if (urlsReady) {
return (
<Page className="playlistPage-wrapper">
{editing}
<Page className="historyPage-wrapper">
<div className={classnames('section card-stack')}>
{info}
<React.Suspense fallback={null}>
<Lazy.DragDropContext onDragEnd={handleOnDragEnd}>
<Lazy.Droppable droppableId="list__ordering">
{(DroppableProvided) => (
<ClaimList
uris={history}
collectionId={collectionId}
// showEdit={showEdit}
droppableProvided={DroppableProvided}
unavailableUris={unavailableUris}
<div className="claim-list__header">
<h1 className="card__title">
<Icon icon={ICONS.EYE} style={{ marginRight: 'var(--spacing-s)' }} />
{__('Watch History')}
</h1>
<div className="claim-list__alt-controls--wrap">
{history.length > 0 && (
<Button
title={__('Clear History')}
button="primary"
label={__('Clear History')}
onClick={() => clearHistory()}
/>
)}
</Lazy.Droppable>
</Lazy.DragDropContext>
</React.Suspense>
</div>
</div>
{history.length > 0 && (
<ClaimList uris={history} collectionId={collectionId} unavailableUris={unavailableUris} inHistory />
)}
{history.length === 0 && <h2 className="main--empty empty">{__('Nothing here')}</h2>}
</div>
</Page>
);
}
}

View file

@ -1205,6 +1205,38 @@ img {
}
}
.historyPage-wrapper {
.claim-preview__wrapper {
.claim-preview__history-remove {
position: absolute;
top: var(--spacing-s);
right: var(--spacing-xs);
opacity: 0;
.icon {
width: 22px;
height: 22px;
}
&:hover {
.icon {
stroke: var(--color-primary);
cursor: pointer;
}
}
}
.menu__button.claim__menu-button {
top: 2.2rem;
}
&:hover {
.claim-preview__history-remove {
opacity: 1;
}
}
}
}
.premium-wrapper {
.membership_title {
.comment__badge {