Resolved search updates #273
8 changed files with 235 additions and 1 deletions
85
dist/bundle.es.js
vendored
85
dist/bundle.es.js
vendored
|
@ -162,6 +162,9 @@ const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI';
|
|||
const SEARCH_START = 'SEARCH_START';
|
||||
const SEARCH_SUCCESS = 'SEARCH_SUCCESS';
|
||||
const SEARCH_FAIL = 'SEARCH_FAIL';
|
||||
const RESOLVED_SEARCH_START = 'RESOLVED_SEARCH_START';
|
||||
const RESOLVED_SEARCH_SUCCESS = 'RESOLVED_SEARCH_SUCCESS';
|
||||
const RESOLVED_SEARCH_FAIL = 'RESOLVED_SEARCH_FAIL';
|
||||
const UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY';
|
||||
const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS';
|
||||
const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS';
|
||||
|
@ -401,6 +404,9 @@ var action_types = /*#__PURE__*/Object.freeze({
|
|||
SEARCH_START: SEARCH_START,
|
||||
SEARCH_SUCCESS: SEARCH_SUCCESS,
|
||||
SEARCH_FAIL: SEARCH_FAIL,
|
||||
RESOLVED_SEARCH_START: RESOLVED_SEARCH_START,
|
||||
RESOLVED_SEARCH_SUCCESS: RESOLVED_SEARCH_SUCCESS,
|
||||
RESOLVED_SEARCH_FAIL: RESOLVED_SEARCH_FAIL,
|
||||
UPDATE_SEARCH_QUERY: UPDATE_SEARCH_QUERY,
|
||||
UPDATE_SEARCH_OPTIONS: UPDATE_SEARCH_OPTIONS,
|
||||
UPDATE_SEARCH_SUGGESTIONS: UPDATE_SEARCH_SUGGESTIONS,
|
||||
|
@ -1330,6 +1336,12 @@ const makeSelectSearchUris = query =>
|
|||
// replace statement below is kind of ugly, and repeated in doSearch action
|
||||
reselect.createSelector(selectSearchUrisByQuery, byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]);
|
||||
|
||||
const selectResolvedSearchResultsByQuery = reselect.createSelector(selectState, state => state.resolvedResultsByQuery);
|
||||
|
||||
const makeSelectResolvedSearchResults = query =>
|
||||
// replace statement below is kind of ugly, and repeated in doSearch action
|
||||
reselect.createSelector(selectResolvedSearchResultsByQuery, byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]);
|
||||
|
||||
const selectSearchBarFocused = reselect.createSelector(selectState, state => state.focused);
|
||||
|
||||
const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selectSuggestions, (query, suggestions) => {
|
||||
|
@ -3995,6 +4007,57 @@ from, isBackgroundSearch = false, options = {}, resolveResults = true) => (dispa
|
|||
});
|
||||
};
|
||||
|
||||
const doResolvedSearch = (rawQuery, size, // only pass in if you don't want to use the users setting (ex: related content)
|
||||
from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => {
|
||||
const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' ');
|
||||
|
||||
if (!query) {
|
||||
dispatch({
|
||||
type: RESOLVED_SEARCH_FAIL
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const state = getState();
|
||||
let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)(state);
|
||||
|
||||
// If we have already searched for something, we don't need to do anything
|
||||
const resultsForQuery = makeSelectResolvedSearchResults(queryWithOptions)(state);
|
||||
if (resultsForQuery && !!resultsForQuery.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: RESOLVED_SEARCH_START
|
||||
});
|
||||
|
||||
if (!state.search.searchQuery && !isBackgroundSearch) {
|
||||
dispatch(doUpdateSearchQuery(query));
|
||||
}
|
||||
|
||||
fetch(`${CONNECTION_STRING}search?resolve=true&${queryWithOptions}`).then(handleFetchResponse).then(data => {
|
||||
const results = [];
|
||||
|
||||
data.forEach(result => {
|
||||
if (result) {
|
||||
results.push(result);
|
||||
}
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: RESOLVED_SEARCH_SUCCESS,
|
||||
data: {
|
||||
query: queryWithOptions,
|
||||
results
|
||||
}
|
||||
});
|
||||
}).catch(e => {
|
||||
dispatch({
|
||||
type: RESOLVED_SEARCH_FAIL
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const doFocusSearchInput = () => dispatch => dispatch({
|
||||
type: SEARCH_FOCUS
|
||||
});
|
||||
|
@ -4999,7 +5062,8 @@ const defaultState$7 = {
|
|||
[SEARCH_OPTIONS.MEDIA_APPLICATION]: true
|
||||
},
|
||||
suggestions: {},
|
||||
urisByQuery: {}
|
||||
urisByQuery: {},
|
||||
resolvedResultsByQuery: {}
|
||||
};
|
||||
|
||||
const searchReducer = handleActions({
|
||||
|
@ -5019,6 +5083,22 @@ const searchReducer = handleActions({
|
|||
searching: false
|
||||
}),
|
||||
|
||||
[RESOLVED_SEARCH_START]: state => _extends$c({}, state, {
|
||||
searching: true
|
||||
}),
|
||||
[RESOLVED_SEARCH_SUCCESS]: (state, action) => {
|
||||
const { query, results } = action.data;
|
||||
|
||||
return _extends$c({}, state, {
|
||||
searching: false,
|
||||
resolvedResultsByQuery: Object.assign({}, state.resolvedResultsByQuery, { [query]: results })
|
||||
});
|
||||
},
|
||||
|
||||
[RESOLVED_SEARCH_FAIL]: state => _extends$c({}, state, {
|
||||
searching: false
|
||||
}),
|
||||
|
||||
[UPDATE_SEARCH_QUERY]: (state, action) => _extends$c({}, state, {
|
||||
searchQuery: action.data.query,
|
||||
isActive: true
|
||||
|
@ -5587,6 +5667,7 @@ exports.doPurchaseUri = doPurchaseUri;
|
|||
exports.doResetThumbnailStatus = doResetThumbnailStatus;
|
||||
exports.doResolveUri = doResolveUri;
|
||||
exports.doResolveUris = doResolveUris;
|
||||
exports.doResolvedSearch = doResolvedSearch;
|
||||
exports.doSearch = doSearch;
|
||||
exports.doSendDraftTransaction = doSendDraftTransaction;
|
||||
exports.doSendTip = doSendTip;
|
||||
|
@ -5655,6 +5736,7 @@ exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri;
|
|||
exports.makeSelectPublishFormValue = makeSelectPublishFormValue;
|
||||
exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions;
|
||||
exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri;
|
||||
exports.makeSelectResolvedSearchResults = makeSelectResolvedSearchResults;
|
||||
exports.makeSelectSearchDownloadUrlsCount = makeSelectSearchDownloadUrlsCount;
|
||||
exports.makeSelectSearchDownloadUrlsForPage = makeSelectSearchDownloadUrlsForPage;
|
||||
exports.makeSelectSearchUris = makeSelectSearchUris;
|
||||
|
@ -5747,6 +5829,7 @@ exports.selectPurchasedUris = selectPurchasedUris;
|
|||
exports.selectReceiveAddress = selectReceiveAddress;
|
||||
exports.selectRecentTransactions = selectRecentTransactions;
|
||||
exports.selectReservedBalance = selectReservedBalance;
|
||||
exports.selectResolvedSearchResultsByQuery = selectResolvedSearchResultsByQuery;
|
||||
exports.selectResolvingUris = selectResolvingUris;
|
||||
exports.selectSearchBarFocused = selectSearchBarFocused;
|
||||
exports.selectSearchOptions = selectSearchOptions;
|
||||
|
|
20
dist/flow-typed/Search.js
vendored
20
dist/flow-typed/Search.js
vendored
|
@ -28,6 +28,7 @@ declare type SearchState = {
|
|||
options: SearchOptions,
|
||||
suggestions: { [string]: Array<SearchSuggestion> },
|
||||
urisByQuery: {},
|
||||
resolvedResultsByQuery: {},
|
||||
};
|
||||
|
||||
declare type SearchSuccess = {
|
||||
|
@ -57,3 +58,22 @@ declare type UpdateSearchOptions = {
|
|||
type: ACTIONS.UPDATE_SEARCH_OPTIONS,
|
||||
data: SearchOptions,
|
||||
};
|
||||
|
||||
declare type ResolvedSearchResult = {
|
||||
channel: string,
|
||||
channel_claim_id: string,
|
||||
claimId: string,
|
||||
fee: number,
|
||||
name: string,
|
||||
release_time: string,
|
||||
thumbnail_url: string,
|
||||
title: string,
|
||||
};
|
||||
|
||||
declare type ResolvedSearchSuccess = {
|
||||
type: ACTIONS.RESOLVED_SEARCH_SUCCESS,
|
||||
data: {
|
||||
query: string,
|
||||
results: Array<ResolvedSearchResult>,
|
||||
},
|
||||
};
|
||||
|
|
20
flow-typed/Search.js
vendored
20
flow-typed/Search.js
vendored
|
@ -28,6 +28,7 @@ declare type SearchState = {
|
|||
options: SearchOptions,
|
||||
suggestions: { [string]: Array<SearchSuggestion> },
|
||||
urisByQuery: {},
|
||||
resolvedResultsByQuery: {},
|
||||
};
|
||||
|
||||
declare type SearchSuccess = {
|
||||
|
@ -57,3 +58,22 @@ declare type UpdateSearchOptions = {
|
|||
type: ACTIONS.UPDATE_SEARCH_OPTIONS,
|
||||
data: SearchOptions,
|
||||
};
|
||||
|
||||
declare type ResolvedSearchResult = {
|
||||
channel: string,
|
||||
channel_claim_id: string,
|
||||
claimId: string,
|
||||
fee: number,
|
||||
name: string,
|
||||
release_time: string,
|
||||
thumbnail_url: string,
|
||||
title: string,
|
||||
};
|
||||
|
||||
declare type ResolvedSearchSuccess = {
|
||||
type: ACTIONS.RESOLVED_SEARCH_SUCCESS,
|
||||
data: {
|
||||
query: string,
|
||||
results: Array<ResolvedSearchResult>,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -139,6 +139,9 @@ export const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI';
|
|||
export const SEARCH_START = 'SEARCH_START';
|
||||
export const SEARCH_SUCCESS = 'SEARCH_SUCCESS';
|
||||
export const SEARCH_FAIL = 'SEARCH_FAIL';
|
||||
export const RESOLVED_SEARCH_START = 'RESOLVED_SEARCH_START';
|
||||
export const RESOLVED_SEARCH_SUCCESS = 'RESOLVED_SEARCH_SUCCESS';
|
||||
export const RESOLVED_SEARCH_FAIL = 'RESOLVED_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';
|
||||
|
|
|
@ -90,6 +90,7 @@ export {
|
|||
|
||||
export {
|
||||
doSearch,
|
||||
doResolvedSearch,
|
||||
doUpdateSearchQuery,
|
||||
doFocusSearchInput,
|
||||
doBlurSearchInput,
|
||||
|
@ -265,9 +266,11 @@ export {
|
|||
export { selectSearchState };
|
||||
export {
|
||||
makeSelectSearchUris,
|
||||
makeSelectResolvedSearchResults,
|
||||
selectSearchValue,
|
||||
selectSearchOptions,
|
||||
selectIsSearching,
|
||||
selectResolvedSearchResultsByQuery,
|
||||
selectSearchUrisByQuery,
|
||||
selectSearchBarFocused,
|
||||
selectSearchSuggestions,
|
||||
|
|
|
@ -4,6 +4,7 @@ import { buildURI } from 'lbryURI';
|
|||
import { doResolveUri } from 'redux/actions/claims';
|
||||
import {
|
||||
makeSelectSearchUris,
|
||||
makeSelectResolvedSearchResults,
|
||||
selectSuggestions,
|
||||
makeSelectQueryWithOptions,
|
||||
selectSearchValue,
|
||||
|
@ -159,6 +160,69 @@ export const doSearch = (
|
|||
});
|
||||
};
|
||||
|
||||
export const doResolvedSearch = (
|
||||
rawQuery: string,
|
||||
size: ?number, // only pass in if you don't want to use the users setting (ex: related content)
|
||||
from: ?number,
|
||||
isBackgroundSearch: boolean = false,
|
||||
options: {
|
||||
related_to?: string,
|
||||
} = {}
|
||||
) => (dispatch: Dispatch, getState: GetState) => {
|
||||
const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' ');
|
||||
|
||||
if (!query) {
|
||||
dispatch({
|
||||
type: ACTIONS.RESOLVED_SEARCH_FAIL,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const state = getState();
|
||||
let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)(
|
||||
state
|
||||
);
|
||||
|
||||
// If we have already searched for something, we don't need to do anything
|
||||
const resultsForQuery = makeSelectResolvedSearchResults(queryWithOptions)(state);
|
||||
if (resultsForQuery && !!resultsForQuery.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
dispatch({
|
||||
type: ACTIONS.RESOLVED_SEARCH_START,
|
||||
});
|
||||
|
||||
if (!state.search.searchQuery && !isBackgroundSearch) {
|
||||
dispatch(doUpdateSearchQuery(query));
|
||||
}
|
||||
|
||||
fetch(`${CONNECTION_STRING}search?resolve=true&${queryWithOptions}`)
|
||||
.then(handleFetchResponse)
|
||||
.then((data: Array<ResolvedSearchResult>) => {
|
||||
const results = [];
|
||||
|
||||
data.forEach(result => {
|
||||
if (result) {
|
||||
results.push(result);
|
||||
}
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: ACTIONS.RESOLVED_SEARCH_SUCCESS,
|
||||
data: {
|
||||
query: queryWithOptions,
|
||||
results,
|
||||
},
|
||||
});
|
||||
})
|
||||
.catch(e => {
|
||||
dispatch({
|
||||
type: ACTIONS.RESOLVED_SEARCH_FAIL,
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
export const doFocusSearchInput = () => (dispatch: Dispatch) =>
|
||||
dispatch({
|
||||
type: ACTIONS.SEARCH_FOCUS,
|
||||
|
|
|
@ -18,6 +18,7 @@ const defaultState = {
|
|||
},
|
||||
suggestions: {},
|
||||
urisByQuery: {},
|
||||
resolvedResultsByQuery: {},
|
||||
};
|
||||
|
||||
export const searchReducer = handleActions(
|
||||
|
@ -41,6 +42,30 @@ export const searchReducer = handleActions(
|
|||
searching: false,
|
||||
}),
|
||||
|
||||
[ACTIONS.RESOLVED_SEARCH_START]: (state: SearchState): SearchState => ({
|
||||
...state,
|
||||
searching: true,
|
||||
}),
|
||||
[ACTIONS.RESOLVED_SEARCH_SUCCESS]: (
|
||||
state: SearchState,
|
||||
action: ResolvedSearchSuccess
|
||||
): SearchState => {
|
||||
const { query, results } = action.data;
|
||||
|
||||
return {
|
||||
...state,
|
||||
searching: false,
|
||||
resolvedResultsByQuery: Object.assign({}, state.resolvedResultsByQuery, {
|
||||
[query]: results,
|
||||
}),
|
||||
};
|
||||
},
|
||||
|
||||
[ACTIONS.RESOLVED_SEARCH_FAIL]: (state: SearchState): SearchState => ({
|
||||
...state,
|
||||
searching: false,
|
||||
}),
|
||||
|
||||
[ACTIONS.UPDATE_SEARCH_QUERY]: (
|
||||
state: SearchState,
|
||||
action: UpdateSearchQuery
|
||||
|
|
|
@ -44,6 +44,22 @@ export const makeSelectSearchUris = (query: string): ((state: State) => Array<st
|
|||
byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]
|
||||
);
|
||||
|
||||
export const selectResolvedSearchResultsByQuery: (
|
||||
state: State
|
||||
) => { [string]: Array<ResolvedSearchResult> } = createSelector(
|
||||
selectState,
|
||||
state => state.resolvedResultsByQuery
|
||||
);
|
||||
|
||||
export const makeSelectResolvedSearchResults = (
|
||||
query: string
|
||||
): ((state: State) => Array<ResolvedSearchResult>) =>
|
||||
// replace statement below is kind of ugly, and repeated in doSearch action
|
||||
createSelector(
|
||||
selectResolvedSearchResultsByQuery,
|
||||
byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]
|
||||
);
|
||||
|
||||
export const selectSearchBarFocused: boolean = createSelector(
|
||||
selectState,
|
||||
state => state.focused
|
||||
|
|
Loading…
Reference in a new issue