Resolved search updates #273

Merged
akinwale merged 7 commits from resolved-search into master 2020-02-10 12:04:35 +01:00
8 changed files with 235 additions and 1 deletions
Showing only changes of commit 9250e0c451 - Show all commits

85
dist/bundle.es.js vendored
View file

@ -162,6 +162,9 @@ const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI';
const SEARCH_START = 'SEARCH_START'; const SEARCH_START = 'SEARCH_START';
const SEARCH_SUCCESS = 'SEARCH_SUCCESS'; const SEARCH_SUCCESS = 'SEARCH_SUCCESS';
const SEARCH_FAIL = 'SEARCH_FAIL'; 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_QUERY = 'UPDATE_SEARCH_QUERY';
const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS'; const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS';
const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS'; const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS';
@ -401,6 +404,9 @@ var action_types = /*#__PURE__*/Object.freeze({
SEARCH_START: SEARCH_START, SEARCH_START: SEARCH_START,
SEARCH_SUCCESS: SEARCH_SUCCESS, SEARCH_SUCCESS: SEARCH_SUCCESS,
SEARCH_FAIL: SEARCH_FAIL, 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_QUERY: UPDATE_SEARCH_QUERY,
UPDATE_SEARCH_OPTIONS: UPDATE_SEARCH_OPTIONS, UPDATE_SEARCH_OPTIONS: UPDATE_SEARCH_OPTIONS,
UPDATE_SEARCH_SUGGESTIONS: UPDATE_SEARCH_SUGGESTIONS, 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 // replace statement below is kind of ugly, and repeated in doSearch action
reselect.createSelector(selectSearchUrisByQuery, byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]); 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 selectSearchBarFocused = reselect.createSelector(selectState, state => state.focused);
const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selectSuggestions, (query, suggestions) => { 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({ const doFocusSearchInput = () => dispatch => dispatch({
type: SEARCH_FOCUS type: SEARCH_FOCUS
}); });
@ -4999,7 +5062,8 @@ const defaultState$7 = {
[SEARCH_OPTIONS.MEDIA_APPLICATION]: true [SEARCH_OPTIONS.MEDIA_APPLICATION]: true
}, },
suggestions: {}, suggestions: {},
urisByQuery: {} urisByQuery: {},
resolvedResultsByQuery: {}
}; };
const searchReducer = handleActions({ const searchReducer = handleActions({
@ -5019,6 +5083,22 @@ const searchReducer = handleActions({
searching: false 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, { [UPDATE_SEARCH_QUERY]: (state, action) => _extends$c({}, state, {
searchQuery: action.data.query, searchQuery: action.data.query,
isActive: true isActive: true
@ -5587,6 +5667,7 @@ exports.doPurchaseUri = doPurchaseUri;
exports.doResetThumbnailStatus = doResetThumbnailStatus; exports.doResetThumbnailStatus = doResetThumbnailStatus;
exports.doResolveUri = doResolveUri; exports.doResolveUri = doResolveUri;
exports.doResolveUris = doResolveUris; exports.doResolveUris = doResolveUris;
exports.doResolvedSearch = doResolvedSearch;
exports.doSearch = doSearch; exports.doSearch = doSearch;
exports.doSendDraftTransaction = doSendDraftTransaction; exports.doSendDraftTransaction = doSendDraftTransaction;
exports.doSendTip = doSendTip; exports.doSendTip = doSendTip;
@ -5655,6 +5736,7 @@ exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri;
exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectPublishFormValue = makeSelectPublishFormValue;
exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions;
exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri;
exports.makeSelectResolvedSearchResults = makeSelectResolvedSearchResults;
exports.makeSelectSearchDownloadUrlsCount = makeSelectSearchDownloadUrlsCount; exports.makeSelectSearchDownloadUrlsCount = makeSelectSearchDownloadUrlsCount;
exports.makeSelectSearchDownloadUrlsForPage = makeSelectSearchDownloadUrlsForPage; exports.makeSelectSearchDownloadUrlsForPage = makeSelectSearchDownloadUrlsForPage;
exports.makeSelectSearchUris = makeSelectSearchUris; exports.makeSelectSearchUris = makeSelectSearchUris;
@ -5747,6 +5829,7 @@ exports.selectPurchasedUris = selectPurchasedUris;
exports.selectReceiveAddress = selectReceiveAddress; exports.selectReceiveAddress = selectReceiveAddress;
exports.selectRecentTransactions = selectRecentTransactions; exports.selectRecentTransactions = selectRecentTransactions;
exports.selectReservedBalance = selectReservedBalance; exports.selectReservedBalance = selectReservedBalance;
exports.selectResolvedSearchResultsByQuery = selectResolvedSearchResultsByQuery;
exports.selectResolvingUris = selectResolvingUris; exports.selectResolvingUris = selectResolvingUris;
exports.selectSearchBarFocused = selectSearchBarFocused; exports.selectSearchBarFocused = selectSearchBarFocused;
exports.selectSearchOptions = selectSearchOptions; exports.selectSearchOptions = selectSearchOptions;

View file

@ -28,6 +28,7 @@ declare type SearchState = {
options: SearchOptions, options: SearchOptions,
suggestions: { [string]: Array<SearchSuggestion> }, suggestions: { [string]: Array<SearchSuggestion> },
urisByQuery: {}, urisByQuery: {},
resolvedResultsByQuery: {},
}; };
declare type SearchSuccess = { declare type SearchSuccess = {
@ -57,3 +58,22 @@ declare type UpdateSearchOptions = {
type: ACTIONS.UPDATE_SEARCH_OPTIONS, type: ACTIONS.UPDATE_SEARCH_OPTIONS,
data: SearchOptions, 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
View file

@ -28,6 +28,7 @@ declare type SearchState = {
options: SearchOptions, options: SearchOptions,
suggestions: { [string]: Array<SearchSuggestion> }, suggestions: { [string]: Array<SearchSuggestion> },
urisByQuery: {}, urisByQuery: {},
resolvedResultsByQuery: {},
}; };
declare type SearchSuccess = { declare type SearchSuccess = {
@ -57,3 +58,22 @@ declare type UpdateSearchOptions = {
type: ACTIONS.UPDATE_SEARCH_OPTIONS, type: ACTIONS.UPDATE_SEARCH_OPTIONS,
data: SearchOptions, 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>,
},
};

View file

@ -139,6 +139,9 @@ export const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI';
export const SEARCH_START = 'SEARCH_START'; export const SEARCH_START = 'SEARCH_START';
export const SEARCH_SUCCESS = 'SEARCH_SUCCESS'; export const SEARCH_SUCCESS = 'SEARCH_SUCCESS';
export const SEARCH_FAIL = 'SEARCH_FAIL'; 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_QUERY = 'UPDATE_SEARCH_QUERY';
export const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS'; export const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS';
export const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS'; export const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS';

View file

@ -90,6 +90,7 @@ export {
export { export {
doSearch, doSearch,
doResolvedSearch,
doUpdateSearchQuery, doUpdateSearchQuery,
doFocusSearchInput, doFocusSearchInput,
doBlurSearchInput, doBlurSearchInput,
@ -265,9 +266,11 @@ export {
export { selectSearchState }; export { selectSearchState };
export { export {
makeSelectSearchUris, makeSelectSearchUris,
makeSelectResolvedSearchResults,
selectSearchValue, selectSearchValue,
selectSearchOptions, selectSearchOptions,
selectIsSearching, selectIsSearching,
selectResolvedSearchResultsByQuery,
selectSearchUrisByQuery, selectSearchUrisByQuery,
selectSearchBarFocused, selectSearchBarFocused,
selectSearchSuggestions, selectSearchSuggestions,

View file

@ -4,6 +4,7 @@ import { buildURI } from 'lbryURI';
import { doResolveUri } from 'redux/actions/claims'; import { doResolveUri } from 'redux/actions/claims';
import { import {
makeSelectSearchUris, makeSelectSearchUris,
makeSelectResolvedSearchResults,
selectSuggestions, selectSuggestions,
makeSelectQueryWithOptions, makeSelectQueryWithOptions,
selectSearchValue, 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) => export const doFocusSearchInput = () => (dispatch: Dispatch) =>
dispatch({ dispatch({
type: ACTIONS.SEARCH_FOCUS, type: ACTIONS.SEARCH_FOCUS,

View file

@ -18,6 +18,7 @@ const defaultState = {
}, },
suggestions: {}, suggestions: {},
urisByQuery: {}, urisByQuery: {},
resolvedResultsByQuery: {},
}; };
export const searchReducer = handleActions( export const searchReducer = handleActions(
@ -41,6 +42,30 @@ export const searchReducer = handleActions(
searching: false, 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]: ( [ACTIONS.UPDATE_SEARCH_QUERY]: (
state: SearchState, state: SearchState,
action: UpdateSearchQuery action: UpdateSearchQuery

View file

@ -44,6 +44,22 @@ export const makeSelectSearchUris = (query: string): ((state: State) => Array<st
byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query] 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( export const selectSearchBarFocused: boolean = createSelector(
selectState, selectState,
state => state.focused state => state.focused