feat: add support for search filters
This commit is contained in:
parent
ec1d5bd41a
commit
2b725cb317
12 changed files with 708 additions and 432 deletions
772
dist/bundle.js
vendored
772
dist/bundle.js
vendored
File diff suppressed because it is too large
Load diff
|
@ -117,6 +117,7 @@ export const SEARCH_START = 'SEARCH_START';
|
|||
export const SEARCH_SUCCESS = 'SEARCH_SUCCESS';
|
||||
export const SEARCH_FAIL = 'SEARCH_FAIL';
|
||||
export const UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY';
|
||||
export const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS';
|
||||
export const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS';
|
||||
export const SEARCH_FOCUS = 'SEARCH_FOCUS';
|
||||
export const SEARCH_BLUR = 'SEARCH_BLUR';
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
export const FILE = 'file';
|
||||
export const CHANNEL = 'channel';
|
||||
export const SEARCH = 'search';
|
||||
export const SEARCH_TYPES = {
|
||||
FILE: 'file',
|
||||
CHANNEL: 'channel',
|
||||
SEARCH: 'search',
|
||||
};
|
||||
|
||||
export const SEARCH_OPTIONS = {
|
||||
RESULT_COUNT: 'size',
|
||||
CLAIM_TYPE: 'claimType',
|
||||
INCLUDE_FILES: 'file',
|
||||
INCLUDE_CHANNELS: 'channel',
|
||||
INCLUDE_FILES_AND_CHANNELS: 'file,channel',
|
||||
MEDIA_AUDIO: 'audio',
|
||||
MEDIA_VIDEO: 'video',
|
||||
MEDIA_TEXT: 'text',
|
||||
MEDIA_IMAGE: 'image',
|
||||
MEDIA_APPLICATION: 'application',
|
||||
};
|
||||
|
|
16
src/index.js
16
src/index.js
|
@ -1,10 +1,10 @@
|
|||
import * as ACTIONS from 'constants/action_types';
|
||||
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
|
||||
import * as SEARCH_TYPES from 'constants/search';
|
||||
import * as SETTINGS from 'constants/settings';
|
||||
import * as TRANSACTIONS from 'constants/transaction_types';
|
||||
import * as SORT_OPTIONS from 'constants/sort_options';
|
||||
import * as PAGES from 'constants/pages';
|
||||
import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search';
|
||||
|
||||
import Lbry from 'lbry';
|
||||
import Lbryapi from 'lbryapi';
|
||||
|
@ -14,7 +14,16 @@ import { selectState as selectSearchState } from 'redux/selectors/search';
|
|||
export { Toast } from 'types/Notification';
|
||||
|
||||
// constants
|
||||
export { ACTIONS, THUMBNAIL_STATUSES, SEARCH_TYPES, SETTINGS, TRANSACTIONS, SORT_OPTIONS, PAGES };
|
||||
export {
|
||||
ACTIONS,
|
||||
THUMBNAIL_STATUSES,
|
||||
SEARCH_TYPES,
|
||||
SEARCH_OPTIONS,
|
||||
SETTINGS,
|
||||
TRANSACTIONS,
|
||||
SORT_OPTIONS,
|
||||
PAGES,
|
||||
};
|
||||
|
||||
// common
|
||||
export { Lbry, Lbryapi };
|
||||
|
@ -59,6 +68,7 @@ export {
|
|||
doFocusSearchInput,
|
||||
doBlurSearchInput,
|
||||
setSearchApi,
|
||||
doUpdateSearchOptions,
|
||||
} from 'redux/actions/search';
|
||||
|
||||
export { doBlackListedOutpointsSubscribe } from 'redux/actions/blacklist';
|
||||
|
@ -191,11 +201,13 @@ export {
|
|||
makeSelectSearchUris,
|
||||
selectSearchQuery,
|
||||
selectSearchValue,
|
||||
selectSearchOptions,
|
||||
selectIsSearching,
|
||||
selectSearchUrisByQuery,
|
||||
selectWunderBarAddress,
|
||||
selectSearchBarFocused,
|
||||
selectSearchSuggestions,
|
||||
makeSelectQueryWithOptions,
|
||||
} from 'redux/selectors/search';
|
||||
|
||||
export {
|
||||
|
|
|
@ -1,32 +1,35 @@
|
|||
// @flow
|
||||
import type { SearchState, SearchOptions } from 'types/Search';
|
||||
import * as ACTIONS from 'constants/action_types';
|
||||
import { buildURI } from 'lbryURI';
|
||||
import { doResolveUri } from 'redux/actions/claims';
|
||||
import { makeSelectSearchUris, selectSuggestions } from 'redux/selectors/search';
|
||||
import {
|
||||
makeSelectSearchUris,
|
||||
selectSuggestions,
|
||||
makeSelectQueryWithOptions,
|
||||
selectSearchQuery,
|
||||
} from 'redux/selectors/search';
|
||||
import { batchActions } from 'util/batchActions';
|
||||
import debounce from 'util/debounce';
|
||||
import handleFetchResponse from 'util/handle-fetch';
|
||||
|
||||
const DEFAULTSEARCHRESULTSIZE = 10;
|
||||
const DEFAULTSEARCHRESULTFROM = 0;
|
||||
const DEBOUNCED_SEARCH_SUGGESTION_MS = 300;
|
||||
type Dispatch = (action: any) => any;
|
||||
type GetState = () => {};
|
||||
type GetState = () => { search: SearchState };
|
||||
|
||||
// We can't use env's because they aren't passed into node_modules
|
||||
let CONNECTION_STRING = 'https://lighthouse.lbry.io/';
|
||||
|
||||
export const setSearchApi = endpoint => {
|
||||
export const setSearchApi = (endpoint: string) => {
|
||||
CONNECTION_STRING = endpoint.replace(/\/*$/, '/'); // exactly one slash at the end;
|
||||
};
|
||||
|
||||
export const doSearch = (
|
||||
rawQuery: string,
|
||||
size: number = DEFAULTSEARCHRESULTSIZE,
|
||||
from: number = DEFAULTSEARCHRESULTFROM,
|
||||
rawQuery: string, // pass in a query if you don't want to search for what's in the search bar
|
||||
size: ?number, // only pass in if you don't want to use the users setting (ex: related content)
|
||||
from: ?number,
|
||||
isBackgroundSearch: boolean = false
|
||||
) => (dispatch: Dispatch, getState: GetState) => {
|
||||
const state = getState();
|
||||
const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' ');
|
||||
|
||||
if (!query) {
|
||||
|
@ -36,8 +39,11 @@ export const doSearch = (
|
|||
return;
|
||||
}
|
||||
|
||||
const state = getState();
|
||||
const queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch)(state);
|
||||
|
||||
// If we have already searched for something, we don't need to do anything
|
||||
const urisForQuery = makeSelectSearchUris(query)(state);
|
||||
const urisForQuery = makeSelectSearchUris(queryWithOptions)(state);
|
||||
if (urisForQuery && !!urisForQuery.length) {
|
||||
return;
|
||||
}
|
||||
|
@ -57,8 +63,7 @@ export const doSearch = (
|
|||
});
|
||||
}
|
||||
|
||||
const encodedQuery = encodeURIComponent(query);
|
||||
fetch(`${CONNECTION_STRING}search?s=${encodedQuery}&size=${size}&from=${from}`)
|
||||
fetch(`${CONNECTION_STRING}search?${queryWithOptions}`)
|
||||
.then(handleFetchResponse)
|
||||
.then(data => {
|
||||
const uris = [];
|
||||
|
@ -76,7 +81,7 @@ export const doSearch = (
|
|||
actions.push({
|
||||
type: ACTIONS.SEARCH_SUCCESS,
|
||||
data: {
|
||||
query,
|
||||
query: queryWithOptions,
|
||||
uris,
|
||||
},
|
||||
});
|
||||
|
@ -149,3 +154,21 @@ export const doBlurSearchInput = () => (dispatch: Dispatch) =>
|
|||
dispatch({
|
||||
type: ACTIONS.SEARCH_BLUR,
|
||||
});
|
||||
|
||||
export const doUpdateSearchOptions = (newOptions: SearchOptions) => (
|
||||
dispatch: Dispatch,
|
||||
getState: GetState
|
||||
) => {
|
||||
const state = getState();
|
||||
const searchQuery = selectSearchQuery(state);
|
||||
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_SEARCH_OPTIONS,
|
||||
data: newOptions,
|
||||
});
|
||||
|
||||
if (searchQuery) {
|
||||
// After updating, perform a search with the new options
|
||||
dispatch(doSearch(searchQuery));
|
||||
}
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import type {
|
||||
NotificationState,
|
||||
DoToast,
|
||||
DoError,
|
||||
DoNotification,
|
||||
DoEditNotification,
|
||||
DoDeleteNotification,
|
||||
|
@ -55,7 +56,7 @@ const notificationsReducer = handleActions(
|
|||
let notifications = state.notifications.slice();
|
||||
|
||||
notifications = notifications.map(
|
||||
(pastNotification) =>
|
||||
pastNotification =>
|
||||
pastNotification.id === notification.id ? notification : pastNotification
|
||||
);
|
||||
|
||||
|
@ -67,7 +68,7 @@ const notificationsReducer = handleActions(
|
|||
[ACTIONS.DELETE_NOTIFICATION]: (state: NotificationState, action: DoDeleteNotification) => {
|
||||
const { id } = action.data;
|
||||
let newNotifications = state.notifications.slice();
|
||||
newNotifications = newNotifications.filter((notification) => notification.id !== id);
|
||||
newNotifications = newNotifications.filter(notification => notification.id !== id);
|
||||
|
||||
return {
|
||||
...state,
|
||||
|
@ -76,7 +77,7 @@ const notificationsReducer = handleActions(
|
|||
},
|
||||
|
||||
// Errors
|
||||
[ACTIONS.CREATE_ERROR]: (state: NotificationState, action: DoToast) => {
|
||||
[ACTIONS.CREATE_ERROR]: (state: NotificationState, action: DoError) => {
|
||||
const error = action.data;
|
||||
const newErrors = state.errors.slice();
|
||||
newErrors.push(error);
|
||||
|
|
|
@ -1,56 +1,29 @@
|
|||
// @flow
|
||||
import * as ACTIONS from 'constants/action_types';
|
||||
import { handleActions } from 'util/redux-utils';
|
||||
|
||||
type SearchSuccess = {
|
||||
type: ACTIONS.SEARCH_SUCCESS,
|
||||
data: {
|
||||
query: string,
|
||||
uris: Array<string>,
|
||||
},
|
||||
};
|
||||
|
||||
type UpdateSearchQuery = {
|
||||
type: ACTIONS.UPDATE_SEARCH_QUERY,
|
||||
data: {
|
||||
query: string,
|
||||
},
|
||||
};
|
||||
|
||||
type SearchSuggestion = {
|
||||
value: string,
|
||||
shorthand: string,
|
||||
type: string,
|
||||
};
|
||||
|
||||
type UpdateSearchSuggestions = {
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: {
|
||||
query: string,
|
||||
suggestions: Array<SearchSuggestion>,
|
||||
},
|
||||
};
|
||||
|
||||
type SearchState = {
|
||||
isActive: boolean,
|
||||
searchQuery: string,
|
||||
suggestions: Array<SearchSuggestion>,
|
||||
urisByQuery: {},
|
||||
};
|
||||
|
||||
type HistoryNavigate = {
|
||||
type: ACTIONS.HISTORY_NAVIGATE,
|
||||
data: {
|
||||
url: string,
|
||||
index?: number,
|
||||
scrollY?: number,
|
||||
},
|
||||
};
|
||||
import { SEARCH_OPTIONS } from 'constants/search';
|
||||
import type {
|
||||
SearchState,
|
||||
SearchSuccess,
|
||||
UpdateSearchQuery,
|
||||
UpdateSearchSuggestions,
|
||||
HistoryNavigate,
|
||||
UpdateSearchOptions,
|
||||
} from 'types/Search';
|
||||
|
||||
const defaultState = {
|
||||
isActive: false, // does the user have any typed text in the search input
|
||||
focused: false, // is the search input focused
|
||||
searchQuery: '', // needs to be an empty string for input focusing
|
||||
options: {
|
||||
[SEARCH_OPTIONS.RESULT_COUNT]: 30,
|
||||
[SEARCH_OPTIONS.CLAIM_TYPE]: SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS,
|
||||
[SEARCH_OPTIONS.MEDIA_AUDIO]: true,
|
||||
[SEARCH_OPTIONS.MEDIA_VIDEO]: true,
|
||||
[SEARCH_OPTIONS.MEDIA_TEXT]: true,
|
||||
[SEARCH_OPTIONS.MEDIA_IMAGE]: true,
|
||||
[SEARCH_OPTIONS.MEDIA_APPLICATION]: true,
|
||||
},
|
||||
suggestions: {},
|
||||
urisByQuery: {},
|
||||
};
|
||||
|
@ -123,6 +96,18 @@ export const searchReducer = handleActions(
|
|||
...state,
|
||||
focused: false,
|
||||
}),
|
||||
[ACTIONS.UPDATE_SEARCH_OPTIONS]: (
|
||||
state: SearchState,
|
||||
action: UpdateSearchOptions
|
||||
): SearchState => {
|
||||
const { options: oldOptions } = state;
|
||||
const newOptions = action.data;
|
||||
const options = { ...oldOptions, ...newOptions };
|
||||
return {
|
||||
...state,
|
||||
options,
|
||||
};
|
||||
},
|
||||
},
|
||||
defaultState
|
||||
);
|
||||
|
|
|
@ -17,7 +17,7 @@ type ActionResult = {
|
|||
type WalletState = {
|
||||
balance: any,
|
||||
blocks: any,
|
||||
latestBlock: number,
|
||||
latestBlock: ?number,
|
||||
transactions: any,
|
||||
fetchingTransactions: boolean,
|
||||
gettingNewAddress: boolean,
|
||||
|
@ -73,7 +73,7 @@ reducers[ACTIONS.FETCH_TRANSACTIONS_COMPLETED] = (state: WalletState, action) =>
|
|||
|
||||
const { transactions } = action.data;
|
||||
|
||||
transactions.forEach((transaction) => {
|
||||
transactions.forEach(transaction => {
|
||||
byId[transaction.txid] = transaction;
|
||||
});
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import { makeSelectCurrentParam } from 'redux/selectors/navigation';
|
|||
import { selectSearchUrisByQuery } from 'redux/selectors/search';
|
||||
import { createSelector } from 'reselect';
|
||||
import { isClaimNsfw } from 'util/claim';
|
||||
import { getSearchQueryString } from 'util/query_params';
|
||||
|
||||
const selectState = state => state.claims || {};
|
||||
|
||||
|
@ -297,7 +298,9 @@ export const makeSelectRecommendedContentForUri = uri =>
|
|||
|
||||
const { title } = claim.value.stream.metadata;
|
||||
|
||||
let searchUris = searchUrisByQuery[title.replace(/\//, ' ')];
|
||||
const searchQuery = getSearchQueryString(title.replace(/\//, ' '));
|
||||
|
||||
let searchUris = searchUrisByQuery[searchQuery];
|
||||
if (searchUris) {
|
||||
searchUris = searchUris.filter(searchUri => searchUri !== currentUri);
|
||||
recommendedContent = searchUris;
|
||||
|
|
|
@ -1,25 +1,48 @@
|
|||
import * as SEARCH_TYPES from 'constants/search';
|
||||
// @flow
|
||||
import type { SearchState, SearchOptions, SearchSuggestion } from 'types/Search';
|
||||
import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search';
|
||||
import { getSearchQueryString } from 'util/query_params';
|
||||
import { normalizeURI, parseURI } from 'lbryURI';
|
||||
import { selectCurrentPage, selectCurrentParams } from 'redux/selectors/navigation';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
export const selectState = state => state.search || {};
|
||||
type State = { search: SearchState };
|
||||
|
||||
export const selectSearchValue = createSelector(selectState, state => state.searchQuery);
|
||||
export const selectState = (state: State): SearchState => state.search;
|
||||
|
||||
export const selectSuggestions = createSelector(selectState, state => state.suggestions);
|
||||
|
||||
export const selectSearchQuery = createSelector(
|
||||
selectCurrentPage,
|
||||
selectCurrentParams,
|
||||
(page, params) => (page === 'search' ? params && params.query : null)
|
||||
export const selectSearchValue: (state: State) => string = createSelector(
|
||||
selectState,
|
||||
state => state.searchQuery
|
||||
);
|
||||
|
||||
export const selectIsSearching = createSelector(selectState, state => state.searching);
|
||||
export const selectSearchOptions: (state: State) => SearchOptions = createSelector(
|
||||
selectState,
|
||||
state => state.options
|
||||
);
|
||||
|
||||
export const selectSearchUrisByQuery = createSelector(selectState, state => state.urisByQuery);
|
||||
export const selectSuggestions: (
|
||||
state: State
|
||||
) => { [string]: Array<SearchSuggestion> } = createSelector(
|
||||
selectState,
|
||||
state => state.suggestions
|
||||
);
|
||||
|
||||
export const makeSelectSearchUris = query =>
|
||||
export const selectSearchQuery: (state: State) => ?string = createSelector(
|
||||
selectCurrentPage,
|
||||
selectCurrentParams,
|
||||
(page: string, params: ?{ query: string }) => (page === 'search' ? params && params.query : null)
|
||||
);
|
||||
|
||||
export const selectIsSearching: (state: State) => boolean = createSelector(
|
||||
selectState,
|
||||
state => state.searching
|
||||
);
|
||||
|
||||
export const selectSearchUrisByQuery: (
|
||||
state: State
|
||||
) => { [string]: Array<string> } = createSelector(selectState, state => state.urisByQuery);
|
||||
|
||||
export const makeSelectSearchUris = (query: string): ((state: State) => Array<string>) =>
|
||||
// replace statement below is kind of ugly, and repeated in doSearch action
|
||||
createSelector(
|
||||
selectSearchUrisByQuery,
|
||||
|
@ -30,7 +53,7 @@ export const selectWunderBarAddress = createSelector(
|
|||
selectCurrentPage,
|
||||
selectSearchQuery,
|
||||
selectCurrentParams,
|
||||
(page, query, params) => {
|
||||
(page: string, query: string, params: { uri: string }) => {
|
||||
// only populate the wunderbar address if we are on the file/channel pages
|
||||
// or show the search query
|
||||
if (page === 'show') {
|
||||
|
@ -40,13 +63,12 @@ export const selectWunderBarAddress = createSelector(
|
|||
}
|
||||
);
|
||||
|
||||
export const selectSearchBarFocused = createSelector(selectState, state => state.focused);
|
||||
// export const selectSear
|
||||
export const selectSearchBarFocused: boolean = createSelector(selectState, state => state.focused);
|
||||
|
||||
export const selectSearchSuggestions = createSelector(
|
||||
export const selectSearchSuggestions: Array<SearchSuggestion> = createSelector(
|
||||
selectSearchValue,
|
||||
selectSuggestions,
|
||||
(query, suggestions) => {
|
||||
(query: string, suggestions: { [string]: Array<string> }) => {
|
||||
if (!query) {
|
||||
return [];
|
||||
}
|
||||
|
@ -117,3 +139,23 @@ export const selectSearchSuggestions = createSelector(
|
|||
return searchSuggestions;
|
||||
}
|
||||
);
|
||||
|
||||
// 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
|
||||
export const makeSelectQueryWithOptions = (
|
||||
customQuery: ?string,
|
||||
customSize: ?number,
|
||||
customFrom: ?number,
|
||||
isBackgroundSearch: boolean = false // If it's a background search, don't use the users settings
|
||||
) =>
|
||||
createSelector(selectSearchQuery, selectSearchOptions, (query, options) => {
|
||||
const size = customSize || options[SEARCH_OPTIONS.RESULT_COUNT];
|
||||
|
||||
const queryString = getSearchQueryString(
|
||||
customQuery || query,
|
||||
{ ...options, size, from: customFrom },
|
||||
!isBackgroundSearch
|
||||
);
|
||||
|
||||
return queryString;
|
||||
});
|
||||
|
|
68
src/types/Search.js
Normal file
68
src/types/Search.js
Normal file
|
@ -0,0 +1,68 @@
|
|||
// @flow
|
||||
import * as ACTIONS from 'constants/action_types';
|
||||
|
||||
export type SearchSuggestion = {
|
||||
value: string,
|
||||
shorthand: string,
|
||||
type: string,
|
||||
};
|
||||
|
||||
export type SearchOptions = {
|
||||
// :(
|
||||
// https://github.com/facebook/flow/issues/6492
|
||||
RESULT_COUNT: number,
|
||||
CLAIM_TYPE: string,
|
||||
INCLUDE_FILES: string,
|
||||
INCLUDE_CHANNELS: string,
|
||||
INCLUDE_FILES_AND_CHANNELS: string,
|
||||
MEDIA_AUDIO: string,
|
||||
MEDIA_VIDEO: string,
|
||||
MEDIA_TEXT: string,
|
||||
MEDIA_IMAGE: string,
|
||||
MEDIA_APPLICATION: string,
|
||||
};
|
||||
|
||||
export type SearchState = {
|
||||
isActive: boolean,
|
||||
searchQuery: string,
|
||||
options: SearchOptions,
|
||||
suggestions: { [string]: Array<SearchSuggestion> },
|
||||
urisByQuery: {},
|
||||
};
|
||||
|
||||
export type SearchSuccess = {
|
||||
type: ACTIONS.SEARCH_SUCCESS,
|
||||
data: {
|
||||
query: string,
|
||||
uris: Array<string>,
|
||||
},
|
||||
};
|
||||
|
||||
export type UpdateSearchQuery = {
|
||||
type: ACTIONS.UPDATE_SEARCH_QUERY,
|
||||
data: {
|
||||
query: string,
|
||||
},
|
||||
};
|
||||
|
||||
export type UpdateSearchSuggestions = {
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: {
|
||||
query: string,
|
||||
suggestions: Array<SearchSuggestion>,
|
||||
},
|
||||
};
|
||||
|
||||
export type HistoryNavigate = {
|
||||
type: ACTIONS.HISTORY_NAVIGATE,
|
||||
data: {
|
||||
url: string,
|
||||
index?: number,
|
||||
scrollY?: number,
|
||||
},
|
||||
};
|
||||
|
||||
export type UpdateSearchOptions = {
|
||||
type: ACTIONS.UPDATE_SEARCH_OPTIONS,
|
||||
data: SearchOptions,
|
||||
};
|
|
@ -1,4 +1,10 @@
|
|||
export function parseQueryParams(queryString) {
|
||||
// @flow
|
||||
import { SEARCH_OPTIONS } from 'constants/search';
|
||||
|
||||
const DEFAULT_SEARCH_RESULT_FROM = 0;
|
||||
const DEFAULT_SEARCH_SIZE = 20;
|
||||
|
||||
export function parseQueryParams(queryString: string) {
|
||||
if (queryString === '') return {};
|
||||
const parts = queryString
|
||||
.split('?')
|
||||
|
@ -14,7 +20,7 @@ export function parseQueryParams(queryString) {
|
|||
return params;
|
||||
}
|
||||
|
||||
export function toQueryString(params) {
|
||||
export function toQueryString(params: { [string]: string | number }) {
|
||||
if (!params) return '';
|
||||
|
||||
const parts = [];
|
||||
|
@ -26,3 +32,39 @@ export function toQueryString(params) {
|
|||
|
||||
return parts.join('&');
|
||||
}
|
||||
|
||||
export const getSearchQueryString = (
|
||||
query: string,
|
||||
options: any = {},
|
||||
includeUserOptions: boolean = false
|
||||
) => {
|
||||
const encodedQuery = encodeURIComponent(query);
|
||||
const queryParams = [
|
||||
`s=${encodedQuery}`,
|
||||
`size=${options.size || DEFAULT_SEARCH_SIZE}`,
|
||||
`from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`,
|
||||
];
|
||||
|
||||
if (includeUserOptions) {
|
||||
queryParams.push(`claimType=${options[SEARCH_OPTIONS.CLAIM_TYPE]}`);
|
||||
|
||||
// If they are only searching for channels, strip out the media info
|
||||
if (options[SEARCH_OPTIONS.CLAIM_TYPE] !== SEARCH_OPTIONS.INCLUDE_CHANNELS) {
|
||||
queryParams.push(
|
||||
`mediaType=${[
|
||||
SEARCH_OPTIONS.MEDIA_FILE,
|
||||
SEARCH_OPTIONS.MEDIA_AUDIO,
|
||||
SEARCH_OPTIONS.MEDIA_VIDEO,
|
||||
SEARCH_OPTIONS.MEDIA_TEXT,
|
||||
SEARCH_OPTIONS.MEDIA_IMAGE,
|
||||
SEARCH_OPTIONS.MEDIA_APPLICATION,
|
||||
].reduce(
|
||||
(acc, currentOption) => (options[currentOption] ? `${acc}${currentOption},` : acc),
|
||||
''
|
||||
)}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return queryParams.join('&');
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue