Fix "exact match" being applied to Recommended #6460

This commit is contained in:
infinite-persistence 2021-07-14 11:18:43 +08:00
commit c5b3d9aef7
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
6 changed files with 27 additions and 77 deletions

View file

@ -1,14 +1,13 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { doUpdateSearchOptions } from 'redux/actions/search'; import { doUpdateSearchOptions } from 'redux/actions/search';
import { selectSearchOptions, makeSelectQueryWithOptions } from 'redux/selectors/search'; import { selectSearchOptions } from 'redux/selectors/search';
import { doToggleSearchExpanded } from 'redux/actions/app'; import { doToggleSearchExpanded } from 'redux/actions/app';
import { selectSearchOptionsExpanded } from 'redux/selectors/app'; import { selectSearchOptionsExpanded } from 'redux/selectors/app';
import SearchOptions from './view'; import SearchOptions from './view';
const select = state => ({ const select = (state) => ({
options: selectSearchOptions(state), options: selectSearchOptions(state),
expanded: selectSearchOptionsExpanded(state), expanded: selectSearchOptionsExpanded(state),
query: makeSelectQueryWithOptions(undefined, {})(state),
}); });
const perform = (dispatch, ownProps) => { const perform = (dispatch, ownProps) => {

View file

@ -2,7 +2,6 @@ import * as MODALS from 'constants/modal_types';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { selectLanguage, selectShowMatureContent } from 'redux/selectors/settings'; import { selectLanguage, selectShowMatureContent } from 'redux/selectors/settings';
import { doToast } from 'redux/actions/notifications'; import { doToast } from 'redux/actions/notifications';
import { doSearch } from 'redux/actions/search';
import { doOpenModal, doHideModal } from 'redux/actions/app'; import { doOpenModal, doHideModal } from 'redux/actions/app';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { doResolveUris } from 'lbry-redux'; import { doResolveUris } from 'lbry-redux';
@ -16,7 +15,6 @@ const select = (state, props) => ({
const perform = (dispatch, ownProps) => ({ const perform = (dispatch, ownProps) => ({
doResolveUris: (uris) => dispatch(doResolveUris(uris)), doResolveUris: (uris) => dispatch(doResolveUris(uris)),
doSearch: (query, options) => dispatch(doSearch(query, options)),
navigateToSearchPage: (query) => { navigateToSearchPage: (query) => {
let encodedQuery = encodeURIComponent(query); let encodedQuery = encodeURIComponent(query);
ownProps.history.push({ pathname: `/$/search`, search: `?q=${encodedQuery}` }); ownProps.history.push({ pathname: `/$/search`, search: `?q=${encodedQuery}` });

View file

@ -1,43 +1,42 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { withRouter } from 'react-router'; import { withRouter } from 'react-router';
import { doSearch } from 'redux/actions/search'; import { doSearch } from 'redux/actions/search';
import { SIMPLE_SITE } from 'config';
import { import {
selectIsSearching, selectIsSearching,
makeSelectSearchUris, makeSelectSearchUris,
makeSelectQueryWithOptions,
selectSearchOptions, selectSearchOptions,
makeSelectHasReachedMaxResultsLength, makeSelectHasReachedMaxResultsLength,
} from 'redux/selectors/search'; } from 'redux/selectors/search';
import { selectShowMatureContent } from 'redux/selectors/settings'; import { selectShowMatureContent } from 'redux/selectors/settings';
import { selectUserVerifiedEmail } from 'redux/selectors/user'; import { selectUserVerifiedEmail } from 'redux/selectors/user';
import { getSearchQueryString } from 'util/query-params';
import SearchPage from './view'; import SearchPage from './view';
const select = (state, props) => { const select = (state, props) => {
const showMature = selectShowMatureContent(state); const showMature = selectShowMatureContent(state);
const urlParams = new URLSearchParams(props.location.search); const urlParams = new URLSearchParams(props.location.search);
let urlQuery = urlParams.get('q') || null; let urlQuery = urlParams.get('q') || null;
if (urlQuery) { if (urlQuery) {
urlQuery = urlQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); urlQuery = urlQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' ');
} }
const query = makeSelectQueryWithOptions(
urlQuery,
SIMPLE_SITE
? { nsfw: false, isBackgroundSearch: false }
: showMature === false
? { nsfw: false, isBackgroundSearch: false }
: { isBackgroundSearch: false }
)(state);
const searchOptions = {
...selectSearchOptions(state),
isBackgroundSearch: false,
nsfw: showMature,
};
const query = getSearchQueryString(urlQuery, searchOptions);
const uris = makeSelectSearchUris(query)(state); const uris = makeSelectSearchUris(query)(state);
const hasReachedMaxResultsLength = makeSelectHasReachedMaxResultsLength(query)(state); const hasReachedMaxResultsLength = makeSelectHasReachedMaxResultsLength(query)(state);
return { return {
urlQuery,
searchOptions,
isSearching: selectIsSearching(state), isSearching: selectIsSearching(state),
showNsfw: showMature,
uris: uris, uris: uris,
isAuthenticated: selectUserVerifiedEmail(state), isAuthenticated: selectUserVerifiedEmail(state),
searchOptions: selectSearchOptions(state),
hasReachedMaxResultsLength: hasReachedMaxResultsLength, hasReachedMaxResultsLength: hasReachedMaxResultsLength,
}; };
}; };

View file

@ -11,43 +11,21 @@ import { formatLbryUrlForWeb } from 'util/url';
import { useHistory } from 'react-router'; import { useHistory } from 'react-router';
import { SEARCH_PAGE_SIZE } from 'constants/search'; import { SEARCH_PAGE_SIZE } from 'constants/search';
type AdditionalOptions = {
isBackgroundSearch: boolean,
nsfw?: boolean,
from?: number,
};
type Props = { type Props = {
search: (string, AdditionalOptions) => void, urlQuery: string,
searchOptions: {}, searchOptions: SearchOptions,
search: (string, SearchOptions) => void,
isSearching: boolean, isSearching: boolean,
location: UrlLocation,
uris: Array<string>, uris: Array<string>,
showNsfw: boolean,
isAuthenticated: boolean, isAuthenticated: boolean,
hasReachedMaxResultsLength: boolean, hasReachedMaxResultsLength: boolean,
}; };
export default function SearchPage(props: Props) { export default function SearchPage(props: Props) {
const { const { urlQuery, searchOptions, search, uris, isSearching, isAuthenticated, hasReachedMaxResultsLength } = props;
search,
uris,
location,
isSearching,
showNsfw,
isAuthenticated,
searchOptions,
hasReachedMaxResultsLength,
} = props;
const { push } = useHistory(); const { push } = useHistory();
const urlParams = new URLSearchParams(location.search);
const urlQuery = urlParams.get('q') || '';
const additionalOptions: AdditionalOptions = { isBackgroundSearch: false };
const [from, setFrom] = React.useState(0); const [from, setFrom] = React.useState(0);
additionalOptions['nsfw'] = SIMPLE_SITE ? false : showNsfw;
additionalOptions['from'] = from;
const modifiedUrlQuery = urlQuery.trim().replace(/\s+/g, '').replace(/:/g, '#'); const modifiedUrlQuery = urlQuery.trim().replace(/\s+/g, '').replace(/:/g, '#');
const uriFromQuery = `lbry://${modifiedUrlQuery}`; const uriFromQuery = `lbry://${modifiedUrlQuery}`;
@ -78,14 +56,14 @@ export default function SearchPage(props: Props) {
} catch (e) {} } catch (e) {}
} }
const stringifiedOptions = JSON.stringify(additionalOptions);
const stringifiedSearchOptions = JSON.stringify(searchOptions); const stringifiedSearchOptions = JSON.stringify(searchOptions);
useEffect(() => { useEffect(() => {
if (urlQuery) { if (urlQuery) {
const jsonOptions = JSON.parse(stringifiedOptions); const searchOptions = JSON.parse(stringifiedSearchOptions);
search(urlQuery, jsonOptions); search(urlQuery, { ...searchOptions, from: from });
} }
}, [search, urlQuery, stringifiedOptions, stringifiedSearchOptions]); }, [search, urlQuery, stringifiedSearchOptions, from]);
function loadMore() { function loadMore() {
if (!isSearching && !hasReachedMaxResultsLength) { if (!isSearching && !hasReachedMaxResultsLength) {
@ -114,7 +92,7 @@ export default function SearchPage(props: Props) {
header={ header={
<SearchOptions <SearchOptions
simple={SIMPLE_SITE} simple={SIMPLE_SITE}
additionalOptions={additionalOptions} additionalOptions={searchOptions}
onSearchOptionsChanged={resetPage} onSearchOptionsChanged={resetPage}
/> />
} }

View file

@ -1,13 +1,9 @@
// @flow // @flow
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
import { buildURI, doResolveUris, batchActions, isURIValid, makeSelectClaimForUri } from 'lbry-redux'; import { buildURI, doResolveUris, batchActions, isURIValid, makeSelectClaimForUri } from 'lbry-redux';
import { import { makeSelectSearchUris, selectSearchValue } from 'redux/selectors/search';
makeSelectSearchUris,
makeSelectQueryWithOptions,
selectSearchValue,
selectSearchOptions,
} from 'redux/selectors/search';
import handleFetchResponse from 'util/handle-fetch'; import handleFetchResponse from 'util/handle-fetch';
import { getSearchQueryString } from 'util/query-params';
type Dispatch = (action: any) => any; type Dispatch = (action: any) => any;
type GetState = () => { search: SearchState }; type GetState = () => { search: SearchState };
@ -44,10 +40,9 @@ export const doSearch = (rawQuery: string, searchOptions: SearchOptions) => (
const state = getState(); const state = getState();
const mainOptions: any = selectSearchOptions(state); const queryWithOptions = getSearchQueryString(query, searchOptions);
const queryWithOptions = makeSelectQueryWithOptions(query, searchOptions)(state);
const size = mainOptions.size; const size = searchOptions.size;
const from = searchOptions.from; const from = searchOptions.from;
// If we have already searched for something, we don't need to do anything // If we have already searched for something, we don't need to do anything
@ -101,7 +96,7 @@ export const doSearch = (rawQuery: string, searchOptions: SearchOptions) => (
}); });
dispatch(batchActions(...actions)); dispatch(batchActions(...actions));
}) })
.catch((e) => { .catch(() => {
dispatch({ dispatch({
type: ACTIONS.SEARCH_FAIL, type: ACTIONS.SEARCH_FAIL,
}); });

View file

@ -57,25 +57,6 @@ export const makeSelectHasReachedMaxResultsLength = (query: string): ((state: St
return hasReachedMaxResultsLength[query]; return hasReachedMaxResultsLength[query];
}); });
// Creates a query string based on the state in the search reducer
// Can be overrided by passing in custom sizes/from values for other areas pagination
type CustomOptions = {
isBackgroundSearch?: boolean,
size?: number,
from?: number,
related_to?: string,
nsfw?: boolean,
};
export const makeSelectQueryWithOptions = (customQuery: ?string, options: CustomOptions) =>
createSelector(selectSearchValue, selectSearchOptions, (query, defaultOptions) => {
const searchOptions = { ...defaultOptions, ...options };
const queryString = getSearchQueryString(customQuery || query, searchOptions);
return queryString;
});
export const makeSelectRecommendedContentForUri = (uri: string) => export const makeSelectRecommendedContentForUri = (uri: string) =>
createSelector( createSelector(
makeSelectClaimForUri(uri), makeSelectClaimForUri(uri),