2018-04-04 18:08:27 +02:00
|
|
|
// @flow
|
2020-07-23 19:02:07 +02:00
|
|
|
import * as PAGES from 'constants/pages';
|
|
|
|
import * as ICONS from 'constants/icons';
|
2022-04-15 05:05:59 +02:00
|
|
|
import React, { useEffect, useMemo } from 'react';
|
2018-03-26 23:32:43 +02:00
|
|
|
import Button from 'component/button';
|
2019-06-19 07:05:43 +02:00
|
|
|
import ClaimList from 'component/claimList';
|
2022-04-04 14:05:46 +02:00
|
|
|
import ClaimPreview from 'component/claimPreview';
|
2018-03-26 23:32:43 +02:00
|
|
|
import Page from 'component/page';
|
2019-09-23 19:32:38 +02:00
|
|
|
import Paginate from 'component/common/paginate';
|
2020-04-24 15:51:00 +02:00
|
|
|
import { PAGE_PARAM, PAGE_SIZE_PARAM } from 'constants/claim';
|
2019-11-15 21:48:57 +01:00
|
|
|
import Spinner from 'component/spinner';
|
2020-09-04 19:14:48 +02:00
|
|
|
import Yrbl from 'component/yrbl';
|
2022-04-15 05:05:59 +02:00
|
|
|
import { FormField, Form } from 'component/common/form';
|
|
|
|
import Icon from 'component/common/icon';
|
|
|
|
import debounce from 'util/debounce';
|
2021-03-15 10:59:48 +01:00
|
|
|
import classnames from 'classnames';
|
|
|
|
|
|
|
|
const FILTER_ALL = 'stream,repost';
|
|
|
|
const FILTER_UPLOADS = 'stream';
|
|
|
|
const FILTER_REPOSTS = 'repost';
|
2022-04-15 05:05:59 +02:00
|
|
|
const PAGINATE_PARAM = 'page';
|
2017-04-23 18:10:45 +02:00
|
|
|
|
2018-04-04 18:08:27 +02:00
|
|
|
type Props = {
|
2018-10-26 06:20:18 +02:00
|
|
|
checkPendingPublishes: () => void,
|
2020-01-08 06:29:01 +01:00
|
|
|
clearPublish: () => void,
|
2018-06-13 23:07:06 +02:00
|
|
|
fetching: boolean,
|
2021-03-15 10:59:48 +01:00
|
|
|
history: { replace: (string) => void, push: (string) => void },
|
2019-09-23 19:32:38 +02:00
|
|
|
page: number,
|
2020-04-24 15:51:00 +02:00
|
|
|
pageSize: number,
|
2022-04-15 05:05:59 +02:00
|
|
|
myClaims: any,
|
|
|
|
fetchAllMyClaims: () => void,
|
|
|
|
location: { search: string },
|
|
|
|
initialSearchTerm: string,
|
2018-04-04 18:08:27 +02:00
|
|
|
};
|
|
|
|
|
2019-06-11 20:10:58 +02:00
|
|
|
function FileListPublished(props: Props) {
|
2022-04-15 05:05:59 +02:00
|
|
|
const {
|
|
|
|
checkPendingPublishes,
|
|
|
|
clearPublish,
|
|
|
|
fetching,
|
|
|
|
page,
|
|
|
|
pageSize,
|
|
|
|
myClaims,
|
|
|
|
fetchAllMyClaims,
|
|
|
|
location,
|
|
|
|
history,
|
|
|
|
initialSearchTerm,
|
|
|
|
} = props;
|
2020-04-24 15:51:00 +02:00
|
|
|
|
2021-03-15 10:59:48 +01:00
|
|
|
const [filterBy, setFilterBy] = React.useState(FILTER_ALL);
|
2022-04-15 05:05:59 +02:00
|
|
|
const [searchText, setSearchText] = React.useState(initialSearchTerm);
|
|
|
|
const [filteredClaims, setFilteredClaims] = React.useState([]);
|
|
|
|
const { search } = location;
|
2020-04-24 15:51:00 +02:00
|
|
|
const params = {};
|
|
|
|
|
|
|
|
params[PAGE_PARAM] = Number(page);
|
|
|
|
params[PAGE_SIZE_PARAM] = Number(pageSize);
|
|
|
|
|
|
|
|
const paramsString = JSON.stringify(params);
|
|
|
|
|
2022-04-15 05:05:59 +02:00
|
|
|
const doFilterClaims = () => {
|
|
|
|
if (fetching) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
const filtered = myClaims.filter((claim) => {
|
|
|
|
const value = claim.value || {};
|
|
|
|
const src = value.source || {};
|
|
|
|
const title = (value.title || '').toLowerCase();
|
|
|
|
const description = (value.description || '').toLowerCase();
|
|
|
|
const tags = (value.tags || []).join('').toLowerCase();
|
|
|
|
const srcName = (src.name || '').toLowerCase();
|
|
|
|
const lowerCaseSearchText = searchText.toLowerCase();
|
|
|
|
const textMatches =
|
|
|
|
!searchText ||
|
|
|
|
title.indexOf(lowerCaseSearchText) !== -1 ||
|
|
|
|
description.indexOf(lowerCaseSearchText) !== -1 ||
|
|
|
|
tags.indexOf(lowerCaseSearchText) !== -1 ||
|
|
|
|
srcName.indexOf(lowerCaseSearchText) !== -1;
|
|
|
|
return textMatches && filterBy.includes(claim.value_type);
|
|
|
|
});
|
|
|
|
setFilteredClaims(filtered);
|
|
|
|
};
|
|
|
|
|
|
|
|
const debounceFilter = debounce(doFilterClaims, 200);
|
|
|
|
|
2019-06-11 20:10:58 +02:00
|
|
|
useEffect(() => {
|
2018-10-26 06:20:18 +02:00
|
|
|
checkPendingPublishes();
|
2020-04-24 15:51:00 +02:00
|
|
|
}, [checkPendingPublishes]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
2022-04-15 05:05:59 +02:00
|
|
|
const params = new URLSearchParams(search);
|
|
|
|
params.set('searchText', searchText);
|
|
|
|
history.replace('?' + params.toString());
|
|
|
|
debounceFilter();
|
|
|
|
}, [myClaims, searchText]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
doFilterClaims();
|
|
|
|
}, [myClaims, filterBy]);
|
|
|
|
|
|
|
|
const urlTotal = filteredClaims.length;
|
|
|
|
|
|
|
|
const urls = useMemo(() => {
|
|
|
|
const params = JSON.parse(paramsString);
|
|
|
|
const zeroIndexPage = Math.max(0, params.page - 1);
|
|
|
|
const paginated = filteredClaims.slice(
|
|
|
|
zeroIndexPage * params.page_size,
|
|
|
|
zeroIndexPage * params.page_size + params.page_size
|
|
|
|
);
|
|
|
|
return paginated.map((claim) => claim.permanent_url);
|
|
|
|
}, [filteredClaims, paramsString]);
|
|
|
|
|
|
|
|
// Go back to the first page when the filtered claims change.
|
|
|
|
// This way, we avoid hiding results just because the
|
|
|
|
// user may be on a different page (page that was calculated
|
|
|
|
// using a different state, ie, different filtered claims)
|
|
|
|
useEffect(() => {
|
|
|
|
const params = new URLSearchParams(search);
|
|
|
|
params.set(PAGINATE_PARAM, '1');
|
|
|
|
history.replace('?' + params.toString());
|
|
|
|
}, [filteredClaims]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
fetchAllMyClaims();
|
|
|
|
}, [fetchAllMyClaims]);
|
2017-04-23 18:10:45 +02:00
|
|
|
|
2019-06-11 20:10:58 +02:00
|
|
|
return (
|
2020-01-02 21:36:03 +01:00
|
|
|
<Page>
|
2020-05-28 16:45:56 +02:00
|
|
|
<div className="card-stack">
|
2021-10-16 07:26:40 +02:00
|
|
|
{!!urls && (
|
2020-09-16 22:12:47 +02:00
|
|
|
<>
|
|
|
|
<ClaimList
|
2021-10-16 07:26:40 +02:00
|
|
|
noEmpty
|
2021-03-16 16:45:14 +01:00
|
|
|
header={
|
|
|
|
<span>
|
|
|
|
<Button
|
|
|
|
label={__('All')}
|
|
|
|
aria-label={__('All uploads')}
|
|
|
|
onClick={() => setFilterBy(FILTER_ALL)}
|
|
|
|
className={classnames(`button-toggle`, {
|
|
|
|
'button-toggle--active': filterBy === FILTER_ALL,
|
|
|
|
})}
|
|
|
|
/>
|
|
|
|
<Button
|
|
|
|
label={__('Uploads')}
|
|
|
|
onClick={() => setFilterBy(FILTER_UPLOADS)}
|
|
|
|
className={classnames(`button-toggle`, {
|
|
|
|
'button-toggle--active': filterBy === FILTER_UPLOADS,
|
|
|
|
})}
|
|
|
|
/>
|
|
|
|
<Button
|
|
|
|
label={__('Reposts')}
|
2022-04-15 05:05:59 +02:00
|
|
|
onClick={() => {
|
|
|
|
setFilterBy(FILTER_REPOSTS);
|
|
|
|
setSearchText('');
|
|
|
|
}}
|
2021-03-16 16:45:14 +01:00
|
|
|
className={classnames(`button-toggle`, {
|
|
|
|
'button-toggle--active': filterBy === FILTER_REPOSTS,
|
|
|
|
})}
|
|
|
|
/>
|
|
|
|
</span>
|
|
|
|
}
|
2020-09-16 22:12:47 +02:00
|
|
|
headerAltControls={
|
|
|
|
<div className="card__actions--inline">
|
2020-06-30 12:14:18 +02:00
|
|
|
<Button
|
2022-04-17 19:04:56 +02:00
|
|
|
button="secondary"
|
2022-04-15 05:05:59 +02:00
|
|
|
label={__('Refresh')}
|
|
|
|
icon={ICONS.REFRESH}
|
|
|
|
disabled={fetching}
|
|
|
|
onClick={fetchAllMyClaims}
|
2020-06-30 12:14:18 +02:00
|
|
|
/>
|
2022-04-17 19:04:56 +02:00
|
|
|
<Button
|
|
|
|
icon={ICONS.PUBLISH}
|
|
|
|
button="primary"
|
|
|
|
label={__('Upload')}
|
|
|
|
navigate={`/$/${PAGES.UPLOAD}`}
|
|
|
|
onClick={() => clearPublish()}
|
|
|
|
/>
|
2022-04-15 05:05:59 +02:00
|
|
|
<Form onSubmit={() => {}} className="wunderbar--inline">
|
|
|
|
<Icon icon={ICONS.SEARCH} />
|
|
|
|
<FormField
|
|
|
|
className="wunderbar__input--inline"
|
|
|
|
value={searchText}
|
|
|
|
onChange={(e) => setSearchText(e.target.value)}
|
|
|
|
type="text"
|
|
|
|
placeholder={__('Search Uploads')}
|
|
|
|
disabled={filterBy === FILTER_REPOSTS}
|
|
|
|
/>
|
|
|
|
</Form>
|
2020-09-16 22:12:47 +02:00
|
|
|
</div>
|
|
|
|
}
|
|
|
|
persistedStorageKey="claim-list-published"
|
2022-04-04 14:05:46 +02:00
|
|
|
uris={fetching ? [] : urls}
|
|
|
|
loading={fetching}
|
2020-09-16 22:12:47 +02:00
|
|
|
/>
|
2022-04-04 14:05:46 +02:00
|
|
|
{fetching &&
|
|
|
|
new Array(Number(pageSize)).fill(1).map((x, i) => <ClaimPreview key={i} placeholder="loading" />)}
|
2020-09-16 22:12:47 +02:00
|
|
|
<Paginate totalPages={urlTotal > 0 ? Math.ceil(urlTotal / Number(pageSize)) : 1} />
|
|
|
|
</>
|
2020-06-02 18:32:58 +02:00
|
|
|
)}
|
2020-05-28 16:45:56 +02:00
|
|
|
</div>
|
2022-04-15 05:05:59 +02:00
|
|
|
{!fetching && myClaims.length === 0 && (
|
2019-11-15 21:48:57 +01:00
|
|
|
<React.Fragment>
|
|
|
|
{!fetching ? (
|
|
|
|
<section className="main--empty">
|
2020-09-04 19:14:48 +02:00
|
|
|
<Yrbl
|
2021-10-16 07:26:40 +02:00
|
|
|
title={filterBy === FILTER_REPOSTS ? __('No Reposts') : __('No uploads')}
|
|
|
|
subtitle={
|
|
|
|
filterBy === FILTER_REPOSTS
|
|
|
|
? __("You haven't reposted anything yet. Do it.")
|
|
|
|
: __("You haven't uploaded anything yet. This is where you can find them when you do!")
|
|
|
|
}
|
2020-09-04 19:14:48 +02:00
|
|
|
actions={
|
2021-10-16 07:26:40 +02:00
|
|
|
filterBy !== FILTER_REPOSTS && (
|
|
|
|
<div className="section__actions">
|
|
|
|
<Button
|
|
|
|
button="primary"
|
|
|
|
navigate={`/$/${PAGES.UPLOAD}`}
|
|
|
|
label={__('Upload Something New')}
|
|
|
|
onClick={() => clearPublish()}
|
|
|
|
/>
|
|
|
|
</div>
|
|
|
|
)
|
2020-09-04 19:14:48 +02:00
|
|
|
}
|
|
|
|
/>
|
2019-11-15 21:48:57 +01:00
|
|
|
</section>
|
|
|
|
) : (
|
|
|
|
<section className="main--empty">
|
2020-09-04 19:14:48 +02:00
|
|
|
<Spinner delayed />
|
2019-11-15 21:48:57 +01:00
|
|
|
</section>
|
|
|
|
)}
|
|
|
|
</React.Fragment>
|
2019-06-11 20:10:58 +02:00
|
|
|
)}
|
|
|
|
</Page>
|
|
|
|
);
|
2017-05-01 08:26:09 +02:00
|
|
|
}
|
2017-04-23 18:10:45 +02:00
|
|
|
|
2017-06-06 06:21:55 +02:00
|
|
|
export default FileListPublished;
|