lbry-desktop/ui/redux/actions/search.js

149 lines
4.2 KiB
JavaScript
Raw Normal View History

2020-07-27 22:04:12 +02:00
// @flow
import * as ACTIONS from 'constants/action_types';
import { selectShowMatureContent } from 'redux/selectors/settings';
import { selectClaimForUri, selectClaimIsNsfwForUri } from 'redux/selectors/claims';
import { doResolveUris } from 'redux/actions/claims';
import { buildURI, isURIValid } from 'util/lbryURI';
import { batchActions } from 'util/batch-actions';
import { makeSelectSearchUrisForQuery, selectSearchValue } from 'redux/selectors/search';
2020-07-27 22:04:12 +02:00
import handleFetchResponse from 'util/handle-fetch';
import { getSearchQueryString } from 'util/query-params';
import { getRecommendationSearchOptions } from 'util/search';
import { SEARCH_SERVER_API } from 'config';
2020-07-27 22:04:12 +02:00
type Dispatch = (action: any) => any;
type GetState = () => { claims: any, search: SearchState };
2020-07-27 22:04:12 +02:00
type SearchOptions = {
size?: number,
from?: number,
related_to?: string,
nsfw?: boolean,
isBackgroundSearch?: boolean,
};
2020-12-03 18:29:47 +01:00
let lighthouse = {
2021-07-29 19:19:12 +02:00
CONNECTION_STRING: SEARCH_SERVER_API,
2020-12-03 18:29:47 +01:00
search: (queryString: string) => fetch(`${lighthouse.CONNECTION_STRING}?${queryString}`).then(handleFetchResponse),
2020-07-27 22:04:12 +02:00
};
2020-12-03 18:29:47 +01:00
export const setSearchApi = (endpoint: string) => {
lighthouse.CONNECTION_STRING = endpoint.replace(/\/*$/, '/'); // exactly one slash at the end;
2020-07-27 22:04:12 +02:00
};
export const doSearch = (rawQuery: string, searchOptions: SearchOptions) => (
dispatch: Dispatch,
getState: GetState
) => {
const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' ');
if (!query) {
dispatch({
type: ACTIONS.SEARCH_FAIL,
});
return;
}
const state = getState();
const queryWithOptions = getSearchQueryString(query, searchOptions);
2021-03-26 09:33:30 +01:00
const size = searchOptions.size;
2021-03-26 09:33:30 +01:00
const from = searchOptions.from;
2020-07-27 22:04:12 +02:00
// If we have already searched for something, we don't need to do anything
const urisForQuery = makeSelectSearchUrisForQuery(queryWithOptions)(state);
2020-07-27 22:04:12 +02:00
if (urisForQuery && !!urisForQuery.length) {
2021-03-26 09:33:30 +01:00
if (!size || !from || from + size < urisForQuery.length) {
return;
}
2020-07-27 22:04:12 +02:00
}
dispatch({
type: ACTIONS.SEARCH_START,
});
2020-12-03 18:29:47 +01:00
lighthouse
.search(queryWithOptions)
.then((data: { body: Array<{ name: string, claimId: string }>, poweredBy: string }) => {
const { body: result, poweredBy } = data;
2020-07-27 22:04:12 +02:00
const uris = [];
const actions = [];
result.forEach((item) => {
if (item) {
const { name, claimId } = item;
2020-07-27 22:04:12 +02:00
const urlObj: LbryUrlObj = {};
if (name.startsWith('@')) {
urlObj.channelName = name;
urlObj.channelClaimId = claimId;
} else {
urlObj.streamName = name;
urlObj.streamClaimId = claimId;
}
const url = buildURI(urlObj);
2021-01-28 20:03:37 +01:00
if (isURIValid(url)) {
uris.push(url);
}
2020-07-27 22:04:12 +02:00
}
});
2020-08-12 19:02:19 +02:00
actions.push(doResolveUris(uris));
2020-07-27 22:04:12 +02:00
actions.push({
type: ACTIONS.SEARCH_SUCCESS,
data: {
query: queryWithOptions,
from: from,
2021-03-26 09:33:30 +01:00
size: size,
2020-07-27 22:04:12 +02:00
uris,
recsys: poweredBy,
2020-07-27 22:04:12 +02:00
},
});
dispatch(batchActions(...actions));
})
.catch(() => {
2020-07-27 22:04:12 +02:00
dispatch({
type: ACTIONS.SEARCH_FAIL,
});
});
};
export const doUpdateSearchOptions = (newOptions: SearchOptions, additionalOptions: SearchOptions) => (
dispatch: Dispatch,
getState: GetState
) => {
const state = getState();
const searchValue = selectSearchValue(state);
dispatch({
type: ACTIONS.UPDATE_SEARCH_OPTIONS,
data: newOptions,
});
if (searchValue) {
// After updating, perform a search with the new options
dispatch(doSearch(searchValue, additionalOptions));
}
};
2020-12-03 18:29:47 +01:00
export const doFetchRecommendedContent = (uri: string) => (dispatch: Dispatch, getState: GetState) => {
const state = getState();
const claim = selectClaimForUri(state, uri);
const matureEnabled = selectShowMatureContent(state);
const claimIsMature = selectClaimIsNsfwForUri(state, uri);
if (claim && claim.value && claim.claim_id) {
const options: SearchOptions = getRecommendationSearchOptions(matureEnabled, claimIsMature, claim.claim_id);
const { title } = claim.value;
if (title && options) {
dispatch(doSearch(title, options));
}
}
};
2020-12-03 18:29:47 +01:00
export { lighthouse };