Revamp search filters
## Issue 4945: Simplify / revamp search filters for odysee (and lbry.tv) ## Changes - Tweaked the "claim type = file | channel | everything" a little to hopefully make it more intuitive. - Added "Sort By". - Added "Upload Date". - Fixed the affected files to handle both Desktop and Odysee. - Tweaked the layout to be more condensed so that we can see some results as we change the filter. - Added animations. - Added "Exact match" option that helps user to surround with quotes.
This commit is contained in:
parent
a9cae23d87
commit
5421a64b65
6 changed files with 300 additions and 96 deletions
|
@ -175,7 +175,6 @@
|
||||||
"These search results are provided by LBRY, Inc.": "These search results are provided by LBRY, Inc.",
|
"These search results are provided by LBRY, Inc.": "These search results are provided by LBRY, Inc.",
|
||||||
"FILTER": "FILTER",
|
"FILTER": "FILTER",
|
||||||
"View file": "View file",
|
"View file": "View file",
|
||||||
"Search For": "Search For",
|
|
||||||
"Files": "Files",
|
"Files": "Files",
|
||||||
"Channels": "Channels",
|
"Channels": "Channels",
|
||||||
"Everything": "Everything",
|
"Everything": "Everything",
|
||||||
|
@ -184,6 +183,15 @@
|
||||||
"Other": "Other",
|
"Other": "Other",
|
||||||
"Other Options": "Other Options",
|
"Other Options": "Other Options",
|
||||||
"Returned Results": "Returned Results",
|
"Returned Results": "Returned Results",
|
||||||
|
"Find results that include all the given words in the exact order.\nThis can also be done by surrounding the search query with quotation marks (e.g. \"hello world\").": "Find results that include all the given words in the exact order.\nThis can also be done by surrounding the search query with quotation marks (e.g. \"hello world\").",
|
||||||
|
"Last Hour": "Last Hour",
|
||||||
|
"Last 24 Hours": "Last 24 Hours",
|
||||||
|
"Relevance": "Relevance",
|
||||||
|
"Newest first": "Newest first",
|
||||||
|
"Oldest first": "Oldest first",
|
||||||
|
"Exact match": "Exact match",
|
||||||
|
"Upload Date": "Upload Date",
|
||||||
|
"Sort By": "Sort By",
|
||||||
"Custom Code": "Custom Code",
|
"Custom Code": "Custom Code",
|
||||||
"Are you a supermodel or rockstar that received a custom reward code? Claim it here.": "Are you a supermodel or rockstar that received a custom reward code? Claim it here.",
|
"Are you a supermodel or rockstar that received a custom reward code? Claim it here.": "Are you a supermodel or rockstar that received a custom reward code? Claim it here.",
|
||||||
"Go To Invites": "Go To Invites",
|
"Go To Invites": "Go To Invites",
|
||||||
|
|
|
@ -195,6 +195,19 @@ export const icons = {
|
||||||
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" />
|
<path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z" />
|
||||||
</g>
|
</g>
|
||||||
),
|
),
|
||||||
|
[ICONS.FILTER]: buildIcon(
|
||||||
|
<g>
|
||||||
|
<line x1="4" y1="21" x2="4" y2="14" />
|
||||||
|
<line x1="4" y1="10" x2="4" y2="3" />
|
||||||
|
<line x1="12" y1="21" x2="12" y2="12" />
|
||||||
|
<line x1="12" y1="8" x2="12" y2="3" />
|
||||||
|
<line x1="20" y1="21" x2="20" y2="16" />
|
||||||
|
<line x1="20" y1="12" x2="20" y2="3" />
|
||||||
|
<line x1="1" y1="14" x2="7" y2="14" />
|
||||||
|
<line x1="9" y1="8" x2="15" y2="8" />
|
||||||
|
<line x1="17" y1="16" x2="23" y2="16" />
|
||||||
|
</g>
|
||||||
|
),
|
||||||
[ICONS.ACCOUNT]: buildIcon(
|
[ICONS.ACCOUNT]: buildIcon(
|
||||||
<g>
|
<g>
|
||||||
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
|
<path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2" />
|
||||||
|
|
|
@ -4,16 +4,49 @@ import * as ICONS from 'constants/icons';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
import { Form, FormField } from 'component/common/form';
|
import { Form, FormField } from 'component/common/form';
|
||||||
import Button from 'component/button';
|
import Button from 'component/button';
|
||||||
|
import Icon from 'component/common/icon';
|
||||||
|
import classnames from 'classnames';
|
||||||
|
|
||||||
|
const CLAIM_TYPES = {
|
||||||
|
[SEARCH_OPTIONS.INCLUDE_FILES]: 'Files',
|
||||||
|
[SEARCH_OPTIONS.INCLUDE_CHANNELS]: 'Channels',
|
||||||
|
[SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS]: 'Everything',
|
||||||
|
};
|
||||||
|
|
||||||
|
const TYPES_ADVANCED = {
|
||||||
|
[SEARCH_OPTIONS.MEDIA_VIDEO]: 'Video',
|
||||||
|
[SEARCH_OPTIONS.MEDIA_AUDIO]: 'Audio',
|
||||||
|
[SEARCH_OPTIONS.MEDIA_IMAGE]: 'Image',
|
||||||
|
[SEARCH_OPTIONS.MEDIA_TEXT]: 'Text',
|
||||||
|
[SEARCH_OPTIONS.MEDIA_APPLICATION]: 'Other',
|
||||||
|
};
|
||||||
|
|
||||||
|
const TIME_FILTER = {
|
||||||
|
'': 'None',
|
||||||
|
[SEARCH_OPTIONS.TIME_FILTER_LAST_HOUR]: 'Last Hour',
|
||||||
|
[SEARCH_OPTIONS.TIME_FILTER_TODAY]: 'Last 24 Hours',
|
||||||
|
[SEARCH_OPTIONS.TIME_FILTER_THIS_WEEK]: 'This Week',
|
||||||
|
[SEARCH_OPTIONS.TIME_FILTER_THIS_MONTH]: 'This Month',
|
||||||
|
[SEARCH_OPTIONS.TIME_FILTER_THIS_YEAR]: 'This Year',
|
||||||
|
};
|
||||||
|
|
||||||
|
const SORT_BY = {
|
||||||
|
'': 'Relevance',
|
||||||
|
[SEARCH_OPTIONS.SORT_DESCENDING]: 'Newest first',
|
||||||
|
[SEARCH_OPTIONS.SORT_ACCENDING]: 'Oldest first',
|
||||||
|
};
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
setSearchOption: (string, boolean | string | number) => void,
|
setSearchOption: (string, boolean | string | number) => void,
|
||||||
options: {},
|
options: {},
|
||||||
|
simple: boolean,
|
||||||
expanded: boolean,
|
expanded: boolean,
|
||||||
toggleSearchExpanded: () => void,
|
toggleSearchExpanded: () => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
const SearchOptions = (props: Props) => {
|
const SearchOptions = (props: Props) => {
|
||||||
const { options, setSearchOption, expanded, toggleSearchExpanded } = props;
|
const { options, simple, setSearchOption, expanded, toggleSearchExpanded } = props;
|
||||||
|
|
||||||
const stringifiedOptions = JSON.stringify(options);
|
const stringifiedOptions = JSON.stringify(options);
|
||||||
const resultCount = options[SEARCH_OPTIONS.RESULT_COUNT];
|
const resultCount = options[SEARCH_OPTIONS.RESULT_COUNT];
|
||||||
|
|
||||||
|
@ -23,83 +56,104 @@ const SearchOptions = (props: Props) => {
|
||||||
return claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS);
|
return claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS);
|
||||||
}, [stringifiedOptions]);
|
}, [stringifiedOptions]);
|
||||||
|
|
||||||
return (
|
if (simple) {
|
||||||
<div>
|
delete TYPES_ADVANCED[SEARCH_OPTIONS.MEDIA_APPLICATION];
|
||||||
<Button
|
}
|
||||||
button="alt"
|
|
||||||
label={__('Filter')}
|
|
||||||
iconRight={expanded ? ICONS.UP : ICONS.DOWN}
|
|
||||||
onClick={toggleSearchExpanded}
|
|
||||||
/>
|
|
||||||
{expanded && (
|
|
||||||
<Form className="search__options">
|
|
||||||
<fieldset>
|
|
||||||
<legend className="search__legend">{__('Search For')}</legend>
|
|
||||||
{[
|
|
||||||
{
|
|
||||||
option: SEARCH_OPTIONS.INCLUDE_FILES,
|
|
||||||
label: __('Files'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
option: SEARCH_OPTIONS.INCLUDE_CHANNELS,
|
|
||||||
label: __('Channels'),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
option: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS,
|
|
||||||
label: __('Everything'),
|
|
||||||
},
|
|
||||||
].map(({ option, label }) => (
|
|
||||||
<FormField
|
|
||||||
key={option}
|
|
||||||
name={option}
|
|
||||||
type="radio"
|
|
||||||
blockWrap={false}
|
|
||||||
label={label}
|
|
||||||
checked={options[SEARCH_OPTIONS.CLAIM_TYPE] === option}
|
|
||||||
onChange={() => setSearchOption(SEARCH_OPTIONS.CLAIM_TYPE, option)}
|
|
||||||
/>
|
|
||||||
))}
|
|
||||||
</fieldset>
|
|
||||||
|
|
||||||
<fieldset disabled={isFilteringByChannel}>
|
function addRow(label: string, value: any) {
|
||||||
<legend className="search__legend">{__('Type')}</legend>
|
return (
|
||||||
{[
|
<tr>
|
||||||
{
|
<td>
|
||||||
option: SEARCH_OPTIONS.MEDIA_VIDEO,
|
<legend className="search__legend">{label}</legend>
|
||||||
label: __('Video'),
|
</td>
|
||||||
},
|
<td>{value}</td>
|
||||||
{
|
</tr>
|
||||||
option: SEARCH_OPTIONS.MEDIA_AUDIO,
|
);
|
||||||
label: __('Audio'),
|
}
|
||||||
},
|
|
||||||
{
|
const OBJ_TO_OPTION_ELEM = (obj) => {
|
||||||
option: SEARCH_OPTIONS.MEDIA_IMAGE,
|
return Object.entries(obj).map((x) => {
|
||||||
label: __('Image'),
|
return (
|
||||||
},
|
<option key={x[0]} value={x[0]}>
|
||||||
{
|
{__(String(x[1]))}
|
||||||
option: SEARCH_OPTIONS.MEDIA_TEXT,
|
</option>
|
||||||
label: __('Text'),
|
);
|
||||||
},
|
});
|
||||||
{
|
};
|
||||||
option: SEARCH_OPTIONS.MEDIA_APPLICATION,
|
|
||||||
label: __('Other'),
|
const typeElem = (
|
||||||
},
|
<>
|
||||||
].map(({ option, label }) => (
|
<div className="filter-values">
|
||||||
|
<div>
|
||||||
|
{Object.entries(CLAIM_TYPES).map((t) => {
|
||||||
|
const option = t[0];
|
||||||
|
if (option === SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<Button
|
||||||
|
key={option}
|
||||||
|
button="alt"
|
||||||
|
label={t[1]}
|
||||||
|
className={classnames(`button-toggle`, {
|
||||||
|
'button-toggle--active': options[SEARCH_OPTIONS.CLAIM_TYPE] === option,
|
||||||
|
})}
|
||||||
|
onClick={() => setSearchOption(SEARCH_OPTIONS.CLAIM_TYPE, option)}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
button="close"
|
||||||
|
className={classnames('close-button', {
|
||||||
|
'close-button--visible': options[SEARCH_OPTIONS.CLAIM_TYPE] !== SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS,
|
||||||
|
})}
|
||||||
|
icon={ICONS.REMOVE}
|
||||||
|
onClick={() => setSearchOption(SEARCH_OPTIONS.CLAIM_TYPE, SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="media-types">
|
||||||
|
{options[SEARCH_OPTIONS.CLAIM_TYPE] === SEARCH_OPTIONS.INCLUDE_FILES &&
|
||||||
|
Object.entries(TYPES_ADVANCED).map((t) => {
|
||||||
|
const option = t[0];
|
||||||
|
return (
|
||||||
<FormField
|
<FormField
|
||||||
key={option}
|
key={option}
|
||||||
name={option}
|
name={option}
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
blockWrap={false}
|
blockWrap={false}
|
||||||
disabled={options[SEARCH_OPTIONS.CLAIM_TYPE] === SEARCH_OPTIONS.INCLUDE_CHANNELS}
|
disabled={options[SEARCH_OPTIONS.CLAIM_TYPE] !== SEARCH_OPTIONS.INCLUDE_FILES}
|
||||||
label={label}
|
label={t[1]}
|
||||||
checked={!isFilteringByChannel && options[option]}
|
checked={!isFilteringByChannel && options[option]}
|
||||||
onChange={() => setSearchOption(option, !options[option])}
|
onChange={() => setSearchOption(option, !options[option])}
|
||||||
/>
|
/>
|
||||||
))}
|
);
|
||||||
</fieldset>
|
})}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
<fieldset>
|
const otherOptionsElem = (
|
||||||
<legend className="search__legend">{__('Other Options')}</legend>
|
<>
|
||||||
|
<div className="filter-values">
|
||||||
|
<FormField
|
||||||
|
type="checkbox"
|
||||||
|
name="exact-match"
|
||||||
|
checked={options[SEARCH_OPTIONS.EXACT]}
|
||||||
|
onChange={() => setSearchOption(SEARCH_OPTIONS.EXACT, !options[SEARCH_OPTIONS.EXACT])}
|
||||||
|
label={__('Exact match')}
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
className="icon--help"
|
||||||
|
icon={ICONS.HELP}
|
||||||
|
tooltip
|
||||||
|
size={16}
|
||||||
|
customTooltipText={__(
|
||||||
|
'Find results that include all the given words in the exact order.\nThis can also be done by surrounding the search query with quotation marks (e.g. "hello world").'
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
{!simple && (
|
||||||
<FormField
|
<FormField
|
||||||
type="select"
|
type="select"
|
||||||
name="result-count"
|
name="result-count"
|
||||||
|
@ -113,9 +167,69 @@ const SearchOptions = (props: Props) => {
|
||||||
<option value={50}>50</option>
|
<option value={50}>50</option>
|
||||||
<option value={100}>100</option>
|
<option value={100}>100</option>
|
||||||
</FormField>
|
</FormField>
|
||||||
</fieldset>
|
|
||||||
</Form>
|
|
||||||
)}
|
)}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
const uploadDateElem = (
|
||||||
|
<div className="filter-values">
|
||||||
|
<FormField
|
||||||
|
type="select"
|
||||||
|
name="upload-date"
|
||||||
|
value={options[SEARCH_OPTIONS.TIME_FILTER]}
|
||||||
|
onChange={(e) => setSearchOption(SEARCH_OPTIONS.TIME_FILTER, e.target.value)}
|
||||||
|
blockWrap={false}
|
||||||
|
>
|
||||||
|
{OBJ_TO_OPTION_ELEM(TIME_FILTER)}
|
||||||
|
</FormField>
|
||||||
|
<Button
|
||||||
|
button="close"
|
||||||
|
className={classnames('close-button', {
|
||||||
|
'close-button--visible': options[SEARCH_OPTIONS.TIME_FILTER] !== '',
|
||||||
|
})}
|
||||||
|
icon={ICONS.REMOVE}
|
||||||
|
onClick={() => setSearchOption(SEARCH_OPTIONS.TIME_FILTER, '')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
const sortByElem = (
|
||||||
|
<div className="filter-values">
|
||||||
|
<FormField
|
||||||
|
type="select"
|
||||||
|
name="sort-by"
|
||||||
|
blockWrap={false}
|
||||||
|
value={options[SEARCH_OPTIONS.SORT]}
|
||||||
|
onChange={(e) => setSearchOption(SEARCH_OPTIONS.SORT, e.target.value)}
|
||||||
|
>
|
||||||
|
{OBJ_TO_OPTION_ELEM(SORT_BY)}
|
||||||
|
</FormField>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
button="alt"
|
||||||
|
label={__('Filter')}
|
||||||
|
icon={ICONS.FILTER}
|
||||||
|
iconRight={expanded ? ICONS.UP : ICONS.DOWN}
|
||||||
|
onClick={toggleSearchExpanded}
|
||||||
|
/>
|
||||||
|
<Form
|
||||||
|
className={classnames('search__options', {
|
||||||
|
'search__options--expanded': expanded,
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<table className="table table--condensed">
|
||||||
|
<tbody>
|
||||||
|
{addRow(__('Type'), typeElem)}
|
||||||
|
{addRow(__('Upload Date'), uploadDateElem)}
|
||||||
|
{addRow(__('Sort By'), sortByElem)}
|
||||||
|
{addRow(__('Other Options'), otherOptionsElem)}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</Form>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,6 +51,7 @@ export const MORE = 'More';
|
||||||
export const SHARE_LINK = 'ShareLink';
|
export const SHARE_LINK = 'ShareLink';
|
||||||
export const ACCOUNT = 'User';
|
export const ACCOUNT = 'User';
|
||||||
export const SETTINGS = 'Settings';
|
export const SETTINGS = 'Settings';
|
||||||
|
export const FILTER = 'Filter';
|
||||||
export const INVITE = 'Users';
|
export const INVITE = 'Users';
|
||||||
export const FILE = 'File';
|
export const FILE = 'File';
|
||||||
export const FULLSCREEN = 'Maximize';
|
export const FULLSCREEN = 'Maximize';
|
||||||
|
|
|
@ -24,8 +24,8 @@ type Props = {
|
||||||
isSearching: boolean,
|
isSearching: boolean,
|
||||||
location: UrlLocation,
|
location: UrlLocation,
|
||||||
uris: Array<string>,
|
uris: Array<string>,
|
||||||
onFeedbackNegative: string => void,
|
onFeedbackNegative: (string) => void,
|
||||||
onFeedbackPositive: string => void,
|
onFeedbackPositive: (string) => void,
|
||||||
showNsfw: boolean,
|
showNsfw: boolean,
|
||||||
isAuthenticated: boolean,
|
isAuthenticated: boolean,
|
||||||
};
|
};
|
||||||
|
@ -49,10 +49,7 @@ export default function SearchPage(props: Props) {
|
||||||
|
|
||||||
additionalOptions['nsfw'] = showNsfw;
|
additionalOptions['nsfw'] = showNsfw;
|
||||||
|
|
||||||
const modifiedUrlQuery = urlQuery
|
const modifiedUrlQuery = urlQuery.trim().replace(/\s+/g, '').replace(/:/g, '#');
|
||||||
.trim()
|
|
||||||
.replace(/\s+/g, '')
|
|
||||||
.replace(/:/g, '#');
|
|
||||||
const uriFromQuery = `lbry://${modifiedUrlQuery}`;
|
const uriFromQuery = `lbry://${modifiedUrlQuery}`;
|
||||||
|
|
||||||
let streamName;
|
let streamName;
|
||||||
|
@ -72,7 +69,7 @@ export default function SearchPage(props: Props) {
|
||||||
try {
|
try {
|
||||||
const dummyUrlForClaimId = `x#${urlQuery}`;
|
const dummyUrlForClaimId = `x#${urlQuery}`;
|
||||||
({ claimId } = parseURI(dummyUrlForClaimId));
|
({ claimId } = parseURI(dummyUrlForClaimId));
|
||||||
Lbry.claim_search({ claim_id: claimId }).then(res => {
|
Lbry.claim_search({ claim_id: claimId }).then((res) => {
|
||||||
if (res.items && res.items.length) {
|
if (res.items && res.items.length) {
|
||||||
const claim = res.items[0];
|
const claim = res.items[0];
|
||||||
const url = formatLbryUrlForWeb(claim.canonical_url);
|
const url = formatLbryUrlForWeb(claim.canonical_url);
|
||||||
|
@ -100,7 +97,7 @@ export default function SearchPage(props: Props) {
|
||||||
<ClaimList
|
<ClaimList
|
||||||
uris={uris}
|
uris={uris}
|
||||||
loading={isSearching}
|
loading={isSearching}
|
||||||
header={!SIMPLE_SITE && <SearchOptions additionalOptions={additionalOptions} />}
|
header={<SearchOptions simple={SIMPLE_SITE} additionalOptions={additionalOptions} />}
|
||||||
injectedItem={
|
injectedItem={
|
||||||
SHOW_ADS && IS_WEB ? (SIMPLE_SITE ? false : !isAuthenticated && <Ads small type={'video'} />) : false
|
SHOW_ADS && IS_WEB ? (SIMPLE_SITE ? false : !isAuthenticated && <Ads small type={'video'} />) : false
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,87 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.search__options {
|
.search__options {
|
||||||
margin-top: var(--spacing-l);
|
margin-top: var(--spacing-s);
|
||||||
|
padding-left: var(--spacing-m);
|
||||||
|
|
||||||
|
transition: all 0.3s ease-out;
|
||||||
|
|
||||||
|
// These will be expanded by 'search__options--expanded'.
|
||||||
|
max-height: 0;
|
||||||
|
opacity: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
.search__legend {
|
.search__legend {
|
||||||
background-color: var(--color-secondary-alt);
|
font-weight: var(--font-weight-bold);
|
||||||
color: var(--color-secondary);
|
font-size: var(--font-small);
|
||||||
margin-bottom: var(--spacing-s);
|
margin-bottom: var(--spacing-s);
|
||||||
padding: var(--spacing-xxs);
|
padding: var(--spacing-xxs);
|
||||||
}
|
}
|
||||||
|
|
||||||
fieldset:not(:first-child) {
|
fieldset:not(:first-child) {
|
||||||
margin-top: var(--spacing-l);
|
margin-top: var(--spacing-m);
|
||||||
|
}
|
||||||
|
|
||||||
|
table {
|
||||||
|
line-height: 1.5;
|
||||||
|
table-layout: fixed;
|
||||||
|
}
|
||||||
|
|
||||||
|
td:nth-of-type(1) {
|
||||||
|
width: 20%;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
|
||||||
|
.claim-type-filter {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button {
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.close-button--visible {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
.filter-values {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
|
||||||
|
.button-toggle {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
@media (min-width: $breakpoint-small) {
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon--help {
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button--close {
|
||||||
|
position: unset;
|
||||||
|
align-self: center;
|
||||||
|
margin-left: var(--spacing-s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.media-types {
|
||||||
|
margin-top: var(--spacing-s);
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio,
|
.radio,
|
||||||
.checkbox {
|
.checkbox {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
margin-top: 0;
|
||||||
|
|
||||||
&:not(:first-of-type) {
|
&:not(:first-of-type) {
|
||||||
margin-left: var(--spacing-m);
|
margin-left: var(--spacing-m);
|
||||||
|
@ -31,6 +96,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search__options--expanded {
|
||||||
|
max-height: 400px; // how to not hardcode this :(
|
||||||
|
opacity: 1;
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
|
||||||
.search__top-link {
|
.search__top-link {
|
||||||
margin-top: var(--spacing-s);
|
margin-top: var(--spacing-s);
|
||||||
font-weight: var(--font-weight-body);
|
font-weight: var(--font-weight-body);
|
||||||
|
|
Loading…
Reference in a new issue