Channel Page: enable filters; add "sort by" filter (#7069)
* Sort props to clarify "client vs. redux". No functional change. * ClaimListHeader: remove SIMPLE_SITE gating * Channel Page: enable filters; add "sort by" filter. ## Issue 7059 Add option to sort oldest first on channel page ## Changes - Enabled filters for Odysee. - Added a new "Sort By" filter, which will only appear for "New" ordering. It doesn't make sense for "Trending" or "Top".
This commit is contained in:
parent
67d9f3907f
commit
30fedf6b45
3 changed files with 68 additions and 11 deletions
|
@ -38,8 +38,9 @@ type Props = {
|
|||
showNoSourceClaims?: boolean,
|
||||
tileLayout: boolean,
|
||||
|
||||
orderBy?: Array<string>,
|
||||
orderBy?: Array<string>, // Trending, New, Top
|
||||
defaultOrderBy?: string,
|
||||
sortBy?: Array<string>, // Newest First, Oldest First
|
||||
freshness?: string,
|
||||
defaultFreshness?: string,
|
||||
|
||||
|
@ -115,6 +116,7 @@ function ClaimListDiscover(props: Props) {
|
|||
blockedUris,
|
||||
hiddenNsfwMessage,
|
||||
defaultOrderBy,
|
||||
sortBy,
|
||||
orderBy,
|
||||
headerLabel,
|
||||
header,
|
||||
|
@ -170,6 +172,7 @@ function ClaimListDiscover(props: Props) {
|
|||
(urlParams.get(CS.TAGS_KEY) !== null && urlParams.get(CS.TAGS_KEY)) ||
|
||||
(defaultTags && getParamFromTags(defaultTags));
|
||||
const freshnessParam = freshness || urlParams.get(CS.FRESH_KEY) || defaultFreshness;
|
||||
const sortByParam = sortBy || urlParams.get(CS.SORT_BY_KEY) || CS.SORT_BY.NEWEST.key;
|
||||
const mutedAndBlockedChannelIds = Array.from(
|
||||
new Set(mutedUris.concat(blockedUris).map((uri) => splitBySeparator(uri)[1]))
|
||||
);
|
||||
|
@ -255,12 +258,7 @@ function ClaimListDiscover(props: Props) {
|
|||
no_totals: true,
|
||||
not_channel_ids: isChannel ? undefined : mutedAndBlockedChannelIds,
|
||||
not_tags: !showNsfw ? MATURE_TAGS : [],
|
||||
order_by:
|
||||
orderParam === CS.ORDER_BY_TRENDING
|
||||
? CS.ORDER_BY_TRENDING_VALUE
|
||||
: orderParam === CS.ORDER_BY_NEW
|
||||
? CS.ORDER_BY_NEW_VALUE
|
||||
: CS.ORDER_BY_TOP_VALUE, // Sort by top
|
||||
order_by: resolveOrderByOption(orderParam, sortByParam),
|
||||
};
|
||||
|
||||
if (ENABLE_NO_SOURCE_CLAIMS && hasNoSource) {
|
||||
|
@ -551,6 +549,21 @@ function ClaimListDiscover(props: Props) {
|
|||
}
|
||||
}
|
||||
|
||||
function resolveOrderByOption(orderBy: string | Array<string>, sortBy: string | Array<string>) {
|
||||
const order_by =
|
||||
orderBy === CS.ORDER_BY_TRENDING
|
||||
? CS.ORDER_BY_TRENDING_VALUE
|
||||
: orderBy === CS.ORDER_BY_NEW
|
||||
? CS.ORDER_BY_NEW_VALUE
|
||||
: CS.ORDER_BY_TOP_VALUE;
|
||||
|
||||
if (orderBy === CS.ORDER_BY_NEW && sortBy === CS.SORT_BY.OLDEST.key) {
|
||||
return order_by.map((x) => `${CS.SORT_BY.OLDEST.opt}${x}`);
|
||||
}
|
||||
|
||||
return order_by;
|
||||
}
|
||||
|
||||
// **************************************************************************
|
||||
// **************************************************************************
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// @flow
|
||||
import { SIMPLE_SITE } from 'config';
|
||||
import * as CS from 'constants/claim_search';
|
||||
import * as ICONS from 'constants/icons';
|
||||
import type { Node } from 'react';
|
||||
|
@ -21,6 +20,7 @@ type Props = {
|
|||
streamType?: string | Array<string>,
|
||||
defaultStreamType?: string | Array<string>,
|
||||
feeAmount: string,
|
||||
sortBy?: string,
|
||||
orderBy?: Array<string>,
|
||||
defaultOrderBy?: string,
|
||||
hideAdvancedFilter: boolean,
|
||||
|
@ -45,6 +45,7 @@ function ClaimListHeader(props: Props) {
|
|||
streamType,
|
||||
defaultStreamType,
|
||||
feeAmount,
|
||||
sortBy,
|
||||
orderBy,
|
||||
defaultOrderBy,
|
||||
hideAdvancedFilter,
|
||||
|
@ -71,6 +72,7 @@ function ClaimListHeader(props: Props) {
|
|||
streamType || (CS.FILE_TYPES.includes(contentTypeParam) && contentTypeParam) || defaultStreamType || null;
|
||||
const durationParam = urlParams.get(CS.DURATION_KEY) || null;
|
||||
const languageParam = urlParams.get(CS.LANGUAGE_KEY) || null;
|
||||
const sortByParam = sortBy || urlParams.get(CS.SORT_BY_KEY) || null;
|
||||
const channelIdsInUrl = urlParams.get(CS.CHANNEL_IDS_KEY);
|
||||
const channelIdsParam = channelIdsInUrl ? channelIdsInUrl.split(',') : channelIds;
|
||||
const feeAmountParam = urlParams.get('fee_amount') || feeAmount || CS.FEE_AMOUNT_ANY;
|
||||
|
@ -153,6 +155,13 @@ function ClaimListHeader(props: Props) {
|
|||
case CS.ORDER_BY_KEY:
|
||||
newUrlParams.set(CS.ORDER_BY_KEY, delta.value);
|
||||
break;
|
||||
case CS.SORT_BY_KEY:
|
||||
if (delta.value === CS.SORT_BY.NEWEST.key) {
|
||||
newUrlParams.delete(CS.SORT_BY_KEY);
|
||||
} else {
|
||||
newUrlParams.set(CS.SORT_BY_KEY, delta.value);
|
||||
}
|
||||
break;
|
||||
case CS.FRESH_KEY:
|
||||
if (delta.value === defaultFreshness || delta.value === CS.FRESH_DEFAULT) {
|
||||
newUrlParams.delete(CS.FRESH_KEY);
|
||||
|
@ -240,7 +249,7 @@ function ClaimListHeader(props: Props) {
|
|||
</div>
|
||||
)}
|
||||
<div className="claim-search__menu-group">
|
||||
{!hideAdvancedFilter && !SIMPLE_SITE && (
|
||||
{!hideAdvancedFilter && (
|
||||
<Button
|
||||
button="alt"
|
||||
aria-label={__('More')}
|
||||
|
@ -266,7 +275,7 @@ function ClaimListHeader(props: Props) {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{expanded && !SIMPLE_SITE && (
|
||||
{expanded && (
|
||||
<>
|
||||
<div className={classnames(`card claim-search__menus`)}>
|
||||
{/* FRESHNESS FIELD */}
|
||||
|
@ -449,6 +458,32 @@ function ClaimListHeader(props: Props) {
|
|||
</FormField>
|
||||
</div>
|
||||
|
||||
{/* SORT FIELD */}
|
||||
{orderParam === CS.ORDER_BY_NEW && (
|
||||
<div className={'claim-search__input-container'}>
|
||||
<FormField
|
||||
className={classnames('claim-search__dropdown', {
|
||||
'claim-search__dropdown--selected': sortByParam,
|
||||
})}
|
||||
label={__('Sort By')}
|
||||
type="select"
|
||||
name="sort_by"
|
||||
value={sortByParam || CS.SORT_BY.NEWEST.key}
|
||||
onChange={(e) => handleChange({ key: CS.SORT_BY_KEY, value: e.target.value })}
|
||||
>
|
||||
{Object.entries(CS.SORT_BY).map(([key, value]) => {
|
||||
return (
|
||||
// $FlowFixMe https://github.com/facebook/flow/issues/2221
|
||||
<option key={value.key} value={value.key}>
|
||||
{/* $FlowFixMe */}
|
||||
{__(value.str)}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</FormField>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{channelIdsInUrl && (
|
||||
<div className={'claim-search__input-container'}>
|
||||
<label>{__('Advanced Filters from URL')}</label>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
export const PAGE_SIZE = 20;
|
||||
|
||||
export const FRESH_KEY = 'fresh';
|
||||
export const ORDER_BY_KEY = 'order';
|
||||
export const ORDER_BY_KEY = 'order'; // Trending, Top, New
|
||||
export const SORT_BY_KEY = 'sort'; // Newest vs Oldest First
|
||||
export const DURATION_KEY = 'duration';
|
||||
export const LANGUAGE_KEY = 'language';
|
||||
export const TAGS_KEY = 't';
|
||||
|
@ -39,6 +40,14 @@ export const DURATION_LONG = 'long';
|
|||
export const DURATION_ALL = 'all';
|
||||
export const DURATION_TYPES = [DURATION_ALL, DURATION_SHORT, DURATION_LONG];
|
||||
|
||||
export const SORT_BY = {
|
||||
// key: Enumeration; can be anything as long as unique. Also used as URLParam.
|
||||
// opt: Value to use for 'claim_search' options; for this case, it is the prefix to 'order_by'.
|
||||
// str: Customer-facing string representation.
|
||||
NEWEST: { key: 'new', opt: '', str: 'Newest first' },
|
||||
OLDEST: { key: 'old', opt: '^', str: 'Oldest first' },
|
||||
};
|
||||
|
||||
export const FILE_VIDEO = 'video';
|
||||
export const FILE_AUDIO = 'audio';
|
||||
export const FILE_DOCUMENT = 'document';
|
||||
|
|
Loading…
Reference in a new issue