From b87e2f92f30b11942a40ddc09b5c0424360c8393 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Wed, 17 Jul 2019 16:50:58 -0400 Subject: [PATCH 1/8] cache claim search results by query --- dist/bundle.es.js | 124 +++++++++++------- src/index.js | 9 +- src/redux/actions/claims.js | 7 +- src/redux/actions/publish.js | 28 ++-- src/redux/actions/search.js | 2 +- src/redux/actions/wallet.js | 4 +- src/redux/reducers/claims.js | 30 +++-- src/redux/selectors/claims.js | 14 +- src/redux/selectors/navigation.js | 68 +++++++--- src/redux/selectors/search.js | 2 +- .../{batchActions.js => batch-actions.js} | 0 src/util/claim-search.js | 8 ++ .../{formatCredits.js => format-credits.js} | 0 src/util/{query_params.js => query-params.js} | 0 14 files changed, 189 insertions(+), 107 deletions(-) rename src/util/{batchActions.js => batch-actions.js} (100%) create mode 100644 src/util/claim-search.js rename src/util/{formatCredits.js => format-credits.js} (100%) rename src/util/{query_params.js => query-params.js} (100%) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f7b480f..ec91553 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -7,6 +7,8 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau require('proxy-polyfill'); var reselect = require('reselect'); var uuid = _interopDefault(require('uuid/v4')); +var formatCredits$1 = require('util/formatCredits'); +require('util/batchActions'); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); @@ -1308,12 +1310,14 @@ const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, // Check if a claim is pending first // It won't be in claimsByUri because resolving it will return nothing + let valid; let claimId; try { ({ claimId } = parseURI(uri)); + valid = true; } catch (e) {} - if (claimId) { + if (valid) { const pendingClaim = pendingById[claimId]; if (pendingClaim) { @@ -1551,7 +1555,7 @@ const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataFo const selectFetchingClaimSearch = reselect.createSelector(selectState$1, state => state.fetchingClaimSearch); -const selectLastClaimSearchUris = reselect.createSelector(selectState$1, state => state.lastClaimSearchUris); +const selectClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.claimSearchSearchByQuery || {}); const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); @@ -1702,34 +1706,6 @@ const selectCurrentHeight = reselect.createSelector(selectState$2, state => stat const selectTransactionListFilter = reselect.createSelector(selectState$2, state => state.transactionListFilter || ''); -function formatCredits(amount, precision) { - if (Number.isNaN(parseFloat(amount))) return '0'; - return parseFloat(amount).toFixed(precision || 1).replace(/\.?0+$/, ''); -} - -function formatFullPrice(amount, precision = 1) { - let formated = ''; - - const quantity = amount.toString().split('.'); - const fraction = quantity[1]; - - if (fraction) { - const decimals = fraction.split(''); - const first = decimals.filter(number => number !== '0')[0]; - const index = decimals.indexOf(first); - - // Set format fraction - formated = `.${fraction.substring(0, index + precision)}`; - } - - return parseFloat(quantity[0] + formated); -} - -function creditsToString(amount) { - const creditString = parseFloat(amount).toFixed(8); - return creditString; -} - function doUpdateBalance() { return (dispatch, getState) => { const { @@ -1902,7 +1878,7 @@ function doSendDraftTransaction(address, amount) { lbryProxy.account_send({ addresses: [address], - amount: creditsToString(amount) + amount: formatCredits$1.creditsToString(amount) }).then(successCallback, errorCallback); }; } @@ -1977,7 +1953,7 @@ function doSendTip(amount, claimId, successCallback, errorCallback) { lbryProxy.support_create({ claim_id: claimId, - amount: creditsToString(amount), + amount: formatCredits$1.creditsToString(amount), tip: isSupport ? false : true }).then(success, error); }; @@ -2084,6 +2060,17 @@ function doUpdateBlockHeight() { }); } +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } + +// +function buildClaimSearchCacheQuery(options) { + // Ignore page because we don't care what the last page searched was, we want everything + // Ignore release_time because that will change depending on when you call claim_search ex: release_time: ">12344567" + const rest = _objectWithoutProperties(options, ["page", "release_time"]); + const query = JSON.stringify(rest); + return query; +} + var _extends$3 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function doResolveUris(uris, returnCachedClaims = false) { @@ -2291,7 +2278,7 @@ function doCreateChannel(name, amount) { return lbryProxy.channel_create({ name, - bid: creditsToString(amount) + bid: formatCredits$1.creditsToString(amount) }) // outputs[0] is the certificate // outputs[1] is the change from the tx, not in the app currently @@ -2317,7 +2304,7 @@ function doUpdateChannel(params) { }); const updateParams = { claim_id: params.claim_id, - bid: creditsToString(params.amount), + bid: formatCredits$1.creditsToString(params.amount), title: params.title, cover_url: params.cover, thumbnail_url: params.thumbnail, @@ -2367,6 +2354,8 @@ function doFetchChannelListMine() { } function doClaimSearch(options = {}) { + const query = buildClaimSearchCacheQuery(options); + return dispatch => { dispatch({ type: CLAIM_SEARCH_STARTED @@ -2382,7 +2371,7 @@ function doClaimSearch(options = {}) { dispatch({ type: CLAIM_SEARCH_COMPLETED, - data: { resolveInfo, uris, append: options.page && options.page !== 1 } + data: { resolveInfo, uris, query, append: options.page && options.page !== 1 } }); }; @@ -2788,12 +2777,40 @@ function batchActions(...actions) { }; } -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } +function formatCredits(amount, precision) { + if (Number.isNaN(parseFloat(amount))) return '0'; + return parseFloat(amount).toFixed(precision || 1).replace(/\.?0+$/, ''); +} + +function formatFullPrice(amount, precision = 1) { + let formated = ''; + + const quantity = amount.toString().split('.'); + const fraction = quantity[1]; + + if (fraction) { + const decimals = fraction.split(''); + const first = decimals.filter(number => number !== '0')[0]; + const index = decimals.indexOf(first); + + // Set format fraction + formated = `.${fraction.substring(0, index + precision)}`; + } + + return parseFloat(quantity[0] + formated); +} + +function creditsToString(amount) { + const creditString = parseFloat(amount).toFixed(8); + return creditString; +} + +function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } const selectState$5 = state => state.publish || {}; const selectPublishFormValues = reselect.createSelector(selectState$5, state => { - const formValues = _objectWithoutProperties(state, ['pendingPublish']); + const formValues = _objectWithoutProperties$1(state, ['pendingPublish']); return formValues; }); const makeSelectPublishFormValue = item => reselect.createSelector(selectState$5, state => state[item]); @@ -3475,6 +3492,7 @@ const defaultState = { fetchingMyChannels: false, abandoningById: {}, pendingById: {}, + claimSearchError: undefined, fetchingClaimSearch: false, claimSearchUrisByTags: {}, fetchingClaimSearchByTags: {}, @@ -3709,27 +3727,34 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { reducers[CLAIM_SEARCH_STARTED] = state => { return Object.assign({}, state, { - fetchingClaimSearch: true + fetchingClaimSearch: true, + claimSearchError: false }); }; -reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { - const { lastClaimSearchUris } = state; - let newClaimSearchUris = []; - if (action.data.append) { - newClaimSearchUris = lastClaimSearchUris.concat(action.data.uris); +reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { + const { claimSearchSearchByQuery } = state; + const { uris, query, append } = action.data; + + let newClaimSearch = _extends$5({}, claimSearchSearchByQuery); + if (!uris) { + newClaimSearch[query] = null; + } else if (append && newClaimSearch[query]) { + newClaimSearch[query] = newClaimSearch[query].concat(uris); } else { - newClaimSearchUris = action.data.uris; + newClaimSearch[query] = uris; } return _extends$5({}, handleClaimAction(state, action), { fetchingClaimSearch: false, - lastClaimSearchUris: newClaimSearchUris + claimSearchSearchByQuery: newClaimSearch }); }; + reducers[CLAIM_SEARCH_FAILED] = state => { return Object.assign({}, state, { - fetchingClaimSearch: false + fetchingClaimSearch: false, + claimSearchError: true }); }; @@ -4209,7 +4234,7 @@ const notificationsReducer = handleActions({ var _extends$b = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; -function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } +function _objectWithoutProperties$2(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } const defaultState$6 = { editingURI: undefined, @@ -4259,7 +4284,7 @@ const publishReducer = handleActions({ publishSuccess: true }), [DO_PREPARE_EDIT]: (state, action) => { - const publishData = _objectWithoutProperties$1(action.data, []); + const publishData = _objectWithoutProperties$2(action.data, []); const { channel, name, uri } = publishData; // The short uri is what is presented to the user @@ -4761,6 +4786,7 @@ exports.SORT_OPTIONS = sort_options; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; exports.batchActions = batchActions; +exports.buildClaimSearchCacheQuery = buildClaimSearchCacheQuery; exports.buildURI = buildURI; exports.claimsReducer = claimsReducer; exports.commentReducer = commentReducer; @@ -4883,6 +4909,7 @@ exports.selectAllMyClaimsByOutpoint = selectAllMyClaimsByOutpoint; exports.selectBalance = selectBalance; exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; +exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchUrisByTags = selectClaimSearchUrisByTags; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; @@ -4914,7 +4941,6 @@ exports.selectIsResolvingPublishUris = selectIsResolvingPublishUris; exports.selectIsSearching = selectIsSearching; exports.selectIsSendingSupport = selectIsSendingSupport; exports.selectIsStillEditing = selectIsStillEditing; -exports.selectLastClaimSearchUris = selectLastClaimSearchUris; exports.selectLastPurchasedUri = selectLastPurchasedUri; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; diff --git a/src/index.js b/src/index.js index 07a30dd..a8117ec 100644 --- a/src/index.js +++ b/src/index.js @@ -113,10 +113,11 @@ export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; export { doCommentList, doCommentCreate } from 'redux/actions/comments'; // utils -export { batchActions } from 'util/batchActions'; -export { parseQueryParams, toQueryString } from 'util/query_params'; -export { formatCredits, formatFullPrice, creditsToString } from 'util/formatCredits'; +export { batchActions } from 'util/batch-actions'; +export { parseQueryParams, toQueryString } from 'util/query-params'; +export { formatCredits, formatFullPrice, creditsToString } from 'util/format-credits'; export { isClaimNsfw } from 'util/claim'; +export { buildClaimSearchCacheQuery } from 'util/claim-search'; // reducers export { claimsReducer } from 'redux/reducers/claims'; @@ -193,11 +194,11 @@ export { selectChannelClaimCounts, selectCurrentChannelPage, selectFetchingClaimSearch, - selectLastClaimSearchUris, selectFetchingClaimSearchByTags, selectClaimSearchUrisByTags, makeSelectFetchingClaimSearchForTags, makeSelectClaimSearchUrisForTags, + selectClaimSearchByQuery, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 34e1be3..49680e7 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -9,6 +9,7 @@ import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { creditsToString } from 'util/formatCredits'; import { batchActions } from 'util/batchActions'; import { createNormalizedTagKey } from 'util/claim'; +import { buildClaimSearchCacheQuery } from 'util/claim-search'; export function doResolveUris(uris: Array<string>, returnCachedClaims: boolean = false) { return (dispatch: Dispatch, getState: GetState) => { @@ -314,7 +315,9 @@ export function doFetchChannelListMine() { }; } -export function doClaimSearch(options: { page_size?: number, page?: number } = {}) { +export function doClaimSearch(options: { page?: number, release_time?: string } = {}) { + const query = buildClaimSearchCacheQuery(options); + return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CLAIM_SEARCH_STARTED, @@ -330,7 +333,7 @@ export function doClaimSearch(options: { page_size?: number, page?: number } = { dispatch({ type: ACTIONS.CLAIM_SEARCH_COMPLETED, - data: { resolveInfo, uris, append: options.page && options.page !== 1 }, + data: { resolveInfo, uris, query, append: options.page && options.page !== 1 }, }); }; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 95b2229..38cb9bd 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -3,8 +3,8 @@ import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/li import * as ACTIONS from 'constants/action_types'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import Lbry from 'lbry'; -import { batchActions } from 'util/batchActions'; -import { creditsToString } from 'util/formatCredits'; +import { batchActions } from 'util/batch-actions'; +import { creditsToString } from 'util/format-credits'; import { doError } from 'redux/actions/notifications'; import { isClaimNsfw } from 'util/claim'; import { @@ -118,12 +118,12 @@ export const doUploadThumbnail = ( .then(json => json.success ? dispatch({ - type: ACTIONS.UPDATE_PUBLISH_FORM, - data: { - uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, - thumbnail: `${json.data.url}${fileExt}`, - }, - }) + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, + thumbnail: `${json.data.url}${fileExt}`, + }, + }) : uploadError(json.message) ) .catch(err => uploadError(err.message)); @@ -157,12 +157,12 @@ export const doUploadThumbnail = ( .then(json => json.success ? dispatch({ - type: ACTIONS.UPDATE_PUBLISH_FORM, - data: { - uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, - thumbnail: `${json.data.url}${fileExt}`, - }, - }) + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, + thumbnail: `${json.data.url}${fileExt}`, + }, + }) : uploadError(json.message) ) .catch(err => uploadError(err.message)); diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 6ce900e..8108e9c 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -8,7 +8,7 @@ import { makeSelectQueryWithOptions, selectSearchValue, } from 'redux/selectors/search'; -import { batchActions } from 'util/batchActions'; +import { batchActions } from 'util/batch-actions'; import debounce from 'util/debounce'; import handleFetchResponse from 'util/handle-fetch'; diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 6e5dce6..73d9e98 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -230,7 +230,9 @@ export function doSendTip(amount, claimId, successCallback, errorCallback) { const success = () => { dispatch( doToast({ - message: isSupport ? __(`You deposited ${amount} LBC as a support!`) : __(`You sent ${amount} LBC as a tip, Mahalo!`), + message: isSupport + ? __(`You deposited ${amount} LBC as a support!`) + : __(`You sent ${amount} LBC as a tip, Mahalo!`), linkText: __('History'), linkTarget: __('/wallet'), }) diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 1681f76..e317af7 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -46,6 +46,7 @@ const defaultState = { fetchingMyChannels: false, abandoningById: {}, pendingById: {}, + claimSearchError: undefined, fetchingClaimSearch: false, claimSearchUrisByTags: {}, fetchingClaimSearchByTags: {}, @@ -292,27 +293,34 @@ reducers[ACTIONS.RESOLVE_URIS_STARTED] = (state: State, action: any): State => { reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State): State => { return Object.assign({}, state, { fetchingClaimSearch: true, + claimSearchError: false, }); }; -reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => { - const { lastClaimSearchUris } = state; - let newClaimSearchUris = []; - if (action.data.append) { - newClaimSearchUris = lastClaimSearchUris.concat(action.data.uris); +reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => { + const { claimSearchSearchByQuery } = state; + const { uris, query, append } = action.data; + + let newClaimSearch = { ...claimSearchSearchByQuery }; + if (!uris) { + newClaimSearch[query] = null; + } else if (append && newClaimSearch[query]) { + newClaimSearch[query] = newClaimSearch[query].concat(uris); } else { - newClaimSearchUris = action.data.uris; + newClaimSearch[query] = uris; } return { ...handleClaimAction(state, action), fetchingClaimSearch: false, - lastClaimSearchUris: newClaimSearchUris, + claimSearchSearchByQuery: newClaimSearch, }; }; + reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State): State => { return Object.assign({}, state, { fetchingClaimSearch: false, + claimSearchError: true, }); }; @@ -321,7 +329,7 @@ reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_STARTED] = (state: State, action: any): St fetchingClaimSearchByTags[action.data.tags] = true; return Object.assign({}, state, { - fetchingClaimSearchByTags + fetchingClaimSearchByTags, }); }; reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_COMPLETED] = (state: State, action: any): State => { @@ -331,8 +339,10 @@ reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_COMPLETED] = (state: State, action: any): if (action.data.append) { // todo: check for duplicate uris when concatenating? - claimSearchUrisByTags[tags] = claimSearchUrisByTags[tags] && claimSearchUrisByTags[tags].length ? - claimSearchUrisByTags[tags].concat(uris) : uris; + claimSearchUrisByTags[tags] = + claimSearchUrisByTags[tags] && claimSearchUrisByTags[tags].length + ? claimSearchUrisByTags[tags].concat(uris) + : uris; } else { claimSearchUrisByTags[tags] = uris; } diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 2019e18..fee7b2a 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -3,7 +3,7 @@ import { normalizeURI, buildURI, parseURI } from 'lbryURI'; import { selectSearchUrisByQuery } from 'redux/selectors/search'; import { createSelector } from 'reselect'; import { isClaimNsfw, createNormalizedTagKey } from 'util/claim'; -import { getSearchQueryString } from 'util/query_params'; +import { getSearchQueryString } from 'util/query-params'; const selectState = state => state.claims || {}; @@ -88,12 +88,14 @@ export const makeSelectClaimForUri = (uri: string) => // Check if a claim is pending first // It won't be in claimsByUri because resolving it will return nothing + let valid; let claimId; try { ({ claimId } = parseURI(uri)); + valid = true; } catch (e) {} - if (claimId) { + if (valid) { const pendingClaim = pendingById[claimId]; if (pendingClaim) { @@ -253,7 +255,9 @@ export const makeSelectThumbnailForUri = (uri: string) => makeSelectClaimForUri(uri), claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; - return thumbnail && thumbnail.url && thumbnail.url.trim().length > 0 ? thumbnail.url : undefined; + return thumbnail && thumbnail.url && thumbnail.url.trim().length > 0 + ? thumbnail.url + : undefined; } ); @@ -499,9 +503,9 @@ export const selectFetchingClaimSearch = createSelector( state => state.fetchingClaimSearch ); -export const selectLastClaimSearchUris = createSelector( +export const selectClaimSearchByQuery = createSelector( selectState, - state => state.lastClaimSearchUris + state => state.claimSearchSearchByQuery || {} ); export const makeSelectShortUrlForUri = (uri: string) => diff --git a/src/redux/selectors/navigation.js b/src/redux/selectors/navigation.js index 8aafd3c..3b81d79 100644 --- a/src/redux/selectors/navigation.js +++ b/src/redux/selectors/navigation.js @@ -1,40 +1,65 @@ import { createSelector } from 'reselect'; -import { parseQueryParams } from 'util/query_params'; +import { parseQueryParams } from 'util/query-params'; export const selectState = state => state.navigation || {}; -export const selectCurrentPath = createSelector(selectState, state => state.currentPath); +export const selectCurrentPath = createSelector( + selectState, + state => state.currentPath +); export const computePageFromPath = path => (path ? path.replace(/^\//, '').split('?')[0] : ''); -export const selectCurrentPage = createSelector(selectCurrentPath, path => - computePageFromPath(path) +export const selectCurrentPage = createSelector( + selectCurrentPath, + path => computePageFromPath(path) ); -export const selectCurrentParams = createSelector(selectCurrentPath, path => { - if (path === undefined) return {}; - if (!path.match(/\?/)) return {}; +export const selectCurrentParams = createSelector( + selectCurrentPath, + path => { + if (path === undefined) return {}; + if (!path.match(/\?/)) return {}; - return parseQueryParams(path.split('?')[1]); -}); + return parseQueryParams(path.split('?')[1]); + } +); export const makeSelectCurrentParam = param => - createSelector(selectCurrentParams, params => (params ? params[param] : undefined)); + createSelector( + selectCurrentParams, + params => (params ? params[param] : undefined) + ); -export const selectPathAfterAuth = createSelector(selectState, state => state.pathAfterAuth); +export const selectPathAfterAuth = createSelector( + selectState, + state => state.pathAfterAuth +); -export const selectIsBackDisabled = createSelector(selectState, state => state.index === 0); +export const selectIsBackDisabled = createSelector( + selectState, + state => state.index === 0 +); export const selectIsForwardDisabled = createSelector( selectState, state => state.index === state.stack.length - 1 ); -export const selectIsHome = createSelector(selectCurrentPage, page => page === 'discover'); +export const selectIsHome = createSelector( + selectCurrentPage, + page => page === 'discover' +); -export const selectHistoryIndex = createSelector(selectState, state => state.index); +export const selectHistoryIndex = createSelector( + selectState, + state => state.index +); -export const selectHistoryStack = createSelector(selectState, state => state.stack); +export const selectHistoryStack = createSelector( + selectState, + state => state.stack +); // returns current page attributes (scrollY, path) export const selectActiveHistoryEntry = createSelector( @@ -42,9 +67,12 @@ export const selectActiveHistoryEntry = createSelector( state => state.stack[state.index] ); -export const selectPageTitle = createSelector(selectCurrentPage, page => { - switch (page) { - default: - return ''; +export const selectPageTitle = createSelector( + selectCurrentPage, + page => { + switch (page) { + default: + return ''; + } } -}); +); diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index 152a99e..660228f 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -1,6 +1,6 @@ // @flow import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; -import { getSearchQueryString } from 'util/query_params'; +import { getSearchQueryString } from 'util/query-params'; import { normalizeURI, parseURI } from 'lbryURI'; import { createSelector } from 'reselect'; diff --git a/src/util/batchActions.js b/src/util/batch-actions.js similarity index 100% rename from src/util/batchActions.js rename to src/util/batch-actions.js diff --git a/src/util/claim-search.js b/src/util/claim-search.js new file mode 100644 index 0000000..44913cf --- /dev/null +++ b/src/util/claim-search.js @@ -0,0 +1,8 @@ +// @flow +export function buildClaimSearchCacheQuery(options: { page?: number, release_time?: string }) { + // Ignore page because we don't care what the last page searched was, we want everything + // Ignore release_time because that will change depending on when you call claim_search ex: release_time: ">12344567" + const { page: optionToIgnoreForQuery, release_time: anotherToIgnore, ...rest } = options; + const query = JSON.stringify(rest); + return query; +} diff --git a/src/util/formatCredits.js b/src/util/format-credits.js similarity index 100% rename from src/util/formatCredits.js rename to src/util/format-credits.js diff --git a/src/util/query_params.js b/src/util/query-params.js similarity index 100% rename from src/util/query_params.js rename to src/util/query-params.js From 3e7b5d05c056dd831c04d848c0b71c983c36b8c3 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Wed, 17 Jul 2019 17:34:00 -0400 Subject: [PATCH 2/8] fix: invalid uri characters --- dist/bundle.es.js | 4 ++-- src/lbryURI.js | 2 +- src/redux/reducers/claims.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ec91553..1e9168b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -904,7 +904,7 @@ const channelNameMinLength = 1; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls -const regexInvalidURI = /[ =&#:$@%?\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/gu; +const regexInvalidURI = /[ =&#:$@%?;/\\"<>%{}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/gu; const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; /** @@ -3492,7 +3492,7 @@ const defaultState = { fetchingMyChannels: false, abandoningById: {}, pendingById: {}, - claimSearchError: undefined, + claimSearchError: false, fetchingClaimSearch: false, claimSearchUrisByTags: {}, fetchingClaimSearchByTags: {}, diff --git a/src/lbryURI.js b/src/lbryURI.js index 42045d0..32c6ce6 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -2,7 +2,7 @@ const channelNameMinLength = 1; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls -export const regexInvalidURI = /[ =&#:$@%?\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/gu; +export const regexInvalidURI = /[ =&#:$@%?;/\\"<>%{}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/gu; export const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; /** diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index e317af7..1ef4c40 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -46,7 +46,7 @@ const defaultState = { fetchingMyChannels: false, abandoningById: {}, pendingById: {}, - claimSearchError: undefined, + claimSearchError: false, fetchingClaimSearch: false, claimSearchUrisByTags: {}, fetchingClaimSearchByTags: {}, From 8910693fe1fc4166fdc748d128344012c3d61874 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Mon, 29 Jul 2019 14:48:44 -0400 Subject: [PATCH 3/8] fix typo --- dist/bundle.es.js | 82 ++++++++++++++++++------------------- src/redux/actions/claims.js | 4 +- src/redux/actions/wallet.js | 2 +- 3 files changed, 43 insertions(+), 45 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1e9168b..9c37e36 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -7,8 +7,6 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau require('proxy-polyfill'); var reselect = require('reselect'); var uuid = _interopDefault(require('uuid/v4')); -var formatCredits$1 = require('util/formatCredits'); -require('util/batchActions'); var fs = _interopDefault(require('fs')); var path = _interopDefault(require('path')); @@ -1706,6 +1704,34 @@ const selectCurrentHeight = reselect.createSelector(selectState$2, state => stat const selectTransactionListFilter = reselect.createSelector(selectState$2, state => state.transactionListFilter || ''); +function formatCredits(amount, precision) { + if (Number.isNaN(parseFloat(amount))) return '0'; + return parseFloat(amount).toFixed(precision || 1).replace(/\.?0+$/, ''); +} + +function formatFullPrice(amount, precision = 1) { + let formated = ''; + + const quantity = amount.toString().split('.'); + const fraction = quantity[1]; + + if (fraction) { + const decimals = fraction.split(''); + const first = decimals.filter(number => number !== '0')[0]; + const index = decimals.indexOf(first); + + // Set format fraction + formated = `.${fraction.substring(0, index + precision)}`; + } + + return parseFloat(quantity[0] + formated); +} + +function creditsToString(amount) { + const creditString = parseFloat(amount).toFixed(8); + return creditString; +} + function doUpdateBalance() { return (dispatch, getState) => { const { @@ -1878,7 +1904,7 @@ function doSendDraftTransaction(address, amount) { lbryProxy.account_send({ addresses: [address], - amount: formatCredits$1.creditsToString(amount) + amount: creditsToString(amount) }).then(successCallback, errorCallback); }; } @@ -1953,7 +1979,7 @@ function doSendTip(amount, claimId, successCallback, errorCallback) { lbryProxy.support_create({ claim_id: claimId, - amount: formatCredits$1.creditsToString(amount), + amount: creditsToString(amount), tip: isSupport ? false : true }).then(success, error); }; @@ -2060,6 +2086,14 @@ function doUpdateBlockHeight() { }); } +// https://github.com/reactjs/redux/issues/911 +function batchActions(...actions) { + return { + type: 'BATCH_ACTIONS', + actions + }; +} + function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } // @@ -2278,7 +2312,7 @@ function doCreateChannel(name, amount) { return lbryProxy.channel_create({ name, - bid: formatCredits$1.creditsToString(amount) + bid: creditsToString(amount) }) // outputs[0] is the certificate // outputs[1] is the change from the tx, not in the app currently @@ -2304,7 +2338,7 @@ function doUpdateChannel(params) { }); const updateParams = { claim_id: params.claim_id, - bid: formatCredits$1.creditsToString(params.amount), + bid: creditsToString(params.amount), title: params.title, cover_url: params.cover, thumbnail_url: params.thumbnail, @@ -2769,42 +2803,6 @@ function doSetFileListSort(page, value) { }; } -// https://github.com/reactjs/redux/issues/911 -function batchActions(...actions) { - return { - type: 'BATCH_ACTIONS', - actions - }; -} - -function formatCredits(amount, precision) { - if (Number.isNaN(parseFloat(amount))) return '0'; - return parseFloat(amount).toFixed(precision || 1).replace(/\.?0+$/, ''); -} - -function formatFullPrice(amount, precision = 1) { - let formated = ''; - - const quantity = amount.toString().split('.'); - const fraction = quantity[1]; - - if (fraction) { - const decimals = fraction.split(''); - const first = decimals.filter(number => number !== '0')[0]; - const index = decimals.indexOf(first); - - // Set format fraction - formated = `.${fraction.substring(0, index + precision)}`; - } - - return parseFloat(quantity[0] + formated); -} - -function creditsToString(amount) { - const creditString = parseFloat(amount).toFixed(8); - return creditString; -} - function _objectWithoutProperties$1(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } const selectState$5 = state => state.publish || {}; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 49680e7..20a9a05 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -6,8 +6,8 @@ import { doToast } from 'redux/actions/notifications'; import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux/selectors/claims'; import { doFetchTransactions } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; -import { creditsToString } from 'util/formatCredits'; -import { batchActions } from 'util/batchActions'; +import { creditsToString } from 'util/format-credits'; +import { batchActions } from 'util/batch-actions'; import { createNormalizedTagKey } from 'util/claim'; import { buildClaimSearchCacheQuery } from 'util/claim-search'; diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 73d9e98..00865bd 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -2,7 +2,7 @@ import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import { doToast } from 'redux/actions/notifications'; import { selectBalance } from 'redux/selectors/wallet'; -import { creditsToString } from 'util/formatCredits'; +import { creditsToString } from 'util/format-credits'; import { selectMyClaimsRaw } from 'redux/selectors/claims'; export function doUpdateBalance() { From a1ae63d0b6c048248aa5615f814601616df15031 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Tue, 30 Jul 2019 11:48:45 -0400 Subject: [PATCH 4/8] handle all options for claim_search cache queries --- dist/bundle.es.js | 176 ++++++++++------------------------ src/index.js | 9 +- src/redux/actions/claims.js | 63 +++--------- src/redux/reducers/claims.js | 87 ++++++----------- src/redux/selectors/claims.js | 50 +++++----- src/util/claim-search.js | 8 -- src/util/claim.js | 10 +- 7 files changed, 120 insertions(+), 283 deletions(-) delete mode 100644 src/util/claim-search.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9c37e36..e0a8de9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1228,6 +1228,8 @@ function doDismissError() { var _extends$2 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; +function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } + const matureTagMap = MATURE_TAGS.reduce((acc, tag) => _extends$2({}, acc, { [tag]: true }), {}); const isClaimNsfw = claim => { @@ -1250,9 +1252,13 @@ const isClaimNsfw = claim => { return false; }; -const createNormalizedTagKey = tags => { - return tags ? tags.sort().join(',') : ''; -}; +function createNormalizedClaimSearchKey(options) { + // Ignore page because we don't care what the last page searched was, we want everything + // Ignore release_time because that will change depending on when you call claim_search ex: release_time: ">12344567" + const rest = _objectWithoutProperties(options, ['page', 'release_time']); + const query = JSON.stringify(rest); + return query; +} // @@ -1551,19 +1557,17 @@ const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataFo return metadata && metadata.tags || []; }); -const selectFetchingClaimSearch = reselect.createSelector(selectState$1, state => state.fetchingClaimSearch); +const selectfetchingClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.fetchingClaimSearchByQuery || {}); -const selectClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.claimSearchSearchByQuery || {}); +const selectFetchingClaimSearch = reselect.createSelector(selectfetchingClaimSearchByQuery, fetchingClaimSearchByQuery => Boolean(Object.keys(fetchingClaimSearchByQuery).length)); + +const selectClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.claimSearchByQuery || {}); const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); -const selectFetchingClaimSearchByTags = reselect.createSelector(selectState$1, state => state.fetchingClaimSearchByTags); +const makeSelectFetchingClaimSearchForTags = tags => reselect.createSelector(selectfetchingClaimSearchByQuery, byQuery => byQuery[createNormalizedClaimSearchKey({ any_tags: tags })]); -const selectClaimSearchUrisByTags = reselect.createSelector(selectState$1, state => state.claimSearchUrisByTags); - -const makeSelectFetchingClaimSearchForTags = tags => reselect.createSelector(selectFetchingClaimSearchByTags, byTags => byTags[createNormalizedTagKey(tags)]); - -const makeSelectClaimSearchUrisForTags = tags => reselect.createSelector(selectClaimSearchUrisByTags, byTags => byTags[createNormalizedTagKey(tags)]); +const makeSelectClaimSearchUrisForTags = tags => reselect.createSelector(selectClaimSearchByQuery, byQuery => byQuery[createNormalizedClaimSearchKey({ any_tags: tags })]); const selectState$2 = state => state.wallet || {}; @@ -2094,17 +2098,6 @@ function batchActions(...actions) { }; } -function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } - -// -function buildClaimSearchCacheQuery(options) { - // Ignore page because we don't care what the last page searched was, we want everything - // Ignore release_time because that will change depending on when you call claim_search ex: release_time: ">12344567" - const rest = _objectWithoutProperties(options, ["page", "release_time"]); - const query = JSON.stringify(rest); - return query; -} - var _extends$3 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; function doResolveUris(uris, returnCachedClaims = false) { @@ -2387,12 +2380,14 @@ function doFetchChannelListMine() { }; } -function doClaimSearch(options = {}) { - const query = buildClaimSearchCacheQuery(options); - +function doClaimSearch(options = { + page_size: 10 +}) { + const query = createNormalizedClaimSearchKey(options); return dispatch => { dispatch({ - type: CLAIM_SEARCH_STARTED + type: CLAIM_SEARCH_STARTED, + data: { query: query } }); const success = data => { @@ -2405,56 +2400,19 @@ function doClaimSearch(options = {}) { dispatch({ type: CLAIM_SEARCH_COMPLETED, - data: { resolveInfo, uris, query, append: options.page && options.page !== 1 } + data: { query, resolveInfo, uris, append: options.page && options.page !== 1 } }); }; const failure = err => { dispatch({ type: CLAIM_SEARCH_FAILED, + data: { query }, error: err }); }; - lbryProxy.claim_search(_extends$3({}, options)).then(success, failure); - }; -} - -// tags can be one or many (comma separated) -function doClaimSearchByTags(tags, amount = 10, options = {}) { - return dispatch => { - const tagList = createNormalizedTagKey(tags); - dispatch({ - type: CLAIM_SEARCH_BY_TAGS_STARTED, - data: { tags: tagList } - }); - - const success = data => { - const resolveInfo = {}; - const uris = []; - data.items.forEach(stream => { - resolveInfo[stream.permanent_url] = { stream }; - uris.push(stream.permanent_url); - }); - - dispatch({ - type: CLAIM_SEARCH_BY_TAGS_COMPLETED, - data: { tags: tagList, resolveInfo, uris, append: options.page && options.page !== 1 } - }); - }; - - const failure = err => { - dispatch({ - type: CLAIM_SEARCH_BY_TAGS_FAILED, - data: { tags: tagList }, - error: err - }); - }; - - lbryProxy.claim_search(_extends$3({ - page_size: amount, - any_tags: tags - }, options)).then(success, failure); + lbryProxy.claim_search(options).then(success, failure); }; } @@ -3491,10 +3449,8 @@ const defaultState = { abandoningById: {}, pendingById: {}, claimSearchError: false, - fetchingClaimSearch: false, - claimSearchUrisByTags: {}, - fetchingClaimSearchByTags: {}, - lastClaimSearchUris: [] + claimSearchByQuery: {}, + fetchingClaimSearchByQuery: {} }; function handleClaimAction(state, action) { @@ -3723,71 +3679,41 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }); }; -reducers[CLAIM_SEARCH_STARTED] = state => { +reducers[CLAIM_SEARCH_STARTED] = (state, action) => { + const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); + fetchingClaimSearchByQuery[action.data.query] = true; + return Object.assign({}, state, { - fetchingClaimSearch: true, - claimSearchError: false + fetchingClaimSearchByQuery }); }; reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { - const { claimSearchSearchByQuery } = state; - const { uris, query, append } = action.data; + const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); + const claimSearchByQuery = Object.assign({}, state.claimSearchByQuery); + const { append, query, uris } = action.data; - let newClaimSearch = _extends$5({}, claimSearchSearchByQuery); - if (!uris) { - newClaimSearch[query] = null; - } else if (append && newClaimSearch[query]) { - newClaimSearch[query] = newClaimSearch[query].concat(uris); - } else { - newClaimSearch[query] = uris; - } - - return _extends$5({}, handleClaimAction(state, action), { - fetchingClaimSearch: false, - claimSearchSearchByQuery: newClaimSearch - }); -}; - -reducers[CLAIM_SEARCH_FAILED] = state => { - return Object.assign({}, state, { - fetchingClaimSearch: false, - claimSearchError: true - }); -}; - -reducers[CLAIM_SEARCH_BY_TAGS_STARTED] = (state, action) => { - const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); - fetchingClaimSearchByTags[action.data.tags] = true; - - return Object.assign({}, state, { - fetchingClaimSearchByTags - }); -}; -reducers[CLAIM_SEARCH_BY_TAGS_COMPLETED] = (state, action) => { - const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); - const claimSearchUrisByTags = Object.assign({}, state.claimSearchUrisByTags); - const { append, tags, uris } = action.data; - - if (action.data.append) { + if (append) { // todo: check for duplicate uris when concatenating? - claimSearchUrisByTags[tags] = claimSearchUrisByTags[tags] && claimSearchUrisByTags[tags].length ? claimSearchUrisByTags[tags].concat(uris) : uris; + claimSearchByQuery[query] = claimSearchByQuery[query] && claimSearchByQuery[query].length ? claimSearchByQuery[query].concat(uris) : uris; } else { - claimSearchUrisByTags[tags] = uris; + claimSearchByQuery[query] = uris; } - fetchingClaimSearchByTags[tags] = false; // or delete the key instead? - return Object.assign({}, state, { - claimSearchUrisByTags, - fetchingClaimSearchByTags - }); + delete fetchingClaimSearchByQuery[query]; + + return Object.assign({}, state, _extends$5({}, handleClaimAction(state, action), { + claimSearchByQuery, + fetchingClaimSearchByQuery + })); }; -reducers[CLAIM_SEARCH_BY_TAGS_FAILED] = (state, action) => { - const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); - fetchingClaimSearchByTags[action.data.tags] = false; + +reducers[CLAIM_SEARCH_FAILED] = (state, action) => { + const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); + fetchingClaimSearchByQuery[action.data.tags] = false; return Object.assign({}, state, { - fetchingClaimSearchByTags + fetchingClaimSearchByQuery }); }; @@ -4784,12 +4710,12 @@ exports.SORT_OPTIONS = sort_options; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; exports.batchActions = batchActions; -exports.buildClaimSearchCacheQuery = buildClaimSearchCacheQuery; exports.buildURI = buildURI; exports.claimsReducer = claimsReducer; exports.commentReducer = commentReducer; exports.contentReducer = contentReducer; exports.convertToShareLink = convertToShareLink; +exports.createNormalizedClaimSearchKey = createNormalizedClaimSearchKey; exports.creditsToString = creditsToString; exports.doAbandonClaim = doAbandonClaim; exports.doAddTag = doAddTag; @@ -4798,7 +4724,6 @@ exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doClaimSearch = doClaimSearch; -exports.doClaimSearchByTags = doClaimSearchByTags; exports.doClearPublish = doClearPublish; exports.doCommentCreate = doCommentCreate; exports.doCommentList = doCommentList; @@ -4908,7 +4833,6 @@ exports.selectBalance = selectBalance; exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; -exports.selectClaimSearchUrisByTags = selectClaimSearchUrisByTags; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; exports.selectCurrentChannelPage = selectCurrentChannelPage; @@ -4922,7 +4846,6 @@ exports.selectDraftTransactionError = selectDraftTransactionError; exports.selectError = selectError; exports.selectFailedPurchaseUris = selectFailedPurchaseUris; exports.selectFetchingClaimSearch = selectFetchingClaimSearch; -exports.selectFetchingClaimSearchByTags = selectFetchingClaimSearchByTags; exports.selectFetchingMyChannels = selectFetchingMyChannels; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; @@ -4986,6 +4909,7 @@ exports.selectWalletState = selectWalletState; exports.selectWalletUnlockPending = selectWalletUnlockPending; exports.selectWalletUnlockResult = selectWalletUnlockResult; exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded; +exports.selectfetchingClaimSearchByQuery = selectfetchingClaimSearchByQuery; exports.setSearchApi = setSearchApi; exports.tagsReducer = tagsReducer; exports.toQueryString = toQueryString; diff --git a/src/index.js b/src/index.js index a8117ec..f6e7d14 100644 --- a/src/index.js +++ b/src/index.js @@ -55,7 +55,6 @@ export { doCreateChannel, doUpdateChannel, doClaimSearch, - doClaimSearchByTags, } from 'redux/actions/claims'; export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -116,8 +115,7 @@ export { doCommentList, doCommentCreate } from 'redux/actions/comments'; export { batchActions } from 'util/batch-actions'; export { parseQueryParams, toQueryString } from 'util/query-params'; export { formatCredits, formatFullPrice, creditsToString } from 'util/format-credits'; -export { isClaimNsfw } from 'util/claim'; -export { buildClaimSearchCacheQuery } from 'util/claim-search'; +export { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; // reducers export { claimsReducer } from 'redux/reducers/claims'; @@ -194,11 +192,10 @@ export { selectChannelClaimCounts, selectCurrentChannelPage, selectFetchingClaimSearch, - selectFetchingClaimSearchByTags, - selectClaimSearchUrisByTags, + selectfetchingClaimSearchByQuery, + selectClaimSearchByQuery, makeSelectFetchingClaimSearchForTags, makeSelectClaimSearchUrisForTags, - selectClaimSearchByQuery, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 20a9a05..902c87b 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -8,8 +8,7 @@ import { doFetchTransactions } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { creditsToString } from 'util/format-credits'; import { batchActions } from 'util/batch-actions'; -import { createNormalizedTagKey } from 'util/claim'; -import { buildClaimSearchCacheQuery } from 'util/claim-search'; +import { createNormalizedClaimSearchKey } from 'util/claim'; export function doResolveUris(uris: Array<string>, returnCachedClaims: boolean = false) { return (dispatch: Dispatch, getState: GetState) => { @@ -315,12 +314,16 @@ export function doFetchChannelListMine() { }; } -export function doClaimSearch(options: { page?: number, release_time?: string } = {}) { - const query = buildClaimSearchCacheQuery(options); - +export function doClaimSearch( + options: { tags?: Array<string>, page?: number, page_size?: number, release_time?: string } = { + page_size: 10, + } +) { + const query = createNormalizedClaimSearchKey(options); return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CLAIM_SEARCH_STARTED, + data: { query: query }, }); const success = (data: ClaimSearchResponse) => { @@ -333,62 +336,18 @@ export function doClaimSearch(options: { page?: number, release_time?: string } dispatch({ type: ACTIONS.CLAIM_SEARCH_COMPLETED, - data: { resolveInfo, uris, query, append: options.page && options.page !== 1 }, + data: { query, resolveInfo, uris, append: options.page && options.page !== 1 }, }); }; const failure = err => { dispatch({ type: ACTIONS.CLAIM_SEARCH_FAILED, + data: { query }, error: err, }); }; - Lbry.claim_search({ - ...options, - }).then(success, failure); - }; -} - -// tags can be one or many (comma separated) -export function doClaimSearchByTags( - tags: Array<string>, - amount: number = 10, - options: { page?: number } = {} -) { - return (dispatch: Dispatch) => { - const tagList = createNormalizedTagKey(tags); - dispatch({ - type: ACTIONS.CLAIM_SEARCH_BY_TAGS_STARTED, - data: { tags: tagList }, - }); - - const success = (data: ClaimSearchResponse) => { - const resolveInfo = {}; - const uris = []; - data.items.forEach((stream: Claim) => { - resolveInfo[stream.permanent_url] = { stream }; - uris.push(stream.permanent_url); - }); - - dispatch({ - type: ACTIONS.CLAIM_SEARCH_BY_TAGS_COMPLETED, - data: { tags: tagList, resolveInfo, uris, append: options.page && options.page !== 1 }, - }); - }; - - const failure = err => { - dispatch({ - type: ACTIONS.CLAIM_SEARCH_BY_TAGS_FAILED, - data: { tags: tagList }, - error: err, - }); - }; - - Lbry.claim_search({ - page_size: amount, - any_tags: tags, - ...options, - }).then(success, failure); + Lbry.claim_search(options).then(success, failure); }; } diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 1ef4c40..a001d3a 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -21,9 +21,8 @@ type State = { abandoningById: { [string]: boolean }, fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, - lastClaimSearchUris: Array<string>, - fetchingClaimSearchByTags: { [string]: boolean }, - claimSearchUrisByTags: { [string]: { all: Array<string> } }, + fetchingClaimSearchByQuery: { [string]: boolean }, + claimSearchByQuery: { [string]: Array<string> }, claimsByChannel: { [string]: { all: Array<string>, @@ -47,10 +46,8 @@ const defaultState = { abandoningById: {}, pendingById: {}, claimSearchError: false, - fetchingClaimSearch: false, - claimSearchUrisByTags: {}, - fetchingClaimSearchByTags: {}, - lastClaimSearchUris: [], + claimSearchByQuery: {}, + fetchingClaimSearchByQuery: {}, }; function handleClaimAction(state: State, action: any): State { @@ -290,75 +287,45 @@ reducers[ACTIONS.RESOLVE_URIS_STARTED] = (state: State, action: any): State => { }); }; -reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State): State => { +reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State, action: any): State => { + const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); + fetchingClaimSearchByQuery[action.data.query] = true; + return Object.assign({}, state, { - fetchingClaimSearch: true, - claimSearchError: false, + fetchingClaimSearchByQuery, }); }; reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => { - const { claimSearchSearchByQuery } = state; - const { uris, query, append } = action.data; + const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); + const claimSearchByQuery = Object.assign({}, state.claimSearchByQuery); + const { append, query, uris } = action.data; - let newClaimSearch = { ...claimSearchSearchByQuery }; - if (!uris) { - newClaimSearch[query] = null; - } else if (append && newClaimSearch[query]) { - newClaimSearch[query] = newClaimSearch[query].concat(uris); - } else { - newClaimSearch[query] = uris; - } - - return { - ...handleClaimAction(state, action), - fetchingClaimSearch: false, - claimSearchSearchByQuery: newClaimSearch, - }; -}; - -reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State): State => { - return Object.assign({}, state, { - fetchingClaimSearch: false, - claimSearchError: true, - }); -}; - -reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_STARTED] = (state: State, action: any): State => { - const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); - fetchingClaimSearchByTags[action.data.tags] = true; - - return Object.assign({}, state, { - fetchingClaimSearchByTags, - }); -}; -reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_COMPLETED] = (state: State, action: any): State => { - const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); - const claimSearchUrisByTags = Object.assign({}, state.claimSearchUrisByTags); - const { append, tags, uris } = action.data; - - if (action.data.append) { + if (append) { // todo: check for duplicate uris when concatenating? - claimSearchUrisByTags[tags] = - claimSearchUrisByTags[tags] && claimSearchUrisByTags[tags].length - ? claimSearchUrisByTags[tags].concat(uris) + claimSearchByQuery[query] = + claimSearchByQuery[query] && claimSearchByQuery[query].length + ? claimSearchByQuery[query].concat(uris) : uris; } else { - claimSearchUrisByTags[tags] = uris; + claimSearchByQuery[query] = uris; } - fetchingClaimSearchByTags[tags] = false; // or delete the key instead? + + delete fetchingClaimSearchByQuery[query]; return Object.assign({}, state, { - claimSearchUrisByTags, - fetchingClaimSearchByTags, + ...handleClaimAction(state, action), + claimSearchByQuery, + fetchingClaimSearchByQuery, }); }; -reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_FAILED] = (state: State, action: any): State => { - const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); - fetchingClaimSearchByTags[action.data.tags] = false; + +reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State, action: any): State => { + const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); + fetchingClaimSearchByQuery[action.data.tags] = false; return Object.assign({}, state, { - fetchingClaimSearchByTags, + fetchingClaimSearchByQuery, }); }; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index fee7b2a..85ff987 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -2,7 +2,7 @@ import { normalizeURI, buildURI, parseURI } from 'lbryURI'; import { selectSearchUrisByQuery } from 'redux/selectors/search'; import { createSelector } from 'reselect'; -import { isClaimNsfw, createNormalizedTagKey } from 'util/claim'; +import { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; import { getSearchQueryString } from 'util/query-params'; const selectState = state => state.claims || {}; @@ -223,8 +223,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -498,40 +498,34 @@ export const makeSelectTagsForUri = (uri: string) => } ); -export const selectFetchingClaimSearch = createSelector( +export const selectfetchingClaimSearchByQuery = createSelector( selectState, - state => state.fetchingClaimSearch + state => state.fetchingClaimSearchByQuery || {} +); + +export const selectFetchingClaimSearch = createSelector( + selectfetchingClaimSearchByQuery, + fetchingClaimSearchByQuery => Boolean(Object.keys(fetchingClaimSearchByQuery).length) ); export const selectClaimSearchByQuery = createSelector( selectState, - state => state.claimSearchSearchByQuery || {} + state => state.claimSearchByQuery || {} ); +export const makeSelectClaimSearchUrisByOptions = (options: {}) => + createSelector( + selectClaimSearchByQuery, + byQuery => { + // We don't care what options are passed to this selector. Just forward them. + // $FlowFixMe + const query = createNormalizedClaimSearchKey(options); + return byQuery[query]; + } + ); + export const makeSelectShortUrlForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), claim => claim && claim.short_url ); - -export const selectFetchingClaimSearchByTags = createSelector( - selectState, - state => state.fetchingClaimSearchByTags -); - -export const selectClaimSearchUrisByTags = createSelector( - selectState, - state => state.claimSearchUrisByTags -); - -export const makeSelectFetchingClaimSearchForTags = (tags: Array<string>) => - createSelector( - selectFetchingClaimSearchByTags, - byTags => byTags[createNormalizedTagKey(tags)] - ); - -export const makeSelectClaimSearchUrisForTags = (tags: Array<string>) => - createSelector( - selectClaimSearchUrisByTags, - byTags => byTags[createNormalizedTagKey(tags)] - ); diff --git a/src/util/claim-search.js b/src/util/claim-search.js deleted file mode 100644 index 44913cf..0000000 --- a/src/util/claim-search.js +++ /dev/null @@ -1,8 +0,0 @@ -// @flow -export function buildClaimSearchCacheQuery(options: { page?: number, release_time?: string }) { - // Ignore page because we don't care what the last page searched was, we want everything - // Ignore release_time because that will change depending on when you call claim_search ex: release_time: ">12344567" - const { page: optionToIgnoreForQuery, release_time: anotherToIgnore, ...rest } = options; - const query = JSON.stringify(rest); - return query; -} diff --git a/src/util/claim.js b/src/util/claim.js index 1e24a10..ece6fc7 100644 --- a/src/util/claim.js +++ b/src/util/claim.js @@ -23,6 +23,10 @@ export const isClaimNsfw = (claim: Claim): boolean => { return false; }; -export const createNormalizedTagKey = (tags: Array<string>): string => { - return tags ? tags.sort().join(',') : ''; -}; +export function createNormalizedClaimSearchKey(options: { page?: number, release_time?: string }) { + // Ignore page because we don't care what the last page searched was, we want everything + // Ignore release_time because that will change depending on when you call claim_search ex: release_time: ">12344567" + const { page: optionToIgnoreForQuery, release_time: anotherToIgnore, ...rest } = options; + const query = JSON.stringify(rest); + return query; +} From c04f6806f7fb3eb77a19ede8651d1498eccfe16c Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Tue, 30 Jul 2019 12:00:36 -0400 Subject: [PATCH 5/8] fix export and url selector --- dist/bundle.es.js | 12 +++++------- src/index.js | 2 -- src/redux/selectors/claims.js | 8 +++++--- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e0a8de9..3311298 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1408,7 +1408,11 @@ const makeSelectContentTypeForUri = uri => reselect.createSelector(makeSelectCla const makeSelectThumbnailForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; - return thumbnail && thumbnail.url && thumbnail.url.trim().length > 0 ? thumbnail.url : undefined; + if (!thumbnail || !thumbnail.url) { + return undefined; + } + + return thumbnail.url.trim(); }); const makeSelectCoverForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { @@ -1565,10 +1569,6 @@ const selectClaimSearchByQuery = reselect.createSelector(selectState$1, state => const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); -const makeSelectFetchingClaimSearchForTags = tags => reselect.createSelector(selectfetchingClaimSearchByQuery, byQuery => byQuery[createNormalizedClaimSearchKey({ any_tags: tags })]); - -const makeSelectClaimSearchUrisForTags = tags => reselect.createSelector(selectClaimSearchByQuery, byQuery => byQuery[createNormalizedClaimSearchKey({ any_tags: tags })]); - const selectState$2 = state => state.wallet || {}; const selectWalletState = selectState$2; @@ -4785,7 +4785,6 @@ exports.makeSelectClaimForUri = makeSelectClaimForUri; exports.makeSelectClaimIsMine = makeSelectClaimIsMine; exports.makeSelectClaimIsNsfw = makeSelectClaimIsNsfw; exports.makeSelectClaimIsPending = makeSelectClaimIsPending; -exports.makeSelectClaimSearchUrisForTags = makeSelectClaimSearchUrisForTags; exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannelForCurrentPageState; exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; exports.makeSelectCommentsForUri = makeSelectCommentsForUri; @@ -4795,7 +4794,6 @@ exports.makeSelectCoverForUri = makeSelectCoverForUri; exports.makeSelectDateForUri = makeSelectDateForUri; exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; -exports.makeSelectFetchingClaimSearchForTags = makeSelectFetchingClaimSearchForTags; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileForUri; exports.makeSelectIsUriResolving = makeSelectIsUriResolving; diff --git a/src/index.js b/src/index.js index f6e7d14..05690a8 100644 --- a/src/index.js +++ b/src/index.js @@ -194,8 +194,6 @@ export { selectFetchingClaimSearch, selectfetchingClaimSearchByQuery, selectClaimSearchByQuery, - makeSelectFetchingClaimSearchForTags, - makeSelectClaimSearchUrisForTags, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 85ff987..180f84c 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -255,9 +255,11 @@ export const makeSelectThumbnailForUri = (uri: string) => makeSelectClaimForUri(uri), claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; - return thumbnail && thumbnail.url && thumbnail.url.trim().length > 0 - ? thumbnail.url - : undefined; + if (!thumbnail || !thumbnail.url) { + return undefined; + } + + return thumbnail.url.trim(); } ); From 3266ebd933bc4af5e24c62c3ca956b5ee967db32 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Tue, 30 Jul 2019 12:04:04 -0400 Subject: [PATCH 6/8] delete unused navigation file --- src/redux/selectors/navigation.js | 78 ------------------------------- 1 file changed, 78 deletions(-) delete mode 100644 src/redux/selectors/navigation.js diff --git a/src/redux/selectors/navigation.js b/src/redux/selectors/navigation.js deleted file mode 100644 index 3b81d79..0000000 --- a/src/redux/selectors/navigation.js +++ /dev/null @@ -1,78 +0,0 @@ -import { createSelector } from 'reselect'; -import { parseQueryParams } from 'util/query-params'; - -export const selectState = state => state.navigation || {}; - -export const selectCurrentPath = createSelector( - selectState, - state => state.currentPath -); - -export const computePageFromPath = path => (path ? path.replace(/^\//, '').split('?')[0] : ''); - -export const selectCurrentPage = createSelector( - selectCurrentPath, - path => computePageFromPath(path) -); - -export const selectCurrentParams = createSelector( - selectCurrentPath, - path => { - if (path === undefined) return {}; - if (!path.match(/\?/)) return {}; - - return parseQueryParams(path.split('?')[1]); - } -); - -export const makeSelectCurrentParam = param => - createSelector( - selectCurrentParams, - params => (params ? params[param] : undefined) - ); - -export const selectPathAfterAuth = createSelector( - selectState, - state => state.pathAfterAuth -); - -export const selectIsBackDisabled = createSelector( - selectState, - state => state.index === 0 -); - -export const selectIsForwardDisabled = createSelector( - selectState, - state => state.index === state.stack.length - 1 -); - -export const selectIsHome = createSelector( - selectCurrentPage, - page => page === 'discover' -); - -export const selectHistoryIndex = createSelector( - selectState, - state => state.index -); - -export const selectHistoryStack = createSelector( - selectState, - state => state.stack -); - -// returns current page attributes (scrollY, path) -export const selectActiveHistoryEntry = createSelector( - selectState, - state => state.stack[state.index] -); - -export const selectPageTitle = createSelector( - selectCurrentPage, - page => { - switch (page) { - default: - return ''; - } - } -); From b257431eae9ff2e3bdb1db7fd7cee389cd8b7fd9 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Tue, 30 Jul 2019 12:15:29 -0400 Subject: [PATCH 7/8] remove /g flag for uri regex --- dist/bundle.es.js | 2 +- src/lbryURI.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3311298..984aefe 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -902,7 +902,7 @@ const channelNameMinLength = 1; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls -const regexInvalidURI = /[ =&#:$@%?;/\\"<>%{}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/gu; +const regexInvalidURI = /[ =&#:$@%?;/\\"<>%{}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/u; const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; /** diff --git a/src/lbryURI.js b/src/lbryURI.js index 32c6ce6..72a6200 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -2,7 +2,7 @@ const channelNameMinLength = 1; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls -export const regexInvalidURI = /[ =&#:$@%?;/\\"<>%{}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/gu; +export const regexInvalidURI = /[ =&#:$@%?;/\\"<>%{}|^~[\]`\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/u; export const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; /** From 2c70556bdfcc4abfffc1a4df9fa410d34638915d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt <sean@lbry.io> Date: Wed, 31 Jul 2019 15:03:56 -0400 Subject: [PATCH 8/8] use null over undefined --- dist/bundle.es.js | 2 +- src/redux/selectors/claims.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 984aefe..e80bf8e 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1409,7 +1409,7 @@ const makeSelectContentTypeForUri = uri => reselect.createSelector(makeSelectCla const makeSelectThumbnailForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; if (!thumbnail || !thumbnail.url) { - return undefined; + return null; } return thumbnail.url.trim(); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 180f84c..c9dc1ac 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -256,7 +256,7 @@ export const makeSelectThumbnailForUri = (uri: string) => claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; if (!thumbnail || !thumbnail.url) { - return undefined; + return null; } return thumbnail.url.trim();