add search suggestions selector
This commit is contained in:
parent
8794a775bf
commit
dc6f19bb7d
5 changed files with 247 additions and 217 deletions
275
dist/bundle.js
vendored
275
dist/bundle.js
vendored
|
@ -104,7 +104,7 @@ return /******/ (function(modules) { // webpackBootstrap
|
|||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.selectWalletUnlockResult = exports.selectWalletUnlockSucceeded = exports.selectWalletUnlockPending = exports.selectWalletDecryptResult = exports.selectWalletDecryptSucceeded = exports.selectWalletDecryptPending = exports.selectWalletEncryptResult = exports.selectWalletEncryptSucceeded = exports.selectWalletEncryptPending = exports.selectWalletState = exports.selectWalletIsEncrypted = exports.selectBlocks = exports.selectDraftTransactionError = exports.selectDraftTransactionAddress = exports.selectDraftTransactionAmount = exports.selectDraftTransaction = exports.selectGettingNewAddress = exports.selectReceiveAddress = exports.selectIsSendingSupport = exports.selectIsFetchingTransactions = exports.selectHasTransactions = exports.selectRecentTransactions = exports.selectTransactionItems = exports.selectTransactionsById = exports.selectBalance = exports.makeSelectBlockDate = exports.selectSearchBarFocused = exports.selectWunderBarAddress = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchValue = exports.selectSearchQuery = exports.makeSelectSearchUris = exports.selectSearchState = exports.selectNavLinks = exports.selectActiveHistoryEntry = exports.selectHistoryStack = exports.selectHistoryIndex = exports.selectIsForwardDisabled = exports.selectIsBackDisabled = exports.selectPathAfterAuth = exports.selectPageTitle = exports.selectHeaderLinks = exports.selectCurrentParams = exports.selectCurrentPage = exports.selectCurrentPath = exports.makeSelectCurrentParam = exports.computePageFromPath = exports.selectSearchDownloadUris = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.selectUrisLoading = exports.selectDownloadingByOutpoint = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.makeSelectLoadingForUri = exports.makeSelectDownloadingForUri = exports.makeSelectFileInfoForUri = exports.selectFetchingCostInfo = exports.selectCostForCurrentPageUri = exports.selectAllCostInfoByUri = exports.makeSelectCostInfoForUri = exports.makeSelectFetchingCostInfoForUri = exports.selectRewardContentClaimIds = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.selectFetchingTrendingUris = exports.selectTrendingUris = undefined;
|
||||
exports.selectWalletUnlockResult = exports.selectWalletUnlockSucceeded = exports.selectWalletUnlockPending = exports.selectWalletDecryptResult = exports.selectWalletDecryptSucceeded = exports.selectWalletDecryptPending = exports.selectWalletEncryptResult = exports.selectWalletEncryptSucceeded = exports.selectWalletEncryptPending = exports.selectWalletState = exports.selectWalletIsEncrypted = exports.selectBlocks = exports.selectDraftTransactionError = exports.selectDraftTransactionAddress = exports.selectDraftTransactionAmount = exports.selectDraftTransaction = exports.selectGettingNewAddress = exports.selectReceiveAddress = exports.selectIsSendingSupport = exports.selectIsFetchingTransactions = exports.selectHasTransactions = exports.selectRecentTransactions = exports.selectTransactionItems = exports.selectTransactionsById = exports.selectBalance = exports.makeSelectBlockDate = exports.selectSearchSuggestions = exports.selectSearchBarFocused = exports.selectWunderBarAddress = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchValue = exports.selectSearchQuery = exports.makeSelectSearchUris = exports.selectSearchState = exports.selectNavLinks = exports.selectActiveHistoryEntry = exports.selectHistoryStack = exports.selectHistoryIndex = exports.selectIsForwardDisabled = exports.selectIsBackDisabled = exports.selectPathAfterAuth = exports.selectPageTitle = exports.selectHeaderLinks = exports.selectCurrentParams = exports.selectCurrentPage = exports.selectCurrentPath = exports.makeSelectCurrentParam = exports.computePageFromPath = exports.selectSearchDownloadUris = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.selectUrisLoading = exports.selectDownloadingByOutpoint = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.makeSelectLoadingForUri = exports.makeSelectDownloadingForUri = exports.makeSelectFileInfoForUri = exports.selectFetchingCostInfo = exports.selectCostForCurrentPageUri = exports.selectAllCostInfoByUri = exports.makeSelectCostInfoForUri = exports.makeSelectFetchingCostInfoForUri = exports.selectRewardContentClaimIds = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.selectFetchingTrendingUris = exports.selectTrendingUris = undefined;
|
||||
exports.selectFetchingFeaturedUris = exports.selectFeaturedUris = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.selectAllFetchingChannelClaims = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = exports.makeSelectRecommendedContentForUri = exports.makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountFromUris = exports.makeSelectTotalPagesForChannel = exports.makeSelectTotalItemsForChannel = exports.makeSelectIsUriResolving = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForPage = exports.makeSelectClaimsInChannelForCurrentPage = exports.makeSelectFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.makeSelectClaimForUri = exports.selectSnack = exports.selectNotificationProps = exports.selectNotification = exports.selectBlackListedOutpoints = exports.blacklistReducer = exports.walletReducer = exports.searchReducer = exports.notificationsReducer = exports.fileInfoReducer = exports.costInfoReducer = exports.claimsReducer = exports.formatFullPrice = exports.formatCredits = exports.toQueryString = exports.parseQueryParams = exports.batchActions = exports.doWalletStatus = exports.doWalletUnlock = exports.doWalletDecrypt = exports.doWalletEncrypt = exports.doSendSupport = exports.doSetDraftTransactionAddress = exports.doSetDraftTransactionAmount = exports.doSendDraftTransaction = exports.doCheckAddressIsMine = exports.doGetNewAddress = exports.doFetchBlock = exports.doFetchTransactions = exports.doBalanceSubscribe = exports.doUpdateBalance = exports.doBlackListedOutpointsSubscribe = exports.doBlurSearchInput = exports.doFocusSearchInput = exports.doUpdateSearchQuery = exports.doSearch = exports.doFetchFileInfosAndPublishedClaims = exports.doFileList = exports.doFetchFileInfo = exports.doFetchCostInfoForUri = exports.doFetchRewardedContent = exports.doFetchTrendingUris = exports.doFetchFeaturedUris = exports.doResolveUri = exports.doResolveUris = exports.doAbandonClaim = exports.doFetchClaimListMine = exports.doFetchClaimCountByChannel = exports.doFetchClaimsByChannel = exports.doHideNotification = exports.doNotify = exports.convertToShareLink = exports.isNameValid = exports.isURIClaimable = exports.isURIValid = exports.normalizeURI = exports.buildURI = exports.parseURI = exports.regexAddress = exports.regexInvalidURI = exports.Lbryapi = exports.Lbry = exports.TRANSACTIONS = exports.SETTINGS = exports.SEARCH_TYPES = exports.THUMBNAIL_STATUSES = exports.MODALS = exports.ACTIONS = exports.Notification = undefined;
|
||||
|
||||
var _Notification = __webpack_require__(1);
|
||||
|
@ -245,7 +245,7 @@ Object.defineProperty(exports, 'doFetchRewardedContent', {
|
|||
}
|
||||
});
|
||||
|
||||
var _cost_info = __webpack_require__(21);
|
||||
var _cost_info = __webpack_require__(22);
|
||||
|
||||
Object.defineProperty(exports, 'doFetchCostInfoForUri', {
|
||||
enumerable: true,
|
||||
|
@ -254,7 +254,7 @@ Object.defineProperty(exports, 'doFetchCostInfoForUri', {
|
|||
}
|
||||
});
|
||||
|
||||
var _file_info = __webpack_require__(22);
|
||||
var _file_info = __webpack_require__(23);
|
||||
|
||||
Object.defineProperty(exports, 'doFetchFileInfo', {
|
||||
enumerable: true,
|
||||
|
@ -275,7 +275,7 @@ Object.defineProperty(exports, 'doFetchFileInfosAndPublishedClaims', {
|
|||
}
|
||||
});
|
||||
|
||||
var _search = __webpack_require__(24);
|
||||
var _search = __webpack_require__(25);
|
||||
|
||||
Object.defineProperty(exports, 'doSearch', {
|
||||
enumerable: true,
|
||||
|
@ -398,7 +398,7 @@ Object.defineProperty(exports, 'doWalletStatus', {
|
|||
}
|
||||
});
|
||||
|
||||
var _batchActions = __webpack_require__(20);
|
||||
var _batchActions = __webpack_require__(21);
|
||||
|
||||
Object.defineProperty(exports, 'batchActions', {
|
||||
enumerable: true,
|
||||
|
@ -788,7 +788,7 @@ Object.defineProperty(exports, 'selectFetchingCostInfo', {
|
|||
}
|
||||
});
|
||||
|
||||
var _file_info3 = __webpack_require__(23);
|
||||
var _file_info3 = __webpack_require__(24);
|
||||
|
||||
Object.defineProperty(exports, 'makeSelectFileInfoForUri', {
|
||||
enumerable: true,
|
||||
|
@ -994,6 +994,12 @@ Object.defineProperty(exports, 'selectSearchBarFocused', {
|
|||
return _search3.selectSearchBarFocused;
|
||||
}
|
||||
});
|
||||
Object.defineProperty(exports, 'selectSearchSuggestions', {
|
||||
enumerable: true,
|
||||
get: function get() {
|
||||
return _search3.selectSearchSuggestions;
|
||||
}
|
||||
});
|
||||
|
||||
var _wallet3 = __webpack_require__(29);
|
||||
|
||||
|
@ -1166,7 +1172,7 @@ var _thumbnail_upload_statuses = __webpack_require__(44);
|
|||
|
||||
var THUMBNAIL_STATUSES = _interopRequireWildcard(_thumbnail_upload_statuses);
|
||||
|
||||
var _search4 = __webpack_require__(25);
|
||||
var _search4 = __webpack_require__(19);
|
||||
|
||||
var SEARCH_TYPES = _interopRequireWildcard(_search4);
|
||||
|
||||
|
@ -1794,7 +1800,7 @@ var _notifications = __webpack_require__(3);
|
|||
|
||||
var _claims = __webpack_require__(14);
|
||||
|
||||
var _batchActions = __webpack_require__(20);
|
||||
var _batchActions = __webpack_require__(21);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
|
@ -3026,7 +3032,7 @@ var _search = __webpack_require__(18);
|
|||
|
||||
var _reselect = __webpack_require__(16);
|
||||
|
||||
var _claim = __webpack_require__(19);
|
||||
var _claim = __webpack_require__(20);
|
||||
|
||||
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
|
||||
|
||||
|
@ -3704,12 +3710,20 @@ function toQueryString(params) {
|
|||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.selectSearchBarFocused = exports.selectWunderBarAddress = exports.makeSelectSearchUris = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchQuery = exports.selectSearchValue = exports.selectState = undefined;
|
||||
exports.selectSearchSuggestions = exports.selectSearchBarFocused = exports.selectWunderBarAddress = exports.makeSelectSearchUris = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchQuery = exports.selectSuggestions = exports.selectSearchValue = exports.selectState = undefined;
|
||||
|
||||
var _search = __webpack_require__(19);
|
||||
|
||||
var SEARCH_TYPES = _interopRequireWildcard(_search);
|
||||
|
||||
var _lbryURI = __webpack_require__(2);
|
||||
|
||||
var _navigation = __webpack_require__(15);
|
||||
|
||||
var _reselect = __webpack_require__(16);
|
||||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
var selectState = exports.selectState = function selectState(state) {
|
||||
return state.search || {};
|
||||
};
|
||||
|
@ -3718,6 +3732,10 @@ var selectSearchValue = exports.selectSearchValue = (0, _reselect.createSelector
|
|||
return state.searchQuery;
|
||||
});
|
||||
|
||||
var selectSuggestions = exports.selectSuggestions = (0, _reselect.createSelector)(selectState, function (state) {
|
||||
return state.suggestions;
|
||||
});
|
||||
|
||||
var selectSearchQuery = exports.selectSearchQuery = (0, _reselect.createSelector)(_navigation.selectCurrentPage, _navigation.selectCurrentParams, function (page, params) {
|
||||
return page === 'search' ? params && params.query : null;
|
||||
});
|
||||
|
@ -3751,6 +3769,80 @@ var selectWunderBarAddress = exports.selectWunderBarAddress = (0, _reselect.crea
|
|||
var selectSearchBarFocused = exports.selectSearchBarFocused = (0, _reselect.createSelector)(selectState, function (state) {
|
||||
return state.focused;
|
||||
});
|
||||
// export const selectSear
|
||||
|
||||
var selectSearchSuggestions = exports.selectSearchSuggestions = (0, _reselect.createSelector)(selectSearchValue, selectSuggestions, function (query, suggestions) {
|
||||
if (!query) {
|
||||
return [];
|
||||
}
|
||||
|
||||
var queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://';
|
||||
|
||||
if (query.startsWith('lbry://') && query !== 'lbry://') {
|
||||
// If it starts with a prefix, don't show any autocomplete results
|
||||
// They are probably typing/pasting in a lbry uri
|
||||
return [{
|
||||
value: query,
|
||||
type: SEARCH_TYPES.FILE
|
||||
}];
|
||||
} else if (queryIsPrefix) {
|
||||
// If it is a prefix, wait until something else comes to figure out what to do
|
||||
return [];
|
||||
}
|
||||
|
||||
var searchSuggestions = [];
|
||||
try {
|
||||
var uri = (0, _lbryURI.normalizeURI)(query);
|
||||
|
||||
var _parseURI = (0, _lbryURI.parseURI)(uri),
|
||||
claimName = _parseURI.claimName,
|
||||
isChannel = _parseURI.isChannel;
|
||||
|
||||
searchSuggestions.push({
|
||||
value: claimName,
|
||||
type: SEARCH_TYPES.SEARCH
|
||||
}, {
|
||||
value: uri,
|
||||
shorthand: isChannel ? claimName.slice(1) : claimName,
|
||||
type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE
|
||||
});
|
||||
} catch (e) {
|
||||
searchSuggestions.push({
|
||||
value: query,
|
||||
type: SEARCH_TYPES.SEARCH
|
||||
});
|
||||
}
|
||||
|
||||
var apiSuggestions = suggestions[query] || [];
|
||||
if (apiSuggestions.length) {
|
||||
searchSuggestions = searchSuggestions.concat(apiSuggestions.filter(function (suggestion) {
|
||||
return suggestion !== query;
|
||||
}).map(function (suggestion) {
|
||||
// determine if it's a channel
|
||||
try {
|
||||
var _uri = (0, _lbryURI.normalizeURI)(suggestion);
|
||||
|
||||
var _parseURI2 = (0, _lbryURI.parseURI)(_uri),
|
||||
_claimName = _parseURI2.claimName,
|
||||
_isChannel = _parseURI2.isChannel;
|
||||
|
||||
return {
|
||||
value: _uri,
|
||||
shorthand: _isChannel ? _claimName.slice(1) : _claimName,
|
||||
type: _isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE
|
||||
};
|
||||
} catch (e) {
|
||||
// search result includes some character that isn't valid in claim names
|
||||
return {
|
||||
value: suggestion,
|
||||
type: SEARCH_TYPES.SEARCH
|
||||
};
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
return searchSuggestions;
|
||||
});
|
||||
|
||||
/***/ }),
|
||||
/* 19 */
|
||||
|
@ -3759,6 +3851,20 @@ var selectSearchBarFocused = exports.selectSearchBarFocused = (0, _reselect.crea
|
|||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
var FILE = exports.FILE = 'file';
|
||||
var CHANNEL = exports.CHANNEL = 'channel';
|
||||
var SEARCH = exports.SEARCH = 'search';
|
||||
|
||||
/***/ }),
|
||||
/* 20 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
|
@ -3767,7 +3873,7 @@ var isClaimNsfw = exports.isClaimNsfw = function isClaimNsfw(claim) {
|
|||
};
|
||||
|
||||
/***/ }),
|
||||
/* 20 */
|
||||
/* 21 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
@ -3790,7 +3896,7 @@ function batchActions() {
|
|||
}
|
||||
|
||||
/***/ }),
|
||||
/* 21 */
|
||||
/* 22 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
@ -3850,7 +3956,7 @@ function doFetchCostInfoForUri(uri) {
|
|||
}
|
||||
|
||||
/***/ }),
|
||||
/* 22 */
|
||||
/* 23 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
@ -3875,7 +3981,7 @@ var _claims = __webpack_require__(5);
|
|||
|
||||
var _claims2 = __webpack_require__(14);
|
||||
|
||||
var _file_info = __webpack_require__(23);
|
||||
var _file_info = __webpack_require__(24);
|
||||
|
||||
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
||||
|
||||
|
@ -3943,7 +4049,7 @@ function doFetchFileInfosAndPublishedClaims() {
|
|||
}
|
||||
|
||||
/***/ }),
|
||||
/* 23 */
|
||||
/* 24 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
@ -4150,7 +4256,7 @@ var selectSearchDownloadUris = exports.selectSearchDownloadUris = function selec
|
|||
};
|
||||
|
||||
/***/ }),
|
||||
/* 24 */
|
||||
/* 25 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
@ -4165,17 +4271,13 @@ var _action_types = __webpack_require__(4);
|
|||
|
||||
var ACTIONS = _interopRequireWildcard(_action_types);
|
||||
|
||||
var _search = __webpack_require__(25);
|
||||
|
||||
var SEARCH_TYPES = _interopRequireWildcard(_search);
|
||||
|
||||
var _lbryURI = __webpack_require__(2);
|
||||
|
||||
var _claims = __webpack_require__(5);
|
||||
|
||||
var _search2 = __webpack_require__(18);
|
||||
var _search = __webpack_require__(18);
|
||||
|
||||
var _batchActions = __webpack_require__(20);
|
||||
var _batchActions = __webpack_require__(21);
|
||||
|
||||
var _handleFetch = __webpack_require__(26);
|
||||
|
||||
|
@ -4185,13 +4287,14 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
|
|||
|
||||
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
|
||||
|
||||
var DEFAULTSEARCHRESULTSIZE = 10; // @flow
|
||||
|
||||
// @flow
|
||||
var DEFAULTSEARCHRESULTSIZE = 10;
|
||||
var DEFAULTSEARCHRESULTFROM = 0;
|
||||
|
||||
var doSearch = exports.doSearch = function doSearch(rawQuery) {
|
||||
var size = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULTSEARCHRESULTSIZE;
|
||||
var from = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULTSEARCHRESULTFROM;
|
||||
var isBackgroundSearch = arguments[3];
|
||||
return function (dispatch, getState) {
|
||||
var state = getState();
|
||||
var query = rawQuery.replace(/^lbry:\/\//i, '');
|
||||
|
@ -4204,7 +4307,7 @@ var doSearch = exports.doSearch = function doSearch(rawQuery) {
|
|||
}
|
||||
|
||||
// If we have already searched for something, we don't need to do anything
|
||||
var urisForQuery = (0, _search2.makeSelectSearchUris)(query)(state);
|
||||
var urisForQuery = (0, _search.makeSelectSearchUris)(query)(state);
|
||||
if (urisForQuery && !!urisForQuery.length) {
|
||||
return;
|
||||
}
|
||||
|
@ -4216,7 +4319,8 @@ var doSearch = exports.doSearch = function doSearch(rawQuery) {
|
|||
// If the user is on the file page with a pre-populated uri and they select
|
||||
// the search option without typing anything, searchQuery will be empty
|
||||
// We need to populate it so the input is filled on the search page
|
||||
if (!state.search.searchQuery) {
|
||||
// isBackgroundSearch means the search is happening in the background, don't update the search query
|
||||
if (!state.search.searchQuery && !isBackgroundSearch) {
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_SEARCH_QUERY,
|
||||
data: { searchQuery: query }
|
||||
|
@ -4252,103 +4356,29 @@ var doSearch = exports.doSearch = function doSearch(rawQuery) {
|
|||
};
|
||||
|
||||
var getSearchSuggestions = exports.getSearchSuggestions = function getSearchSuggestions(value /*: string*/) {
|
||||
return function (dispatch) {
|
||||
return function (dispatch, getState) {
|
||||
var query = value.trim();
|
||||
|
||||
var isPrefix = function isPrefix() {
|
||||
return query === '@' || query === 'lbry:' || query === 'lbry:/' || query === 'lbry://';
|
||||
};
|
||||
|
||||
if (!query || isPrefix()) {
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: { suggestions: [] }
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
var suggestions = [];
|
||||
try {
|
||||
// If the user is about to manually add the claim id ignore it until they
|
||||
// actually add one. This would hardly ever happen, but then the search
|
||||
// suggestions won't change just from adding a '#' after a uri
|
||||
var uriQuery = query;
|
||||
if (uriQuery.endsWith('#')) {
|
||||
uriQuery = uriQuery.slice(0, -1);
|
||||
}
|
||||
|
||||
var uri = (0, _lbryURI.normalizeURI)(uriQuery);
|
||||
|
||||
var _parseURI = (0, _lbryURI.parseURI)(uri),
|
||||
claimName = _parseURI.claimName,
|
||||
isChannel = _parseURI.isChannel;
|
||||
|
||||
suggestions.push({
|
||||
value: uri,
|
||||
shorthand: isChannel ? claimName.slice(1) : claimName,
|
||||
type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE
|
||||
}, {
|
||||
value: claimName,
|
||||
type: SEARCH_TYPES.SEARCH
|
||||
});
|
||||
} catch (e) {
|
||||
suggestions.push({
|
||||
value: query,
|
||||
type: SEARCH_TYPES.SEARCH
|
||||
});
|
||||
}
|
||||
|
||||
// Populate the current search query suggestion before fetching results
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: { suggestions: suggestions }
|
||||
});
|
||||
|
||||
// strip out any basic stuff for more accurate search results
|
||||
var searchValue = value.replace(/lbry:\/\//g, '').replace(/-/g, ' ');
|
||||
var searchValue = query.replace(/lbry:\/\//g, '').replace(/-/g, ' ');
|
||||
if (searchValue.includes('#')) {
|
||||
// This should probably be more robust, but I think it's fine for now
|
||||
// Remove everything after # to get rid of the claim id
|
||||
searchValue = searchValue.substring(0, searchValue.indexOf('#'));
|
||||
}
|
||||
|
||||
var suggestions = (0, _search.selectSuggestions)(getState());
|
||||
if (suggestions[searchValue]) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch('https://lighthouse.lbry.io/autocomplete?s=' + searchValue).then(_handleFetch2.default).then(function (apiSuggestions) {
|
||||
// Suggestion could be a channel, uri, or search term
|
||||
var formattedSuggestions = apiSuggestions.slice(0, 6).filter(function (suggestion) {
|
||||
return suggestion !== query;
|
||||
}).map(function (suggestion) {
|
||||
if (suggestion.includes(' ')) {
|
||||
return {
|
||||
value: suggestion,
|
||||
type: SEARCH_TYPES.SEARCH
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
var _uri = (0, _lbryURI.normalizeURI)(suggestion);
|
||||
|
||||
var _parseURI2 = (0, _lbryURI.parseURI)(_uri),
|
||||
_claimName = _parseURI2.claimName,
|
||||
_isChannel = _parseURI2.isChannel;
|
||||
|
||||
return {
|
||||
value: _uri,
|
||||
shorthand: _isChannel ? _claimName.slice(1) : _claimName,
|
||||
type: _isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE
|
||||
};
|
||||
} catch (e) {
|
||||
// search result includes some character that isn't valid in claim names
|
||||
return {
|
||||
value: suggestion,
|
||||
type: SEARCH_TYPES.SEARCH
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
suggestions = suggestions.concat(formattedSuggestions);
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: { suggestions: suggestions }
|
||||
data: {
|
||||
query: searchValue,
|
||||
suggestions: apiSuggestions
|
||||
}
|
||||
});
|
||||
}).catch(function () {
|
||||
// If the fetch fails, do nothing
|
||||
|
@ -4387,20 +4417,6 @@ var doBlurSearchInput = exports.doBlurSearchInput = function doBlurSearchInput()
|
|||
};
|
||||
};
|
||||
|
||||
/***/ }),
|
||||
/* 25 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
||||
"use strict";
|
||||
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
var FILE = exports.FILE = 'file';
|
||||
var CHANNEL = exports.CHANNEL = 'channel';
|
||||
var SEARCH = exports.SEARCH = 'search';
|
||||
|
||||
/***/ }),
|
||||
/* 26 */
|
||||
/***/ (function(module, exports, __webpack_require__) {
|
||||
|
@ -5903,6 +5919,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
|
|||
/*:: type UpdateSearchSuggestions = {
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: {
|
||||
query: string,
|
||||
suggestions: Array<SearchSuggestion>,
|
||||
},
|
||||
};*/
|
||||
|
@ -5926,7 +5943,7 @@ var 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
|
||||
suggestions: [],
|
||||
suggestions: {},
|
||||
urisByQuery: {}
|
||||
};
|
||||
|
||||
|
@ -5955,15 +5972,15 @@ var searchReducer = exports.searchReducer = (0, _reduxUtils.handleActions)((_han
|
|||
});
|
||||
}), _defineProperty(_handleActions, ACTIONS.UPDATE_SEARCH_SUGGESTIONS, function (state /*: SearchState*/, action /*: UpdateSearchSuggestions*/) /*: SearchState*/ {
|
||||
return _extends({}, state, {
|
||||
suggestions: action.data.suggestions
|
||||
suggestions: _extends({}, state.suggestions, _defineProperty({}, action.data.query, action.data.suggestions))
|
||||
});
|
||||
}), _defineProperty(_handleActions, ACTIONS.HISTORY_NAVIGATE, function (state /*: SearchState*/, action /*: HistoryNavigate*/) /*: SearchState*/ {
|
||||
var url = action.data.url;
|
||||
|
||||
return _extends({}, state, {
|
||||
searchQuery: url.indexOf('/search') === 0 ? url.slice(14) : '',
|
||||
suggestions: [],
|
||||
isActive: url.indexOf('/search') === 0
|
||||
isActive: url.indexOf('/search') === 0,
|
||||
suggestions: {}
|
||||
});
|
||||
}), _defineProperty(_handleActions, ACTIONS.DISMISS_NOTIFICATION, function (state /*: SearchState*/) /*: SearchState*/ {
|
||||
return _extends({}, state, {
|
||||
|
|
|
@ -189,6 +189,7 @@ export {
|
|||
selectSearchUrisByQuery,
|
||||
selectWunderBarAddress,
|
||||
selectSearchBarFocused,
|
||||
selectSearchSuggestions,
|
||||
} from 'redux/selectors/search';
|
||||
|
||||
export {
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
// @flow
|
||||
import * as ACTIONS from 'constants/action_types';
|
||||
import * as SEARCH_TYPES from 'constants/search';
|
||||
import { normalizeURI, buildURI, parseURI } from 'lbryURI';
|
||||
import { buildURI } from 'lbryURI';
|
||||
import { doResolveUri } from 'redux/actions/claims';
|
||||
import { makeSelectSearchUris } from 'redux/selectors/search';
|
||||
import { makeSelectSearchUris, selectSuggestions } from 'redux/selectors/search';
|
||||
import { batchActions } from 'util/batchActions';
|
||||
import handleFetchResponse from 'util/handle-fetch';
|
||||
|
||||
|
@ -77,102 +76,31 @@ export const doSearch = (
|
|||
});
|
||||
};
|
||||
|
||||
export const getSearchSuggestions = (value: string) => dispatch => {
|
||||
export const getSearchSuggestions = (value: string) => (dispatch, getState) => {
|
||||
const query = value.trim();
|
||||
|
||||
const isPrefix = () =>
|
||||
query === '@' || query === 'lbry:' || query === 'lbry:/' || query === 'lbry://';
|
||||
|
||||
if (!query || isPrefix()) {
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: { suggestions: [] },
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
let suggestions = [];
|
||||
try {
|
||||
// If the user is about to manually add the claim id ignore it until they
|
||||
// actually add one. This would hardly ever happen, but then the search
|
||||
// suggestions won't change just from adding a '#' after a uri
|
||||
let uriQuery = query;
|
||||
if (uriQuery.endsWith('#')) {
|
||||
uriQuery = uriQuery.slice(0, -1);
|
||||
}
|
||||
|
||||
const uri = normalizeURI(uriQuery);
|
||||
const { claimName, isChannel } = parseURI(uri);
|
||||
|
||||
suggestions.push(
|
||||
{
|
||||
value: uri,
|
||||
shorthand: isChannel ? claimName.slice(1) : claimName,
|
||||
type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE,
|
||||
},
|
||||
{
|
||||
value: claimName,
|
||||
type: SEARCH_TYPES.SEARCH,
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
suggestions.push({
|
||||
value: query,
|
||||
type: SEARCH_TYPES.SEARCH,
|
||||
});
|
||||
}
|
||||
|
||||
// Populate the current search query suggestion before fetching results
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: { suggestions },
|
||||
});
|
||||
|
||||
// strip out any basic stuff for more accurate search results
|
||||
let searchValue = value.replace(/lbry:\/\//g, '').replace(/-/g, ' ');
|
||||
let searchValue = query.replace(/lbry:\/\//g, '').replace(/-/g, ' ');
|
||||
if (searchValue.includes('#')) {
|
||||
// This should probably be more robust, but I think it's fine for now
|
||||
// Remove everything after # to get rid of the claim id
|
||||
searchValue = searchValue.substring(0, searchValue.indexOf('#'));
|
||||
}
|
||||
|
||||
const suggestions = selectSuggestions(getState());
|
||||
if (suggestions[searchValue]) {
|
||||
return;
|
||||
}
|
||||
|
||||
fetch(`https://lighthouse.lbry.io/autocomplete?s=${searchValue}`)
|
||||
.then(handleFetchResponse)
|
||||
.then(apiSuggestions => {
|
||||
// Suggestion could be a channel, uri, or search term
|
||||
const formattedSuggestions = apiSuggestions
|
||||
.slice(0, 6)
|
||||
.filter(suggestion => suggestion !== query)
|
||||
.map(suggestion => {
|
||||
if (suggestion.includes(' ')) {
|
||||
return {
|
||||
value: suggestion,
|
||||
type: SEARCH_TYPES.SEARCH,
|
||||
};
|
||||
}
|
||||
|
||||
try {
|
||||
const uri = normalizeURI(suggestion);
|
||||
const { claimName, isChannel } = parseURI(uri);
|
||||
|
||||
return {
|
||||
value: uri,
|
||||
shorthand: isChannel ? claimName.slice(1) : claimName,
|
||||
type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE,
|
||||
};
|
||||
} catch (e) {
|
||||
// search result includes some character that isn't valid in claim names
|
||||
return {
|
||||
value: suggestion,
|
||||
type: SEARCH_TYPES.SEARCH,
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
suggestions = suggestions.concat(formattedSuggestions);
|
||||
dispatch({
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: { suggestions },
|
||||
data: {
|
||||
query: searchValue,
|
||||
suggestions: apiSuggestions,
|
||||
},
|
||||
});
|
||||
})
|
||||
.catch(() => {
|
||||
|
|
|
@ -26,6 +26,7 @@ type SearchSuggestion = {
|
|||
type UpdateSearchSuggestions = {
|
||||
type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS,
|
||||
data: {
|
||||
query: string,
|
||||
suggestions: Array<SearchSuggestion>,
|
||||
},
|
||||
};
|
||||
|
@ -50,7 +51,7 @@ 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
|
||||
suggestions: [],
|
||||
suggestions: {},
|
||||
urisByQuery: {},
|
||||
};
|
||||
|
||||
|
@ -89,7 +90,10 @@ export const searchReducer = handleActions(
|
|||
action: UpdateSearchSuggestions
|
||||
): SearchState => ({
|
||||
...state,
|
||||
suggestions: action.data.suggestions,
|
||||
suggestions: {
|
||||
...state.suggestions,
|
||||
[action.data.query]: action.data.suggestions,
|
||||
},
|
||||
}),
|
||||
|
||||
// clear the searchQuery on back/forward unless to search page
|
||||
|
@ -98,8 +102,8 @@ export const searchReducer = handleActions(
|
|||
return {
|
||||
...state,
|
||||
searchQuery: url.indexOf('/search') === 0 ? url.slice(14) : '',
|
||||
suggestions: [],
|
||||
isActive: url.indexOf('/search') === 0,
|
||||
suggestions: {},
|
||||
};
|
||||
},
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import * as SEARCH_TYPES from 'constants/search';
|
||||
import { normalizeURI, parseURI } from 'lbryURI';
|
||||
import { selectCurrentPage, selectCurrentParams } from 'redux/selectors/navigation';
|
||||
import { createSelector } from 'reselect';
|
||||
|
||||
|
@ -5,6 +7,8 @@ export const selectState = state => state.search || {};
|
|||
|
||||
export const selectSearchValue = createSelector(selectState, state => state.searchQuery);
|
||||
|
||||
export const selectSuggestions = createSelector(selectState, state => state.suggestions);
|
||||
|
||||
export const selectSearchQuery = createSelector(
|
||||
selectCurrentPage,
|
||||
selectCurrentParams,
|
||||
|
@ -37,3 +41,79 @@ export const selectWunderBarAddress = createSelector(
|
|||
);
|
||||
|
||||
export const selectSearchBarFocused = createSelector(selectState, state => state.focused);
|
||||
// export const selectSear
|
||||
|
||||
export const selectSearchSuggestions = createSelector(
|
||||
selectSearchValue,
|
||||
selectSuggestions,
|
||||
(query, suggestions) => {
|
||||
if (!query) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://';
|
||||
|
||||
if (query.startsWith('lbry://') && query !== 'lbry://') {
|
||||
// If it starts with a prefix, don't show any autocomplete results
|
||||
// They are probably typing/pasting in a lbry uri
|
||||
return [
|
||||
{
|
||||
value: query,
|
||||
type: SEARCH_TYPES.FILE,
|
||||
},
|
||||
];
|
||||
} else if (queryIsPrefix) {
|
||||
// If it is a prefix, wait until something else comes to figure out what to do
|
||||
return [];
|
||||
}
|
||||
|
||||
let searchSuggestions = [];
|
||||
try {
|
||||
const uri = normalizeURI(query);
|
||||
const { claimName, isChannel } = parseURI(uri);
|
||||
searchSuggestions.push(
|
||||
{
|
||||
value: claimName,
|
||||
type: SEARCH_TYPES.SEARCH,
|
||||
},
|
||||
{
|
||||
value: uri,
|
||||
shorthand: isChannel ? claimName.slice(1) : claimName,
|
||||
type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE,
|
||||
}
|
||||
);
|
||||
} catch (e) {
|
||||
searchSuggestions.push({
|
||||
value: query,
|
||||
type: SEARCH_TYPES.SEARCH,
|
||||
});
|
||||
}
|
||||
|
||||
const apiSuggestions = suggestions[query] || [];
|
||||
if (apiSuggestions.length) {
|
||||
searchSuggestions = searchSuggestions.concat(
|
||||
apiSuggestions.filter(suggestion => suggestion !== query).map(suggestion => {
|
||||
// determine if it's a channel
|
||||
try {
|
||||
const uri = normalizeURI(suggestion);
|
||||
const { claimName, isChannel } = parseURI(uri);
|
||||
|
||||
return {
|
||||
value: uri,
|
||||
shorthand: isChannel ? claimName.slice(1) : claimName,
|
||||
type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE,
|
||||
};
|
||||
} catch (e) {
|
||||
// search result includes some character that isn't valid in claim names
|
||||
return {
|
||||
value: suggestion,
|
||||
type: SEARCH_TYPES.SEARCH,
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
return searchSuggestions;
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue