Add pagination support to channel search (#791)
* Add pagination support to channel search * fix #605 - channelContent component - replace lighthouse.search() to doSearch() * #605 - Add pagination support to channel search - create ClaimListSearch component to support channel search instead of ClaimListDiscover * #605 - Add pagination support to channel search - fix lint errors & component naming error Co-authored-by: Kyle <kyle.mai@wiredcraft.com>
This commit is contained in:
parent
2606758c0d
commit
b3c4ce05fa
6 changed files with 400 additions and 69 deletions
|
@ -7,7 +7,6 @@ import {
|
||||||
makeSelectTotalPagesInChannelSearch,
|
makeSelectTotalPagesInChannelSearch,
|
||||||
selectClaimForUri,
|
selectClaimForUri,
|
||||||
} from 'redux/selectors/claims';
|
} from 'redux/selectors/claims';
|
||||||
import { doResolveUris } from 'redux/actions/claims';
|
|
||||||
import * as SETTINGS from 'constants/settings';
|
import * as SETTINGS from 'constants/settings';
|
||||||
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
import { makeSelectChannelIsMuted } from 'redux/selectors/blocked';
|
||||||
import { withRouter } from 'react-router';
|
import { withRouter } from 'react-router';
|
||||||
|
@ -41,7 +40,6 @@ const select = (state, props) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const perform = (dispatch) => ({
|
const perform = (dispatch) => ({
|
||||||
doResolveUris: (uris, returnCachedUris) => dispatch(doResolveUris(uris, returnCachedUris)),
|
|
||||||
doFetchChannelLiveStatus: (channelID) => dispatch(doFetchChannelLiveStatus(channelID)),
|
doFetchChannelLiveStatus: (channelID) => dispatch(doFetchChannelLiveStatus(channelID)),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,14 @@ import HiddenNsfwClaims from 'component/hiddenNsfwClaims';
|
||||||
import { useHistory } from 'react-router-dom';
|
import { useHistory } from 'react-router-dom';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
import ClaimListDiscover from 'component/claimListDiscover';
|
import ClaimListDiscover from 'component/claimListDiscover';
|
||||||
|
import ClaimListSearch from 'component/claimListSearch';
|
||||||
import Ads from 'web/component/ads';
|
import Ads from 'web/component/ads';
|
||||||
import Icon from 'component/common/icon';
|
import Icon from 'component/common/icon';
|
||||||
import LivestreamLink from 'component/livestreamLink';
|
import LivestreamLink from 'component/livestreamLink';
|
||||||
import { Form, FormField } from 'component/common/form';
|
import { Form, FormField } from 'component/common/form';
|
||||||
import { DEBOUNCE_WAIT_DURATION_MS } from 'constants/search';
|
import { DEBOUNCE_WAIT_DURATION_MS } from 'constants/search';
|
||||||
import { lighthouse } from 'redux/actions/search';
|
|
||||||
import ScheduledStreams from 'component/scheduledStreams';
|
import ScheduledStreams from 'component/scheduledStreams';
|
||||||
|
import { useIsLargeScreen } from 'effects/use-screensize';
|
||||||
|
|
||||||
const TYPES_TO_ALLOW_FILTER = ['stream', 'repost'];
|
const TYPES_TO_ALLOW_FILTER = ['stream', 'repost'];
|
||||||
|
|
||||||
|
@ -34,7 +35,6 @@ type Props = {
|
||||||
showMature: boolean,
|
showMature: boolean,
|
||||||
tileLayout: boolean,
|
tileLayout: boolean,
|
||||||
viewHiddenChannels: boolean,
|
viewHiddenChannels: boolean,
|
||||||
doResolveUris: (Array<string>, boolean) => void,
|
|
||||||
claimType: string,
|
claimType: string,
|
||||||
empty?: string,
|
empty?: string,
|
||||||
doFetchChannelLiveStatus: (string) => void,
|
doFetchChannelLiveStatus: (string) => void,
|
||||||
|
@ -56,7 +56,6 @@ function ChannelContent(props: Props) {
|
||||||
showMature,
|
showMature,
|
||||||
tileLayout,
|
tileLayout,
|
||||||
viewHiddenChannels,
|
viewHiddenChannels,
|
||||||
doResolveUris,
|
|
||||||
claimType,
|
claimType,
|
||||||
empty,
|
empty,
|
||||||
doFetchChannelLiveStatus,
|
doFetchChannelLiveStatus,
|
||||||
|
@ -66,7 +65,8 @@ function ChannelContent(props: Props) {
|
||||||
// const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
|
// const claimsInChannel = (claim && claim.meta.claims_in_channel) || 0;
|
||||||
const claimsInChannel = 9999;
|
const claimsInChannel = 9999;
|
||||||
const [searchQuery, setSearchQuery] = React.useState('');
|
const [searchQuery, setSearchQuery] = React.useState('');
|
||||||
const [searchResults, setSearchResults] = React.useState(undefined);
|
const [isSearch, setIsSearch] = React.useState(false);
|
||||||
|
const isLargeScreen = useIsLargeScreen();
|
||||||
const {
|
const {
|
||||||
location: { pathname, search },
|
location: { pathname, search },
|
||||||
} = useHistory();
|
} = useHistory();
|
||||||
|
@ -78,6 +78,7 @@ function ChannelContent(props: Props) {
|
||||||
(Array.isArray(claimType)
|
(Array.isArray(claimType)
|
||||||
? claimType.every((ct) => TYPES_TO_ALLOW_FILTER.includes(ct))
|
? claimType.every((ct) => TYPES_TO_ALLOW_FILTER.includes(ct))
|
||||||
: TYPES_TO_ALLOW_FILTER.includes(claimType));
|
: TYPES_TO_ALLOW_FILTER.includes(claimType));
|
||||||
|
const dynamicPageSize = isLargeScreen ? Math.ceil(defaultPageSize * (3 / 2)) : defaultPageSize;
|
||||||
|
|
||||||
function handleInputChange(e) {
|
function handleInputChange(e) {
|
||||||
const { value } = e.target;
|
const { value } = e.target;
|
||||||
|
@ -87,38 +88,17 @@ function ChannelContent(props: Props) {
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
if (searchQuery.trim().length < 3 || !claimId) {
|
if (searchQuery.trim().length < 3 || !claimId) {
|
||||||
// In order to display original search results, search results must be set to null. A query of '' should display original results.
|
setIsSearch(false);
|
||||||
return setSearchResults(null);
|
|
||||||
} else {
|
} else {
|
||||||
lighthouse
|
setIsSearch(true);
|
||||||
.search(
|
|
||||||
`s=${encodeURIComponent(searchQuery)}&channel_id=${encodeURIComponent(claimId)}${
|
|
||||||
!showMature ? '&nsfw=false&size=50&from=0' : ''
|
|
||||||
}`
|
|
||||||
)
|
|
||||||
.then(({ body: results }) => {
|
|
||||||
const urls = results.map(({ name, claimId }) => {
|
|
||||||
return `lbry://${name}#${claimId}`;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Batch-resolve the urls before calling 'setSearchResults', as the
|
|
||||||
// latter will immediately cause the tiles to resolve, ending up
|
|
||||||
// calling doResolveUri one by one before the batched one.
|
|
||||||
doResolveUris(urls, true);
|
|
||||||
|
|
||||||
setSearchResults(urls);
|
|
||||||
})
|
|
||||||
.catch(() => {
|
|
||||||
setSearchResults(null);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}, DEBOUNCE_WAIT_DURATION_MS);
|
}, DEBOUNCE_WAIT_DURATION_MS);
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [claimId, searchQuery, showMature, doResolveUris]);
|
}, [claimId, searchQuery]);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setSearchQuery('');
|
setSearchQuery('');
|
||||||
setSearchResults(null);
|
setIsSearch(false);
|
||||||
}, [url]);
|
}, [url]);
|
||||||
|
|
||||||
const isInitialized = Boolean(activeLivestreamForChannel) || activeLivestreamInitialized;
|
const isInitialized = Boolean(activeLivestreamForChannel) || activeLivestreamInitialized;
|
||||||
|
@ -177,7 +157,44 @@ function ChannelContent(props: Props) {
|
||||||
|
|
||||||
{/* <Ads type="homepage" /> */}
|
{/* <Ads type="homepage" /> */}
|
||||||
|
|
||||||
{!fetching && (
|
{!fetching &&
|
||||||
|
(isSearch ? (
|
||||||
|
<ClaimListSearch
|
||||||
|
defaultFreshness={CS.FRESH_ALL}
|
||||||
|
showHiddenByUser={viewHiddenChannels}
|
||||||
|
fetchViewCount
|
||||||
|
hideFilters={!showFilters}
|
||||||
|
hideAdvancedFilter={!showFilters}
|
||||||
|
tileLayout={tileLayout}
|
||||||
|
streamType={SIMPLE_SITE ? CS.CONTENT_ALL : undefined}
|
||||||
|
channelIds={[claimId]}
|
||||||
|
claimId={claimId}
|
||||||
|
claimType={claimType}
|
||||||
|
feeAmount={CS.FEE_AMOUNT_ANY}
|
||||||
|
defaultOrderBy={CS.ORDER_BY_NEW}
|
||||||
|
pageSize={dynamicPageSize}
|
||||||
|
infiniteScroll={defaultInfiniteScroll}
|
||||||
|
injectedItem={SHOW_ADS && !isAuthenticated && IS_WEB && <Ads type="video" />}
|
||||||
|
meta={
|
||||||
|
showFilters && (
|
||||||
|
<Form onSubmit={() => {}} className="wunderbar--inline">
|
||||||
|
<Icon icon={ICONS.SEARCH} />
|
||||||
|
<FormField
|
||||||
|
className="wunderbar__input--inline"
|
||||||
|
value={searchQuery}
|
||||||
|
onChange={handleInputChange}
|
||||||
|
type="text"
|
||||||
|
placeholder={__('Search')}
|
||||||
|
/>
|
||||||
|
</Form>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
channelIsMine={channelIsMine}
|
||||||
|
empty={empty}
|
||||||
|
showMature={showMature}
|
||||||
|
searchKeyword={searchQuery}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
<ClaimListDiscover
|
<ClaimListDiscover
|
||||||
hasSource
|
hasSource
|
||||||
defaultFreshness={CS.FRESH_ALL}
|
defaultFreshness={CS.FRESH_ALL}
|
||||||
|
@ -187,7 +204,6 @@ function ChannelContent(props: Props) {
|
||||||
hideFilters={!showFilters}
|
hideFilters={!showFilters}
|
||||||
hideAdvancedFilter={!showFilters}
|
hideAdvancedFilter={!showFilters}
|
||||||
tileLayout={tileLayout}
|
tileLayout={tileLayout}
|
||||||
uris={searchResults}
|
|
||||||
streamType={SIMPLE_SITE ? CS.CONTENT_ALL : undefined}
|
streamType={SIMPLE_SITE ? CS.CONTENT_ALL : undefined}
|
||||||
channelIds={[claimId]}
|
channelIds={[claimId]}
|
||||||
claimType={claimType}
|
claimType={claimType}
|
||||||
|
@ -214,7 +230,7 @@ function ChannelContent(props: Props) {
|
||||||
channelIsMine={channelIsMine}
|
channelIsMine={channelIsMine}
|
||||||
empty={empty}
|
empty={empty}
|
||||||
/>
|
/>
|
||||||
)}
|
))}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
47
ui/component/claimListSearch/index.js
Normal file
47
ui/component/claimListSearch/index.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
import { connect } from 'react-redux';
|
||||||
|
import { selectClaimsByUri } from 'redux/selectors/claims';
|
||||||
|
import {
|
||||||
|
selectIsSearching,
|
||||||
|
makeSelectSearchUrisForQuery,
|
||||||
|
makeSelectHasReachedMaxResultsLength,
|
||||||
|
} from 'redux/selectors/search';
|
||||||
|
import { getSearchQueryString } from 'util/query-params';
|
||||||
|
import { doSearch } from 'redux/actions/search';
|
||||||
|
import ClaimListSearch from './view';
|
||||||
|
import { doFetchViewCount } from 'lbryinc';
|
||||||
|
|
||||||
|
const select = (state, props) => {
|
||||||
|
const { searchKeyword, pageSize, claimId, showMature } = props;
|
||||||
|
const channel_id = encodeURIComponent(claimId);
|
||||||
|
const isBackgroundSearch = false;
|
||||||
|
const searchOptions = showMature
|
||||||
|
? {
|
||||||
|
channel_id,
|
||||||
|
isBackgroundSearch,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
channel_id,
|
||||||
|
size: pageSize,
|
||||||
|
nsfw: false,
|
||||||
|
isBackgroundSearch,
|
||||||
|
};
|
||||||
|
|
||||||
|
const searchQueryString = getSearchQueryString(searchKeyword, searchOptions);
|
||||||
|
const searchResult = makeSelectSearchUrisForQuery(searchQueryString)(state);
|
||||||
|
const searchResultLastPageReached = makeSelectHasReachedMaxResultsLength(searchQueryString)(state);
|
||||||
|
|
||||||
|
return {
|
||||||
|
claimsByUri: selectClaimsByUri(state),
|
||||||
|
loading: props.loading !== undefined ? props.loading : selectIsSearching(state),
|
||||||
|
searchOptions,
|
||||||
|
searchResult,
|
||||||
|
searchResultLastPageReached,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const perform = {
|
||||||
|
doFetchViewCount,
|
||||||
|
doSearch,
|
||||||
|
};
|
||||||
|
|
||||||
|
export default connect(select, perform)(ClaimListSearch);
|
267
ui/component/claimListSearch/view.jsx
Normal file
267
ui/component/claimListSearch/view.jsx
Normal file
|
@ -0,0 +1,267 @@
|
||||||
|
// @flow
|
||||||
|
import { SIMPLE_SITE } from 'config';
|
||||||
|
import type { Node } from 'react';
|
||||||
|
import * as CS from 'constants/claim_search';
|
||||||
|
import React from 'react';
|
||||||
|
import { withRouter } from 'react-router';
|
||||||
|
import { MATURE_TAGS } from 'constants/tags';
|
||||||
|
import ClaimList from 'component/claimList';
|
||||||
|
import ClaimPreview from 'component/claimPreview';
|
||||||
|
import ClaimPreviewTile from 'component/claimPreviewTile';
|
||||||
|
import ClaimListHeader from 'component/claimListHeader';
|
||||||
|
import useFetchViewCount from 'effects/use-fetch-view-count';
|
||||||
|
|
||||||
|
export type SearchOptions = {
|
||||||
|
size?: number,
|
||||||
|
from?: number,
|
||||||
|
related_to?: string,
|
||||||
|
nsfw?: boolean,
|
||||||
|
channel_id?: string,
|
||||||
|
isBackgroundSearch?: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
uris: Array<string>,
|
||||||
|
type: string,
|
||||||
|
pageSize: number,
|
||||||
|
|
||||||
|
fetchViewCount?: boolean,
|
||||||
|
hideAdvancedFilter?: boolean,
|
||||||
|
hideFilters?: boolean,
|
||||||
|
infiniteScroll?: Boolean,
|
||||||
|
showHeader: boolean,
|
||||||
|
showHiddenByUser?: boolean,
|
||||||
|
tileLayout: boolean,
|
||||||
|
|
||||||
|
defaultOrderBy?: string,
|
||||||
|
defaultFreshness?: string,
|
||||||
|
|
||||||
|
tags: string, // these are just going to be string. pass a CSV if you want multi
|
||||||
|
defaultTags: string,
|
||||||
|
|
||||||
|
claimType?: string | Array<string>,
|
||||||
|
|
||||||
|
streamType?: string | Array<string>,
|
||||||
|
defaultStreamType?: string | Array<string>,
|
||||||
|
|
||||||
|
empty?: string,
|
||||||
|
feeAmount?: string,
|
||||||
|
repostedClaimId?: string,
|
||||||
|
maxPages?: number,
|
||||||
|
|
||||||
|
channelIds?: Array<string>,
|
||||||
|
claimId: string,
|
||||||
|
|
||||||
|
header?: Node,
|
||||||
|
headerLabel?: string | Node,
|
||||||
|
injectedItem: ?Node,
|
||||||
|
meta?: Node,
|
||||||
|
|
||||||
|
location: { search: string, pathname: string },
|
||||||
|
|
||||||
|
// --- select ---
|
||||||
|
claimsByUri: { [string]: any },
|
||||||
|
loading: boolean,
|
||||||
|
searchResult: Array<string>,
|
||||||
|
searchResultLastPageReached: boolean,
|
||||||
|
|
||||||
|
// --- perform ---
|
||||||
|
doFetchViewCount: (claimIdCsv: string) => void,
|
||||||
|
doSearch: (query: string, options: SearchOptions) => void,
|
||||||
|
|
||||||
|
hideLayoutButton?: boolean,
|
||||||
|
maxClaimRender?: number,
|
||||||
|
useSkeletonScreen?: boolean,
|
||||||
|
excludeUris?: Array<string>,
|
||||||
|
|
||||||
|
swipeLayout: boolean,
|
||||||
|
|
||||||
|
showMature: boolean,
|
||||||
|
searchKeyword: string,
|
||||||
|
searchOptions: SearchOptions,
|
||||||
|
};
|
||||||
|
|
||||||
|
function ClaimListSearch(props: Props) {
|
||||||
|
const {
|
||||||
|
showHeader = true,
|
||||||
|
type,
|
||||||
|
tags,
|
||||||
|
defaultTags,
|
||||||
|
loading,
|
||||||
|
meta,
|
||||||
|
channelIds,
|
||||||
|
// eslint-disable-next-line no-unused-vars
|
||||||
|
claimId,
|
||||||
|
fetchViewCount,
|
||||||
|
location,
|
||||||
|
defaultOrderBy,
|
||||||
|
headerLabel,
|
||||||
|
header,
|
||||||
|
claimType,
|
||||||
|
pageSize,
|
||||||
|
streamType,
|
||||||
|
defaultStreamType = SIMPLE_SITE ? [CS.FILE_VIDEO, CS.FILE_AUDIO] : undefined, // add param for DEFAULT_STREAM_TYPE
|
||||||
|
defaultFreshness = CS.FRESH_WEEK,
|
||||||
|
repostedClaimId,
|
||||||
|
hideAdvancedFilter,
|
||||||
|
infiniteScroll = true,
|
||||||
|
injectedItem,
|
||||||
|
feeAmount,
|
||||||
|
uris,
|
||||||
|
tileLayout,
|
||||||
|
hideFilters = false,
|
||||||
|
maxPages,
|
||||||
|
showHiddenByUser = false,
|
||||||
|
empty,
|
||||||
|
claimsByUri,
|
||||||
|
doFetchViewCount,
|
||||||
|
hideLayoutButton = false,
|
||||||
|
maxClaimRender,
|
||||||
|
useSkeletonScreen = true,
|
||||||
|
excludeUris = [],
|
||||||
|
swipeLayout = false,
|
||||||
|
|
||||||
|
// search
|
||||||
|
showMature,
|
||||||
|
searchKeyword,
|
||||||
|
searchOptions,
|
||||||
|
searchResult,
|
||||||
|
searchResultLastPageReached,
|
||||||
|
doSearch,
|
||||||
|
} = props;
|
||||||
|
const { search } = location;
|
||||||
|
const [page, setPage] = React.useState(1);
|
||||||
|
const urlParams = new URLSearchParams(search);
|
||||||
|
const tagsParam = // can be 'x,y,z' or 'x' or ['x','y'] or CS.CONSTANT
|
||||||
|
(tags && getParamFromTags(tags)) ||
|
||||||
|
(urlParams.get(CS.TAGS_KEY) !== null && urlParams.get(CS.TAGS_KEY)) ||
|
||||||
|
(defaultTags && getParamFromTags(defaultTags));
|
||||||
|
const hasMatureTags = tagsParam && tagsParam.split(',').some((t) => MATURE_TAGS.includes(t));
|
||||||
|
|
||||||
|
const renderUris = uris || searchResult;
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// Helpers
|
||||||
|
// **************************************************************************
|
||||||
|
function getParamFromTags(t) {
|
||||||
|
if (t === CS.TAGS_ALL || t === CS.TAGS_FOLLOWED) {
|
||||||
|
return t;
|
||||||
|
} else if (Array.isArray(t)) {
|
||||||
|
return t.join(',');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleScrollBottom() {
|
||||||
|
if (maxPages !== undefined && page === maxPages) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!loading && infiniteScroll) {
|
||||||
|
if (searchResult && !searchResultLastPageReached) {
|
||||||
|
setPage(page + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
useFetchViewCount(fetchViewCount, renderUris, claimsByUri, doFetchViewCount);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
doSearch(
|
||||||
|
searchKeyword,
|
||||||
|
showMature
|
||||||
|
? searchOptions
|
||||||
|
: {
|
||||||
|
...searchOptions,
|
||||||
|
from: pageSize * (page - 1),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}, [doSearch, searchKeyword, showMature, pageSize, page]);
|
||||||
|
|
||||||
|
const headerToUse = header || (
|
||||||
|
<ClaimListHeader
|
||||||
|
channelIds={channelIds}
|
||||||
|
defaultTags={defaultTags}
|
||||||
|
tags={tags}
|
||||||
|
defaultFreshness={defaultFreshness}
|
||||||
|
claimType={claimType}
|
||||||
|
streamType={streamType}
|
||||||
|
defaultStreamType={defaultStreamType}
|
||||||
|
feeAmount={feeAmount} // ENABLE_PAID_CONTENT_DISCOVER or something
|
||||||
|
defaultOrderBy={defaultOrderBy}
|
||||||
|
hideAdvancedFilter={hideAdvancedFilter}
|
||||||
|
hasMatureTags={hasMatureTags}
|
||||||
|
setPage={setPage}
|
||||||
|
tileLayout={tileLayout}
|
||||||
|
hideLayoutButton={hideLayoutButton}
|
||||||
|
hideFilters={hideFilters}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
{headerLabel && <label className="claim-list__header-label">{headerLabel}</label>}
|
||||||
|
{tileLayout ? (
|
||||||
|
<div>
|
||||||
|
{!repostedClaimId && (
|
||||||
|
<div className="section__header--actions">
|
||||||
|
{headerToUse}
|
||||||
|
{meta && <div className="section__actions--no-margin">{meta}</div>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ClaimList
|
||||||
|
tileLayout
|
||||||
|
loading={loading}
|
||||||
|
uris={renderUris}
|
||||||
|
onScrollBottom={handleScrollBottom}
|
||||||
|
page={page}
|
||||||
|
pageSize={pageSize}
|
||||||
|
injectedItem={injectedItem}
|
||||||
|
showHiddenByUser={showHiddenByUser}
|
||||||
|
empty={empty}
|
||||||
|
maxClaimRender={maxClaimRender}
|
||||||
|
excludeUris={excludeUris}
|
||||||
|
swipeLayout={swipeLayout}
|
||||||
|
/>
|
||||||
|
{loading && useSkeletonScreen && (
|
||||||
|
<div className="claim-grid">
|
||||||
|
{new Array(pageSize).fill(1).map((x, i) => (
|
||||||
|
<ClaimPreviewTile key={i} placeholder="loading" />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
{showHeader && (
|
||||||
|
<div className="section__header--actions">
|
||||||
|
{headerToUse}
|
||||||
|
{meta && <div className="section__actions--no-margin">{meta}</div>}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<ClaimList
|
||||||
|
type={type}
|
||||||
|
loading={loading}
|
||||||
|
uris={renderUris}
|
||||||
|
onScrollBottom={handleScrollBottom}
|
||||||
|
page={page}
|
||||||
|
pageSize={pageSize}
|
||||||
|
injectedItem={injectedItem}
|
||||||
|
showHiddenByUser={showHiddenByUser}
|
||||||
|
empty={empty}
|
||||||
|
maxClaimRender={maxClaimRender}
|
||||||
|
excludeUris={excludeUris}
|
||||||
|
swipeLayout={swipeLayout}
|
||||||
|
/>
|
||||||
|
{loading &&
|
||||||
|
useSkeletonScreen &&
|
||||||
|
new Array(pageSize).fill(1).map((x, i) => <ClaimPreview key={i} placeholder="loading" type={type} />)}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withRouter(ClaimListSearch);
|
|
@ -34,6 +34,7 @@ export const SEARCH_OPTIONS = {
|
||||||
TIME_FILTER_THIS_WEEK: 'thisweek',
|
TIME_FILTER_THIS_WEEK: 'thisweek',
|
||||||
TIME_FILTER_THIS_MONTH: 'thismonth',
|
TIME_FILTER_THIS_MONTH: 'thismonth',
|
||||||
TIME_FILTER_THIS_YEAR: 'thisyear',
|
TIME_FILTER_THIS_YEAR: 'thisyear',
|
||||||
|
CHANNEL_ID: 'channel_id',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const SEARCH_PAGE_SIZE = 20;
|
export const SEARCH_PAGE_SIZE = 20;
|
||||||
|
|
|
@ -80,10 +80,12 @@ export const getSearchQueryString = (query: string, options: any = {}) => {
|
||||||
const { related_to } = options;
|
const { related_to } = options;
|
||||||
const { nsfw } = options;
|
const { nsfw } = options;
|
||||||
const { free_only } = options;
|
const { free_only } = options;
|
||||||
|
const { channel_id } = options;
|
||||||
|
|
||||||
if (related_to) additionalOptions[SEARCH_OPTIONS.RELATED_TO] = related_to;
|
if (related_to) additionalOptions[SEARCH_OPTIONS.RELATED_TO] = related_to;
|
||||||
if (free_only) additionalOptions[SEARCH_OPTIONS.PRICE_FILTER_FREE] = true;
|
if (free_only) additionalOptions[SEARCH_OPTIONS.PRICE_FILTER_FREE] = true;
|
||||||
if (nsfw === false) additionalOptions[SEARCH_OPTIONS.INCLUDE_MATURE] = false;
|
if (nsfw === false) additionalOptions[SEARCH_OPTIONS.INCLUDE_MATURE] = false;
|
||||||
|
if (channel_id) additionalOptions[SEARCH_OPTIONS.CHANNEL_ID] = channel_id;
|
||||||
|
|
||||||
if (additionalOptions) {
|
if (additionalOptions) {
|
||||||
Object.keys(additionalOptions).forEach((key) => {
|
Object.keys(additionalOptions).forEach((key) => {
|
||||||
|
|
Loading…
Add table
Reference in a new issue