lbry-desktop/ui/component/common/paginate.jsx
infinite-persistence 345d9e76b5
Blocklist: paginate + search (#7055)
* Paginate: add option to disable history and url param

* Refactored blocklists into `BlockList`; no functional change

Reason:
- With each list (Personal, Admin, Mod, Muted), there's a bunch of useEffects and variables needed to handle the state. All of them are doing 99% similar things.

* Paginate blocklists

6834

* Improve 'moderator-block' list visuals

- Added "Blocked on behalf of" to make things clearer.
- Use smaller ClaimPreview for delegators to save space (there might be lots of delegators)

* Add search bar to BlockList

6834

- Only supports channel-name search, per 6834. Channel-title search would probably be too heavy on the client side.
- Fuzzy search is possible, but is too slow on huge lists. Ended up with a simpler `matchSorter.rankings.CONTAINS`, which I think would cover typical cases.
2021-09-10 11:36:08 -04:00

88 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// @flow
import React from 'react';
import { withRouter } from 'react-router';
import { Form, FormField } from 'component/common/form';
import ReactPaginate from 'react-paginate';
import { useIsMobile } from 'effects/use-screensize';
const PAGINATE_PARAM = 'page';
type Props = {
totalPages: number,
location: { search: string },
history: { push: (string) => void },
onPageChange?: (number) => void,
disableHistory?: boolean, // Disables the use of '&page=' param and history stack.
};
function Paginate(props: Props) {
const { totalPages = 1, location, history, onPageChange, disableHistory } = props;
const { search } = location;
const [textValue, setTextValue] = React.useState('');
const urlParams = new URLSearchParams(search);
const initialPage = disableHistory ? 1 : Number(urlParams.get(PAGINATE_PARAM)) || 1;
const [currentPage, setCurrentPage] = React.useState(initialPage);
const isMobile = useIsMobile();
function handleChangePage(newPageNumber: number) {
if (onPageChange) {
onPageChange(newPageNumber);
}
if (currentPage !== newPageNumber) {
setCurrentPage(newPageNumber);
if (!disableHistory) {
const params = new URLSearchParams(search);
params.set(PAGINATE_PARAM, newPageNumber.toString());
history.push('?' + params.toString());
}
}
}
function handlePaginateKeyUp() {
const newPage = Number(textValue);
if (newPage && newPage > 0 && newPage <= totalPages) {
handleChangePage(newPage);
}
}
return (
// Hide the paginate controls if we are loading or there is only one page
// It should still be rendered to trigger the onPageChange callback
<Form style={totalPages <= 1 ? { display: 'none' } : null} onSubmit={handlePaginateKeyUp}>
<fieldset-group class="fieldset-group--smushed fieldgroup--paginate">
<fieldset-section>
<ReactPaginate
pageCount={totalPages}
pageRangeDisplayed={2}
previousLabel=""
nextLabel=""
activeClassName="pagination__item--selected"
pageClassName="pagination__item"
previousClassName="pagination__item pagination__item--previous"
nextClassName="pagination__item pagination__item--next"
breakClassName="pagination__item pagination__item--break"
marginPagesDisplayed={2}
onPageChange={(e) => handleChangePage(e.selected + 1)}
forcePage={currentPage - 1}
initialPage={currentPage - 1}
containerClassName="pagination"
/>
</fieldset-section>
{!isMobile && (
<FormField
value={textValue}
onChange={(e) => setTextValue(e.target.value)}
className="paginate-channel"
label={__('Go to page:')}
type="text"
name="paginate-file"
/>
)}
</fieldset-group>
</Form>
);
}
export default withRouter(Paginate);