WunderBar customizations for re-use
This commit is contained in:
parent
d36c8748e3
commit
510056a479
3 changed files with 63 additions and 20 deletions
|
@ -7,15 +7,24 @@ import WunderbarSuggestions from 'component/wunderbarSuggestions';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
doOpenMobileSearch: () => void,
|
doOpenMobileSearch: () => void,
|
||||||
|
channelsOnly?: boolean,
|
||||||
|
noTopSuggestion?: boolean,
|
||||||
|
noBottomLinks?: boolean,
|
||||||
|
customSelectAction?: (string) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function WunderBar(props: Props) {
|
export default function WunderBar(props: Props) {
|
||||||
const { doOpenMobileSearch } = props;
|
const { doOpenMobileSearch, channelsOnly, noTopSuggestion, noBottomLinks, customSelectAction } = props;
|
||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
return isMobile ? (
|
return isMobile ? (
|
||||||
<Button icon={ICONS.SEARCH} className="wunderbar__mobile-search" onClick={() => doOpenMobileSearch()} />
|
<Button icon={ICONS.SEARCH} className="wunderbar__mobile-search" onClick={() => doOpenMobileSearch()} />
|
||||||
) : (
|
) : (
|
||||||
<WunderbarSuggestions />
|
<WunderbarSuggestions
|
||||||
|
channelsOnly={channelsOnly}
|
||||||
|
noTopSuggestion={noTopSuggestion}
|
||||||
|
noBottomLinks={noBottomLinks}
|
||||||
|
customSelectAction={customSelectAction}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import { useHistory } from 'react-router';
|
||||||
import { formatLbryUrlForWeb } from 'util/url';
|
import { formatLbryUrlForWeb } from 'util/url';
|
||||||
import useThrottle from 'effects/use-throttle';
|
import useThrottle from 'effects/use-throttle';
|
||||||
import Yrbl from 'component/yrbl';
|
import Yrbl from 'component/yrbl';
|
||||||
|
import { SEARCH_OPTIONS } from 'constants/search';
|
||||||
|
|
||||||
const LBRY_PROTOCOL = 'lbry://';
|
const LBRY_PROTOCOL = 'lbry://';
|
||||||
const WEB_DEV_PREFIX = `${URL_DEV}/`;
|
const WEB_DEV_PREFIX = `${URL_DEV}/`;
|
||||||
|
@ -39,10 +40,25 @@ type Props = {
|
||||||
showMature: boolean,
|
showMature: boolean,
|
||||||
isMobile: boolean,
|
isMobile: boolean,
|
||||||
doCloseMobileSearch: () => void,
|
doCloseMobileSearch: () => void,
|
||||||
|
channelsOnly?: boolean,
|
||||||
|
noTopSuggestion?: boolean,
|
||||||
|
noBottomLinks?: boolean,
|
||||||
|
customSelectAction?: (string) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function WunderBarSuggestions(props: Props) {
|
export default function WunderBarSuggestions(props: Props) {
|
||||||
const { navigateToSearchPage, doShowSnackBar, doResolveUris, showMature, isMobile, doCloseMobileSearch } = props;
|
const {
|
||||||
|
navigateToSearchPage,
|
||||||
|
doShowSnackBar,
|
||||||
|
doResolveUris,
|
||||||
|
showMature,
|
||||||
|
isMobile,
|
||||||
|
doCloseMobileSearch,
|
||||||
|
channelsOnly,
|
||||||
|
noTopSuggestion,
|
||||||
|
noBottomLinks,
|
||||||
|
customSelectAction,
|
||||||
|
} = props;
|
||||||
const inputRef: ElementRef<any> = React.useRef();
|
const inputRef: ElementRef<any> = React.useRef();
|
||||||
const isFocused = inputRef && inputRef.current && inputRef.current === document.activeElement;
|
const isFocused = inputRef && inputRef.current && inputRef.current === document.activeElement;
|
||||||
|
|
||||||
|
@ -55,7 +71,10 @@ export default function WunderBarSuggestions(props: Props) {
|
||||||
const [term, setTerm] = React.useState(queryFromUrl);
|
const [term, setTerm] = React.useState(queryFromUrl);
|
||||||
const throttledTerm = useThrottle(term, 500) || '';
|
const throttledTerm = useThrottle(term, 500) || '';
|
||||||
const searchSize = isMobile ? 20 : 5;
|
const searchSize = isMobile ? 20 : 5;
|
||||||
const { results, loading } = useLighthouse(throttledTerm, showMature, searchSize);
|
const additionalOptions = channelsOnly
|
||||||
|
? { isBackgroundSearch: false, [SEARCH_OPTIONS.CLAIM_TYPE]: SEARCH_OPTIONS.INCLUDE_CHANNELS }
|
||||||
|
: {};
|
||||||
|
const { results, loading } = useLighthouse(throttledTerm, showMature, searchSize, additionalOptions);
|
||||||
const noResults = throttledTerm && !loading && results && results.length === 0;
|
const noResults = throttledTerm && !loading && results && results.length === 0;
|
||||||
const nameFromQuery = throttledTerm.trim().replace(/\s+/g, '').replace(/:/g, '#');
|
const nameFromQuery = throttledTerm.trim().replace(/\s+/g, '').replace(/:/g, '#');
|
||||||
const uriFromQuery = `lbry://${nameFromQuery}`;
|
const uriFromQuery = `lbry://${nameFromQuery}`;
|
||||||
|
@ -91,6 +110,12 @@ export default function WunderBarSuggestions(props: Props) {
|
||||||
inputRef.current.blur();
|
inputRef.current.blur();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (customSelectAction) {
|
||||||
|
// Give them full results, as our resolved one might truncate the claimId.
|
||||||
|
customSelectAction(results ? results.find((r) => r.startsWith(value)) : '');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (wasCopiedFromWeb) {
|
if (wasCopiedFromWeb) {
|
||||||
const prefix = webDomainList[webDomainIndex];
|
const prefix = webDomainList[webDomainIndex];
|
||||||
let query = value.slice(prefix.length).replace(/:/g, '#');
|
let query = value.slice(prefix.length).replace(/:/g, '#');
|
||||||
|
@ -266,24 +291,26 @@ export default function WunderBarSuggestions(props: Props) {
|
||||||
className={classnames('wunderbar__suggestions', { 'wunderbar__suggestions--mobile': isMobile })}
|
className={classnames('wunderbar__suggestions', { 'wunderbar__suggestions--mobile': isMobile })}
|
||||||
>
|
>
|
||||||
<ComboboxList>
|
<ComboboxList>
|
||||||
{uriFromQueryIsValid ? <WunderbarTopSuggestion query={nameFromQuery} /> : null}
|
{uriFromQueryIsValid && !noTopSuggestion ? <WunderbarTopSuggestion query={nameFromQuery} /> : null}
|
||||||
|
|
||||||
<div className="wunderbar__label">{__('Search Results')}</div>
|
<div className="wunderbar__label">{__('Search Results')}</div>
|
||||||
{results.slice(0, isMobile ? 20 : 5).map((uri) => (
|
{results.slice(0, isMobile ? 20 : 5).map((uri) => (
|
||||||
<WunderbarSuggestion key={uri} uri={uri} />
|
<WunderbarSuggestion key={uri} uri={uri} />
|
||||||
))}
|
))}
|
||||||
|
|
||||||
<div className="wunderbar__bottom-links">
|
{!noBottomLinks && (
|
||||||
<ComboboxOption value={term} className="wunderbar__more-results">
|
<div className="wunderbar__bottom-links">
|
||||||
<Button button="link" label={__('View All Results')} />
|
<ComboboxOption value={term} className="wunderbar__more-results">
|
||||||
</ComboboxOption>
|
<Button button="link" label={__('View All Results')} />
|
||||||
<ComboboxOption value={`${TAG_SEARCH_PREFIX}${term}`} className="wunderbar__more-results">
|
</ComboboxOption>
|
||||||
<Button className="wunderbar__tag-search" button="link">
|
<ComboboxOption value={`${TAG_SEARCH_PREFIX}${term}`} className="wunderbar__more-results">
|
||||||
{__('Explore')}
|
<Button className="wunderbar__tag-search" button="link">
|
||||||
<div className="tag">{term.split(' ').join('')}</div>
|
{__('Explore')}
|
||||||
</Button>
|
<div className="tag">{term.split(' ').join('')}</div>
|
||||||
</ComboboxOption>
|
</Button>
|
||||||
</div>
|
</ComboboxOption>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</ComboboxList>
|
</ComboboxList>
|
||||||
</ComboboxPopover>
|
</ComboboxPopover>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -5,10 +5,15 @@ import { getSearchQueryString } from 'util/query-params';
|
||||||
import { isURIValid } from 'lbry-redux';
|
import { isURIValid } from 'lbry-redux';
|
||||||
import useThrottle from './use-throttle';
|
import useThrottle from './use-throttle';
|
||||||
|
|
||||||
export default function useLighthouse(query: string, showMature?: boolean, size?: number = 5) {
|
export default function useLighthouse(
|
||||||
|
query: string,
|
||||||
|
showMature?: boolean,
|
||||||
|
size?: number = 5,
|
||||||
|
additionalOptions: any = {}
|
||||||
|
) {
|
||||||
const [results, setResults] = React.useState();
|
const [results, setResults] = React.useState();
|
||||||
const [loading, setLoading] = React.useState();
|
const [loading, setLoading] = React.useState();
|
||||||
const queryString = query ? getSearchQueryString(query, { nsfw: showMature, size }) : '';
|
const queryString = query ? getSearchQueryString(query, { nsfw: showMature, size, ...additionalOptions }) : '';
|
||||||
const throttledQuery = useThrottle(queryString, 500);
|
const throttledQuery = useThrottle(queryString, 500);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
@ -19,9 +24,11 @@ export default function useLighthouse(query: string, showMature?: boolean, size?
|
||||||
let isSubscribed = true;
|
let isSubscribed = true;
|
||||||
lighthouse
|
lighthouse
|
||||||
.search(throttledQuery)
|
.search(throttledQuery)
|
||||||
.then(results => {
|
.then((results) => {
|
||||||
if (isSubscribed) {
|
if (isSubscribed) {
|
||||||
setResults(results.map(result => `lbry://${result.name}#${result.claimId}`).filter(uri => isURIValid(uri)));
|
setResults(
|
||||||
|
results.map((result) => `lbry://${result.name}#${result.claimId}`).filter((uri) => isURIValid(uri))
|
||||||
|
);
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in a new issue