From a5580e3ac0664bb4e1491ed1e0d85f2a3bd45cc4 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 25 Apr 2019 14:21:41 -0400 Subject: [PATCH 001/371] comments --- .lintstagedrc.json | 12 +- README.md | 9 + dist/bundle.es.js | 24 +- dist/bundle.js | 5929 -------------------------- src/lbry.js | 3 + src/redux/selectors/content.js | 18 +- src/redux/selectors/file_info.js | 191 +- src/redux/selectors/navigation.js | 66 +- src/redux/selectors/notifications.js | 44 +- src/redux/selectors/wallet.js | 275 +- src/util/formatCredits.js | 2 +- 11 files changed, 392 insertions(+), 6181 deletions(-) delete mode 100644 dist/bundle.js diff --git a/.lintstagedrc.json b/.lintstagedrc.json index caae289..6abc007 100644 --- a/.lintstagedrc.json +++ b/.lintstagedrc.json @@ -1,6 +1,12 @@ { "linters": { - "src/**/*.{js,json}": ["prettier --write", "git add"], - "src/**/*.js": ["eslint --fix", "git add"] + "src/**/*.{js,json}": [ + "prettier --write", + "git add" + ], + "src/**/*.js": [ + "eslint --fix", + "git add" + ] } -} +} \ No newline at end of file diff --git a/README.md b/README.md index d464b1c..cf44e21 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,15 @@ npm link lbry-redux ### Build Run `$ yarn build`. If the symlink does not work, just build the file and move the `bundle.js` file in to the `node_modules/` folder. +#### Local Development with `lbry-desktop` +If you're working with the desktop app and you've followed the steps above, then you'll want to +run `$ yarn dev` (or equivalently `$ webpack --watch`). This will allow any changes made to the code +to be automatically reflected in `dist/bundle.js`. + +Once you've made your changes, running `(lbry-desktop)$ yarn dev` should have it automatically +reloading changes. If this doesn't happen, just rebuild `lbry-redux` and +[relink it to `lbry-desktop`](.README.md:11) + ## Contributing We :heart: contributions from everyone! We welcome [bug reports](https://github.com/lbryio/lbry-redux/issues/), [bug fixes](https://github.com/lbryio/lbry-redux/pulls) and feedback on the module is always appreciated. diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 87be288..07340a5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -653,6 +653,9 @@ const Lbry = { sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), + comment_list: (params = {}) => daemonCallWithResult('comment_list', params), + comment_create: (params = {}) => daemonCallWithResult('comment_create', params), + // Connect to the sdk connect: () => { if (Lbry.connectPromise === null) { @@ -1430,9 +1433,14 @@ const selectTransactionItems = reselect.createSelector(selectTransactionsById, b append.push(...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: ABANDON }))); if (!append.length) { - append.push(Object.assign({}, tx, { - type: tx.value < 0 ? SPEND : RECEIVE - })); + append.push(...tx.claim_info.map(item => Object.assign({}, tx, item, { + type: item.claim_name[0] === '@' ? CHANNEL : PUBLISH + }))); + append.push(...tx.support_info.map(item => Object.assign({}, tx, item, { + type: !item.is_tip ? SUPPORT : TIP + }))); + append.push(...tx.update_info.map(item => Object.assign({}, tx, item, { type: UPDATE }))); + append.push(...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: ABANDON }))); } items.push(...append.map(item => { @@ -2229,14 +2237,18 @@ const selectSearchDownloadUris = query => reselect.createSelector(selectFileInfo }); return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(fileInfo => { - const { channel_name: channelName, claim_id: claimId, claim_name: claimName } = fileInfo; + const { + channel_name: channelName, + claim_id: claimId, + claim_name: claimName + } = fileInfo; const uriParams = {}; if (channelName) { const claim = claimsById[claimId]; - if (claim && claim.value) { - uriParams.claimId = claim.value.publisherSignature.certificateId; + if (claim) { + uriParams.claimId = claim.channel_id; } else { uriParams.claimId = claimId; } diff --git a/dist/bundle.js b/dist/bundle.js deleted file mode 100644 index f2d5996..0000000 --- a/dist/bundle.js +++ /dev/null @@ -1,5929 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else { - var a = factory(); - for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; - } -})((typeof self !== 'undefined' ? self : this), function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.selectTransactionListFilter = 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.selectTotalBalance = exports.selectBalance = exports.makeSelectBlockDate = exports.makeSelectQueryWithOptions = exports.selectSearchSuggestions = exports.selectSearchBarFocused = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchOptions = exports.selectSearchValue = exports.makeSelectSearchUris = exports.selectSearchState = exports.selectFileListPublishedSort = exports.selectFileListDownloadedSort = 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.selectCurrentChannelPage = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = undefined; -exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.selectAllFetchingChannelClaims = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = exports.selectPendingById = exports.makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectPendingByUri = exports.makeSelectClaimIsPending = exports.makeSelectChannelForClaimUri = exports.makeSelectFirstRecommendedFileForUri = exports.makeSelectRecommendedContentForUri = exports.makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountFromUris = exports.makeSelectTotalPagesForChannel = exports.makeSelectTotalItemsForChannel = exports.makeSelectIsUriResolving = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForPage = exports.makeSelectFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.makeSelectClaimForUri = exports.selectError = exports.selectToast = exports.makeSelectContentPositionForUri = exports.contentReducer = exports.walletReducer = exports.searchReducer = exports.notificationsReducer = exports.fileInfoReducer = exports.claimsReducer = exports.creditsToString = exports.formatFullPrice = exports.formatCredits = exports.toQueryString = exports.parseQueryParams = exports.batchActions = exports.doUpdateBlockHeight = exports.doSetTransactionListFilter = exports.doWalletStatus = exports.doWalletUnlock = exports.doWalletDecrypt = exports.doWalletEncrypt = exports.doSendTip = exports.doSetDraftTransactionAddress = exports.doSetDraftTransactionAmount = exports.doSendDraftTransaction = exports.doCheckAddressIsMine = exports.doGetNewAddress = exports.doFetchBlock = exports.doFetchTransactions = exports.doTotalBalanceSubscribe = exports.doUpdateTotalBalance = exports.doBalanceSubscribe = exports.doUpdateBalance = exports.savePosition = exports.doUpdateSearchOptions = exports.setSearchApi = exports.doBlurSearchInput = exports.doFocusSearchInput = exports.doUpdateSearchQuery = exports.doSearch = exports.doSetFileListSort = exports.doFetchFileInfosAndPublishedClaims = exports.doFileList = exports.doFetchFileInfo = exports.doResolveUri = exports.doResolveUris = exports.doAbandonClaim = exports.doFetchClaimListMine = exports.doFetchClaimCountByChannel = exports.doFetchClaimsByChannel = exports.doDismissError = exports.doError = exports.doDismissToast = exports.doToast = exports.convertToShareLink = exports.isNameValid = exports.isURIClaimable = exports.isURIValid = exports.normalizeURI = exports.buildURI = exports.parseURI = exports.regexAddress = exports.regexInvalidURI = exports.Lbry = exports.PAGES = exports.SORT_OPTIONS = exports.TRANSACTIONS = exports.SETTINGS = exports.SEARCH_OPTIONS = exports.SEARCH_TYPES = exports.THUMBNAIL_STATUSES = exports.ACTIONS = undefined; - -var _lbryURI = __webpack_require__(1); - -Object.defineProperty(exports, 'regexInvalidURI', { - enumerable: true, - get: function get() { - return _lbryURI.regexInvalidURI; - } -}); -Object.defineProperty(exports, 'regexAddress', { - enumerable: true, - get: function get() { - return _lbryURI.regexAddress; - } -}); -Object.defineProperty(exports, 'parseURI', { - enumerable: true, - get: function get() { - return _lbryURI.parseURI; - } -}); -Object.defineProperty(exports, 'buildURI', { - enumerable: true, - get: function get() { - return _lbryURI.buildURI; - } -}); -Object.defineProperty(exports, 'normalizeURI', { - enumerable: true, - get: function get() { - return _lbryURI.normalizeURI; - } -}); -Object.defineProperty(exports, 'isURIValid', { - enumerable: true, - get: function get() { - return _lbryURI.isURIValid; - } -}); -Object.defineProperty(exports, 'isURIClaimable', { - enumerable: true, - get: function get() { - return _lbryURI.isURIClaimable; - } -}); -Object.defineProperty(exports, 'isNameValid', { - enumerable: true, - get: function get() { - return _lbryURI.isNameValid; - } -}); -Object.defineProperty(exports, 'convertToShareLink', { - enumerable: true, - get: function get() { - return _lbryURI.convertToShareLink; - } -}); - -var _notifications = __webpack_require__(2); - -Object.defineProperty(exports, 'doToast', { - enumerable: true, - get: function get() { - return _notifications.doToast; - } -}); -Object.defineProperty(exports, 'doDismissToast', { - enumerable: true, - get: function get() { - return _notifications.doDismissToast; - } -}); -Object.defineProperty(exports, 'doError', { - enumerable: true, - get: function get() { - return _notifications.doError; - } -}); -Object.defineProperty(exports, 'doDismissError', { - enumerable: true, - get: function get() { - return _notifications.doDismissError; - } -}); - -var _claims = __webpack_require__(7); - -Object.defineProperty(exports, 'doFetchClaimsByChannel', { - enumerable: true, - get: function get() { - return _claims.doFetchClaimsByChannel; - } -}); -Object.defineProperty(exports, 'doFetchClaimCountByChannel', { - enumerable: true, - get: function get() { - return _claims.doFetchClaimCountByChannel; - } -}); -Object.defineProperty(exports, 'doFetchClaimListMine', { - enumerable: true, - get: function get() { - return _claims.doFetchClaimListMine; - } -}); -Object.defineProperty(exports, 'doAbandonClaim', { - enumerable: true, - get: function get() { - return _claims.doAbandonClaim; - } -}); -Object.defineProperty(exports, 'doResolveUris', { - enumerable: true, - get: function get() { - return _claims.doResolveUris; - } -}); -Object.defineProperty(exports, 'doResolveUri', { - enumerable: true, - get: function get() { - return _claims.doResolveUri; - } -}); - -var _file_info = __webpack_require__(21); - -Object.defineProperty(exports, 'doFetchFileInfo', { - enumerable: true, - get: function get() { - return _file_info.doFetchFileInfo; - } -}); -Object.defineProperty(exports, 'doFileList', { - enumerable: true, - get: function get() { - return _file_info.doFileList; - } -}); -Object.defineProperty(exports, 'doFetchFileInfosAndPublishedClaims', { - enumerable: true, - get: function get() { - return _file_info.doFetchFileInfosAndPublishedClaims; - } -}); -Object.defineProperty(exports, 'doSetFileListSort', { - enumerable: true, - get: function get() { - return _file_info.doSetFileListSort; - } -}); - -var _search = __webpack_require__(23); - -Object.defineProperty(exports, 'doSearch', { - enumerable: true, - get: function get() { - return _search.doSearch; - } -}); -Object.defineProperty(exports, 'doUpdateSearchQuery', { - enumerable: true, - get: function get() { - return _search.doUpdateSearchQuery; - } -}); -Object.defineProperty(exports, 'doFocusSearchInput', { - enumerable: true, - get: function get() { - return _search.doFocusSearchInput; - } -}); -Object.defineProperty(exports, 'doBlurSearchInput', { - enumerable: true, - get: function get() { - return _search.doBlurSearchInput; - } -}); -Object.defineProperty(exports, 'setSearchApi', { - enumerable: true, - get: function get() { - return _search.setSearchApi; - } -}); -Object.defineProperty(exports, 'doUpdateSearchOptions', { - enumerable: true, - get: function get() { - return _search.doUpdateSearchOptions; - } -}); - -var _content = __webpack_require__(27); - -Object.defineProperty(exports, 'savePosition', { - enumerable: true, - get: function get() { - return _content.savePosition; - } -}); - -var _wallet = __webpack_require__(17); - -Object.defineProperty(exports, 'doUpdateBalance', { - enumerable: true, - get: function get() { - return _wallet.doUpdateBalance; - } -}); -Object.defineProperty(exports, 'doBalanceSubscribe', { - enumerable: true, - get: function get() { - return _wallet.doBalanceSubscribe; - } -}); -Object.defineProperty(exports, 'doUpdateTotalBalance', { - enumerable: true, - get: function get() { - return _wallet.doUpdateTotalBalance; - } -}); -Object.defineProperty(exports, 'doTotalBalanceSubscribe', { - enumerable: true, - get: function get() { - return _wallet.doTotalBalanceSubscribe; - } -}); -Object.defineProperty(exports, 'doFetchTransactions', { - enumerable: true, - get: function get() { - return _wallet.doFetchTransactions; - } -}); -Object.defineProperty(exports, 'doFetchBlock', { - enumerable: true, - get: function get() { - return _wallet.doFetchBlock; - } -}); -Object.defineProperty(exports, 'doGetNewAddress', { - enumerable: true, - get: function get() { - return _wallet.doGetNewAddress; - } -}); -Object.defineProperty(exports, 'doCheckAddressIsMine', { - enumerable: true, - get: function get() { - return _wallet.doCheckAddressIsMine; - } -}); -Object.defineProperty(exports, 'doSendDraftTransaction', { - enumerable: true, - get: function get() { - return _wallet.doSendDraftTransaction; - } -}); -Object.defineProperty(exports, 'doSetDraftTransactionAmount', { - enumerable: true, - get: function get() { - return _wallet.doSetDraftTransactionAmount; - } -}); -Object.defineProperty(exports, 'doSetDraftTransactionAddress', { - enumerable: true, - get: function get() { - return _wallet.doSetDraftTransactionAddress; - } -}); -Object.defineProperty(exports, 'doSendTip', { - enumerable: true, - get: function get() { - return _wallet.doSendTip; - } -}); -Object.defineProperty(exports, 'doWalletEncrypt', { - enumerable: true, - get: function get() { - return _wallet.doWalletEncrypt; - } -}); -Object.defineProperty(exports, 'doWalletDecrypt', { - enumerable: true, - get: function get() { - return _wallet.doWalletDecrypt; - } -}); -Object.defineProperty(exports, 'doWalletUnlock', { - enumerable: true, - get: function get() { - return _wallet.doWalletUnlock; - } -}); -Object.defineProperty(exports, 'doWalletStatus', { - enumerable: true, - get: function get() { - return _wallet.doWalletStatus; - } -}); -Object.defineProperty(exports, 'doSetTransactionListFilter', { - enumerable: true, - get: function get() { - return _wallet.doSetTransactionListFilter; - } -}); -Object.defineProperty(exports, 'doUpdateBlockHeight', { - enumerable: true, - get: function get() { - return _wallet.doUpdateBlockHeight; - } -}); - -var _batchActions = __webpack_require__(24); - -Object.defineProperty(exports, 'batchActions', { - enumerable: true, - get: function get() { - return _batchActions.batchActions; - } -}); - -var _query_params = __webpack_require__(14); - -Object.defineProperty(exports, 'parseQueryParams', { - enumerable: true, - get: function get() { - return _query_params.parseQueryParams; - } -}); -Object.defineProperty(exports, 'toQueryString', { - enumerable: true, - get: function get() { - return _query_params.toQueryString; - } -}); - -var _formatCredits = __webpack_require__(20); - -Object.defineProperty(exports, 'formatCredits', { - enumerable: true, - get: function get() { - return _formatCredits.formatCredits; - } -}); -Object.defineProperty(exports, 'formatFullPrice', { - enumerable: true, - get: function get() { - return _formatCredits.formatFullPrice; - } -}); -Object.defineProperty(exports, 'creditsToString', { - enumerable: true, - get: function get() { - return _formatCredits.creditsToString; - } -}); - -var _claims2 = __webpack_require__(28); - -Object.defineProperty(exports, 'claimsReducer', { - enumerable: true, - get: function get() { - return _claims2.claimsReducer; - } -}); - -var _file_info2 = __webpack_require__(29); - -Object.defineProperty(exports, 'fileInfoReducer', { - enumerable: true, - get: function get() { - return _file_info2.fileInfoReducer; - } -}); - -var _notifications2 = __webpack_require__(32); - -Object.defineProperty(exports, 'notificationsReducer', { - enumerable: true, - get: function get() { - return _notifications2.notificationsReducer; - } -}); - -var _search2 = __webpack_require__(34); - -Object.defineProperty(exports, 'searchReducer', { - enumerable: true, - get: function get() { - return _search2.searchReducer; - } -}); - -var _wallet2 = __webpack_require__(35); - -Object.defineProperty(exports, 'walletReducer', { - enumerable: true, - get: function get() { - return _wallet2.walletReducer; - } -}); - -var _content2 = __webpack_require__(36); - -Object.defineProperty(exports, 'contentReducer', { - enumerable: true, - get: function get() { - return _content2.contentReducer; - } -}); - -var _content3 = __webpack_require__(37); - -Object.defineProperty(exports, 'makeSelectContentPositionForUri', { - enumerable: true, - get: function get() { - return _content3.makeSelectContentPositionForUri; - } -}); - -var _notifications3 = __webpack_require__(38); - -Object.defineProperty(exports, 'selectToast', { - enumerable: true, - get: function get() { - return _notifications3.selectToast; - } -}); -Object.defineProperty(exports, 'selectError', { - enumerable: true, - get: function get() { - return _notifications3.selectError; - } -}); - -var _claims3 = __webpack_require__(11); - -Object.defineProperty(exports, 'makeSelectClaimForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimForUri; - } -}); -Object.defineProperty(exports, 'makeSelectClaimIsMine', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimIsMine; - } -}); -Object.defineProperty(exports, 'makeSelectFetchingChannelClaims', { - enumerable: true, - get: function get() { - return _claims3.makeSelectFetchingChannelClaims; - } -}); -Object.defineProperty(exports, 'makeSelectClaimsInChannelForPage', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimsInChannelForPage; - } -}); -Object.defineProperty(exports, 'makeSelectMetadataForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectMetadataForUri; - } -}); -Object.defineProperty(exports, 'makeSelectTitleForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectTitleForUri; - } -}); -Object.defineProperty(exports, 'makeSelectContentTypeForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectContentTypeForUri; - } -}); -Object.defineProperty(exports, 'makeSelectIsUriResolving', { - enumerable: true, - get: function get() { - return _claims3.makeSelectIsUriResolving; - } -}); -Object.defineProperty(exports, 'makeSelectTotalItemsForChannel', { - enumerable: true, - get: function get() { - return _claims3.makeSelectTotalItemsForChannel; - } -}); -Object.defineProperty(exports, 'makeSelectTotalPagesForChannel', { - enumerable: true, - get: function get() { - return _claims3.makeSelectTotalPagesForChannel; - } -}); -Object.defineProperty(exports, 'makeSelectNsfwCountFromUris', { - enumerable: true, - get: function get() { - return _claims3.makeSelectNsfwCountFromUris; - } -}); -Object.defineProperty(exports, 'makeSelectNsfwCountForChannel', { - enumerable: true, - get: function get() { - return _claims3.makeSelectNsfwCountForChannel; - } -}); -Object.defineProperty(exports, 'makeSelectRecommendedContentForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectRecommendedContentForUri; - } -}); -Object.defineProperty(exports, 'makeSelectFirstRecommendedFileForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectFirstRecommendedFileForUri; - } -}); -Object.defineProperty(exports, 'makeSelectChannelForClaimUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectChannelForClaimUri; - } -}); -Object.defineProperty(exports, 'makeSelectClaimIsPending', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimIsPending; - } -}); -Object.defineProperty(exports, 'makeSelectPendingByUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectPendingByUri; - } -}); -Object.defineProperty(exports, 'makeSelectClaimsInChannelForCurrentPageState', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimsInChannelForCurrentPageState; - } -}); -Object.defineProperty(exports, 'selectPendingById', { - enumerable: true, - get: function get() { - return _claims3.selectPendingById; - } -}); -Object.defineProperty(exports, 'selectClaimsById', { - enumerable: true, - get: function get() { - return _claims3.selectClaimsById; - } -}); -Object.defineProperty(exports, 'selectClaimsByUri', { - enumerable: true, - get: function get() { - return _claims3.selectClaimsByUri; - } -}); -Object.defineProperty(exports, 'selectAllClaimsByChannel', { - enumerable: true, - get: function get() { - return _claims3.selectAllClaimsByChannel; - } -}); -Object.defineProperty(exports, 'selectMyClaimsRaw', { - enumerable: true, - get: function get() { - return _claims3.selectMyClaimsRaw; - } -}); -Object.defineProperty(exports, 'selectAbandoningIds', { - enumerable: true, - get: function get() { - return _claims3.selectAbandoningIds; - } -}); -Object.defineProperty(exports, 'selectMyActiveClaims', { - enumerable: true, - get: function get() { - return _claims3.selectMyActiveClaims; - } -}); -Object.defineProperty(exports, 'selectAllFetchingChannelClaims', { - enumerable: true, - get: function get() { - return _claims3.selectAllFetchingChannelClaims; - } -}); -Object.defineProperty(exports, 'selectIsFetchingClaimListMine', { - enumerable: true, - get: function get() { - return _claims3.selectIsFetchingClaimListMine; - } -}); -Object.defineProperty(exports, 'selectPendingClaims', { - enumerable: true, - get: function get() { - return _claims3.selectPendingClaims; - } -}); -Object.defineProperty(exports, 'selectMyClaims', { - enumerable: true, - get: function get() { - return _claims3.selectMyClaims; - } -}); -Object.defineProperty(exports, 'selectMyClaimsWithoutChannels', { - enumerable: true, - get: function get() { - return _claims3.selectMyClaimsWithoutChannels; - } -}); -Object.defineProperty(exports, 'selectAllMyClaimsByOutpoint', { - enumerable: true, - get: function get() { - return _claims3.selectAllMyClaimsByOutpoint; - } -}); -Object.defineProperty(exports, 'selectMyClaimsOutpoints', { - enumerable: true, - get: function get() { - return _claims3.selectMyClaimsOutpoints; - } -}); -Object.defineProperty(exports, 'selectFetchingMyChannels', { - enumerable: true, - get: function get() { - return _claims3.selectFetchingMyChannels; - } -}); -Object.defineProperty(exports, 'selectMyChannelClaims', { - enumerable: true, - get: function get() { - return _claims3.selectMyChannelClaims; - } -}); -Object.defineProperty(exports, 'selectResolvingUris', { - enumerable: true, - get: function get() { - return _claims3.selectResolvingUris; - } -}); -Object.defineProperty(exports, 'selectPlayingUri', { - enumerable: true, - get: function get() { - return _claims3.selectPlayingUri; - } -}); -Object.defineProperty(exports, 'selectChannelClaimCounts', { - enumerable: true, - get: function get() { - return _claims3.selectChannelClaimCounts; - } -}); -Object.defineProperty(exports, 'selectCurrentChannelPage', { - enumerable: true, - get: function get() { - return _claims3.selectCurrentChannelPage; - } -}); - -var _file_info3 = __webpack_require__(22); - -Object.defineProperty(exports, 'makeSelectFileInfoForUri', { - enumerable: true, - get: function get() { - return _file_info3.makeSelectFileInfoForUri; - } -}); -Object.defineProperty(exports, 'makeSelectDownloadingForUri', { - enumerable: true, - get: function get() { - return _file_info3.makeSelectDownloadingForUri; - } -}); -Object.defineProperty(exports, 'makeSelectLoadingForUri', { - enumerable: true, - get: function get() { - return _file_info3.makeSelectLoadingForUri; - } -}); -Object.defineProperty(exports, 'selectFileInfosByOutpoint', { - enumerable: true, - get: function get() { - return _file_info3.selectFileInfosByOutpoint; - } -}); -Object.defineProperty(exports, 'selectIsFetchingFileList', { - enumerable: true, - get: function get() { - return _file_info3.selectIsFetchingFileList; - } -}); -Object.defineProperty(exports, 'selectIsFetchingFileListDownloadedOrPublished', { - enumerable: true, - get: function get() { - return _file_info3.selectIsFetchingFileListDownloadedOrPublished; - } -}); -Object.defineProperty(exports, 'selectDownloadingByOutpoint', { - enumerable: true, - get: function get() { - return _file_info3.selectDownloadingByOutpoint; - } -}); -Object.defineProperty(exports, 'selectUrisLoading', { - enumerable: true, - get: function get() { - return _file_info3.selectUrisLoading; - } -}); -Object.defineProperty(exports, 'selectFileInfosDownloaded', { - enumerable: true, - get: function get() { - return _file_info3.selectFileInfosDownloaded; - } -}); -Object.defineProperty(exports, 'selectDownloadingFileInfos', { - enumerable: true, - get: function get() { - return _file_info3.selectDownloadingFileInfos; - } -}); -Object.defineProperty(exports, 'selectTotalDownloadProgress', { - enumerable: true, - get: function get() { - return _file_info3.selectTotalDownloadProgress; - } -}); -Object.defineProperty(exports, 'selectSearchDownloadUris', { - enumerable: true, - get: function get() { - return _file_info3.selectSearchDownloadUris; - } -}); -Object.defineProperty(exports, 'selectFileListDownloadedSort', { - enumerable: true, - get: function get() { - return _file_info3.selectFileListDownloadedSort; - } -}); -Object.defineProperty(exports, 'selectFileListPublishedSort', { - enumerable: true, - get: function get() { - return _file_info3.selectFileListPublishedSort; - } -}); - -var _search3 = __webpack_require__(12); - -Object.defineProperty(exports, 'makeSelectSearchUris', { - enumerable: true, - get: function get() { - return _search3.makeSelectSearchUris; - } -}); -Object.defineProperty(exports, 'selectSearchValue', { - enumerable: true, - get: function get() { - return _search3.selectSearchValue; - } -}); -Object.defineProperty(exports, 'selectSearchOptions', { - enumerable: true, - get: function get() { - return _search3.selectSearchOptions; - } -}); -Object.defineProperty(exports, 'selectIsSearching', { - enumerable: true, - get: function get() { - return _search3.selectIsSearching; - } -}); -Object.defineProperty(exports, 'selectSearchUrisByQuery', { - enumerable: true, - get: function get() { - return _search3.selectSearchUrisByQuery; - } -}); -Object.defineProperty(exports, 'selectSearchBarFocused', { - enumerable: true, - get: function get() { - return _search3.selectSearchBarFocused; - } -}); -Object.defineProperty(exports, 'selectSearchSuggestions', { - enumerable: true, - get: function get() { - return _search3.selectSearchSuggestions; - } -}); -Object.defineProperty(exports, 'makeSelectQueryWithOptions', { - enumerable: true, - get: function get() { - return _search3.makeSelectQueryWithOptions; - } -}); - -var _wallet3 = __webpack_require__(18); - -Object.defineProperty(exports, 'makeSelectBlockDate', { - enumerable: true, - get: function get() { - return _wallet3.makeSelectBlockDate; - } -}); -Object.defineProperty(exports, 'selectBalance', { - enumerable: true, - get: function get() { - return _wallet3.selectBalance; - } -}); -Object.defineProperty(exports, 'selectTotalBalance', { - enumerable: true, - get: function get() { - return _wallet3.selectTotalBalance; - } -}); -Object.defineProperty(exports, 'selectTransactionsById', { - enumerable: true, - get: function get() { - return _wallet3.selectTransactionsById; - } -}); -Object.defineProperty(exports, 'selectTransactionItems', { - enumerable: true, - get: function get() { - return _wallet3.selectTransactionItems; - } -}); -Object.defineProperty(exports, 'selectRecentTransactions', { - enumerable: true, - get: function get() { - return _wallet3.selectRecentTransactions; - } -}); -Object.defineProperty(exports, 'selectHasTransactions', { - enumerable: true, - get: function get() { - return _wallet3.selectHasTransactions; - } -}); -Object.defineProperty(exports, 'selectIsFetchingTransactions', { - enumerable: true, - get: function get() { - return _wallet3.selectIsFetchingTransactions; - } -}); -Object.defineProperty(exports, 'selectIsSendingSupport', { - enumerable: true, - get: function get() { - return _wallet3.selectIsSendingSupport; - } -}); -Object.defineProperty(exports, 'selectReceiveAddress', { - enumerable: true, - get: function get() { - return _wallet3.selectReceiveAddress; - } -}); -Object.defineProperty(exports, 'selectGettingNewAddress', { - enumerable: true, - get: function get() { - return _wallet3.selectGettingNewAddress; - } -}); -Object.defineProperty(exports, 'selectDraftTransaction', { - enumerable: true, - get: function get() { - return _wallet3.selectDraftTransaction; - } -}); -Object.defineProperty(exports, 'selectDraftTransactionAmount', { - enumerable: true, - get: function get() { - return _wallet3.selectDraftTransactionAmount; - } -}); -Object.defineProperty(exports, 'selectDraftTransactionAddress', { - enumerable: true, - get: function get() { - return _wallet3.selectDraftTransactionAddress; - } -}); -Object.defineProperty(exports, 'selectDraftTransactionError', { - enumerable: true, - get: function get() { - return _wallet3.selectDraftTransactionError; - } -}); -Object.defineProperty(exports, 'selectBlocks', { - enumerable: true, - get: function get() { - return _wallet3.selectBlocks; - } -}); -Object.defineProperty(exports, 'selectWalletIsEncrypted', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletIsEncrypted; - } -}); -Object.defineProperty(exports, 'selectWalletState', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletState; - } -}); -Object.defineProperty(exports, 'selectWalletEncryptPending', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletEncryptPending; - } -}); -Object.defineProperty(exports, 'selectWalletEncryptSucceeded', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletEncryptSucceeded; - } -}); -Object.defineProperty(exports, 'selectWalletEncryptResult', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletEncryptResult; - } -}); -Object.defineProperty(exports, 'selectWalletDecryptPending', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletDecryptPending; - } -}); -Object.defineProperty(exports, 'selectWalletDecryptSucceeded', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletDecryptSucceeded; - } -}); -Object.defineProperty(exports, 'selectWalletDecryptResult', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletDecryptResult; - } -}); -Object.defineProperty(exports, 'selectWalletUnlockPending', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletUnlockPending; - } -}); -Object.defineProperty(exports, 'selectWalletUnlockSucceeded', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletUnlockSucceeded; - } -}); -Object.defineProperty(exports, 'selectWalletUnlockResult', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletUnlockResult; - } -}); -Object.defineProperty(exports, 'selectTransactionListFilter', { - enumerable: true, - get: function get() { - return _wallet3.selectTransactionListFilter; - } -}); - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _thumbnail_upload_statuses = __webpack_require__(39); - -var THUMBNAIL_STATUSES = _interopRequireWildcard(_thumbnail_upload_statuses); - -var _settings = __webpack_require__(40); - -var SETTINGS = _interopRequireWildcard(_settings); - -var _transaction_types = __webpack_require__(19); - -var TRANSACTIONS = _interopRequireWildcard(_transaction_types); - -var _sort_options = __webpack_require__(30); - -var SORT_OPTIONS = _interopRequireWildcard(_sort_options); - -var _pages = __webpack_require__(31); - -var PAGES = _interopRequireWildcard(_pages); - -var _search4 = __webpack_require__(13); - -var _lbry = __webpack_require__(8); - -var _lbry2 = _interopRequireDefault(_lbry); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -// types -// export { Toast } from 'types/Notification'; - -// constants -exports.ACTIONS = ACTIONS; -exports.THUMBNAIL_STATUSES = THUMBNAIL_STATUSES; -exports.SEARCH_TYPES = _search4.SEARCH_TYPES; -exports.SEARCH_OPTIONS = _search4.SEARCH_OPTIONS; -exports.SETTINGS = SETTINGS; -exports.TRANSACTIONS = TRANSACTIONS; -exports.SORT_OPTIONS = SORT_OPTIONS; -exports.PAGES = PAGES; - -// common - -exports.Lbry = _lbry2.default; -exports.selectSearchState = _search3.selectState; - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = 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; }; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -exports.parseURI = parseURI; -exports.buildURI = buildURI; -exports.normalizeURI = normalizeURI; -exports.isURIValid = isURIValid; -exports.isNameValid = isNameValid; -exports.isURIClaimable = isURIClaimable; -exports.convertToShareLink = convertToShareLink; -var channelNameMinLength = 1; -var claimIdMaxLength = 40; - -var regexInvalidURI = exports.regexInvalidURI = /[^A-Za-z0-9-]/g; -var regexAddress = exports.regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; - -/** - * Parses a LBRY name into its component parts. Throws errors with user-friendly - * messages for invalid names. - * - * N.B. that "name" indicates the value in the name position of the URI. For - * claims for channel content, this will actually be the channel name, and - * the content name is in the path (e.g. lbry://@channel/content) - * - * In most situations, you'll want to use the contentName and channelName keys - * and ignore the name key. - * - * Returns a dictionary with keys: - * - name (string): The value in the "name" position in the URI. Note that this - * could be either content name or channel name; see above. - * - path (string, if persent) - * - claimSequence (int, if present) - * - bidPosition (int, if present) - * - claimId (string, if present) - * - isChannel (boolean) - * - contentName (string): For anon claims, the name; for channel claims, the path - * - channelName (string, if present): Channel name without @ - */ -function parseURI(URI) { - var requireProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - // Break into components. Empty sub-matches are converted to null - var componentsRegex = new RegExp('^((?:lbry://)?)' + // protocol - '([^:$#/]*)' + // claim name (stops at the first separator or end) - '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) - '(/?)(.*)' // path separator, path - ); - - var _componentsRegex$exec = componentsRegex.exec(URI).slice(1).map(function (match) { - return match || null; - }), - _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 6), - proto = _componentsRegex$exec2[0], - claimName = _componentsRegex$exec2[1], - modSep = _componentsRegex$exec2[2], - modVal = _componentsRegex$exec2[3], - pathSep = _componentsRegex$exec2[4], - path = _componentsRegex$exec2[5]; - - var contentName = void 0; - - // Validate protocol - if (requireProto && !proto) { - throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); - } - - // Validate and process name - if (!claimName) { - throw new Error(__('URI does not include name.')); - } - - var isChannel = claimName.startsWith('@'); - var channelName = isChannel ? claimName.slice(1) : claimName; - - if (isChannel) { - if (!channelName) { - throw new Error(__('No channel name after @.')); - } - - if (channelName.length < channelNameMinLength) { - throw new Error(__('Channel names must be at least %s characters.', channelNameMinLength)); - } - - contentName = path; - } - - var nameBadChars = (channelName || claimName).match(regexInvalidURI); - if (nameBadChars) { - throw new Error(__('Invalid character %s in name: %s.', nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); - } - - // Validate and process modifier (claim ID, bid position or claim sequence) - var claimId = void 0; - var claimSequence = void 0; - var bidPosition = void 0; - if (modSep) { - if (!modVal) { - throw new Error(__('No modifier provided after separator %s.', modSep)); - } - - if (modSep === '#') { - claimId = modVal; - } else if (modSep === ':') { - claimSequence = modVal; - } else if (modSep === '$') { - bidPosition = modVal; - } - } - - if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__('Invalid claim ID %s.', claimId)); - } - - if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Claim sequence must be a number.')); - } - - if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Bid position must be a number.')); - } - - // Validate and process path - if (path) { - if (!isChannel) { - throw new Error(__('Only channel URIs may have a path.')); - } - - var pathBadChars = path.match(regexInvalidURI); - if (pathBadChars) { - throw new Error(__('Invalid character in path: %s', pathBadChars.join(', '))); - } - - contentName = path; - } else if (pathSep) { - throw new Error(__('No path provided after /')); - } - - return _extends({ - claimName: claimName, - path: path, - isChannel: isChannel - }, contentName ? { contentName: contentName } : {}, channelName ? { channelName: channelName } : {}, claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}, bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}, claimId ? { claimId: claimId } : {}, path ? { path: path } : {}); -} - -/** - * Takes an object in the same format returned by parse() and builds a URI. - * - * The channelName key will accept names with or without the @ prefix. - */ -function buildURI(URIObj) { - var includeProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var protoDefault = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'lbry://'; - var claimId = URIObj.claimId, - claimSequence = URIObj.claimSequence, - bidPosition = URIObj.bidPosition, - contentName = URIObj.contentName, - channelName = URIObj.channelName; - var claimName = URIObj.claimName, - path = URIObj.path; - - - if (channelName) { - var channelNameFormatted = channelName.startsWith('@') ? channelName : '@' + channelName; - if (!claimName) { - claimName = channelNameFormatted; - } else if (claimName !== channelNameFormatted) { - throw new Error(__('Received a channel content URI, but claim name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.')); - } - } - - if (contentName) { - if (!claimName) { - claimName = contentName; - } else if (!path) { - path = contentName; - } - if (path && path !== contentName) { - throw new Error(__('Path and contentName do not match. Only one is required; most likely you wanted contentName.')); - } - } - - return (includeProto ? protoDefault : '') + claimName + (claimId ? '#' + claimId : '') + (claimSequence ? ':' + claimSequence : '') + (bidPosition ? '' + bidPosition : '') + (path ? '/' + path : ''); -} - -/* Takes a parseable LBRY URI and converts it to standard, canonical format */ -function normalizeURI(URI) { - var _parseURI = parseURI(URI), - claimName = _parseURI.claimName, - path = _parseURI.path, - bidPosition = _parseURI.bidPosition, - claimSequence = _parseURI.claimSequence, - claimId = _parseURI.claimId; - - return buildURI({ claimName: claimName, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }); -} - -function isURIValid(URI) { - var parts = void 0; - try { - parts = parseURI(normalizeURI(URI)); - } catch (error) { - return false; - } - return parts && parts.claimName; -} - -function isNameValid(claimName) { - var checkCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - - var regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); - return regexp.test(claimName); -} - -function isURIClaimable(URI) { - var parts = void 0; - try { - parts = parseURI(normalizeURI(URI)); - } catch (error) { - return false; - } - return parts && parts.claimName && !parts.claimId && !parts.bidPosition && !parts.claimSequence && !parts.isChannel && !parts.path; -} - -function convertToShareLink(URI) { - var _parseURI2 = parseURI(URI), - claimName = _parseURI2.claimName, - path = _parseURI2.path, - bidPosition = _parseURI2.bidPosition, - claimSequence = _parseURI2.claimSequence, - claimId = _parseURI2.claimId; - - return buildURI({ claimName: claimName, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }, true, 'https://open.lbry.io/'); -} - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doToast = doToast; -exports.doDismissToast = doDismissToast; -exports.doError = doError; -exports.doDismissError = doDismissError; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _v = __webpack_require__(4); - -var _v2 = _interopRequireDefault(_v); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -// @flow -/*:: import type { ToastParams } from 'types/Notification';*/ -function doToast(params /*: ToastParams*/) { - if (!params) { - throw Error("'params' object is required to create a toast notification"); - } - - return { - type: ACTIONS.CREATE_TOAST, - data: { - id: (0, _v2.default)(), - params: params - } - }; -} - -function doDismissToast() { - return { - type: ACTIONS.DISMISS_TOAST - }; -} - -function doError(error /*: string | {}*/) { - return { - type: ACTIONS.CREATE_ERROR, - data: { - error: error - } - }; -} - -function doDismissError() { - return { - type: ACTIONS.DISMISS_ERROR - }; -} - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var WINDOW_FOCUSED = exports.WINDOW_FOCUSED = 'WINDOW_FOCUSED'; -var DAEMON_READY = exports.DAEMON_READY = 'DAEMON_READY'; -var DAEMON_VERSION_MATCH = exports.DAEMON_VERSION_MATCH = 'DAEMON_VERSION_MATCH'; -var DAEMON_VERSION_MISMATCH = exports.DAEMON_VERSION_MISMATCH = 'DAEMON_VERSION_MISMATCH'; -var VOLUME_CHANGED = exports.VOLUME_CHANGED = 'VOLUME_CHANGED'; - -// Navigation -var CHANGE_AFTER_AUTH_PATH = exports.CHANGE_AFTER_AUTH_PATH = 'CHANGE_AFTER_AUTH_PATH'; -var WINDOW_SCROLLED = exports.WINDOW_SCROLLED = 'WINDOW_SCROLLED'; -var HISTORY_NAVIGATE = exports.HISTORY_NAVIGATE = 'HISTORY_NAVIGATE'; - -// Upgrades -var UPGRADE_CANCELLED = exports.UPGRADE_CANCELLED = 'UPGRADE_CANCELLED'; -var DOWNLOAD_UPGRADE = exports.DOWNLOAD_UPGRADE = 'DOWNLOAD_UPGRADE'; -var UPGRADE_DOWNLOAD_STARTED = exports.UPGRADE_DOWNLOAD_STARTED = 'UPGRADE_DOWNLOAD_STARTED'; -var UPGRADE_DOWNLOAD_COMPLETED = exports.UPGRADE_DOWNLOAD_COMPLETED = 'UPGRADE_DOWNLOAD_COMPLETED'; -var UPGRADE_DOWNLOAD_PROGRESSED = exports.UPGRADE_DOWNLOAD_PROGRESSED = 'UPGRADE_DOWNLOAD_PROGRESSED'; -var CHECK_UPGRADE_AVAILABLE = exports.CHECK_UPGRADE_AVAILABLE = 'CHECK_UPGRADE_AVAILABLE'; -var CHECK_UPGRADE_START = exports.CHECK_UPGRADE_START = 'CHECK_UPGRADE_START'; -var CHECK_UPGRADE_SUCCESS = exports.CHECK_UPGRADE_SUCCESS = 'CHECK_UPGRADE_SUCCESS'; -var CHECK_UPGRADE_FAIL = exports.CHECK_UPGRADE_FAIL = 'CHECK_UPGRADE_FAIL'; -var CHECK_UPGRADE_SUBSCRIBE = exports.CHECK_UPGRADE_SUBSCRIBE = 'CHECK_UPGRADE_SUBSCRIBE'; -var UPDATE_VERSION = exports.UPDATE_VERSION = 'UPDATE_VERSION'; -var UPDATE_REMOTE_VERSION = exports.UPDATE_REMOTE_VERSION = 'UPDATE_REMOTE_VERSION'; -var SKIP_UPGRADE = exports.SKIP_UPGRADE = 'SKIP_UPGRADE'; -var START_UPGRADE = exports.START_UPGRADE = 'START_UPGRADE'; -var AUTO_UPDATE_DECLINED = exports.AUTO_UPDATE_DECLINED = 'AUTO_UPDATE_DECLINED'; -var AUTO_UPDATE_DOWNLOADED = exports.AUTO_UPDATE_DOWNLOADED = 'AUTO_UPDATE_DOWNLOADED'; -var CLEAR_UPGRADE_TIMER = exports.CLEAR_UPGRADE_TIMER = 'CLEAR_UPGRADE_TIMER'; - -// Wallet -var GET_NEW_ADDRESS_STARTED = exports.GET_NEW_ADDRESS_STARTED = 'GET_NEW_ADDRESS_STARTED'; -var GET_NEW_ADDRESS_COMPLETED = exports.GET_NEW_ADDRESS_COMPLETED = 'GET_NEW_ADDRESS_COMPLETED'; -var FETCH_TRANSACTIONS_STARTED = exports.FETCH_TRANSACTIONS_STARTED = 'FETCH_TRANSACTIONS_STARTED'; -var FETCH_TRANSACTIONS_COMPLETED = exports.FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'; -var UPDATE_BALANCE = exports.UPDATE_BALANCE = 'UPDATE_BALANCE'; -var UPDATE_TOTAL_BALANCE = exports.UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; -var CHECK_ADDRESS_IS_MINE_STARTED = exports.CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; -var CHECK_ADDRESS_IS_MINE_COMPLETED = exports.CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED'; -var SEND_TRANSACTION_STARTED = exports.SEND_TRANSACTION_STARTED = 'SEND_TRANSACTION_STARTED'; -var SEND_TRANSACTION_COMPLETED = exports.SEND_TRANSACTION_COMPLETED = 'SEND_TRANSACTION_COMPLETED'; -var SEND_TRANSACTION_FAILED = exports.SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'; -var FETCH_BLOCK_SUCCESS = exports.FETCH_BLOCK_SUCCESS = 'FETCH_BLOCK_SUCCESS'; -var SUPPORT_TRANSACTION_STARTED = exports.SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED'; -var SUPPORT_TRANSACTION_COMPLETED = exports.SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED'; -var SUPPORT_TRANSACTION_FAILED = exports.SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED'; -var WALLET_ENCRYPT_START = exports.WALLET_ENCRYPT_START = 'WALLET_ENCRYPT_START'; -var WALLET_ENCRYPT_COMPLETED = exports.WALLET_ENCRYPT_COMPLETED = 'WALLET_ENCRYPT_COMPLETED'; -var WALLET_ENCRYPT_FAILED = exports.WALLET_ENCRYPT_FAILED = 'WALLET_ENCRYPT_FAILED'; -var WALLET_UNLOCK_START = exports.WALLET_UNLOCK_START = 'WALLET_UNLOCK_START'; -var WALLET_UNLOCK_COMPLETED = exports.WALLET_UNLOCK_COMPLETED = 'WALLET_UNLOCK_COMPLETED'; -var WALLET_UNLOCK_FAILED = exports.WALLET_UNLOCK_FAILED = 'WALLET_UNLOCK_FAILED'; -var WALLET_DECRYPT_START = exports.WALLET_DECRYPT_START = 'WALLET_DECRYPT_START'; -var WALLET_DECRYPT_COMPLETED = exports.WALLET_DECRYPT_COMPLETED = 'WALLET_DECRYPT_COMPLETED'; -var WALLET_DECRYPT_FAILED = exports.WALLET_DECRYPT_FAILED = 'WALLET_DECRYPT_FAILED'; -var WALLET_LOCK_START = exports.WALLET_LOCK_START = 'WALLET_LOCK_START'; -var WALLET_LOCK_COMPLETED = exports.WALLET_LOCK_COMPLETED = 'WALLET_LOCK_COMPLETED'; -var WALLET_LOCK_FAILED = exports.WALLET_LOCK_FAILED = 'WALLET_LOCK_FAILED'; -var WALLET_STATUS_START = exports.WALLET_STATUS_START = 'WALLET_STATUS_START'; -var WALLET_STATUS_COMPLETED = exports.WALLET_STATUS_COMPLETED = 'WALLET_STATUS_COMPLETED'; -var SET_TRANSACTION_LIST_FILTER = exports.SET_TRANSACTION_LIST_FILTER = 'SET_TRANSACTION_LIST_FILTER'; -var UPDATE_CURRENT_HEIGHT = exports.UPDATE_CURRENT_HEIGHT = 'UPDATE_CURRENT_HEIGHT'; -var SET_DRAFT_TRANSACTION_AMOUNT = exports.SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; -var SET_DRAFT_TRANSACTION_ADDRESS = exports.SET_DRAFT_TRANSACTION_ADDRESS = 'SET_DRAFT_TRANSACTION_ADDRESS'; - -// Claims -var RESOLVE_URIS_STARTED = exports.RESOLVE_URIS_STARTED = 'RESOLVE_URIS_STARTED'; -var RESOLVE_URIS_COMPLETED = exports.RESOLVE_URIS_COMPLETED = 'RESOLVE_URIS_COMPLETED'; -var FETCH_CHANNEL_CLAIMS_STARTED = exports.FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED'; -var FETCH_CHANNEL_CLAIMS_COMPLETED = exports.FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED'; -var FETCH_CHANNEL_CLAIM_COUNT_STARTED = exports.FETCH_CHANNEL_CLAIM_COUNT_STARTED = 'FETCH_CHANNEL_CLAIM_COUNT_STARTED'; -var FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = exports.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = 'FETCH_CHANNEL_CLAIM_COUNT_COMPLETED'; -var FETCH_CLAIM_LIST_MINE_STARTED = exports.FETCH_CLAIM_LIST_MINE_STARTED = 'FETCH_CLAIM_LIST_MINE_STARTED'; -var FETCH_CLAIM_LIST_MINE_COMPLETED = exports.FETCH_CLAIM_LIST_MINE_COMPLETED = 'FETCH_CLAIM_LIST_MINE_COMPLETED'; -var ABANDON_CLAIM_STARTED = exports.ABANDON_CLAIM_STARTED = 'ABANDON_CLAIM_STARTED'; -var ABANDON_CLAIM_SUCCEEDED = exports.ABANDON_CLAIM_SUCCEEDED = 'ABANDON_CLAIM_SUCCEEDED'; -var FETCH_CHANNEL_LIST_STARTED = exports.FETCH_CHANNEL_LIST_STARTED = 'FETCH_CHANNEL_LIST_STARTED'; -var FETCH_CHANNEL_LIST_COMPLETED = exports.FETCH_CHANNEL_LIST_COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED'; -var CREATE_CHANNEL_STARTED = exports.CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED'; -var CREATE_CHANNEL_COMPLETED = exports.CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; -var PUBLISH_STARTED = exports.PUBLISH_STARTED = 'PUBLISH_STARTED'; -var PUBLISH_COMPLETED = exports.PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; -var PUBLISH_FAILED = exports.PUBLISH_FAILED = 'PUBLISH_FAILED'; -var SET_PLAYING_URI = exports.SET_PLAYING_URI = 'SET_PLAYING_URI'; -var SET_CONTENT_POSITION = exports.SET_CONTENT_POSITION = 'SET_CONTENT_POSITION'; -var SET_CONTENT_LAST_VIEWED = exports.SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED'; -var CLEAR_CONTENT_HISTORY_URI = exports.CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI'; -var CLEAR_CONTENT_HISTORY_ALL = exports.CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL'; - -// Files -var FILE_LIST_STARTED = exports.FILE_LIST_STARTED = 'FILE_LIST_STARTED'; -var FILE_LIST_SUCCEEDED = exports.FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; -var FETCH_FILE_INFO_STARTED = exports.FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'; -var FETCH_FILE_INFO_COMPLETED = exports.FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'; -var LOADING_VIDEO_STARTED = exports.LOADING_VIDEO_STARTED = 'LOADING_VIDEO_STARTED'; -var LOADING_VIDEO_COMPLETED = exports.LOADING_VIDEO_COMPLETED = 'LOADING_VIDEO_COMPLETED'; -var LOADING_VIDEO_FAILED = exports.LOADING_VIDEO_FAILED = 'LOADING_VIDEO_FAILED'; -var DOWNLOADING_STARTED = exports.DOWNLOADING_STARTED = 'DOWNLOADING_STARTED'; -var DOWNLOADING_PROGRESSED = exports.DOWNLOADING_PROGRESSED = 'DOWNLOADING_PROGRESSED'; -var DOWNLOADING_COMPLETED = exports.DOWNLOADING_COMPLETED = 'DOWNLOADING_COMPLETED'; -var DOWNLOADING_CANCELED = exports.DOWNLOADING_CANCELED = 'DOWNLOADING_CANCELED'; -var PLAY_VIDEO_STARTED = exports.PLAY_VIDEO_STARTED = 'PLAY_VIDEO_STARTED'; -var FETCH_AVAILABILITY_STARTED = exports.FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'; -var FETCH_AVAILABILITY_COMPLETED = exports.FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'; -var FILE_DELETE = exports.FILE_DELETE = 'FILE_DELETE'; -var SET_FILE_LIST_SORT = exports.SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; - -// Search -var SEARCH_START = exports.SEARCH_START = 'SEARCH_START'; -var SEARCH_SUCCESS = exports.SEARCH_SUCCESS = 'SEARCH_SUCCESS'; -var SEARCH_FAIL = exports.SEARCH_FAIL = 'SEARCH_FAIL'; -var UPDATE_SEARCH_QUERY = exports.UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY'; -var UPDATE_SEARCH_OPTIONS = exports.UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS'; -var UPDATE_SEARCH_SUGGESTIONS = exports.UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS'; -var SEARCH_FOCUS = exports.SEARCH_FOCUS = 'SEARCH_FOCUS'; -var SEARCH_BLUR = exports.SEARCH_BLUR = 'SEARCH_BLUR'; - -// Settings -var DAEMON_SETTINGS_RECEIVED = exports.DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; -var CLIENT_SETTING_CHANGED = exports.CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; -var UPDATE_IS_NIGHT = exports.UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT'; - -// User -var AUTHENTICATION_STARTED = exports.AUTHENTICATION_STARTED = 'AUTHENTICATION_STARTED'; -var AUTHENTICATION_SUCCESS = exports.AUTHENTICATION_SUCCESS = 'AUTHENTICATION_SUCCESS'; -var AUTHENTICATION_FAILURE = exports.AUTHENTICATION_FAILURE = 'AUTHENTICATION_FAILURE'; -var USER_EMAIL_DECLINE = exports.USER_EMAIL_DECLINE = 'USER_EMAIL_DECLINE'; -var USER_EMAIL_NEW_STARTED = exports.USER_EMAIL_NEW_STARTED = 'USER_EMAIL_NEW_STARTED'; -var USER_EMAIL_NEW_SUCCESS = exports.USER_EMAIL_NEW_SUCCESS = 'USER_EMAIL_NEW_SUCCESS'; -var USER_EMAIL_NEW_EXISTS = exports.USER_EMAIL_NEW_EXISTS = 'USER_EMAIL_NEW_EXISTS'; -var USER_EMAIL_NEW_FAILURE = exports.USER_EMAIL_NEW_FAILURE = 'USER_EMAIL_NEW_FAILURE'; -var USER_EMAIL_VERIFY_SET = exports.USER_EMAIL_VERIFY_SET = 'USER_EMAIL_VERIFY_SET'; -var USER_EMAIL_VERIFY_STARTED = exports.USER_EMAIL_VERIFY_STARTED = 'USER_EMAIL_VERIFY_STARTED'; -var USER_EMAIL_VERIFY_SUCCESS = exports.USER_EMAIL_VERIFY_SUCCESS = 'USER_EMAIL_VERIFY_SUCCESS'; -var USER_EMAIL_VERIFY_FAILURE = exports.USER_EMAIL_VERIFY_FAILURE = 'USER_EMAIL_VERIFY_FAILURE'; -var USER_EMAIL_VERIFY_RETRY = exports.USER_EMAIL_VERIFY_RETRY = 'USER_EMAIL_VERIFY_RETRY'; -var USER_PHONE_RESET = exports.USER_PHONE_RESET = 'USER_PHONE_RESET'; -var USER_PHONE_NEW_STARTED = exports.USER_PHONE_NEW_STARTED = 'USER_PHONE_NEW_STARTED'; -var USER_PHONE_NEW_SUCCESS = exports.USER_PHONE_NEW_SUCCESS = 'USER_PHONE_NEW_SUCCESS'; -var USER_PHONE_NEW_FAILURE = exports.USER_PHONE_NEW_FAILURE = 'USER_PHONE_NEW_FAILURE'; -var USER_PHONE_VERIFY_STARTED = exports.USER_PHONE_VERIFY_STARTED = 'USER_PHONE_VERIFY_STARTED'; -var USER_PHONE_VERIFY_SUCCESS = exports.USER_PHONE_VERIFY_SUCCESS = 'USER_PHONE_VERIFY_SUCCESS'; -var USER_PHONE_VERIFY_FAILURE = exports.USER_PHONE_VERIFY_FAILURE = 'USER_PHONE_VERIFY_FAILURE'; -var USER_IDENTITY_VERIFY_STARTED = exports.USER_IDENTITY_VERIFY_STARTED = 'USER_IDENTITY_VERIFY_STARTED'; -var USER_IDENTITY_VERIFY_SUCCESS = exports.USER_IDENTITY_VERIFY_SUCCESS = 'USER_IDENTITY_VERIFY_SUCCESS'; -var USER_IDENTITY_VERIFY_FAILURE = exports.USER_IDENTITY_VERIFY_FAILURE = 'USER_IDENTITY_VERIFY_FAILURE'; -var USER_FETCH_STARTED = exports.USER_FETCH_STARTED = 'USER_FETCH_STARTED'; -var USER_FETCH_SUCCESS = exports.USER_FETCH_SUCCESS = 'USER_FETCH_SUCCESS'; -var USER_FETCH_FAILURE = exports.USER_FETCH_FAILURE = 'USER_FETCH_FAILURE'; -var USER_INVITE_STATUS_FETCH_STARTED = exports.USER_INVITE_STATUS_FETCH_STARTED = 'USER_INVITE_STATUS_FETCH_STARTED'; -var USER_INVITE_STATUS_FETCH_SUCCESS = exports.USER_INVITE_STATUS_FETCH_SUCCESS = 'USER_INVITE_STATUS_FETCH_SUCCESS'; -var USER_INVITE_STATUS_FETCH_FAILURE = exports.USER_INVITE_STATUS_FETCH_FAILURE = 'USER_INVITE_STATUS_FETCH_FAILURE'; -var USER_INVITE_NEW_STARTED = exports.USER_INVITE_NEW_STARTED = 'USER_INVITE_NEW_STARTED'; -var USER_INVITE_NEW_SUCCESS = exports.USER_INVITE_NEW_SUCCESS = 'USER_INVITE_NEW_SUCCESS'; -var USER_INVITE_NEW_FAILURE = exports.USER_INVITE_NEW_FAILURE = 'USER_INVITE_NEW_FAILURE'; -var FETCH_ACCESS_TOKEN_SUCCESS = exports.FETCH_ACCESS_TOKEN_SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS'; - -// Rewards -var FETCH_REWARDS_STARTED = exports.FETCH_REWARDS_STARTED = 'FETCH_REWARDS_STARTED'; -var FETCH_REWARDS_COMPLETED = exports.FETCH_REWARDS_COMPLETED = 'FETCH_REWARDS_COMPLETED'; -var CLAIM_REWARD_STARTED = exports.CLAIM_REWARD_STARTED = 'CLAIM_REWARD_STARTED'; -var CLAIM_REWARD_SUCCESS = exports.CLAIM_REWARD_SUCCESS = 'CLAIM_REWARD_SUCCESS'; -var CLAIM_REWARD_FAILURE = exports.CLAIM_REWARD_FAILURE = 'CLAIM_REWARD_FAILURE'; -var CLAIM_REWARD_CLEAR_ERROR = exports.CLAIM_REWARD_CLEAR_ERROR = 'CLAIM_REWARD_CLEAR_ERROR'; -var FETCH_REWARD_CONTENT_COMPLETED = exports.FETCH_REWARD_CONTENT_COMPLETED = 'FETCH_REWARD_CONTENT_COMPLETED'; - -// Language -var DOWNLOAD_LANGUAGE_SUCCEEDED = exports.DOWNLOAD_LANGUAGE_SUCCEEDED = 'DOWNLOAD_LANGUAGE_SUCCEEDED'; -var DOWNLOAD_LANGUAGE_FAILED = exports.DOWNLOAD_LANGUAGE_FAILED = 'DOWNLOAD_LANGUAGE_FAILED'; - -// ShapeShift -var GET_SUPPORTED_COINS_START = exports.GET_SUPPORTED_COINS_START = 'GET_SUPPORTED_COINS_START'; -var GET_SUPPORTED_COINS_SUCCESS = exports.GET_SUPPORTED_COINS_SUCCESS = 'GET_SUPPORTED_COINS_SUCCESS'; -var GET_SUPPORTED_COINS_FAIL = exports.GET_SUPPORTED_COINS_FAIL = 'GET_SUPPORTED_COINS_FAIL'; -var GET_COIN_STATS_START = exports.GET_COIN_STATS_START = 'GET_COIN_STATS_START'; -var GET_COIN_STATS_SUCCESS = exports.GET_COIN_STATS_SUCCESS = 'GET_COIN_STATS_SUCCESS'; -var GET_COIN_STATS_FAIL = exports.GET_COIN_STATS_FAIL = 'GET_COIN_STATS_FAIL'; -var PREPARE_SHAPE_SHIFT_START = exports.PREPARE_SHAPE_SHIFT_START = 'PREPARE_SHAPE_SHIFT_START'; -var PREPARE_SHAPE_SHIFT_SUCCESS = exports.PREPARE_SHAPE_SHIFT_SUCCESS = 'PREPARE_SHAPE_SHIFT_SUCCESS'; -var PREPARE_SHAPE_SHIFT_FAIL = exports.PREPARE_SHAPE_SHIFT_FAIL = 'PREPARE_SHAPE_SHIFT_FAIL'; -var GET_ACTIVE_SHIFT_START = exports.GET_ACTIVE_SHIFT_START = 'GET_ACTIVE_SHIFT_START'; -var GET_ACTIVE_SHIFT_SUCCESS = exports.GET_ACTIVE_SHIFT_SUCCESS = 'GET_ACTIVE_SHIFT_SUCCESS'; -var GET_ACTIVE_SHIFT_FAIL = exports.GET_ACTIVE_SHIFT_FAIL = 'GET_ACTIVE_SHIFT_FAIL'; -var CLEAR_SHAPE_SHIFT = exports.CLEAR_SHAPE_SHIFT = 'CLEAR_SHAPE_SHIFT'; - -// Subscriptions -var CHANNEL_SUBSCRIBE = exports.CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE'; -var CHANNEL_UNSUBSCRIBE = exports.CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE'; -var HAS_FETCHED_SUBSCRIPTIONS = exports.HAS_FETCHED_SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS'; -var SET_SUBSCRIPTION_LATEST = exports.SET_SUBSCRIPTION_LATEST = 'SET_SUBSCRIPTION_LATEST'; -var SET_SUBSCRIPTION_NOTIFICATION = exports.SET_SUBSCRIPTION_NOTIFICATION = 'SET_SUBSCRIPTION_NOTIFICATION'; -var SET_SUBSCRIPTION_NOTIFICATIONS = exports.SET_SUBSCRIPTION_NOTIFICATIONS = 'SET_SUBSCRIPTION_NOTIFICATIONS'; -var CHECK_SUBSCRIPTION_STARTED = exports.CHECK_SUBSCRIPTION_STARTED = 'CHECK_SUBSCRIPTION_STARTED'; -var CHECK_SUBSCRIPTION_COMPLETED = exports.CHECK_SUBSCRIPTION_COMPLETED = 'CHECK_SUBSCRIPTION_COMPLETED'; -var CHECK_SUBSCRIPTIONS_SUBSCRIBE = exports.CHECK_SUBSCRIPTIONS_SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE'; - -// Publishing -var CLEAR_PUBLISH = exports.CLEAR_PUBLISH = 'CLEAR_PUBLISH'; -var UPDATE_PUBLISH_FORM = exports.UPDATE_PUBLISH_FORM = 'UPDATE_PUBLISH_FORM'; -var PUBLISH_START = exports.PUBLISH_START = 'PUBLISH_START'; -var PUBLISH_SUCCESS = exports.PUBLISH_SUCCESS = 'PUBLISH_SUCCESS'; -var PUBLISH_FAIL = exports.PUBLISH_FAIL = 'PUBLISH_FAIL'; -var CLEAR_PUBLISH_ERROR = exports.CLEAR_PUBLISH_ERROR = 'CLEAR_PUBLISH_ERROR'; -var REMOVE_PENDING_PUBLISH = exports.REMOVE_PENDING_PUBLISH = 'REMOVE_PENDING_PUBLISH'; -var DO_PREPARE_EDIT = exports.DO_PREPARE_EDIT = 'DO_PREPARE_EDIT'; - -// Notifications -var CREATE_NOTIFICATION = exports.CREATE_NOTIFICATION = 'CREATE_NOTIFICATION'; -var EDIT_NOTIFICATION = exports.EDIT_NOTIFICATION = 'EDIT_NOTIFICATION'; -var DELETE_NOTIFICATION = exports.DELETE_NOTIFICATION = 'DELETE_NOTIFICATION'; -var DISMISS_NOTIFICATION = exports.DISMISS_NOTIFICATION = 'DISMISS_NOTIFICATION'; -var CREATE_TOAST = exports.CREATE_TOAST = 'CREATE_TOAST'; -var DISMISS_TOAST = exports.DISMISS_TOAST = 'DISMISS_TOAST'; -var CREATE_ERROR = exports.CREATE_ERROR = 'CREATE_ERROR'; -var DISMISS_ERROR = exports.DISMISS_ERROR = 'DISMISS_ERROR'; - -var FETCH_DATE = exports.FETCH_DATE = 'FETCH_DATE'; - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -var rng = __webpack_require__(5); -var bytesToUuid = __webpack_require__(6); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - - -/***/ }), -/* 5 */ -/***/ (function(module, exports) { - -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - - -/***/ }), -/* 6 */ -/***/ (function(module, exports) { - -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -exports.doResolveUris = doResolveUris; -exports.doResolveUri = doResolveUri; -exports.doFetchClaimListMine = doFetchClaimListMine; -exports.doAbandonClaim = doAbandonClaim; -exports.doFetchClaimsByChannel = doFetchClaimsByChannel; -exports.doFetchClaimCountByChannel = doFetchClaimCountByChannel; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbry = __webpack_require__(8); - -var _lbry2 = _interopRequireDefault(_lbry); - -var _lbryURI = __webpack_require__(1); - -var _notifications = __webpack_require__(2); - -var _claims = __webpack_require__(11); - -var _wallet = __webpack_require__(17); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -function doResolveUris(uris) { - var returnCachedClaims = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - return function (dispatch, getState) { - var normalizedUris = uris.map(_lbryURI.normalizeURI); - var state = getState(); - - var resolvingUris = (0, _claims.selectResolvingUris)(state); - var claimsByUri = (0, _claims.selectClaimsByUri)(state); - var urisToResolve = normalizedUris.filter(function (uri) { - if (resolvingUris.includes(uri)) { - return false; - } - - return returnCachedClaims ? !claimsByUri[uri] : true; - }); - - if (urisToResolve.length === 0) { - return; - } - - dispatch({ - type: ACTIONS.RESOLVE_URIS_STARTED, - data: { uris: normalizedUris } - }); - - var resolveInfo = {}; - _lbry2.default.resolve({ urls: urisToResolve }).then(function (result) { - Object.entries(result).forEach(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - uri = _ref2[0], - uriResolveInfo = _ref2[1]; - - var fallbackResolveInfo = { - claim: null, - claimsInChannel: null, - certificate: null - }; - - var _ref3 = uriResolveInfo && !uriResolveInfo.error ? uriResolveInfo : fallbackResolveInfo, - claim = _ref3.claim, - certificate = _ref3.certificate, - claimsInChannel = _ref3.claims_in_channel; - - resolveInfo[uri] = { claim: claim, certificate: certificate, claimsInChannel: claimsInChannel }; - }); - - dispatch({ - type: ACTIONS.RESOLVE_URIS_COMPLETED, - data: { resolveInfo: resolveInfo } - }); - }); - }; -} - -function doResolveUri(uri) { - return doResolveUris([uri]); -} - -function doFetchClaimListMine() { - return function (dispatch) { - dispatch({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED - }); - - _lbry2.default.claim_list_mine().then(function (claims) { - dispatch({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims: claims - } - }); - }); - }; -} - -function doAbandonClaim(txid, nout) { - return function (dispatch, getState) { - var state = getState(); - var myClaims = (0, _claims.selectMyClaimsRaw)(state); - - var _myClaims$find = myClaims.find(function (claim) { - return claim.txid === txid && claim.nout === nout; - }), - claimId = _myClaims$find.claim_id; - - dispatch({ - type: ACTIONS.ABANDON_CLAIM_STARTED, - data: { - claimId: claimId - } - }); - - var errorCallback = function errorCallback() { - dispatch((0, _notifications.doToast)({ - message: 'Transaction failed', - isError: true - })); - }; - - var successCallback = function successCallback(results) { - if (results.success === true) { - dispatch({ - type: ACTIONS.ABANDON_CLAIM_SUCCEEDED, - data: { - claimId: claimId - } - }); - dispatch((0, _notifications.doToast)({ - message: 'Successfully abandoned your claim' - })); - - // After abandoning, call claim_list_mine to show the claim as abandoned - // Also fetch transactions to show the new abandon transaction - dispatch(doFetchClaimListMine()); - dispatch((0, _wallet.doFetchTransactions)()); - } else { - dispatch((0, _notifications.doToast)({ - message: 'Error abandoning claim', - isError: true - })); - } - }; - - _lbry2.default.claim_abandon({ - txid: txid, - nout: nout - }).then(successCallback, errorCallback); - }; -} - -function doFetchClaimsByChannel(uri, page) { - return function (dispatch) { - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIMS_STARTED, - data: { uri: uri, page: page } - }); - - _lbry2.default.claim_list_by_channel({ uri: uri, page: page || 1 }).then(function (result) { - var claimResult = result[uri] || {}; - var claimsInChannel = claimResult.claims_in_channel, - returnedPage = claimResult.returned_page; - - - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, - data: { - uri: uri, - claims: claimsInChannel || [], - page: returnedPage || undefined - } - }); - }); - }; -} - -function doFetchClaimCountByChannel(uri) { - return function (dispatch) { - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_STARTED, - data: { uri: uri } - }); - - _lbry2.default.claim_list_by_channel({ uri: uri }).then(function (result) { - var claimResult = result[uri]; - var totalClaims = claimResult ? claimResult.claims_in_channel : 0; - - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED, - data: { - uri: uri, - totalClaims: totalClaims - } - }); - }); - }; -} - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // @flow - - -__webpack_require__(9); - -var CHECK_DAEMON_STARTED_TRY_NUMBER = 200; - -var Lbry = { - isConnected: false, - daemonConnectionString: 'http://localhost:5279', - pendingPublishTimeout: 20 * 60 * 1000 -}; - -function checkAndParse(response) { - if (response.status >= 200 && response.status < 300) { - return response.json(); - } - return response.json().then(function (json) { - var error = void 0; - if (json.error) { - var errorMessage = _typeof(json.error) === 'object' ? json.error.message : json.error; - error = new Error(errorMessage); - } else { - error = new Error('Protocol error with unknown response signature'); - } - return Promise.reject(error); - }); -} - -function apiCall(method /*: string*/, params /*: ?{}*/, resolve /*: Function*/, reject /*: Function*/) { - var counter = new Date().getTime(); - var options = { - method: 'POST', - body: JSON.stringify({ - jsonrpc: '2.0', - method: method, - params: params, - id: counter - }) - }; - - return fetch(Lbry.daemonConnectionString, options).then(checkAndParse).then(function (response) { - var error = response.error || response.result && response.result.error; - - if (error) { - return reject(error); - } - return resolve(response.result); - }).catch(reject); -} - -var daemonCallWithResult = function daemonCallWithResult(name) { - var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - return new Promise(function (resolve, reject) { - apiCall(name, params, function (result) { - resolve(result); - }, reject); - }); -}; - -// blobs -Lbry.blob_delete = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('blob_delete', params); -}; -Lbry.blob_list = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('blob_list', params); -}; - -// core -Lbry.status = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('status', params); -}; -Lbry.version = function () { - return daemonCallWithResult('version', {}); -}; -Lbry.file_delete = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('file_delete', params); -}; -Lbry.file_set_status = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('file_set_status', params); -}; -Lbry.stop = function () { - return daemonCallWithResult('stop', {}); -}; - -// claims -Lbry.claim_list_by_channel = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('claim_list_by_channel', params); -}; - -// wallet -Lbry.account_balance = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('account_balance', params); -}; -Lbry.account_decrypt = function () { - return daemonCallWithResult('account_decrypt', {}); -}; -Lbry.account_encrypt = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('account_encrypt', params); -}; -Lbry.account_list = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('account_list', params); -}; -Lbry.address_is_mine = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('address_is_mine', params); -}; -Lbry.wallet_lock = function () { - return daemonCallWithResult('wallet_lock', {}); -}; -Lbry.address_unused = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('address_unused', params); -}; -Lbry.wallet_send = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('wallet_send', params); -}; -Lbry.account_unlock = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('account_unlock', params); -}; -Lbry.address_unused = function () { - return daemonCallWithResult('address_unused', {}); -}; -Lbry.claim_tip = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('claim_tip', params); -}; - -// transactions -Lbry.transaction_list = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('transaction_list', params); -}; -Lbry.utxo_release = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('utxo_release', params); -}; - -// sync -Lbry.sync_hash = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('sync_hash', params); -}; -Lbry.sync_apply = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('sync_apply', params); -}; - -Lbry.connectPromise = null; -Lbry.connect = function () { - if (Lbry.connectPromise === null) { - Lbry.connectPromise = new Promise(function (resolve, reject) { - var tryNum = 0; - // Check every half second to see if the daemon is accepting connections - function checkDaemonStarted() { - tryNum += 1; - Lbry.status().then(resolve).catch(function () { - if (tryNum <= CHECK_DAEMON_STARTED_TRY_NUMBER) { - setTimeout(checkDaemonStarted, tryNum < 50 ? 400 : 1000); - } else { - reject(new Error('Unable to connect to LBRY')); - } - }); - } - - checkDaemonStarted(); - }); - } - - return Lbry.connectPromise; -}; - -Lbry.getMediaType = function (contentType, extname) { - if (extname) { - var formats = [[/^(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/^(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/^(html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org)$/i, 'document'], [/^(stl|obj|fbx|gcode)$/i, '3D-file']]; - var res = formats.reduce(function (ret, testpair) { - switch (testpair[0].test(ret)) { - case true: - return testpair[1]; - default: - return ret; - } - }, extname); - return res === extname ? 'unknown' : res; - } else if (contentType) { - return (/^[^/]+/.exec(contentType)[0] - ); - } - return 'unknown'; -}; - -/** - * Wrappers for API methods to simulate missing or future behavior. Unlike the old-style stubs, - * these are designed to be transparent wrappers around the corresponding API methods. - */ - -/** - * Returns results from the file_list API method, plus dummy entries for pending publishes. - * (If a real publish with the same name is found, the pending publish will be ignored and removed.) - */ -Lbry.file_list = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall('file_list', params, function (fileInfos) { - resolve(fileInfos); - }, reject); - }); -}; - -Lbry.claim_list_mine = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall('claim_list_mine', params, function (claims) { - resolve(claims); - }, reject); - }); -}; - -Lbry.get = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall('get', params, function (streamInfo) { - resolve(streamInfo); - }, reject); - }); -}; - -Lbry.resolve = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall('resolve', params, function (data) { - resolve(data || {}); - }, reject); - }); -}; - -Lbry.publish = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - if (Lbry.overrides.publish) { - Lbry.overrides.publish(params).then(resolve, reject); - } else { - apiCall('publish', params, resolve, reject); - } - }); -}; - -// Allow overriding Lbry methods -Lbry.overrides = {}; -Lbry.setOverride = function (methodName, newMethod) { - Lbry.overrides[methodName] = newMethod; -}; - -// Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) -Lbry.setDaemonConnectionString = function (value) { - Lbry.daemonConnectionString = value; -}; - -var lbryProxy = new Proxy(Lbry, { - get: function get(target, name) { - if (name in target) { - return target[name]; - } - - return function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall(name, params, resolve, reject); - }); - }; - } -}); - -exports.default = lbryProxy; - -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(global) {/* - * Copyright 2016 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - - - - -(function(scope) { - if (scope['Proxy']) { - return; - } - let lastRevokeFn = null; - - /** - * @param {*} o - * @return {boolean} whether this is probably a (non-null) Object - */ - function isObject(o) { - return o ? (typeof o == 'object' || typeof o == 'function') : false; - } - - /** - * @constructor - * @param {!Object} target - * @param {{apply, construct, get, set}} handler - */ - scope.Proxy = function(target, handler) { - if (!isObject(target) || !isObject(handler)) { - throw new TypeError('Cannot create proxy with a non-object as target or handler'); - } - - // Construct revoke function, and set lastRevokeFn so that Proxy.revocable can steal it. - // The caller might get the wrong revoke function if a user replaces or wraps scope.Proxy - // to call itself, but that seems unlikely especially when using the polyfill. - let throwRevoked = function() {}; - lastRevokeFn = function() { - throwRevoked = function(trap) { - throw new TypeError(`Cannot perform '${trap}' on a proxy that has been revoked`); - }; - }; - - // Fail on unsupported traps: Chrome doesn't do this, but ensure that users of the polyfill - // are a bit more careful. Copy the internal parts of handler to prevent user changes. - let unsafeHandler = handler; - handler = {'get': null, 'set': null, 'apply': null, 'construct': null}; - for (let k in unsafeHandler) { - if (!(k in handler)) { - throw new TypeError(`Proxy polyfill does not support trap '${k}'`); - } - handler[k] = unsafeHandler[k]; - } - if (typeof unsafeHandler == 'function') { - // Allow handler to be a function (which has an 'apply' method). This matches what is - // probably a bug in native versions. It treats the apply call as a trap to be configured. - handler.apply = unsafeHandler.apply.bind(unsafeHandler); - } - - // Define proxy as this, or a Function (if either it's callable, or apply is set). - // TODO(samthor): Closure compiler doesn't know about 'construct', attempts to rename it. - let proxy = this; - let isMethod = false; - let targetIsFunction = typeof target == 'function'; - if (handler.apply || handler['construct'] || targetIsFunction) { - proxy = function Proxy() { - let usingNew = (this && this.constructor === proxy); - throwRevoked(usingNew ? 'construct' : 'apply'); - - if (usingNew && handler['construct']) { - return handler['construct'].call(this, target, arguments); - } else if (!usingNew && handler.apply) { - return handler.apply(target, this, arguments); - } else if (targetIsFunction) { - // since the target was a function, fallback to calling it directly. - if (usingNew) { - // inspired by answers to https://stackoverflow.com/q/1606797 - let all = Array.prototype.slice.call(arguments); - all.unshift(target); // pass class as first arg to constructor, although irrelevant - // nb. cast to convince Closure compiler that this is a constructor - let f = /** @type {!Function} */ (target.bind.apply(target, all)); - return new f(); - } - return target.apply(this, arguments); - } - throw new TypeError(usingNew ? 'not a constructor' : 'not a function'); - }; - isMethod = true; - } - - // Create default getters/setters. Create different code paths as handler.get/handler.set can't - // change after creation. - let getter = handler.get ? function(prop) { - throwRevoked('get'); - return handler.get(this, prop, proxy); - } : function(prop) { - throwRevoked('get'); - return this[prop]; - }; - let setter = handler.set ? function(prop, value) { - throwRevoked('set'); - let status = handler.set(this, prop, value, proxy); - if (!status) { - // TODO(samthor): If the calling code is in strict mode, throw TypeError. - // It's (sometimes) possible to work this out, if this code isn't strict- try to load the - // callee, and if it's available, that code is non-strict. However, this isn't exhaustive. - } - } : function(prop, value) { - throwRevoked('set'); - this[prop] = value; - }; - - // Clone direct properties (i.e., not part of a prototype). - let propertyNames = Object.getOwnPropertyNames(target); - let propertyMap = {}; - propertyNames.forEach(function(prop) { - if (isMethod && prop in proxy) { - return; // ignore properties already here, e.g. 'bind', 'prototype' etc - } - let real = Object.getOwnPropertyDescriptor(target, prop); - let desc = { - enumerable: !!real.enumerable, - get: getter.bind(target, prop), - set: setter.bind(target, prop), - }; - Object.defineProperty(proxy, prop, desc); - propertyMap[prop] = true; - }); - - // Set the prototype, or clone all prototype methods (always required if a getter is provided). - // TODO(samthor): We don't allow prototype methods to be set. It's (even more) awkward. - // An alternative here would be to _just_ clone methods to keep behavior consistent. - let prototypeOk = true; - if (Object.setPrototypeOf) { - Object.setPrototypeOf(proxy, Object.getPrototypeOf(target)); - } else if (proxy.__proto__) { - proxy.__proto__ = target.__proto__; - } else { - prototypeOk = false; - } - if (handler.get || !prototypeOk) { - for (let k in target) { - if (propertyMap[k]) { - continue; - } - Object.defineProperty(proxy, k, {get: getter.bind(target, k)}); - } - } - - // The Proxy polyfill cannot handle adding new properties. Seal the target and proxy. - Object.seal(target); - Object.seal(proxy); - - return proxy; // nb. if isMethod is true, proxy != this - }; - - scope.Proxy.revocable = function(target, handler) { - let p = new scope.Proxy(target, handler); - return {'proxy': p, 'revoke': lastRevokeFn}; - }; - - scope.Proxy['revocable'] = scope.Proxy.revocable; - scope['Proxy'] = scope.Proxy; -})(typeof module !== 'undefined' && module['exports'] ? global : window); - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(10))) - -/***/ }), -/* 10 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || Function("return this")() || (1, eval)("this"); -} catch (e) { - // This works if the window reference is available - if (typeof window === "object") g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.makeSelectChannelForClaimUri = exports.makeSelectFirstRecommendedFileForUri = exports.makeSelectRecommendedContentForUri = exports.makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountFromUris = exports.makeSelectTotalPagesForChannel = exports.makeSelectTotalItemsForChannel = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.makeSelectIsUriResolving = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectIsFetchingClaimListMine = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectClaimsInChannelForPage = exports.makeSelectFetchingChannelClaims = exports.selectAllFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.makeSelectClaimForUri = exports.makeSelectPendingByUri = exports.makeSelectClaimIsPending = exports.selectPendingClaims = exports.selectPendingById = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectCurrentChannelPage = exports.selectClaimsById = undefined; - -var _lbryURI = __webpack_require__(1); - -var _search = __webpack_require__(12); - -var _reselect = __webpack_require__(15); - -var _claim = __webpack_require__(16); - -var _query_params = __webpack_require__(14); - -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); } } - -var selectState = function selectState(state) { - return state.claims || {}; -}; - -var selectClaimsById = exports.selectClaimsById = (0, _reselect.createSelector)(selectState, function (state) { - return state.byId || {}; -}); - -var selectCurrentChannelPage = exports.selectCurrentChannelPage = (0, _reselect.createSelector)(selectState, function (state) { - return state.currentChannelPage || 1; -}); - -var selectClaimsByUri = exports.selectClaimsByUri = (0, _reselect.createSelector)(selectState, selectClaimsById, function (state, byId) { - var byUri = state.claimsByUri || {}; - var claims = {}; - - Object.keys(byUri).forEach(function (uri) { - var claimId = byUri[uri]; - - // NOTE returning a null claim allows us to differentiate between an - // undefined (never fetched claim) and one which just doesn't exist. Not - // the cleanest solution but couldn't think of anything better right now - if (claimId === null) { - claims[uri] = null; - } else { - claims[uri] = byId[claimId]; - } - }); - - return claims; -}); - -var selectAllClaimsByChannel = exports.selectAllClaimsByChannel = (0, _reselect.createSelector)(selectState, function (state) { - return state.claimsByChannel || {}; -}); - -var selectPendingById = exports.selectPendingById = (0, _reselect.createSelector)(selectState, function (state) { - return state.pendingById || {}; -}); - -var selectPendingClaims = exports.selectPendingClaims = (0, _reselect.createSelector)(selectState, function (state) { - return Object.values(state.pendingById || []); -}); - -var makeSelectClaimIsPending = exports.makeSelectClaimIsPending = function makeSelectClaimIsPending(uri) { - return (0, _reselect.createSelector)(selectPendingById, function (pendingById) { - var _parseURI = (0, _lbryURI.parseURI)(uri), - claimId = _parseURI.claimId; - - return Boolean(pendingById[claimId]); - }); -}; - -var makeSelectPendingByUri = exports.makeSelectPendingByUri = function makeSelectPendingByUri(uri) { - return (0, _reselect.createSelector)(selectPendingById, function (pendingById) { - var _parseURI2 = (0, _lbryURI.parseURI)(uri), - claimId = _parseURI2.claimId; - - return pendingById[claimId]; - }); -}; - -var makeSelectClaimForUri = exports.makeSelectClaimForUri = function makeSelectClaimForUri(uri) { - return (0, _reselect.createSelector)(selectClaimsByUri, selectPendingById, function (byUri, pendingById) { - // Check if a claim is pending first - // It won't be in claimsByUri because resolving it will return nothing - var _parseURI3 = (0, _lbryURI.parseURI)(uri), - claimId = _parseURI3.claimId; - - var pendingClaim = pendingById[claimId]; - if (pendingClaim) { - return pendingClaim; - } - - return byUri && byUri[(0, _lbryURI.normalizeURI)(uri)]; - }); -}; - -var selectMyClaimsRaw = exports.selectMyClaimsRaw = (0, _reselect.createSelector)(selectState, function (state) { - return state.myClaims; -}); - -var selectAbandoningIds = exports.selectAbandoningIds = (0, _reselect.createSelector)(selectState, function (state) { - return Object.keys(state.abandoningById || {}); -}); - -var selectMyActiveClaims = exports.selectMyActiveClaims = (0, _reselect.createSelector)(selectMyClaimsRaw, selectAbandoningIds, function (claims, abandoningIds) { - return new Set(claims && claims.map(function (claim) { - return claim.claim_id; - }).filter(function (claimId) { - return Object.keys(abandoningIds).indexOf(claimId) === -1; - })); -}); - -var makeSelectClaimIsMine = exports.makeSelectClaimIsMine = function makeSelectClaimIsMine(rawUri) { - var uri = (0, _lbryURI.normalizeURI)(rawUri); - return (0, _reselect.createSelector)(selectClaimsByUri, selectMyActiveClaims, function (claims, myClaims) { - return claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); - }); -}; - -var selectAllFetchingChannelClaims = exports.selectAllFetchingChannelClaims = (0, _reselect.createSelector)(selectState, function (state) { - return state.fetchingChannelClaims || {}; -}); - -var makeSelectFetchingChannelClaims = exports.makeSelectFetchingChannelClaims = function makeSelectFetchingChannelClaims(uri) { - return (0, _reselect.createSelector)(selectAllFetchingChannelClaims, function (fetching) { - return fetching && fetching[uri]; - }); -}; - -var makeSelectClaimsInChannelForPage = exports.makeSelectClaimsInChannelForPage = function makeSelectClaimsInChannelForPage(uri, page) { - return (0, _reselect.createSelector)(selectClaimsById, selectAllClaimsByChannel, function (byId, allClaims) { - var byChannel = allClaims[uri] || {}; - var claimIds = byChannel[page || 1]; - - if (!claimIds) return claimIds; - - return claimIds.map(function (claimId) { - return byId[claimId]; - }); - }); -}; - -var makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectClaimsInChannelForCurrentPageState = function makeSelectClaimsInChannelForCurrentPageState(uri) { - return (0, _reselect.createSelector)(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, function (byId, allClaims, page) { - var byChannel = allClaims[uri] || {}; - var claimIds = byChannel[page || 1]; - - if (!claimIds) return claimIds; - - return claimIds.map(function (claimId) { - return byId[claimId]; - }); - }); -}; - -var makeSelectMetadataForUri = exports.makeSelectMetadataForUri = function makeSelectMetadataForUri(uri) { - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { - var metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata; - - return metadata || (claim === undefined ? undefined : null); - }); -}; - -var makeSelectTitleForUri = exports.makeSelectTitleForUri = function makeSelectTitleForUri(uri) { - return (0, _reselect.createSelector)(makeSelectMetadataForUri(uri), function (metadata) { - return metadata && metadata.title; - }); -}; - -var makeSelectContentTypeForUri = exports.makeSelectContentTypeForUri = function makeSelectContentTypeForUri(uri) { - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { - var source = claim && claim.value && claim.value.stream && claim.value.stream.source; - return source ? source.contentType : undefined; - }); -}; - -var selectIsFetchingClaimListMine = exports.selectIsFetchingClaimListMine = (0, _reselect.createSelector)(selectState, function (state) { - return state.isFetchingClaimListMine; -}); - -var selectMyClaims = exports.selectMyClaims = (0, _reselect.createSelector)(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, function (myClaimIds, byId, abandoningIds, pendingClaims) { - var claims = []; - - myClaimIds.forEach(function (id) { - var claim = byId[id]; - - if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); - }); - - return [].concat(claims, _toConsumableArray(pendingClaims)); -}); - -var selectMyClaimsWithoutChannels = exports.selectMyClaimsWithoutChannels = (0, _reselect.createSelector)(selectMyClaims, function (myClaims) { - return myClaims.filter(function (claim) { - return !claim.name.match(/^@/); - }); -}); - -var selectAllMyClaimsByOutpoint = exports.selectAllMyClaimsByOutpoint = (0, _reselect.createSelector)(selectMyClaimsRaw, function (claims) { - return new Set(claims && claims.length ? claims.map(function (claim) { - return claim.txid + ':' + claim.nout; - }) : null); -}); - -var selectMyClaimsOutpoints = exports.selectMyClaimsOutpoints = (0, _reselect.createSelector)(selectMyClaims, function (myClaims) { - var outpoints = []; - - myClaims.forEach(function (claim) { - return outpoints.push(claim.txid + ':' + claim.nout); - }); - - return outpoints; -}); - -var selectFetchingMyChannels = exports.selectFetchingMyChannels = (0, _reselect.createSelector)(selectState, function (state) { - return state.fetchingMyChannels; -}); - -var selectMyChannelClaims = exports.selectMyChannelClaims = (0, _reselect.createSelector)(selectState, selectClaimsById, function (state, byId) { - var ids = state.myChannelClaims || []; - var claims = []; - - ids.forEach(function (id) { - if (byId[id]) { - // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544 - claims.push(byId[id]); - } - }); - - return claims; -}); - -var selectResolvingUris = exports.selectResolvingUris = (0, _reselect.createSelector)(selectState, function (state) { - return state.resolvingUris || []; -}); - -var makeSelectIsUriResolving = exports.makeSelectIsUriResolving = function makeSelectIsUriResolving(uri) { - return (0, _reselect.createSelector)(selectResolvingUris, function (resolvingUris) { - return resolvingUris && resolvingUris.indexOf(uri) !== -1; - }); -}; - -var selectPlayingUri = exports.selectPlayingUri = (0, _reselect.createSelector)(selectState, function (state) { - return state.playingUri; -}); - -var selectChannelClaimCounts = exports.selectChannelClaimCounts = (0, _reselect.createSelector)(selectState, function (state) { - return state.channelClaimCounts || {}; -}); - -var makeSelectTotalItemsForChannel = exports.makeSelectTotalItemsForChannel = function makeSelectTotalItemsForChannel(uri) { - return (0, _reselect.createSelector)(selectChannelClaimCounts, function (byUri) { - return byUri && byUri[uri]; - }); -}; - -var makeSelectTotalPagesForChannel = exports.makeSelectTotalPagesForChannel = function makeSelectTotalPagesForChannel(uri) { - var pageSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; - return (0, _reselect.createSelector)(selectChannelClaimCounts, function (byUri) { - return byUri && byUri[uri] && Math.ceil(byUri[uri] / pageSize); - }); -}; - -var makeSelectNsfwCountFromUris = exports.makeSelectNsfwCountFromUris = function makeSelectNsfwCountFromUris(uris) { - return (0, _reselect.createSelector)(selectClaimsByUri, function (claims) { - return uris.reduce(function (acc, uri) { - var claim = claims[uri]; - if ((0, _claim.isClaimNsfw)(claim)) { - return acc + 1; - } - return acc; - }, 0); - }); -}; - -var makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountForChannel = function makeSelectNsfwCountForChannel(uri) { - return (0, _reselect.createSelector)(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, function (byId, allClaims, page) { - var byChannel = allClaims[uri] || {}; - var claimIds = byChannel[page || 1]; - - if (!claimIds) return 0; - - return claimIds.reduce(function (acc, claimId) { - var claim = byId[claimId]; - if ((0, _claim.isClaimNsfw)(claim)) { - return acc + 1; - } - return acc; - }, 0); - }); -}; - -var makeSelectRecommendedContentForUri = exports.makeSelectRecommendedContentForUri = function makeSelectRecommendedContentForUri(uri) { - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), _search.selectSearchUrisByQuery, function (claim, searchUrisByQuery) { - var atVanityURI = !uri.includes('#'); - - var recommendedContent = void 0; - if (claim) { - // If we are at a vanity uri, build the full uri so we can properly filter - var currentUri = atVanityURI ? (0, _lbryURI.buildURI)({ claimId: claim.claim_id, claimName: claim.name }) : uri; - - var title = claim.value.stream.metadata.title; - - - var searchQuery = (0, _query_params.getSearchQueryString)(title.replace(/\//, ' ')); - - var searchUris = searchUrisByQuery[searchQuery]; - if (searchUris) { - searchUris = searchUris.filter(function (searchUri) { - return searchUri !== currentUri; - }); - recommendedContent = searchUris; - } - } - - return recommendedContent; - }); -}; - -var makeSelectFirstRecommendedFileForUri = exports.makeSelectFirstRecommendedFileForUri = function makeSelectFirstRecommendedFileForUri(uri) { - return (0, _reselect.createSelector)(makeSelectRecommendedContentForUri(uri), function (recommendedContent) { - return recommendedContent ? recommendedContent[0] : null; - }); -}; - -// Returns the associated channel uri for a given claim uri -var makeSelectChannelForClaimUri = exports.makeSelectChannelForClaimUri = function makeSelectChannelForClaimUri(uri) { - var includePrefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { - if (!claim) { - return null; - } - - var channelName = claim.channel_name, - value = claim.value; - - var channelClaimId = value && value.publisherSignature && value.publisherSignature.certificateId; - - return channelName && channelClaimId ? (0, _lbryURI.buildURI)({ channelName: channelName, claimId: channelClaimId }, includePrefix) : null; - }); -}; - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.makeSelectQueryWithOptions = exports.selectSearchSuggestions = exports.selectSearchBarFocused = exports.makeSelectSearchUris = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSuggestions = exports.selectSearchOptions = exports.selectSearchValue = exports.selectState = undefined; - -var _extends = 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; }; - -var _search = __webpack_require__(13); - -var _query_params = __webpack_require__(14); - -var _lbryURI = __webpack_require__(1); - -var _reselect = __webpack_require__(15); - -// @flow -/*:: import type { SearchState, SearchOptions, SearchSuggestion } from 'types/Search';*/ -/*:: type State = { search: SearchState };*/ -var selectState = exports.selectState = function selectState(state /*: State*/) /*: SearchState*/ { - return state.search; -}; - -var selectSearchValue /*: (state: State) => string*/ = exports.selectSearchValue = (0, _reselect.createSelector)(selectState, function (state) { - return state.searchQuery; -}); - -var selectSearchOptions /*: (state: State) => SearchOptions*/ = exports.selectSearchOptions = (0, _reselect.createSelector)(selectState, function (state) { - return state.options; -}); - -var selectSuggestions /*: ( - state: State - ) => { [string]: Array }*/ = exports.selectSuggestions = (0, _reselect.createSelector)(selectState, function (state) { - return state.suggestions; -}); - -var selectIsSearching /*: (state: State) => boolean*/ = exports.selectIsSearching = (0, _reselect.createSelector)(selectState, function (state) { - return state.searching; -}); - -var selectSearchUrisByQuery /*: ( - state: State - ) => { [string]: Array }*/ = exports.selectSearchUrisByQuery = (0, _reselect.createSelector)(selectState, function (state) { - return state.urisByQuery; -}); - -var makeSelectSearchUris = exports.makeSelectSearchUris = function makeSelectSearchUris(query -// replace statement below is kind of ugly, and repeated in doSearch action -/*: string*/) /*: ((state: State) => Array)*/ { - return (0, _reselect.createSelector)(selectSearchUrisByQuery, function (byQuery) { - return byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]; - }); -}; - -var selectSearchBarFocused /*: boolean*/ = exports.selectSearchBarFocused = (0, _reselect.createSelector)(selectState, function (state) { - return state.focused; -}); - -var selectSearchSuggestions /*: Array*/ = exports.selectSearchSuggestions = (0, _reselect.createSelector)(selectSearchValue, selectSuggestions, function (query /*: string*/, suggestions /*: { [string]: Array }*/) { - 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.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.SEARCH_TYPES.SEARCH - }, { - value: uri, - shorthand: isChannel ? claimName.slice(1) : claimName, - type: isChannel ? _search.SEARCH_TYPES.CHANNEL : _search.SEARCH_TYPES.FILE - }); - } catch (e) { - searchSuggestions.push({ - value: query, - type: _search.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.SEARCH_TYPES.CHANNEL : _search.SEARCH_TYPES.FILE - }; - } catch (e) { - // search result includes some character that isn't valid in claim names - return { - value: suggestion, - type: _search.SEARCH_TYPES.SEARCH - }; - } - })); - } - - return searchSuggestions; -}); - -// Creates a query string based on the state in the search reducer -// Can be overrided by passing in custom sizes/from values for other areas pagination -var makeSelectQueryWithOptions = exports.makeSelectQueryWithOptions = function makeSelectQueryWithOptions(customQuery /*: ?string*/, customSize /*: ?number*/, customFrom // If it's a background search, don't use the users settings -/*: ?number*/) { - var isBackgroundSearch /*: boolean*/ = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - return (0, _reselect.createSelector)(selectSearchValue, selectSearchOptions, function (query, options) { - var size = customSize || options[_search.SEARCH_OPTIONS.RESULT_COUNT]; - - var queryString = (0, _query_params.getSearchQueryString)(customQuery || query, _extends({}, options, { size: size, from: customFrom }), !isBackgroundSearch); - - return queryString; - }); -}; - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var SEARCH_TYPES = exports.SEARCH_TYPES = { - FILE: 'file', - CHANNEL: 'channel', - SEARCH: 'search' -}; - -var SEARCH_OPTIONS = exports.SEARCH_OPTIONS = { - RESULT_COUNT: 'size', - CLAIM_TYPE: 'claimType', - INCLUDE_FILES: 'file', - INCLUDE_CHANNELS: 'channel', - INCLUDE_FILES_AND_CHANNELS: 'file,channel', - MEDIA_AUDIO: 'audio', - MEDIA_VIDEO: 'video', - MEDIA_TEXT: 'text', - MEDIA_IMAGE: 'image', - MEDIA_APPLICATION: 'application' -}; - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getSearchQueryString = undefined; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); // @flow - - -exports.parseQueryParams = parseQueryParams; -exports.toQueryString = toQueryString; - -var _search = __webpack_require__(13); - -var DEFAULT_SEARCH_RESULT_FROM = 0; -var DEFAULT_SEARCH_SIZE = 20; - -function parseQueryParams(queryString /*: string*/) { - if (queryString === '') return {}; - var parts = queryString.split('?').pop().split('&').map(function (p) { - return p.split('='); - }); - - var params = {}; - parts.forEach(function (array) { - var _array = _slicedToArray(array, 2), - first = _array[0], - second = _array[1]; - - params[first] = second; - }); - return params; -} - -function toQueryString(params /*: { [string]: string | number }*/) { - if (!params) return ''; - - var parts = []; - Object.keys(params).forEach(function (key) { - if (Object.prototype.hasOwnProperty.call(params, key) && params[key]) { - parts.push(key + '=' + params[key]); - } - }); - - return parts.join('&'); -} - -var getSearchQueryString = exports.getSearchQueryString = function getSearchQueryString(query /*: string*/) { - var options /*: any*/ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var includeUserOptions /*: boolean*/ = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - var encodedQuery = encodeURIComponent(query); - var queryParams = ['s=' + encodedQuery, 'size=' + (options.size || DEFAULT_SEARCH_SIZE), 'from=' + (options.from || DEFAULT_SEARCH_RESULT_FROM)]; - - if (includeUserOptions) { - queryParams.push('claimType=' + options[_search.SEARCH_OPTIONS.CLAIM_TYPE]); - - // If they are only searching for channels, strip out the media info - if (options[_search.SEARCH_OPTIONS.CLAIM_TYPE] !== _search.SEARCH_OPTIONS.INCLUDE_CHANNELS) { - queryParams.push('mediaType=' + [_search.SEARCH_OPTIONS.MEDIA_FILE, _search.SEARCH_OPTIONS.MEDIA_AUDIO, _search.SEARCH_OPTIONS.MEDIA_VIDEO, _search.SEARCH_OPTIONS.MEDIA_TEXT, _search.SEARCH_OPTIONS.MEDIA_IMAGE, _search.SEARCH_OPTIONS.MEDIA_APPLICATION].reduce(function (acc, currentOption) { - return options[currentOption] ? '' + acc + currentOption + ',' : acc; - }, '')); - } - } - - return queryParams.join('&'); -}; - -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.defaultMemoize = defaultMemoize; -exports.createSelectorCreator = createSelectorCreator; -exports.createStructuredSelector = createStructuredSelector; -function defaultEqualityCheck(a, b) { - return a === b; -} - -function areArgumentsShallowlyEqual(equalityCheck, prev, next) { - if (prev === null || next === null || prev.length !== next.length) { - return false; - } - - // Do this in a for loop (and not a `forEach` or an `every`) so we can determine equality as fast as possible. - var length = prev.length; - for (var i = 0; i < length; i++) { - if (!equalityCheck(prev[i], next[i])) { - return false; - } - } - - return true; -} - -function defaultMemoize(func) { - var equalityCheck = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultEqualityCheck; - - var lastArgs = null; - var lastResult = null; - // we reference arguments instead of spreading them for performance reasons - return function () { - if (!areArgumentsShallowlyEqual(equalityCheck, lastArgs, arguments)) { - // apply arguments instead of spreading for performance. - lastResult = func.apply(null, arguments); - } - - lastArgs = arguments; - return lastResult; - }; -} - -function getDependencies(funcs) { - var dependencies = Array.isArray(funcs[0]) ? funcs[0] : funcs; - - if (!dependencies.every(function (dep) { - return typeof dep === 'function'; - })) { - var dependencyTypes = dependencies.map(function (dep) { - return typeof dep; - }).join(', '); - throw new Error('Selector creators expect all input-selectors to be functions, ' + ('instead received the following types: [' + dependencyTypes + ']')); - } - - return dependencies; -} - -function createSelectorCreator(memoize) { - for (var _len = arguments.length, memoizeOptions = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - memoizeOptions[_key - 1] = arguments[_key]; - } - - return function () { - for (var _len2 = arguments.length, funcs = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - funcs[_key2] = arguments[_key2]; - } - - var recomputations = 0; - var resultFunc = funcs.pop(); - var dependencies = getDependencies(funcs); - - var memoizedResultFunc = memoize.apply(undefined, [function () { - recomputations++; - // apply arguments instead of spreading for performance. - return resultFunc.apply(null, arguments); - }].concat(memoizeOptions)); - - // If a selector is called with the exact same arguments we don't need to traverse our dependencies again. - var selector = defaultMemoize(function () { - var params = []; - var length = dependencies.length; - - for (var i = 0; i < length; i++) { - // apply arguments instead of spreading and mutate a local list of params for performance. - params.push(dependencies[i].apply(null, arguments)); - } - - // apply arguments instead of spreading for performance. - return memoizedResultFunc.apply(null, params); - }); - - selector.resultFunc = resultFunc; - selector.recomputations = function () { - return recomputations; - }; - selector.resetRecomputations = function () { - return recomputations = 0; - }; - return selector; - }; -} - -var createSelector = exports.createSelector = createSelectorCreator(defaultMemoize); - -function createStructuredSelector(selectors) { - var selectorCreator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createSelector; - - if (typeof selectors !== 'object') { - throw new Error('createStructuredSelector expects first argument to be an object ' + ('where each property is a selector, instead received a ' + typeof selectors)); - } - var objectKeys = Object.keys(selectors); - return selectorCreator(objectKeys.map(function (key) { - return selectors[key]; - }), function () { - for (var _len3 = arguments.length, values = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { - values[_key3] = arguments[_key3]; - } - - return values.reduce(function (composition, value, index) { - composition[objectKeys[index]] = value; - return composition; - }, {}); - }); -} - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var isClaimNsfw = exports.isClaimNsfw = function isClaimNsfw(claim) { - return claim && claim.value && claim.value.stream && claim.value.stream.metadata.nsfw; -}; - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doUpdateBalance = doUpdateBalance; -exports.doUpdateTotalBalance = doUpdateTotalBalance; -exports.doBalanceSubscribe = doBalanceSubscribe; -exports.doTotalBalanceSubscribe = doTotalBalanceSubscribe; -exports.doFetchTransactions = doFetchTransactions; -exports.doFetchBlock = doFetchBlock; -exports.doGetNewAddress = doGetNewAddress; -exports.doCheckAddressIsMine = doCheckAddressIsMine; -exports.doSendDraftTransaction = doSendDraftTransaction; -exports.doSetDraftTransactionAmount = doSetDraftTransactionAmount; -exports.doSetDraftTransactionAddress = doSetDraftTransactionAddress; -exports.doSendTip = doSendTip; -exports.doWalletEncrypt = doWalletEncrypt; -exports.doWalletUnlock = doWalletUnlock; -exports.doWalletLock = doWalletLock; -exports.doWalletDecrypt = doWalletDecrypt; -exports.doWalletStatus = doWalletStatus; -exports.doSetTransactionListFilter = doSetTransactionListFilter; -exports.doUpdateBlockHeight = doUpdateBlockHeight; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbry = __webpack_require__(8); - -var _lbry2 = _interopRequireDefault(_lbry); - -var _notifications = __webpack_require__(2); - -var _wallet = __webpack_require__(18); - -var _formatCredits = __webpack_require__(20); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -function doUpdateBalance() { - return function (dispatch, getState) { - var _getState = getState(), - balanceInStore = _getState.wallet.balance; - - _lbry2.default.account_balance().then(function (balanceAsString) { - var balance = parseFloat(balanceAsString); - if (balanceInStore !== balance) { - dispatch({ - type: ACTIONS.UPDATE_BALANCE, - data: { - balance: balance - } - }); - } - }); - }; -} - -function doUpdateTotalBalance() { - return function (dispatch, getState) { - var _getState2 = getState(), - totalBalanceInStore = _getState2.wallet.totalBalance; - - _lbry2.default.account_list().then(function (accountList) { - var accounts = accountList.lbc_mainnet; - - var totalSatoshis = accounts.length === 1 ? accounts[0].satoshis : accounts.reduce(function (a, b) { - return a.satoshis + b.satoshis; - }); - var totalBalance = (Number.isNaN(totalSatoshis) ? 0 : totalSatoshis) / Math.pow(10, 8); - if (totalBalanceInStore !== totalBalance) { - dispatch({ - type: ACTIONS.UPDATE_TOTAL_BALANCE, - data: { - totalBalance: totalBalance - } - }); - } - }); - }; -} - -function doBalanceSubscribe() { - return function (dispatch) { - dispatch(doUpdateBalance()); - setInterval(function () { - return dispatch(doUpdateBalance()); - }, 5000); - }; -} - -function doTotalBalanceSubscribe() { - return function (dispatch) { - dispatch(doUpdateTotalBalance()); - setInterval(function () { - return dispatch(doUpdateTotalBalance()); - }, 5000); - }; -} - -function doFetchTransactions() { - return function (dispatch) { - dispatch({ - type: ACTIONS.FETCH_TRANSACTIONS_STARTED - }); - - _lbry2.default.utxo_release().then(function () { - return _lbry2.default.transaction_list(); - }).then(function (results) { - dispatch({ - type: ACTIONS.FETCH_TRANSACTIONS_COMPLETED, - data: { - transactions: results - } - }); - }); - }; -} - -function doFetchBlock(height) { - return function (dispatch) { - _lbry2.default.block_show({ height: height }).then(function (block) { - dispatch({ - type: ACTIONS.FETCH_BLOCK_SUCCESS, - data: { block: block } - }); - }); - }; -} - -function doGetNewAddress() { - return function (dispatch) { - dispatch({ - type: ACTIONS.GET_NEW_ADDRESS_STARTED - }); - - // Removed localStorage use, since address is expected to be stored in redux store - _lbry2.default.address_unused().then(function (address) { - dispatch({ - type: ACTIONS.GET_NEW_ADDRESS_COMPLETED, - data: { address: address } - }); - }); - }; -} - -function doCheckAddressIsMine(address) { - return function (dispatch) { - dispatch({ - type: ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED - }); - - _lbry2.default.address_is_mine({ address: address }).then(function (isMine) { - if (!isMine) dispatch(doGetNewAddress()); - - dispatch({ - type: ACTIONS.CHECK_ADDRESS_IS_MINE_COMPLETED - }); - }); - }; -} - -function doSendDraftTransaction(address, amount) { - return function (dispatch, getState) { - var state = getState(); - var balance = (0, _wallet.selectBalance)(state); - - if (balance - amount <= 0) { - dispatch((0, _notifications.doToast)({ - title: 'Insufficient credits', - message: 'Insufficient credits' - })); - return; - } - - dispatch({ - type: ACTIONS.SEND_TRANSACTION_STARTED - }); - - var successCallback = function successCallback(response) { - if (response.txid) { - dispatch({ - type: ACTIONS.SEND_TRANSACTION_COMPLETED - }); - dispatch((0, _notifications.doToast)({ - message: 'You sent ' + amount + ' LBC', - linkText: 'History', - linkTarget: '/wallet' - })); - } else { - dispatch({ - type: ACTIONS.SEND_TRANSACTION_FAILED, - data: { error: response } - }); - dispatch((0, _notifications.doToast)({ - message: 'Transaction failed', - isError: true - })); - } - }; - - var errorCallback = function errorCallback(error) { - dispatch({ - type: ACTIONS.SEND_TRANSACTION_FAILED, - data: { error: error.message } - }); - dispatch((0, _notifications.doToast)({ - message: 'Transaction failed', - isError: true - })); - }; - - _lbry2.default.wallet_send({ - address: address, - amount: (0, _formatCredits.creditsToString)(amount) - }).then(successCallback, errorCallback); - }; -} - -function doSetDraftTransactionAmount(amount) { - return { - type: ACTIONS.SET_DRAFT_TRANSACTION_AMOUNT, - data: { amount: amount } - }; -} - -function doSetDraftTransactionAddress(address) { - return { - type: ACTIONS.SET_DRAFT_TRANSACTION_ADDRESS, - data: { address: address } - }; -} - -function doSendTip(amount, claimId, uri, successCallback, errorCallback) { - return function (dispatch, getState) { - var state = getState(); - var balance = (0, _wallet.selectBalance)(state); - - if (balance - amount <= 0) { - dispatch((0, _notifications.doToast)({ - message: 'Insufficient credits', - isError: true - })); - return; - } - - var success = function success() { - dispatch((0, _notifications.doToast)({ - message: __('You sent ' + amount + ' LBC as a tip, Mahalo!'), - linkText: __('History'), - linkTarget: __('/wallet') - })); - - dispatch({ - type: ACTIONS.SUPPORT_TRANSACTION_COMPLETED - }); - - if (successCallback) { - successCallback(); - } - }; - - var error = function error(err) { - dispatch((0, _notifications.doToast)({ - message: __('There was an error sending support funds.'), - isError: true - })); - - dispatch({ - type: ACTIONS.SUPPORT_TRANSACTION_FAILED, - data: { - error: err - } - }); - - if (errorCallback) { - errorCallback(); - } - }; - - dispatch({ - type: ACTIONS.SUPPORT_TRANSACTION_STARTED - }); - - _lbry2.default.claim_tip({ - claim_id: claimId, - amount: (0, _formatCredits.creditsToString)(amount) - }).then(success, error); - }; -} - -function doWalletEncrypt(newPassword) { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_ENCRYPT_START - }); - - _lbry2.default.account_encrypt({ new_password: newPassword }).then(function (result) { - if (result === true) { - dispatch({ - type: ACTIONS.WALLET_ENCRYPT_COMPLETED, - result: result - }); - } else { - dispatch({ - type: ACTIONS.WALLET_ENCRYPT_FAILED, - result: result - }); - } - }); - }; -} - -function doWalletUnlock(password) { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_UNLOCK_START - }); - - _lbry2.default.account_unlock({ password: password }).then(function (result) { - if (result === true) { - dispatch({ - type: ACTIONS.WALLET_UNLOCK_COMPLETED, - result: result - }); - } else { - dispatch({ - type: ACTIONS.WALLET_UNLOCK_FAILED, - result: result - }); - } - }); - }; -} - -function doWalletLock() { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_LOCK_START - }); - - _lbry2.default.wallet_lock().then(function (result) { - if (result === true) { - dispatch({ - type: ACTIONS.WALLET_LOCK_COMPLETED, - result: result - }); - } else { - dispatch({ - type: ACTIONS.WALLET_LOCK_FAILED, - result: result - }); - } - }); - }; -} - -function doWalletDecrypt() { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_DECRYPT_START - }); - - _lbry2.default.account_decrypt().then(function (result) { - if (result === true) { - dispatch({ - type: ACTIONS.WALLET_DECRYPT_COMPLETED, - result: result - }); - } else { - dispatch({ - type: ACTIONS.WALLET_DECRYPT_FAILED, - result: result - }); - } - }); - }; -} - -function doWalletStatus() { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_STATUS_START - }); - - _lbry2.default.status().then(function (status) { - if (status && status.wallet) { - dispatch({ - type: ACTIONS.WALLET_STATUS_COMPLETED, - result: status.wallet.is_encrypted - }); - } - }); - }; -} - -function doSetTransactionListFilter(filterOption) { - return { - type: ACTIONS.SET_TRANSACTION_LIST_FILTER, - data: filterOption - }; -} - -function doUpdateBlockHeight() { - return function (dispatch) { - return _lbry2.default.status().then(function (status) { - if (status.wallet) { - dispatch({ - type: ACTIONS.UPDATE_CURRENT_HEIGHT, - data: status.wallet.blocks - }); - } - }); - }; -} - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.selectTransactionListFilter = exports.makeSelectBlockDate = exports.selectCurrentHeight = 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.selectTotalBalance = exports.selectBalance = exports.selectWalletLockResult = exports.selectWalletLockSucceeded = exports.selectWalletLockPending = exports.selectWalletUnlockResult = exports.selectWalletUnlockSucceeded = exports.selectWalletUnlockPending = exports.selectWalletDecryptResult = exports.selectWalletDecryptSucceeded = exports.selectWalletDecryptPending = exports.selectWalletEncryptResult = exports.selectWalletEncryptSucceeded = exports.selectWalletEncryptPending = exports.selectWalletIsEncrypted = exports.selectWalletState = exports.selectState = undefined; - -var _reselect = __webpack_require__(15); - -var _transaction_types = __webpack_require__(19); - -var TRANSACTIONS = _interopRequireWildcard(_transaction_types); - -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; } } - -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); } } - -var selectState = exports.selectState = function selectState(state) { - return state.wallet || {}; -}; - -var selectWalletState = exports.selectWalletState = selectState; - -var selectWalletIsEncrypted = exports.selectWalletIsEncrypted = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletIsEncrypted; -}); - -var selectWalletEncryptPending = exports.selectWalletEncryptPending = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletEncryptPending; -}); - -var selectWalletEncryptSucceeded = exports.selectWalletEncryptSucceeded = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletEncryptSucceded; -}); - -var selectWalletEncryptResult = exports.selectWalletEncryptResult = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletEncryptResult; -}); - -var selectWalletDecryptPending = exports.selectWalletDecryptPending = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletDecryptPending; -}); - -var selectWalletDecryptSucceeded = exports.selectWalletDecryptSucceeded = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletDecryptSucceded; -}); - -var selectWalletDecryptResult = exports.selectWalletDecryptResult = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletDecryptResult; -}); - -var selectWalletUnlockPending = exports.selectWalletUnlockPending = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletUnlockPending; -}); - -var selectWalletUnlockSucceeded = exports.selectWalletUnlockSucceeded = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletUnlockSucceded; -}); - -var selectWalletUnlockResult = exports.selectWalletUnlockResult = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletUnlockResult; -}); - -var selectWalletLockPending = exports.selectWalletLockPending = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletLockPending; -}); - -var selectWalletLockSucceeded = exports.selectWalletLockSucceeded = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletLockSucceded; -}); - -var selectWalletLockResult = exports.selectWalletLockResult = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletLockResult; -}); - -var selectBalance = exports.selectBalance = (0, _reselect.createSelector)(selectState, function (state) { - return state.balance; -}); - -var selectTotalBalance = exports.selectTotalBalance = (0, _reselect.createSelector)(selectState, function (state) { - return state.totalBalance; -}); - -var selectTransactionsById = exports.selectTransactionsById = (0, _reselect.createSelector)(selectState, function (state) { - return state.transactions; -}); - -var selectTransactionItems = exports.selectTransactionItems = (0, _reselect.createSelector)(selectTransactionsById, function (byId) { - var items = []; - - Object.keys(byId).forEach(function (txid) { - var tx = byId[txid]; - - // ignore dust/fees - // it is fee only txn if all infos are also empty - if (Math.abs(tx.value) === Math.abs(tx.fee) && tx.claim_info.length === 0 && tx.support_info.length === 0 && tx.update_info.length === 0 && tx.abandon_info.length === 0) { - return; - } - - var append = []; - - append.push.apply(append, _toConsumableArray(tx.claim_info.map(function (item) { - return Object.assign({}, tx, item, { - type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH - }); - }))); - append.push.apply(append, _toConsumableArray(tx.support_info.map(function (item) { - return Object.assign({}, tx, item, { - type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP - }); - }))); - append.push.apply(append, _toConsumableArray(tx.update_info.map(function (item) { - return Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE }); - }))); - append.push.apply(append, _toConsumableArray(tx.abandon_info.map(function (item) { - return Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON }); - }))); - - if (!append.length) { - append.push(Object.assign({}, tx, { - type: tx.value < 0 ? TRANSACTIONS.SPEND : TRANSACTIONS.RECEIVE - })); - } - - items.push.apply(items, _toConsumableArray(append.map(function (item) { - // value on transaction, amount on outpoint - // amount is always positive, but should match sign of value - var balanceDelta = parseFloat(item.balance_delta); - var value = parseFloat(item.value); - var amount = balanceDelta || value; - var fee = parseFloat(tx.fee); - - return { - txid: txid, - timestamp: tx.timestamp, - date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, - amount: amount, - fee: fee, - claim_id: item.claim_id, - claim_name: item.claim_name, - type: item.type || TRANSACTIONS.SPEND, - nout: item.nout, - confirmations: tx.confirmations - }; - }))); - }); - - return items.sort(function (tx1, tx2) { - if (!tx1.timestamp && !tx2.timestamp) { - return 0; - } else if (!tx1.timestamp && tx2.timestamp) { - return -1; - } else if (tx1.timestamp && !tx2.timestamp) { - return 1; - } - - return tx2.timestamp - tx1.timestamp; - }); -}); - -var selectRecentTransactions = exports.selectRecentTransactions = (0, _reselect.createSelector)(selectTransactionItems, function (transactions) { - var threshold = new Date(); - threshold.setDate(threshold.getDate() - 7); - return transactions.filter(function (transaction) { - if (!transaction.date) { - return true; // pending transaction - } - - return transaction.date > threshold; - }); -}); - -var selectHasTransactions = exports.selectHasTransactions = (0, _reselect.createSelector)(selectTransactionItems, function (transactions) { - return transactions && transactions.length > 0; -}); - -var selectIsFetchingTransactions = exports.selectIsFetchingTransactions = (0, _reselect.createSelector)(selectState, function (state) { - return state.fetchingTransactions; -}); - -var selectIsSendingSupport = exports.selectIsSendingSupport = (0, _reselect.createSelector)(selectState, function (state) { - return state.sendingSupport; -}); - -var selectReceiveAddress = exports.selectReceiveAddress = (0, _reselect.createSelector)(selectState, function (state) { - return state.receiveAddress; -}); - -var selectGettingNewAddress = exports.selectGettingNewAddress = (0, _reselect.createSelector)(selectState, function (state) { - return state.gettingNewAddress; -}); - -var selectDraftTransaction = exports.selectDraftTransaction = (0, _reselect.createSelector)(selectState, function (state) { - return state.draftTransaction || {}; -}); - -var selectDraftTransactionAmount = exports.selectDraftTransactionAmount = (0, _reselect.createSelector)(selectDraftTransaction, function (draft) { - return draft.amount; -}); - -var selectDraftTransactionAddress = exports.selectDraftTransactionAddress = (0, _reselect.createSelector)(selectDraftTransaction, function (draft) { - return draft.address; -}); - -var selectDraftTransactionError = exports.selectDraftTransactionError = (0, _reselect.createSelector)(selectDraftTransaction, function (draft) { - return draft.error; -}); - -var selectBlocks = exports.selectBlocks = (0, _reselect.createSelector)(selectState, function (state) { - return state.blocks; -}); - -var selectCurrentHeight = exports.selectCurrentHeight = (0, _reselect.createSelector)(selectState, function (state) { - return state.latestBlock; -}); - -var makeSelectBlockDate = exports.makeSelectBlockDate = function makeSelectBlockDate(block) { - return (0, _reselect.createSelector)(selectBlocks, selectCurrentHeight, function (blocks, latestBlock) { - // If we have the block data, look at the actual date, - // If not, try to simulate it based on 2.5 minute blocks - // Adding this on 11/7/2018 because caling block_show for every claim is causing - // performance issues. - if (blocks && blocks[block]) { - return new Date(blocks[block].time * 1000); - } - - // Pending claim - if (block < 1) { - return null; - } - - var difference = latestBlock - block; - var msSincePublish = difference * 2.5 * 60 * 1000; // Number of blocks * 2.5 minutes in ms - var publishDate = Date.now() - msSincePublish; - return new Date(publishDate); - }); -}; - -var selectTransactionListFilter = exports.selectTransactionListFilter = (0, _reselect.createSelector)(selectState, function (state) { - return state.transactionListFilter || ''; -}); - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -// eslint-disable-next-line import/prefer-default-export -var ALL = exports.ALL = 'all'; -var SPEND = exports.SPEND = 'spend'; -var RECEIVE = exports.RECEIVE = 'receive'; -var PUBLISH = exports.PUBLISH = 'publish'; -var CHANNEL = exports.CHANNEL = 'channel'; -var TIP = exports.TIP = 'tip'; -var SUPPORT = exports.SUPPORT = 'support'; -var UPDATE = exports.UPDATE = 'update'; -var ABANDON = exports.ABANDON = 'abandon'; - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.formatCredits = formatCredits; -exports.formatFullPrice = formatFullPrice; -exports.creditsToString = creditsToString; -function formatCredits(amount, precision) { - if (Number.isNaN(parseFloat(amount))) return '0'; - return parseFloat(amount).toFixed(precision || 1).replace(/\.?0+$/, ''); -} - -function formatFullPrice(amount) { - var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - - var formated = ''; - - var quantity = amount.toString().split('.'); - var fraction = quantity[1]; - - if (fraction) { - var decimals = fraction.split(''); - var first = decimals.filter(function (number) { - return number !== '0'; - })[0]; - var index = decimals.indexOf(first); - - // Set format fraction - formated = '.' + fraction.substring(0, index + precision); - } - - return parseFloat(quantity[0] + formated); -} - -function creditsToString(amount) { - var creditString = parseFloat(amount).toFixed(8); - return creditString; -} - -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doFetchFileInfo = doFetchFileInfo; -exports.doFileList = doFileList; -exports.doFetchFileInfosAndPublishedClaims = doFetchFileInfosAndPublishedClaims; -exports.doSetFileListSort = doSetFileListSort; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbry = __webpack_require__(8); - -var _lbry2 = _interopRequireDefault(_lbry); - -var _claims = __webpack_require__(7); - -var _claims2 = __webpack_require__(11); - -var _file_info = __webpack_require__(22); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -function doFetchFileInfo(uri) { - return function (dispatch, getState) { - var state = getState(); - var claim = (0, _claims2.selectClaimsByUri)(state)[uri]; - var outpoint = claim ? claim.txid + ':' + claim.nout : null; - var alreadyFetching = !!(0, _file_info.selectUrisLoading)(state)[uri]; - - if (!alreadyFetching) { - dispatch({ - type: ACTIONS.FETCH_FILE_INFO_STARTED, - data: { - outpoint: outpoint - } - }); - - _lbry2.default.file_list({ outpoint: outpoint, full_status: true }).then(function (fileInfos) { - dispatch({ - type: ACTIONS.FETCH_FILE_INFO_COMPLETED, - data: { - outpoint: outpoint, - fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null - } - }); - }); - } - }; -} - -function doFileList() { - return function (dispatch, getState) { - var state = getState(); - var isFetching = (0, _file_info.selectIsFetchingFileList)(state); - - if (!isFetching) { - dispatch({ - type: ACTIONS.FILE_LIST_STARTED - }); - - _lbry2.default.file_list().then(function (fileInfos) { - dispatch({ - type: ACTIONS.FILE_LIST_SUCCEEDED, - data: { - fileInfos: fileInfos - } - }); - }); - } - }; -} - -function doFetchFileInfosAndPublishedClaims() { - return function (dispatch, getState) { - var state = getState(); - var isFetchingClaimListMine = (0, _claims2.selectIsFetchingClaimListMine)(state); - var isFetchingFileInfo = (0, _file_info.selectIsFetchingFileList)(state); - - if (!isFetchingClaimListMine) dispatch((0, _claims.doFetchClaimListMine)()); - if (!isFetchingFileInfo) dispatch(doFileList()); - }; -} - -function doSetFileListSort(page, value) { - return { - type: ACTIONS.SET_FILE_LIST_SORT, - data: { page: page, value: value } - }; -} - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.selectFileListDownloadedSort = exports.selectFileListPublishedSort = exports.selectSearchDownloadUris = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.makeSelectLoadingForUri = exports.selectUrisLoading = exports.makeSelectDownloadingForUri = exports.selectDownloadingByOutpoint = exports.makeSelectFileInfoForUri = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.selectState = undefined; - -var _claims = __webpack_require__(11); - -var _reselect = __webpack_require__(15); - -var _lbryURI = __webpack_require__(1); - -var selectState = exports.selectState = function selectState(state) { - return state.fileInfo || {}; -}; - -var selectFileInfosByOutpoint = exports.selectFileInfosByOutpoint = (0, _reselect.createSelector)(selectState, function (state) { - return state.byOutpoint || {}; -}); - -var selectIsFetchingFileList = exports.selectIsFetchingFileList = (0, _reselect.createSelector)(selectState, function (state) { - return state.isFetchingFileList; -}); - -var selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileListDownloadedOrPublished = (0, _reselect.createSelector)(selectIsFetchingFileList, _claims.selectIsFetchingClaimListMine, function (isFetchingFileList, isFetchingClaimListMine) { - return isFetchingFileList || isFetchingClaimListMine; -}); - -var makeSelectFileInfoForUri = exports.makeSelectFileInfoForUri = function makeSelectFileInfoForUri(uri) { - return (0, _reselect.createSelector)(_claims.selectClaimsByUri, selectFileInfosByOutpoint, function (claims, byOutpoint) { - var claim = claims[uri]; - var outpoint = claim ? claim.txid + ':' + claim.nout : undefined; - return outpoint ? byOutpoint[outpoint] : undefined; - }); -}; - -var selectDownloadingByOutpoint = exports.selectDownloadingByOutpoint = (0, _reselect.createSelector)(selectState, function (state) { - return state.downloadingByOutpoint || {}; -}); - -var makeSelectDownloadingForUri = exports.makeSelectDownloadingForUri = function makeSelectDownloadingForUri(uri) { - return (0, _reselect.createSelector)(selectDownloadingByOutpoint, makeSelectFileInfoForUri(uri), function (byOutpoint, fileInfo) { - if (!fileInfo) return false; - return byOutpoint[fileInfo.outpoint]; - }); -}; - -var selectUrisLoading = exports.selectUrisLoading = (0, _reselect.createSelector)(selectState, function (state) { - return state.urisLoading || {}; -}); - -var makeSelectLoadingForUri = exports.makeSelectLoadingForUri = function makeSelectLoadingForUri(uri) { - return (0, _reselect.createSelector)(selectUrisLoading, function (byUri) { - return byUri && byUri[uri]; - }); -}; - -var selectFileInfosDownloaded = exports.selectFileInfosDownloaded = (0, _reselect.createSelector)(selectFileInfosByOutpoint, _claims.selectMyClaims, function (byOutpoint, myClaims) { - return Object.values(byOutpoint).filter(function (fileInfo) { - var myClaimIds = myClaims.map(function (claim) { - return claim.claim_id; - }); - - return fileInfo && myClaimIds.indexOf(fileInfo.claim_id) === -1 && (fileInfo.completed || fileInfo.written_bytes); - }); -}); - -// export const selectFileInfoForUri = (state, props) => { -// const claims = selectClaimsByUri(state), -// claim = claims[props.uri], -// fileInfos = selectAllFileInfos(state), -// outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; - -// return outpoint && fileInfos ? fileInfos[outpoint] : undefined; -// }; - -var selectDownloadingFileInfos = exports.selectDownloadingFileInfos = (0, _reselect.createSelector)(selectDownloadingByOutpoint, selectFileInfosByOutpoint, function (downloadingByOutpoint, fileInfosByOutpoint) { - var outpoints = Object.keys(downloadingByOutpoint); - var fileInfos = []; - - outpoints.forEach(function (outpoint) { - var fileInfo = fileInfosByOutpoint[outpoint]; - - if (fileInfo) fileInfos.push(fileInfo); - }); - - return fileInfos; -}); - -var selectTotalDownloadProgress = exports.selectTotalDownloadProgress = (0, _reselect.createSelector)(selectDownloadingFileInfos, function (fileInfos) { - var progress = []; - - fileInfos.forEach(function (fileInfo) { - progress.push(fileInfo.written_bytes / fileInfo.total_bytes * 100); - }); - - var totalProgress = progress.reduce(function (a, b) { - return a + b; - }, 0); - - if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; - return -1; -}); - -var selectSearchDownloadUris = exports.selectSearchDownloadUris = function selectSearchDownloadUris(query) { - return (0, _reselect.createSelector)(selectFileInfosDownloaded, _claims.selectClaimsById, function (fileInfos, claimsById) { - if (!query || !fileInfos.length) { - return null; - } - - var queryParts = query.toLowerCase().split(' '); - var searchQueryDictionary = {}; - queryParts.forEach(function (subQuery) { - searchQueryDictionary[subQuery] = subQuery; - }); - - var arrayContainsQueryPart = function arrayContainsQueryPart(array) { - for (var i = 0; i < array.length; i += 1) { - var subQuery = array[i]; - if (searchQueryDictionary[subQuery]) { - return true; - } - } - return false; - }; - - var downloadResultsFromQuery = []; - fileInfos.forEach(function (fileInfo) { - var channelName = fileInfo.channel_name, - claimName = fileInfo.claim_name, - metadata = fileInfo.metadata; - var author = metadata.author, - description = metadata.description, - title = metadata.title; - - - if (channelName) { - var lowerCaseChannel = channelName.toLowerCase(); - var strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ - if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - var nameParts = claimName.toLowerCase().split('-'); - if (arrayContainsQueryPart(nameParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - var titleParts = title.toLowerCase().split(' '); - if (arrayContainsQueryPart(titleParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - if (author) { - var authorParts = author.toLowerCase().split(' '); - if (arrayContainsQueryPart(authorParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - if (description) { - var descriptionParts = description.toLowerCase().split(' '); - if (arrayContainsQueryPart(descriptionParts)) { - downloadResultsFromQuery.push(fileInfo); - } - } - }); - - return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(function (fileInfo) { - var channelName = fileInfo.channel_name, - claimId = fileInfo.claim_id, - claimName = fileInfo.claim_name; - - - var uriParams = {}; - - if (channelName) { - var claim = claimsById[claimId]; - if (claim && claim.value) { - uriParams.claimId = claim.value.publisherSignature.certificateId; - } else { - uriParams.claimId = claimId; - } - uriParams.channelName = channelName; - uriParams.contentName = claimName; - } else { - uriParams.claimId = claimId; - uriParams.claimName = claimName; - } - - var uri = (0, _lbryURI.buildURI)(uriParams); - return uri; - }) : null; - }); -}; - -var selectFileListPublishedSort = exports.selectFileListPublishedSort = (0, _reselect.createSelector)(selectState, function (state) { - return state.fileListPublishedSort; -}); - -var selectFileListDownloadedSort = exports.selectFileListDownloadedSort = (0, _reselect.createSelector)(selectState, function (state) { - return state.fileListDownloadedSort; -}); - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doUpdateSearchOptions = exports.doBlurSearchInput = exports.doFocusSearchInput = exports.doSearch = exports.doUpdateSearchQuery = exports.getSearchSuggestions = exports.setSearchApi = undefined; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbryURI = __webpack_require__(1); - -var _claims = __webpack_require__(7); - -var _search = __webpack_require__(12); - -var _batchActions = __webpack_require__(24); - -var _debounce = __webpack_require__(25); - -var _debounce2 = _interopRequireDefault(_debounce); - -var _handleFetch = __webpack_require__(26); - -var _handleFetch2 = _interopRequireDefault(_handleFetch); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -// @flow -/*:: import type { SearchState, SearchOptions } from 'types/Search';*/ - - -var DEBOUNCED_SEARCH_SUGGESTION_MS = 300; -/*:: type Dispatch = (action: any) => any;*/ - - -// We can't use env's because they aren't passed into node_modules -/*:: type GetState = () => { search: SearchState };*/ -var CONNECTION_STRING = 'https://lighthouse.lbry.io/'; - -var setSearchApi = exports.setSearchApi = function setSearchApi(endpoint /*: string*/) { - CONNECTION_STRING = endpoint.replace(/\/*$/, '/'); // exactly one slash at the end; -}; - -var getSearchSuggestions = exports.getSearchSuggestions = function getSearchSuggestions(value /*: string*/) { - return function (dispatch /*: Dispatch*/, getState /*: GetState*/) { - var query = value.trim(); - - // strip out any basic stuff for more accurate search results - 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(CONNECTION_STRING + 'autocomplete?s=' + searchValue).then(_handleFetch2.default).then(function (apiSuggestions) { - dispatch({ - type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS, - data: { - query: searchValue, - suggestions: apiSuggestions - } - }); - }).catch(function () { - // If the fetch fails, do nothing - // Basic search suggestions are already populated at this point - }); - }; -}; - -var throttledSearchSuggestions = (0, _debounce2.default)(function (dispatch, query) { - dispatch(getSearchSuggestions(query)); -}, DEBOUNCED_SEARCH_SUGGESTION_MS); - -var doUpdateSearchQuery = exports.doUpdateSearchQuery = function doUpdateSearchQuery(query /*: string*/, shouldSkipSuggestions /*: ?boolean*/) { - return function (dispatch /*: Dispatch*/) { - dispatch({ - type: ACTIONS.UPDATE_SEARCH_QUERY, - data: { query: query } - }); - - // Don't fetch new suggestions if the user just added a space - if (!query.endsWith(' ') || !shouldSkipSuggestions) { - throttledSearchSuggestions(dispatch, query); - } - }; -}; - -var doSearch = exports.doSearch = function doSearch(rawQuery /*: string*/, size /*: ?number*/, from /*: ?number*/) { - var isBackgroundSearch /*: boolean*/ = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - return function (dispatch /*: Dispatch*/, getState /*: GetState*/) { - var query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); - - if (!query) { - dispatch({ - type: ACTIONS.SEARCH_FAIL - }); - return; - } - - var state = getState(); - var queryWithOptions = (0, _search.makeSelectQueryWithOptions)(query, size, from, isBackgroundSearch)(state); - - // If we have already searched for something, we don't need to do anything - var urisForQuery = (0, _search.makeSelectSearchUris)(queryWithOptions)(state); - if (urisForQuery && !!urisForQuery.length) { - return; - } - - dispatch({ - type: ACTIONS.SEARCH_START - }); - - // 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 - // isBackgroundSearch means the search is happening in the background, don't update the search query - if (!state.search.searchQuery && !isBackgroundSearch) { - dispatch(doUpdateSearchQuery(query)); - } - - fetch(CONNECTION_STRING + 'search?' + queryWithOptions).then(_handleFetch2.default).then(function (data) { - var uris = []; - var actions = []; - - data.forEach(function (result) { - var uri = (0, _lbryURI.buildURI)({ - claimName: result.name, - claimId: result.claimId - }); - actions.push((0, _claims.doResolveUri)(uri)); - uris.push(uri); - }); - - actions.push({ - type: ACTIONS.SEARCH_SUCCESS, - data: { - query: queryWithOptions, - uris: uris - } - }); - dispatch(_batchActions.batchActions.apply(undefined, actions)); - }).catch(function () { - dispatch({ - type: ACTIONS.SEARCH_FAIL - }); - }); - }; -}; - -var doFocusSearchInput = exports.doFocusSearchInput = function doFocusSearchInput() { - return function (dispatch /*: Dispatch*/) { - return dispatch({ - type: ACTIONS.SEARCH_FOCUS - }); - }; -}; - -var doBlurSearchInput = exports.doBlurSearchInput = function doBlurSearchInput() { - return function (dispatch /*: Dispatch*/) { - return dispatch({ - type: ACTIONS.SEARCH_BLUR - }); - }; -}; - -var doUpdateSearchOptions = exports.doUpdateSearchOptions = function doUpdateSearchOptions(newOptions /*: SearchOptions*/) { - return function (dispatch /*: Dispatch*/, getState /*: GetState*/) { - var state = getState(); - var searchValue = (0, _search.selectSearchValue)(state); - - dispatch({ - type: ACTIONS.UPDATE_SEARCH_OPTIONS, - data: newOptions - }); - - if (searchValue) { - // After updating, perform a search with the new options - dispatch(doSearch(searchValue)); - } - }; -}; - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.batchActions = batchActions; -// https://github.com/reactjs/redux/issues/911 -function batchActions() { - for (var _len = arguments.length, actions = Array(_len), _key = 0; _key < _len; _key++) { - actions[_key] = arguments[_key]; - } - - return { - type: 'BATCH_ACTIONS', - actions: actions - }; -} - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = debouce; -// Returns a function, that, as long as it continues to be invoked, will not -// be triggered. The function will be called after it stops being called for -// N milliseconds. If `immediate` is passed, trigger the function on the -// leading edge, instead of the trailing. -function debouce(func, wait, immediate) { - var timeout = void 0; - - return function () { - var context = this; - var args = arguments; - var later = function later() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) func.apply(context, args); - }; -} - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = handleFetchResponse; -function handleFetchResponse(response) { - return response.status === 200 ? Promise.resolve(response.json()) : Promise.reject(new Error(response.statusText)); -} - -/***/ }), -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.savePosition = savePosition; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -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; } } - -function savePosition(claimId /*: string*/, outpoint /*: string*/, position /*: number*/) { - return function (dispatch) { - dispatch({ - type: ACTIONS.SET_CONTENT_POSITION, - data: { claimId: claimId, outpoint: outpoint, position: position } - }); - }; -} - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -exports.claimsReducer = claimsReducer; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbryURI = __webpack_require__(1); - -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 reducers = {}; - -var defaultState = { - channelClaimCounts: {} -}; - -reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = function (state, action) { - var resolveInfo = action.data.resolveInfo; - - var byUri = Object.assign({}, state.claimsByUri); - var byId = Object.assign({}, state.byId); - var channelClaimCounts = Object.assign({}, state.channelClaimCounts); - - Object.entries(resolveInfo).forEach(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - uri = _ref2[0], - _ref2$ = _ref2[1], - certificate = _ref2$.certificate, - claimsInChannel = _ref2$.claimsInChannel; - - if (certificate && !Number.isNaN(claimsInChannel)) { - channelClaimCounts[uri] = claimsInChannel; - } - }); - - Object.entries(resolveInfo).forEach(function (_ref3) { - var _ref4 = _slicedToArray(_ref3, 2), - uri = _ref4[0], - _ref4$ = _ref4[1], - certificate = _ref4$.certificate, - claim = _ref4$.claim; - - if (claim) { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; - } else if (claim === undefined && certificate !== undefined) { - byId[certificate.claim_id] = certificate; - // Don't point URI at the channel certificate unless it actually is - // a channel URI. This is brittle. - if (!uri.split(certificate.name)[1].match(/\//)) { - byUri[uri] = certificate.claim_id; - } else { - byUri[uri] = null; - } - } else { - byUri[uri] = null; - } - }); - - return Object.assign({}, state, { - byId: byId, - claimsByUri: byUri, - channelClaimCounts: channelClaimCounts, - resolvingUris: (state.resolvingUris || []).filter(function (uri) { - return !resolveInfo[uri]; - }) - }); -}; - -reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = function (state) { - return Object.assign({}, state, { - isFetchingClaimListMine: true - }); -}; - -reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = function (state, action) { - var claims = action.data.claims; - - var byId = Object.assign({}, state.byId); - var byUri = Object.assign({}, state.claimsByUri); - var pendingById = Object.assign({}, state.pendingById); - - claims.forEach(function (claim) { - var uri = (0, _lbryURI.buildURI)({ claimName: claim.name, claimId: claim.claim_id }); - - if (claim.type && claim.type.match(/claim|update/)) { - if (claim.confirmations < 1) { - pendingById[claim.claim_id] = claim; - delete byId[claim.claim_id]; - delete byUri[claim.claim_id]; - } else { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; - } - } - }); - - // Remove old pending publishes - Object.values(pendingById).filter(function (pendingClaim) { - return byId[pendingClaim.claim_id]; - }).forEach(function (pendingClaim) { - delete pendingById[pendingClaim.claim_id]; - }); - - return Object.assign({}, state, { - isFetchingClaimListMine: false, - myClaims: claims, - byId: byId, - claimsByUri: byUri, - pendingById: pendingById - }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_LIST_STARTED] = function (state) { - return Object.assign({}, state, { fetchingMyChannels: true }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = function (state, action) { - var claims = action.data.claims; - - var myChannelClaims = new Set(state.myChannelClaims); - var byId = Object.assign({}, state.byId); - - claims.forEach(function (claim) { - myChannelClaims.add(claim.claim_id); - byId[claim.claim_id] = claim; - }); - - return Object.assign({}, state, { - byId: byId, - fetchingMyChannels: false, - myChannelClaims: myChannelClaims - }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_STARTED] = function (state, action) { - var _action$data = action.data, - uri = _action$data.uri, - page = _action$data.page; - - var fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); - - fetchingChannelClaims[uri] = page; - - return Object.assign({}, state, { - fetchingChannelClaims: fetchingChannelClaims, - currentChannelPage: page - }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = function (state, action) { - var _action$data2 = action.data, - uri = _action$data2.uri, - claims = _action$data2.claims, - page = _action$data2.page; - - - var claimsByChannel = Object.assign({}, state.claimsByChannel); - var byChannel = Object.assign({}, claimsByChannel[uri]); - var allClaimIds = new Set(byChannel.all); - var currentPageClaimIds = []; - var byId = Object.assign({}, state.byId); - var fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); - var claimsByUri = Object.assign({}, state.claimsByUri); - - if (claims !== undefined) { - claims.forEach(function (claim) { - allClaimIds.add(claim.claim_id); - currentPageClaimIds.push(claim.claim_id); - byId[claim.claim_id] = claim; - claimsByUri['lbry://' + claim.name + '#' + claim.claim_id] = claim.claim_id; - }); - } - - byChannel.all = allClaimIds; - byChannel[page] = currentPageClaimIds; - claimsByChannel[uri] = byChannel; - delete fetchingChannelClaims[uri]; - - return Object.assign({}, state, { - claimsByChannel: claimsByChannel, - byId: byId, - fetchingChannelClaims: fetchingChannelClaims, - claimsByUri: claimsByUri, - currentChannelPage: page - }); -}; - -reducers[ACTIONS.ABANDON_CLAIM_STARTED] = function (state, action) { - var claimId = action.data.claimId; - - var abandoningById = Object.assign({}, state.abandoningById); - - abandoningById[claimId] = true; - - return Object.assign({}, state, { - abandoningById: abandoningById - }); -}; - -reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = function (state, action) { - var claimId = action.data.claimId; - - var byId = Object.assign({}, state.byId); - var claimsByUri = Object.assign({}, state.claimsByUri); - - Object.keys(claimsByUri).forEach(function (uri) { - if (claimsByUri[uri] === claimId) { - delete claimsByUri[uri]; - } - }); - - delete byId[claimId]; - - return Object.assign({}, state, { - byId: byId, - claimsByUri: claimsByUri - }); -}; - -reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = function (state, action) { - var channelClaim = action.data.channelClaim; - - var byId = Object.assign({}, state.byId); - var myChannelClaims = new Set(state.myChannelClaims); - - byId[channelClaim.claim_id] = channelClaim; - myChannelClaims.add(channelClaim.claim_id); - - return Object.assign({}, state, { - byId: byId, - myChannelClaims: myChannelClaims - }); -}; - -reducers[ACTIONS.RESOLVE_URIS_STARTED] = function (state, action) { - var uris = action.data.uris; - - - var oldResolving = state.resolvingUris || []; - var newResolving = Object.assign([], oldResolving); - - uris.forEach(function (uri) { - if (!newResolving.includes(uri)) { - newResolving.push(uri); - } - }); - - return Object.assign({}, state, { - resolvingUris: newResolving - }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED] = function (state, action) { - var channelClaimCounts = Object.assign({}, state.channelClaimCounts); - var _action$data3 = action.data, - uri = _action$data3.uri, - totalClaims = _action$data3.totalClaims; - - - channelClaimCounts[uri] = totalClaims; - - return Object.assign({}, state, { - channelClaimCounts: channelClaimCounts - }); -}; - -function claimsReducer() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action = arguments[1]; - - var handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} - -/***/ }), -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = 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; }; - -exports.fileInfoReducer = fileInfoReducer; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _sort_options = __webpack_require__(30); - -var SORT_OPTIONS = _interopRequireWildcard(_sort_options); - -var _pages = __webpack_require__(31); - -var PAGES = _interopRequireWildcard(_pages); - -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; } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var reducers = {}; -var defaultState = { - fileListPublishedSort: SORT_OPTIONS.DATE_NEW, - fileListDownloadedSort: SORT_OPTIONS.DATE_NEW -}; - -reducers[ACTIONS.FILE_LIST_STARTED] = function (state) { - return Object.assign({}, state, { - isFetchingFileList: true - }); -}; - -reducers[ACTIONS.FILE_LIST_SUCCEEDED] = function (state, action) { - var fileInfos = action.data.fileInfos; - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var pendingByOutpoint = Object.assign({}, state.pendingByOutpoint); - - fileInfos.forEach(function (fileInfo) { - var outpoint = fileInfo.outpoint; - - - if (outpoint) newByOutpoint[fileInfo.outpoint] = fileInfo; - }); - - return Object.assign({}, state, { - isFetchingFileList: false, - byOutpoint: newByOutpoint, - pendingByOutpoint: pendingByOutpoint - }); -}; - -reducers[ACTIONS.FETCH_FILE_INFO_STARTED] = function (state, action) { - var outpoint = action.data.outpoint; - - var newFetching = Object.assign({}, state.fetching); - - newFetching[outpoint] = true; - - return Object.assign({}, state, { - fetching: newFetching - }); -}; - -reducers[ACTIONS.FETCH_FILE_INFO_COMPLETED] = function (state, action) { - var _action$data = action.data, - fileInfo = _action$data.fileInfo, - outpoint = _action$data.outpoint; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var newFetching = Object.assign({}, state.fetching); - - newByOutpoint[outpoint] = fileInfo; - delete newFetching[outpoint]; - - return Object.assign({}, state, { - byOutpoint: newByOutpoint, - fetching: newFetching - }); -}; - -reducers[ACTIONS.DOWNLOADING_STARTED] = function (state, action) { - var _action$data2 = action.data, - uri = _action$data2.uri, - outpoint = _action$data2.outpoint, - fileInfo = _action$data2.fileInfo; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var newDownloading = Object.assign({}, state.downloadingByOutpoint); - var newLoading = Object.assign({}, state.urisLoading); - - newDownloading[outpoint] = true; - newByOutpoint[outpoint] = fileInfo; - delete newLoading[uri]; - - return Object.assign({}, state, { - downloadingByOutpoint: newDownloading, - urisLoading: newLoading, - byOutpoint: newByOutpoint - }); -}; - -reducers[ACTIONS.DOWNLOADING_PROGRESSED] = function (state, action) { - var _action$data3 = action.data, - outpoint = _action$data3.outpoint, - fileInfo = _action$data3.fileInfo; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var newDownloading = Object.assign({}, state.downloadingByOutpoint); - - newByOutpoint[outpoint] = fileInfo; - newDownloading[outpoint] = true; - - return Object.assign({}, state, { - byOutpoint: newByOutpoint, - downloadingByOutpoint: newDownloading - }); -}; - -reducers[ACTIONS.DOWNLOADING_CANCELED] = function (state, action) { - var outpoint = action.data.outpoint; - - - var newDownloading = Object.assign({}, state.downloadingByOutpoint); - delete newDownloading[outpoint]; - - return Object.assign({}, state, { - downloadingByOutpoint: newDownloading - }); -}; - -reducers[ACTIONS.DOWNLOADING_COMPLETED] = function (state, action) { - var _action$data4 = action.data, - outpoint = _action$data4.outpoint, - fileInfo = _action$data4.fileInfo; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var newDownloading = Object.assign({}, state.downloadingByOutpoint); - - newByOutpoint[outpoint] = fileInfo; - delete newDownloading[outpoint]; - - return Object.assign({}, state, { - byOutpoint: newByOutpoint, - downloadingByOutpoint: newDownloading - }); -}; - -reducers[ACTIONS.FILE_DELETE] = function (state, action) { - var outpoint = action.data.outpoint; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var downloadingByOutpoint = Object.assign({}, state.downloadingByOutpoint); - - delete newByOutpoint[outpoint]; - delete downloadingByOutpoint[outpoint]; - - return Object.assign({}, state, { - byOutpoint: newByOutpoint, - downloadingByOutpoint: downloadingByOutpoint - }); -}; - -reducers[ACTIONS.LOADING_VIDEO_STARTED] = function (state, action) { - var uri = action.data.uri; - - - var newLoading = Object.assign({}, state.urisLoading); - newLoading[uri] = true; - - var newErrors = _extends({}, state.errors); - if (uri in newErrors) delete newErrors[uri]; - - return Object.assign({}, state, { - urisLoading: newLoading, - errors: _extends({}, newErrors) - }); -}; - -reducers[ACTIONS.LOADING_VIDEO_FAILED] = function (state, action) { - var uri = action.data.uri; - - - var newLoading = Object.assign({}, state.urisLoading); - delete newLoading[uri]; - - var newErrors = _extends({}, state.errors); - newErrors[uri] = true; - - return Object.assign({}, state, { - urisLoading: newLoading, - errors: _extends({}, newErrors) - }); -}; - -reducers[ACTIONS.FETCH_DATE] = function (state, action) { - var time = action.data.time; - - if (time) { - return Object.assign({}, state, { - publishedDate: time - }); - } - return null; -}; - -reducers[ACTIONS.SET_FILE_LIST_SORT] = function (state, action) { - var _pageSortStates; - - var pageSortStates = (_pageSortStates = {}, _defineProperty(_pageSortStates, PAGES.PUBLISHED, 'fileListPublishedSort'), _defineProperty(_pageSortStates, PAGES.DOWNLOADED, 'fileListDownloadedSort'), _pageSortStates); - var pageSortState = pageSortStates[action.data.page]; - var value = action.data.value; - - - return Object.assign({}, state, _defineProperty({}, pageSortState, value)); -}; - -function fileInfoReducer() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action = arguments[1]; - - var handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} - -/***/ }), -/* 30 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var DATE_NEW = exports.DATE_NEW = 'dateNew'; -var DATE_OLD = exports.DATE_OLD = 'dateOld'; -var TITLE = exports.TITLE = 'title'; -var FILENAME = exports.FILENAME = 'filename'; - -/***/ }), -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var AUTH = exports.AUTH = 'auth'; -var BACKUP = exports.BACKUP = 'backup'; -var CHANNEL = exports.CHANNEL = 'channel'; -var DISCOVER = exports.DISCOVER = 'discover'; -var FILE = exports.FILE = 'file'; -var DOWNLOADED = exports.DOWNLOADED = 'downloaded'; -var PUBLISHED = exports.PUBLISHED = 'published'; -var GET_CREDITS = exports.GET_CREDITS = 'getcredits'; -var HELP = exports.HELP = 'help'; -var INVITE = exports.INVITE = 'invite'; -var PUBLISH = exports.PUBLISH = 'publish'; -var REPORT = exports.REPORT = 'report'; -var REWARDS = exports.REWARDS = 'rewards'; -var SEARCH = exports.SEARCH = 'search'; -var SEND_CREDITS = exports.SEND_CREDITS = 'send'; -var SETTINGS = exports.SETTINGS = 'settings'; -var SHOW = exports.SHOW = 'show'; -var SUBSCRIPTIONS = exports.SUBSCRIPTIONS = 'subscriptions'; -var TRANSACTION_HISTORY = exports.TRANSACTION_HISTORY = 'history'; -var HISTORY = exports.HISTORY = 'user_history'; -var WALLET = exports.WALLET = 'wallet'; - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.notificationsReducer = undefined; - -var _handleActions; - -var _extends = 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; }; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _reduxUtils = __webpack_require__(33); - -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; } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -// @flow -/*:: import type { - NotificationState, - DoToast, - DoError, - DoNotification, - DoEditNotification, - DoDeleteNotification, -} from 'types/Notification';*/ - - -var defaultState /*: NotificationState*/ = { - notifications: [], - toasts: [], - errors: [] -}; - -var notificationsReducer = (0, _reduxUtils.handleActions)((_handleActions = {}, _defineProperty(_handleActions, ACTIONS.CREATE_TOAST, function (state /*: NotificationState*/, action /*: DoToast*/) { - var toast = action.data; - var newToasts = state.toasts.slice(); - newToasts.push(toast); - - return _extends({}, state, { - toasts: newToasts - }); -}), _defineProperty(_handleActions, ACTIONS.DISMISS_TOAST, function (state /*: NotificationState*/) { - var newToasts = state.toasts.slice(); - newToasts.shift(); - - return _extends({}, state, { - toasts: newToasts - }); -}), _defineProperty(_handleActions, ACTIONS.CREATE_NOTIFICATION, function (state /*: NotificationState*/, action /*: DoNotification*/) { - var notification = action.data; - var newNotifications = state.notifications.slice(); - newNotifications.push(notification); - - return _extends({}, state, { - notifications: newNotifications - }); -}), _defineProperty(_handleActions, ACTIONS.EDIT_NOTIFICATION, function (state /*: NotificationState*/, action /*: DoEditNotification*/) { - var notification = action.data.notification; - - var notifications = state.notifications.slice(); - - notifications = notifications.map(function (pastNotification) { - return pastNotification.id === notification.id ? notification : pastNotification; - }); - - return _extends({}, state, { - notifications: notifications - }); -}), _defineProperty(_handleActions, ACTIONS.DELETE_NOTIFICATION, function (state /*: NotificationState*/, action /*: DoDeleteNotification*/) { - var id = action.data.id; - - var newNotifications = state.notifications.slice(); - newNotifications = newNotifications.filter(function (notification) { - return notification.id !== id; - }); - - return _extends({}, state, { - notifications: newNotifications - }); -}), _defineProperty(_handleActions, ACTIONS.CREATE_ERROR, function (state /*: NotificationState*/, action /*: DoError*/) { - var error = action.data; - var newErrors = state.errors.slice(); - newErrors.push(error); - - return _extends({}, state, { - errors: newErrors - }); -}), _defineProperty(_handleActions, ACTIONS.DISMISS_ERROR, function (state /*: NotificationState*/) { - var newErrors = state.errors.slice(); - newErrors.shift(); - - return _extends({}, state, { - errors: newErrors - }); -}), _handleActions), defaultState); - -exports.notificationsReducer = notificationsReducer; - -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -// util for creating reducers -// based off of redux-actions -// https://redux-actions.js.org/docs/api/handleAction.html#handleactions - -// eslint-disable-next-line import/prefer-default-export -var handleActions = exports.handleActions = function handleActions(actionMap, defaultState) { - return function () { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action = arguments[1]; - - var handler = actionMap[action.type]; - - if (handler) { - var newState = handler(state, action); - return Object.assign({}, state, newState); - } - - // just return the original state if no handler - // returning a copy here breaks redux-persist - return state; - }; -}; - -/***/ }), -/* 34 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.searchReducer = undefined; - -var _extends = 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; }; - -var _options, _handleActions; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _reduxUtils = __webpack_require__(33); - -var _search = __webpack_require__(13); - -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; } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // @flow - - -/*:: import type { - SearchState, - SearchSuccess, - UpdateSearchQuery, - UpdateSearchSuggestions, - HistoryNavigate, - UpdateSearchOptions, -} from 'types/Search';*/ - - -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 - options: (_options = {}, _defineProperty(_options, _search.SEARCH_OPTIONS.RESULT_COUNT, 30), _defineProperty(_options, _search.SEARCH_OPTIONS.CLAIM_TYPE, _search.SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_AUDIO, true), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_VIDEO, true), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_TEXT, true), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_IMAGE, true), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_APPLICATION, true), _options), - suggestions: {}, - urisByQuery: {} -}; - -var searchReducer = exports.searchReducer = (0, _reduxUtils.handleActions)((_handleActions = {}, _defineProperty(_handleActions, ACTIONS.SEARCH_START, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - searching: true - }); -}), _defineProperty(_handleActions, ACTIONS.SEARCH_SUCCESS, function (state /*: SearchState*/, action /*: SearchSuccess*/) /*: SearchState*/ { - var _action$data = action.data, - query = _action$data.query, - uris = _action$data.uris; - - - return _extends({}, state, { - searching: false, - urisByQuery: Object.assign({}, state.urisByQuery, _defineProperty({}, query, uris)) - }); -}), _defineProperty(_handleActions, ACTIONS.SEARCH_FAIL, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - searching: false - }); -}), _defineProperty(_handleActions, ACTIONS.UPDATE_SEARCH_QUERY, function (state /*: SearchState*/, action /*: UpdateSearchQuery*/) /*: SearchState*/ { - return _extends({}, state, { - searchQuery: action.data.query, - isActive: true - }); -}), _defineProperty(_handleActions, ACTIONS.UPDATE_SEARCH_SUGGESTIONS, function (state /*: SearchState*/, action /*: UpdateSearchSuggestions*/) /*: SearchState*/ { - return _extends({}, state, { - 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) : '', - isActive: url.indexOf('/search') === 0, - suggestions: {} - }); -}), _defineProperty(_handleActions, ACTIONS.DISMISS_NOTIFICATION, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - isActive: false - }); -}), _defineProperty(_handleActions, ACTIONS.SEARCH_FOCUS, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - focused: true - }); -}), _defineProperty(_handleActions, ACTIONS.SEARCH_BLUR, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - focused: false - }); -}), _defineProperty(_handleActions, ACTIONS.UPDATE_SEARCH_OPTIONS, function (state /*: SearchState*/, action /*: UpdateSearchOptions*/) /*: SearchState*/ { - var oldOptions = state.options; - - var newOptions = action.data; - var options = _extends({}, oldOptions, newOptions); - return _extends({}, state, { - options: options - }); -}), _handleActions), defaultState); - -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.walletReducer = walletReducer; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -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 reducers = {}; // @flow - -var buildDraftTransaction = function buildDraftTransaction() { - return { - amount: undefined, - address: undefined - }; -}; - -// TODO: Split into common success and failure types -// See details in https://github.com/lbryio/lbry/issues/1307 -/*:: type ActionResult = { - type: any, - result: any, -};*/ -/*:: type WalletState = { - balance: any, - blocks: any, - latestBlock: ?number, - transactions: any, - fetchingTransactions: boolean, - gettingNewAddress: boolean, - draftTransaction: any, - sendingSupport: boolean, - walletIsEncrypted: boolean, - walletEncryptPending: boolean, - walletEncryptSucceded: ?boolean, - walletEncryptResult: ?boolean, - walletDecryptPending: boolean, - walletDecryptSucceded: ?boolean, - walletDecryptResult: ?boolean, - walletUnlockPending: boolean, - walletUnlockSucceded: ?boolean, - walletUnlockResult: ?boolean, - walletLockPending: boolean, - walletLockSucceded: ?boolean, - walletLockResult: ?boolean, -};*/ - - -var defaultState = { - balance: undefined, - totalBalance: undefined, - blocks: {}, - latestBlock: undefined, - transactions: {}, - fetchingTransactions: false, - gettingNewAddress: false, - draftTransaction: buildDraftTransaction(), - sendingSupport: false, - walletIsEncrypted: false, - walletEncryptPending: false, - walletEncryptSucceded: null, - walletEncryptResult: null, - walletDecryptPending: false, - walletDecryptSucceded: null, - walletDecryptResult: null, - walletUnlockPending: false, - walletUnlockSucceded: null, - walletUnlockResult: null, - walletLockPending: false, - walletLockSucceded: null, - walletLockResult: null, - transactionListFilter: 'all' -}; - -reducers[ACTIONS.FETCH_TRANSACTIONS_STARTED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - fetchingTransactions: true - }); -}; - -reducers[ACTIONS.FETCH_TRANSACTIONS_COMPLETED] = function (state /*: WalletState*/, action) { - var byId = Object.assign({}, state.transactions); - - var transactions = action.data.transactions; - - - transactions.forEach(function (transaction) { - byId[transaction.txid] = transaction; - }); - - return Object.assign({}, state, { - transactions: byId, - fetchingTransactions: false - }); -}; - -reducers[ACTIONS.GET_NEW_ADDRESS_STARTED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - gettingNewAddress: true - }); -}; - -reducers[ACTIONS.GET_NEW_ADDRESS_COMPLETED] = function (state /*: WalletState*/, action) { - var address = action.data.address; - - // Say no to localStorage! - - return Object.assign({}, state, { - gettingNewAddress: false, - receiveAddress: address - }); -}; - -reducers[ACTIONS.UPDATE_BALANCE] = function (state /*: WalletState*/, action) { - return Object.assign({}, state, { - balance: action.data.balance - }); -}; - -reducers[ACTIONS.UPDATE_TOTAL_BALANCE] = function (state /*: WalletState*/, action) { - return Object.assign({}, state, { - totalBalance: action.data.totalBalance - }); -}; - -reducers[ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - checkingAddressOwnership: true - }); -}; - -reducers[ACTIONS.CHECK_ADDRESS_IS_MINE_COMPLETED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - checkingAddressOwnership: false - }); -}; - -reducers[ACTIONS.SET_DRAFT_TRANSACTION_AMOUNT] = function (state /*: WalletState*/, action) { - var oldDraft = state.draftTransaction; - var newDraft = Object.assign({}, oldDraft, { - amount: parseFloat(action.data.amount) - }); - - return Object.assign({}, state, { - draftTransaction: newDraft - }); -}; - -reducers[ACTIONS.SET_DRAFT_TRANSACTION_ADDRESS] = function (state /*: WalletState*/, action) { - var oldDraft = state.draftTransaction; - var newDraft = Object.assign({}, oldDraft, { - address: action.data.address - }); - - return Object.assign({}, state, { - draftTransaction: newDraft - }); -}; - -reducers[ACTIONS.SEND_TRANSACTION_STARTED] = function (state /*: WalletState*/) { - var newDraftTransaction = Object.assign({}, state.draftTransaction, { - sending: true - }); - - return Object.assign({}, state, { - draftTransaction: newDraftTransaction - }); -}; - -reducers[ACTIONS.SEND_TRANSACTION_COMPLETED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - draftTransaction: buildDraftTransaction() - }); -}; - -reducers[ACTIONS.SEND_TRANSACTION_FAILED] = function (state /*: WalletState*/, action) { - var newDraftTransaction = Object.assign({}, state.draftTransaction, { - sending: false, - error: action.data.error - }); - - return Object.assign({}, state, { - draftTransaction: newDraftTransaction - }); -}; - -reducers[ACTIONS.SUPPORT_TRANSACTION_STARTED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - sendingSupport: true - }); -}; - -reducers[ACTIONS.SUPPORT_TRANSACTION_COMPLETED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - sendingSupport: false - }); -}; - -reducers[ACTIONS.SUPPORT_TRANSACTION_FAILED] = function (state /*: WalletState*/, action) { - return Object.assign({}, state, { - error: action.data.error, - sendingSupport: false - }); -}; - -reducers[ACTIONS.FETCH_BLOCK_SUCCESS] = function (state /*: WalletState*/, action) { - var _action$data = action.data, - block = _action$data.block, - height = _action$data.block.height; - - var blocks = Object.assign({}, state.blocks); - - blocks[height] = block; - - return Object.assign({}, state, { blocks: blocks }); -}; - -reducers[ACTIONS.WALLET_STATUS_COMPLETED] = function (state /*: WalletState*/, action) { - return Object.assign({}, state, { - walletIsEncrypted: action.result - }); -}; - -reducers[ACTIONS.WALLET_ENCRYPT_START] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - walletEncryptPending: true, - walletEncryptSucceded: null, - walletEncryptResult: null - }); -}; - -reducers[ACTIONS.WALLET_ENCRYPT_COMPLETED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletEncryptPending: false, - walletEncryptSucceded: true, - walletEncryptResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_ENCRYPT_FAILED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletEncryptPending: false, - walletEncryptSucceded: false, - walletEncryptResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_DECRYPT_START] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - walletDecryptPending: true, - walletDecryptSucceded: null, - walletDecryptResult: null - }); -}; - -reducers[ACTIONS.WALLET_DECRYPT_COMPLETED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletDecryptPending: false, - walletDecryptSucceded: true, - walletDecryptResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_DECRYPT_FAILED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletDecryptPending: false, - walletDecryptSucceded: false, - walletDecryptResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_UNLOCK_START] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - walletUnlockPending: true, - walletUnlockSucceded: null, - walletUnlockResult: null - }); -}; - -reducers[ACTIONS.WALLET_UNLOCK_COMPLETED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletUnlockPending: false, - walletUnlockSucceded: true, - walletUnlockResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_UNLOCK_FAILED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletUnlockPending: false, - walletUnlockSucceded: false, - walletUnlockResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_LOCK_START] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: null, - walletLockResult: null - }); -}; - -reducers[ACTIONS.WALLET_LOCK_COMPLETED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: true, - walletLockResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_LOCK_FAILED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: false, - walletLockResult: action.result - }); -}; - -reducers[ACTIONS.SET_TRANSACTION_LIST_FILTER] = function (state /*: WalletState*/, action /*: {}*/) { - return Object.assign({}, state, { - transactionListFilter: action.data - }); -}; - -reducers[ACTIONS.UPDATE_CURRENT_HEIGHT] = function (state /*: WalletState*/, action /*: { data: number }*/) { - return Object.assign({}, state, { - latestBlock: action.data - }); -}; - -function walletReducer() { - var state /*: WalletState*/ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action /*: ActionResult*/ = arguments[1]; - - var handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} - -/***/ }), -/* 36 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = 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; }; - -exports.contentReducer = contentReducer; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -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; } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var reducers = {}; -var defaultState = { - positions: {} -}; - -reducers[ACTIONS.SET_CONTENT_POSITION] = function (state, action) { - var _action$data = action.data, - claimId = _action$data.claimId, - outpoint = _action$data.outpoint, - position = _action$data.position; - - return _extends({}, state, { - positions: _extends({}, state.positions, _defineProperty({}, claimId, _extends({}, state.positions[claimId], _defineProperty({}, outpoint, position)))) - }); -}; - -function contentReducer() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action = arguments[1]; - - var handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} - -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.makeSelectContentPositionForUri = exports.selectState = undefined; - -var _reselect = __webpack_require__(15); - -var _claims = __webpack_require__(11); - -var selectState = exports.selectState = function selectState(state /*: any*/) { - return state.content || {}; -}; - -var makeSelectContentPositionForUri = exports.makeSelectContentPositionForUri = function makeSelectContentPositionForUri(uri /*: string*/) { - return (0, _reselect.createSelector)(selectState, (0, _claims.makeSelectClaimForUri)(uri), function (state, claim) { - if (!claim) { - return null; - } - var outpoint = claim.txid + ':' + claim.nout; - var id = claim.claim_id; - return state.positions[id] ? state.positions[id][outpoint] : null; - }); -}; - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.selectError = exports.selectToast = exports.selectState = undefined; - -var _extends = 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; }; - -var _reselect = __webpack_require__(15); - -var selectState = exports.selectState = function selectState(state) { - return state.notifications || {}; -}; - -var selectToast = exports.selectToast = (0, _reselect.createSelector)(selectState, function (state) { - if (state.toasts.length) { - var _state$toasts$ = state.toasts[0], - id = _state$toasts$.id, - params = _state$toasts$.params; - - return _extends({ - id: id - }, params); - } - - return null; -}); - -var selectError = exports.selectError = (0, _reselect.createSelector)(selectState, function (state) { - if (state.errors.length) { - var error = state.errors[0].error; - - return { - error: error - }; - } - - return null; -}); - -/***/ }), -/* 39 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var API_DOWN = exports.API_DOWN = 'apiDown'; -var READY = exports.READY = 'ready'; -var IN_PROGRESS = exports.IN_PROGRESS = 'inProgress'; -var COMPLETE = exports.COMPLETE = 'complete'; -var MANUAL = exports.MANUAL = 'manual'; - -/***/ }), -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ -/* Many SETTINGS are stored in the localStorage by their name - - be careful about changing the value of a SETTINGS constant, as doing so can invalidate existing SETTINGS */ -var CREDIT_REQUIRED_ACKNOWLEDGED = exports.CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged'; -var NEW_USER_ACKNOWLEDGED = exports.NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged'; -var EMAIL_COLLECTION_ACKNOWLEDGED = exports.EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; -var LANGUAGE = exports.LANGUAGE = 'language'; -var SHOW_NSFW = exports.SHOW_NSFW = 'showNsfw'; -var SHOW_UNAVAILABLE = exports.SHOW_UNAVAILABLE = 'showUnavailable'; -var INSTANT_PURCHASE_ENABLED = exports.INSTANT_PURCHASE_ENABLED = 'instantPurchaseEnabled'; -var INSTANT_PURCHASE_MAX = exports.INSTANT_PURCHASE_MAX = 'instantPurchaseMax'; -var THEME = exports.THEME = 'theme'; -var THEMES = exports.THEMES = 'themes'; -var AUTOMATIC_DARK_MODE_ENABLED = exports.AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; - -// mobile settings -var BACKGROUND_PLAY_ENABLED = exports.BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; -var FOREGROUND_NOTIFICATION_ENABLED = exports.FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; -var KEEP_DAEMON_RUNNING = exports.KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; - -/***/ }) -/******/ ]); -}); \ No newline at end of file diff --git a/src/lbry.js b/src/lbry.js index 1d306bb..093f4fb 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -90,6 +90,9 @@ const Lbry: LbryTypes = { sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), + comment_list: (params = {}) => daemonCallWithResult('comment_list', params), + comment_create: (params = {}) => daemonCallWithResult('comment_create', params), + // Connect to the sdk connect: () => { if (Lbry.connectPromise === null) { diff --git a/src/redux/selectors/content.js b/src/redux/selectors/content.js index f494fab..f3d967f 100644 --- a/src/redux/selectors/content.js +++ b/src/redux/selectors/content.js @@ -4,11 +4,15 @@ import { makeSelectClaimForUri } from 'redux/selectors/claims'; export const selectState = (state: any) => state.content || {}; export const makeSelectContentPositionForUri = (uri: string) => - createSelector(selectState, makeSelectClaimForUri(uri), (state, claim) => { - if (!claim) { - return null; + createSelector( + selectState, + makeSelectClaimForUri(uri), + (state, claim) => { + if (!claim) { + return null; + } + const outpoint = `${claim.txid}:${claim.nout}`; + const id = claim.claim_id; + return state.positions[id] ? state.positions[id][outpoint] : null; } - const outpoint = `${claim.txid}:${claim.nout}`; - const id = claim.claim_id; - return state.positions[id] ? state.positions[id][outpoint] : null; - }); + ); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index ac346af..d1e3744 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -26,11 +26,15 @@ export const selectIsFetchingFileListDownloadedOrPublished = createSelector( ); export const makeSelectFileInfoForUri = uri => - createSelector(selectClaimsByUri, selectFileInfosByOutpoint, (claims, byOutpoint) => { - const claim = claims[uri]; - const outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; - return outpoint ? byOutpoint[outpoint] : undefined; - }); + createSelector( + selectClaimsByUri, + selectFileInfosByOutpoint, + (claims, byOutpoint) => { + const claim = claims[uri]; + const outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; + return outpoint ? byOutpoint[outpoint] : undefined; + } + ); export const selectDownloadingByOutpoint = createSelector( selectState, @@ -47,10 +51,16 @@ export const makeSelectDownloadingForUri = uri => } ); -export const selectUrisLoading = createSelector(selectState, state => state.urisLoading || {}); +export const selectUrisLoading = createSelector( + selectState, + state => state.urisLoading || {} +); export const makeSelectLoadingForUri = uri => - createSelector(selectUrisLoading, byUri => byUri && byUri[uri]); + createSelector( + selectUrisLoading, + byUri => byUri && byUri[uri] + ); export const selectFileInfosDownloaded = createSelector( selectFileInfosByOutpoint, @@ -93,108 +103,119 @@ export const selectDownloadingFileInfos = createSelector( } ); -export const selectTotalDownloadProgress = createSelector(selectDownloadingFileInfos, fileInfos => { - const progress = []; +export const selectTotalDownloadProgress = createSelector( + selectDownloadingFileInfos, + fileInfos => { + const progress = []; - fileInfos.forEach(fileInfo => { - progress.push((fileInfo.written_bytes / fileInfo.total_bytes) * 100); - }); + fileInfos.forEach(fileInfo => { + progress.push((fileInfo.written_bytes / fileInfo.total_bytes) * 100); + }); - const totalProgress = progress.reduce((a, b) => a + b, 0); + const totalProgress = progress.reduce((a, b) => a + b, 0); - if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; - return -1; -}); + if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; + return -1; + } +); export const selectSearchDownloadUris = query => - createSelector(selectFileInfosDownloaded, selectClaimsById, (fileInfos, claimsById) => { - if (!query || !fileInfos.length) { - return null; - } - - const queryParts = query.toLowerCase().split(' '); - const searchQueryDictionary = {}; - queryParts.forEach(subQuery => { - searchQueryDictionary[subQuery] = subQuery; - }); - - const arrayContainsQueryPart = array => { - for (let i = 0; i < array.length; i += 1) { - const subQuery = array[i]; - if (searchQueryDictionary[subQuery]) { - return true; - } + createSelector( + selectFileInfosDownloaded, + selectClaimsById, + (fileInfos, claimsById) => { + if (!query || !fileInfos.length) { + return null; } - return false; - }; - const downloadResultsFromQuery = []; - fileInfos.forEach(fileInfo => { - const { channel_name: channelName, claim_name: claimName, metadata } = fileInfo; - const { author, description, title } = metadata; + const queryParts = query.toLowerCase().split(' '); + const searchQueryDictionary = {}; + queryParts.forEach(subQuery => { + searchQueryDictionary[subQuery] = subQuery; + }); - if (channelName) { - const lowerCaseChannel = channelName.toLowerCase(); - const strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ - if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { + const arrayContainsQueryPart = array => { + for (let i = 0; i < array.length; i += 1) { + const subQuery = array[i]; + if (searchQueryDictionary[subQuery]) { + return true; + } + } + return false; + }; + + const downloadResultsFromQuery = []; + fileInfos.forEach(fileInfo => { + const { channel_name: channelName, claim_name: claimName, metadata } = fileInfo; + const { author, description, title } = metadata; + + if (channelName) { + const lowerCaseChannel = channelName.toLowerCase(); + const strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ + if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { + downloadResultsFromQuery.push(fileInfo); + return; + } + } + + const nameParts = claimName.toLowerCase().split('-'); + if (arrayContainsQueryPart(nameParts)) { downloadResultsFromQuery.push(fileInfo); return; } - } - const nameParts = claimName.toLowerCase().split('-'); - if (arrayContainsQueryPart(nameParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - const titleParts = title.toLowerCase().split(' '); - if (arrayContainsQueryPart(titleParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - if (author) { - const authorParts = author.toLowerCase().split(' '); - if (arrayContainsQueryPart(authorParts)) { + const titleParts = title.toLowerCase().split(' '); + if (arrayContainsQueryPart(titleParts)) { downloadResultsFromQuery.push(fileInfo); return; } - } - if (description) { - const descriptionParts = description.toLowerCase().split(' '); - if (arrayContainsQueryPart(descriptionParts)) { - downloadResultsFromQuery.push(fileInfo); + if (author) { + const authorParts = author.toLowerCase().split(' '); + if (arrayContainsQueryPart(authorParts)) { + downloadResultsFromQuery.push(fileInfo); + return; + } } - } - }); - return downloadResultsFromQuery.length - ? downloadResultsFromQuery.map(fileInfo => { - const { channel_name: channelName, claim_id: claimId, claim_name: claimName } = fileInfo; + if (description) { + const descriptionParts = description.toLowerCase().split(' '); + if (arrayContainsQueryPart(descriptionParts)) { + downloadResultsFromQuery.push(fileInfo); + } + } + }); - const uriParams = {}; + return downloadResultsFromQuery.length + ? downloadResultsFromQuery.map(fileInfo => { + const { + channel_name: channelName, + claim_id: claimId, + claim_name: claimName, + } = fileInfo; - if (channelName) { - const claim = claimsById[claimId]; - if (claim && claim.value) { - uriParams.claimId = claim.value.publisherSignature.certificateId; + const uriParams = {}; + + if (channelName) { + const claim = claimsById[claimId]; + if (claim) { + uriParams.claimId = claim.channel_id; + } else { + uriParams.claimId = claimId; + } + uriParams.channelName = channelName; + uriParams.contentName = claimName; } else { uriParams.claimId = claimId; + uriParams.claimName = claimName; } - uriParams.channelName = channelName; - uriParams.contentName = claimName; - } else { - uriParams.claimId = claimId; - uriParams.claimName = claimName; - } - const uri = buildURI(uriParams); - return uri; - }) - : null; - }); + const uri = buildURI(uriParams); + return uri; + }) + : null; + } + ); export const selectFileListPublishedSort = createSelector( selectState, diff --git a/src/redux/selectors/navigation.js b/src/redux/selectors/navigation.js index 8aafd3c..71992c7 100644 --- a/src/redux/selectors/navigation.js +++ b/src/redux/selectors/navigation.js @@ -3,38 +3,63 @@ 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/notifications.js b/src/redux/selectors/notifications.js index 00844be..8894442 100644 --- a/src/redux/selectors/notifications.js +++ b/src/redux/selectors/notifications.js @@ -1,26 +1,32 @@ import { createSelector } from 'reselect'; -export const selectState = (state) => state.notifications || {}; +export const selectState = state => state.notifications || {}; -export const selectToast = createSelector(selectState, (state) => { - if (state.toasts.length) { - const { id, params } = state.toasts[0]; - return { - id, - ...params, - }; +export const selectToast = createSelector( + selectState, + state => { + if (state.toasts.length) { + const { id, params } = state.toasts[0]; + return { + id, + ...params, + }; + } + + return null; } +); - return null; -}); +export const selectError = createSelector( + selectState, + state => { + if (state.errors.length) { + const { error } = state.errors[0]; + return { + error, + }; + } -export const selectError = createSelector(selectState, (state) => { - if (state.errors.length) { - const { error } = state.errors[0]; - return { - error, - }; + return null; } - - return null; -}); +); diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index af5d340..636c406 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -65,112 +65,147 @@ export const selectWalletLockSucceeded = createSelector( state => state.walletLockSucceded ); -export const selectWalletLockResult = createSelector(selectState, state => state.walletLockResult); +export const selectWalletLockResult = createSelector( + selectState, + state => state.walletLockResult +); -export const selectBalance = createSelector(selectState, state => state.balance); +export const selectBalance = createSelector( + selectState, + state => state.balance +); -export const selectTotalBalance = createSelector(selectState, state => state.totalBalance); +export const selectTotalBalance = createSelector( + selectState, + state => state.totalBalance +); -export const selectTransactionsById = createSelector(selectState, state => state.transactions); +export const selectTransactionsById = createSelector( + selectState, + state => state.transactions +); -export const selectTransactionItems = createSelector(selectTransactionsById, byId => { - const items = []; +export const selectTransactionItems = createSelector( + selectTransactionsById, + byId => { + const items = []; - Object.keys(byId).forEach(txid => { - const tx = byId[txid]; + Object.keys(byId).forEach(txid => { + const tx = byId[txid]; - // ignore dust/fees - // it is fee only txn if all infos are also empty - if ( - Math.abs(tx.value) === Math.abs(tx.fee) && - tx.claim_info.length === 0 && - tx.support_info.length === 0 && - tx.update_info.length === 0 && - tx.abandon_info.length === 0 - ) { - return; - } + // ignore dust/fees + // it is fee only txn if all infos are also empty + if ( + Math.abs(tx.value) === Math.abs(tx.fee) && + tx.claim_info.length === 0 && + tx.support_info.length === 0 && + tx.update_info.length === 0 && + tx.abandon_info.length === 0 + ) { + return; + } - const append = []; + const append = []; - append.push( - ...tx.claim_info.map(item => - Object.assign({}, tx, item, { - type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH, - }) - ) - ); - append.push( - ...tx.support_info.map(item => - Object.assign({}, tx, item, { - type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP, - }) - ) - ); - append.push( - ...tx.update_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE })) - ); - append.push( - ...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON })) - ); - - if (!append.length) { append.push( - Object.assign({}, tx, { - type: tx.value < 0 ? TRANSACTIONS.SPEND : TRANSACTIONS.RECEIVE, + ...tx.claim_info.map(item => + Object.assign({}, tx, item, { + type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH, + }) + ) + ); + append.push( + ...tx.support_info.map(item => + Object.assign({}, tx, item, { + type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP, + }) + ) + ); + append.push( + ...tx.update_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE })) + ); + append.push( + ...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON })) + ); + + if (!append.length) { + append.push( + ...tx.claim_info.map(item => + Object.assign({}, tx, item, { + type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH, + }) + ) + ); + append.push( + ...tx.support_info.map(item => + Object.assign({}, tx, item, { + type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP, + }) + ) + ); + append.push( + ...tx.update_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE })) + ); + append.push( + ...tx.abandon_info.map(item => + Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON }) + ) + ); + } + + items.push( + ...append.map(item => { + // value on transaction, amount on outpoint + // amount is always positive, but should match sign of value + const balanceDelta = parseFloat(item.balance_delta); + const value = parseFloat(item.value); + const amount = balanceDelta || value; + const fee = parseFloat(tx.fee); + + return { + txid, + timestamp: tx.timestamp, + date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, + amount, + fee, + claim_id: item.claim_id, + claim_name: item.claim_name, + type: item.type || TRANSACTIONS.SPEND, + nout: item.nout, + confirmations: tx.confirmations, + }; }) ); - } + }); - items.push( - ...append.map(item => { - // value on transaction, amount on outpoint - // amount is always positive, but should match sign of value - const balanceDelta = parseFloat(item.balance_delta); - const value = parseFloat(item.value); - const amount = balanceDelta || value; - const fee = parseFloat(tx.fee); + return items.sort((tx1, tx2) => { + if (!tx1.timestamp && !tx2.timestamp) { + return 0; + } else if (!tx1.timestamp && tx2.timestamp) { + return -1; + } else if (tx1.timestamp && !tx2.timestamp) { + return 1; + } - return { - txid, - timestamp: tx.timestamp, - date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, - amount, - fee, - claim_id: item.claim_id, - claim_name: item.claim_name, - type: item.type || TRANSACTIONS.SPEND, - nout: item.nout, - confirmations: tx.confirmations, - }; - }) - ); - }); + return tx2.timestamp - tx1.timestamp; + }); + } +); - return items.sort((tx1, tx2) => { - if (!tx1.timestamp && !tx2.timestamp) { - return 0; - } else if (!tx1.timestamp && tx2.timestamp) { - return -1; - } else if (tx1.timestamp && !tx2.timestamp) { - return 1; - } +export const selectRecentTransactions = createSelector( + selectTransactionItems, + transactions => { + const threshold = new Date(); + threshold.setDate(threshold.getDate() - 7); + return transactions.filter(transaction => { + if (!transaction.date) { + return true; // pending transaction + } - return tx2.timestamp - tx1.timestamp; - }); -}); - -export const selectRecentTransactions = createSelector(selectTransactionItems, transactions => { - const threshold = new Date(); - threshold.setDate(threshold.getDate() - 7); - return transactions.filter(transaction => { - if (!transaction.date) { - return true; // pending transaction - } - - return transaction.date > threshold; - }); -}); + return transaction.date > threshold; + }); + } +); export const selectHasTransactions = createSelector( selectTransactionItems, @@ -182,9 +217,15 @@ export const selectIsFetchingTransactions = createSelector( state => state.fetchingTransactions ); -export const selectIsSendingSupport = createSelector(selectState, state => state.sendingSupport); +export const selectIsSendingSupport = createSelector( + selectState, + state => state.sendingSupport +); -export const selectReceiveAddress = createSelector(selectState, state => state.receiveAddress); +export const selectReceiveAddress = createSelector( + selectState, + state => state.receiveAddress +); export const selectGettingNewAddress = createSelector( selectState, @@ -211,30 +252,40 @@ export const selectDraftTransactionError = createSelector( draft => draft.error ); -export const selectBlocks = createSelector(selectState, state => state.blocks); +export const selectBlocks = createSelector( + selectState, + state => state.blocks +); -export const selectCurrentHeight = createSelector(selectState, state => state.latestBlock); +export const selectCurrentHeight = createSelector( + selectState, + state => state.latestBlock +); export const makeSelectBlockDate = block => - createSelector(selectBlocks, selectCurrentHeight, (blocks, latestBlock) => { - // If we have the block data, look at the actual date, - // If not, try to simulate it based on 2.5 minute blocks - // Adding this on 11/7/2018 because caling block_show for every claim is causing - // performance issues. - if (blocks && blocks[block]) { - return new Date(blocks[block].time * 1000); - } + createSelector( + selectBlocks, + selectCurrentHeight, + (blocks, latestBlock) => { + // If we have the block data, look at the actual date, + // If not, try to simulate it based on 2.5 minute blocks + // Adding this on 11/7/2018 because caling block_show for every claim is causing + // performance issues. + if (blocks && blocks[block]) { + return new Date(blocks[block].time * 1000); + } - // Pending claim - if (block < 1) { - return null; - } + // Pending claim + if (block < 1) { + return null; + } - const difference = latestBlock - block; - const msSincePublish = difference * 2.5 * 60 * 1000; // Number of blocks * 2.5 minutes in ms - const publishDate = Date.now() - msSincePublish; - return new Date(publishDate); - }); + const difference = latestBlock - block; + const msSincePublish = difference * 2.5 * 60 * 1000; // Number of blocks * 2.5 minutes in ms + const publishDate = Date.now() - msSincePublish; + return new Date(publishDate); + } + ); export const selectTransactionListFilter = createSelector( selectState, diff --git a/src/util/formatCredits.js b/src/util/formatCredits.js index e32b2d8..d4c4b49 100644 --- a/src/util/formatCredits.js +++ b/src/util/formatCredits.js @@ -13,7 +13,7 @@ export function formatFullPrice(amount, precision = 1) { if (fraction) { const decimals = fraction.split(''); - const first = decimals.filter((number) => number !== '0')[0]; + const first = decimals.filter(number => number !== '0')[0]; const index = decimals.indexOf(first); // Set format fraction -- 2.45.2 From f432c42de19e54f97b8b1bec86e977c771159b42 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 25 Apr 2019 14:24:33 -0400 Subject: [PATCH 002/371] wip --- src/redux/selectors/file_info.js | 38 ++++++++++++++++---------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index d1e3744..7ccfe7c 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -188,31 +188,31 @@ export const selectSearchDownloadUris = query => return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(fileInfo => { - const { - channel_name: channelName, - claim_id: claimId, - claim_name: claimName, - } = fileInfo; + const { + channel_name: channelName, + claim_id: claimId, + claim_name: claimName, + } = fileInfo; - const uriParams = {}; + const uriParams = {}; - if (channelName) { - const claim = claimsById[claimId]; - if (claim) { - uriParams.claimId = claim.channel_id; - } else { - uriParams.claimId = claimId; - } - uriParams.channelName = channelName; - uriParams.contentName = claimName; + if (channelName) { + const claim = claimsById[claimId]; + if (claim) { + uriParams.claimId = claim.channel_id; } else { uriParams.claimId = claimId; - uriParams.claimName = claimName; } + uriParams.channelName = channelName; + uriParams.contentName = claimName; + } else { + uriParams.claimId = claimId; + uriParams.claimName = claimName; + } - const uri = buildURI(uriParams); - return uri; - }) + const uri = buildURI(uriParams); + return uri; + }) : null; } ); -- 2.45.2 From 11d3b6676913438be470d48e4caa156d2ff8b34d Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Sat, 27 Apr 2019 20:01:26 +0100 Subject: [PATCH 003/371] set main to bundle.es.js after removing webpack --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0ed595a..4d15c96 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "name": "LBRY Inc.", "email": "hello@lbry.io" }, - "main": "dist/bundle.js", + "main": "dist/bundle.es.js", "module": "dist/bundle.es.js", "scripts": { "build": "rollup --config", -- 2.45.2 From 4b3769fc2dcc4c93771aa4c5dbb64d0e97f6375f Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 29 Apr 2019 15:29:24 +0100 Subject: [PATCH 004/371] Claim search fix (#134) * fix claim_search in doFetchClaimsByChannel * remove dist/bundle.js --- dist/bundle.es.js | 7 +- dist/bundle.js | 5929 ----------------------------------- src/redux/actions/claims.js | 29 +- 3 files changed, 20 insertions(+), 5945 deletions(-) delete mode 100644 dist/bundle.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 87be288..08a1745 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2039,9 +2039,10 @@ function doFetchClaimsByChannel(uri, page = 1) { data: { uri, page } }); - lbryProxy.claim_search({ uri, page: page || 1 }).then(result => { - const claimResult = result[uri] || {}; - const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult; + const { claimId } = parseURI(uri); + + lbryProxy.claim_search({ channel_id: claimId, page: page || 1 }).then(result => { + const { items: claimsInChannel, page: returnedPage } = result; dispatch({ type: FETCH_CHANNEL_CLAIMS_COMPLETED, diff --git a/dist/bundle.js b/dist/bundle.js deleted file mode 100644 index f2d5996..0000000 --- a/dist/bundle.js +++ /dev/null @@ -1,5929 +0,0 @@ -(function webpackUniversalModuleDefinition(root, factory) { - if(typeof exports === 'object' && typeof module === 'object') - module.exports = factory(); - else if(typeof define === 'function' && define.amd) - define([], factory); - else { - var a = factory(); - for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i]; - } -})((typeof self !== 'undefined' ? self : this), function() { -return /******/ (function(modules) { // webpackBootstrap -/******/ // The module cache -/******/ var installedModules = {}; -/******/ -/******/ // The require function -/******/ function __webpack_require__(moduleId) { -/******/ -/******/ // Check if module is in cache -/******/ if(installedModules[moduleId]) { -/******/ return installedModules[moduleId].exports; -/******/ } -/******/ // Create a new module (and put it into the cache) -/******/ var module = installedModules[moduleId] = { -/******/ i: moduleId, -/******/ l: false, -/******/ exports: {} -/******/ }; -/******/ -/******/ // Execute the module function -/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ -/******/ // Flag the module as loaded -/******/ module.l = true; -/******/ -/******/ // Return the exports of the module -/******/ return module.exports; -/******/ } -/******/ -/******/ -/******/ // expose the modules object (__webpack_modules__) -/******/ __webpack_require__.m = modules; -/******/ -/******/ // expose the module cache -/******/ __webpack_require__.c = installedModules; -/******/ -/******/ // define getter function for harmony exports -/******/ __webpack_require__.d = function(exports, name, getter) { -/******/ if(!__webpack_require__.o(exports, name)) { -/******/ Object.defineProperty(exports, name, { -/******/ configurable: false, -/******/ enumerable: true, -/******/ get: getter -/******/ }); -/******/ } -/******/ }; -/******/ -/******/ // define __esModule on exports -/******/ __webpack_require__.r = function(exports) { -/******/ Object.defineProperty(exports, '__esModule', { value: true }); -/******/ }; -/******/ -/******/ // getDefaultExport function for compatibility with non-harmony modules -/******/ __webpack_require__.n = function(module) { -/******/ var getter = module && module.__esModule ? -/******/ function getDefault() { return module['default']; } : -/******/ function getModuleExports() { return module; }; -/******/ __webpack_require__.d(getter, 'a', getter); -/******/ return getter; -/******/ }; -/******/ -/******/ // Object.prototype.hasOwnProperty.call -/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; -/******/ -/******/ // __webpack_public_path__ -/******/ __webpack_require__.p = ""; -/******/ -/******/ -/******/ // Load entry module and return exports -/******/ return __webpack_require__(__webpack_require__.s = 0); -/******/ }) -/************************************************************************/ -/******/ ([ -/* 0 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.selectTransactionListFilter = 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.selectTotalBalance = exports.selectBalance = exports.makeSelectBlockDate = exports.makeSelectQueryWithOptions = exports.selectSearchSuggestions = exports.selectSearchBarFocused = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSearchOptions = exports.selectSearchValue = exports.makeSelectSearchUris = exports.selectSearchState = exports.selectFileListPublishedSort = exports.selectFileListDownloadedSort = 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.selectCurrentChannelPage = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = undefined; -exports.selectPendingClaims = exports.selectIsFetchingClaimListMine = exports.selectAllFetchingChannelClaims = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectClaimsById = exports.selectPendingById = exports.makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectPendingByUri = exports.makeSelectClaimIsPending = exports.makeSelectChannelForClaimUri = exports.makeSelectFirstRecommendedFileForUri = exports.makeSelectRecommendedContentForUri = exports.makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountFromUris = exports.makeSelectTotalPagesForChannel = exports.makeSelectTotalItemsForChannel = exports.makeSelectIsUriResolving = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForPage = exports.makeSelectFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.makeSelectClaimForUri = exports.selectError = exports.selectToast = exports.makeSelectContentPositionForUri = exports.contentReducer = exports.walletReducer = exports.searchReducer = exports.notificationsReducer = exports.fileInfoReducer = exports.claimsReducer = exports.creditsToString = exports.formatFullPrice = exports.formatCredits = exports.toQueryString = exports.parseQueryParams = exports.batchActions = exports.doUpdateBlockHeight = exports.doSetTransactionListFilter = exports.doWalletStatus = exports.doWalletUnlock = exports.doWalletDecrypt = exports.doWalletEncrypt = exports.doSendTip = exports.doSetDraftTransactionAddress = exports.doSetDraftTransactionAmount = exports.doSendDraftTransaction = exports.doCheckAddressIsMine = exports.doGetNewAddress = exports.doFetchBlock = exports.doFetchTransactions = exports.doTotalBalanceSubscribe = exports.doUpdateTotalBalance = exports.doBalanceSubscribe = exports.doUpdateBalance = exports.savePosition = exports.doUpdateSearchOptions = exports.setSearchApi = exports.doBlurSearchInput = exports.doFocusSearchInput = exports.doUpdateSearchQuery = exports.doSearch = exports.doSetFileListSort = exports.doFetchFileInfosAndPublishedClaims = exports.doFileList = exports.doFetchFileInfo = exports.doResolveUri = exports.doResolveUris = exports.doAbandonClaim = exports.doFetchClaimListMine = exports.doFetchClaimCountByChannel = exports.doFetchClaimsByChannel = exports.doDismissError = exports.doError = exports.doDismissToast = exports.doToast = exports.convertToShareLink = exports.isNameValid = exports.isURIClaimable = exports.isURIValid = exports.normalizeURI = exports.buildURI = exports.parseURI = exports.regexAddress = exports.regexInvalidURI = exports.Lbry = exports.PAGES = exports.SORT_OPTIONS = exports.TRANSACTIONS = exports.SETTINGS = exports.SEARCH_OPTIONS = exports.SEARCH_TYPES = exports.THUMBNAIL_STATUSES = exports.ACTIONS = undefined; - -var _lbryURI = __webpack_require__(1); - -Object.defineProperty(exports, 'regexInvalidURI', { - enumerable: true, - get: function get() { - return _lbryURI.regexInvalidURI; - } -}); -Object.defineProperty(exports, 'regexAddress', { - enumerable: true, - get: function get() { - return _lbryURI.regexAddress; - } -}); -Object.defineProperty(exports, 'parseURI', { - enumerable: true, - get: function get() { - return _lbryURI.parseURI; - } -}); -Object.defineProperty(exports, 'buildURI', { - enumerable: true, - get: function get() { - return _lbryURI.buildURI; - } -}); -Object.defineProperty(exports, 'normalizeURI', { - enumerable: true, - get: function get() { - return _lbryURI.normalizeURI; - } -}); -Object.defineProperty(exports, 'isURIValid', { - enumerable: true, - get: function get() { - return _lbryURI.isURIValid; - } -}); -Object.defineProperty(exports, 'isURIClaimable', { - enumerable: true, - get: function get() { - return _lbryURI.isURIClaimable; - } -}); -Object.defineProperty(exports, 'isNameValid', { - enumerable: true, - get: function get() { - return _lbryURI.isNameValid; - } -}); -Object.defineProperty(exports, 'convertToShareLink', { - enumerable: true, - get: function get() { - return _lbryURI.convertToShareLink; - } -}); - -var _notifications = __webpack_require__(2); - -Object.defineProperty(exports, 'doToast', { - enumerable: true, - get: function get() { - return _notifications.doToast; - } -}); -Object.defineProperty(exports, 'doDismissToast', { - enumerable: true, - get: function get() { - return _notifications.doDismissToast; - } -}); -Object.defineProperty(exports, 'doError', { - enumerable: true, - get: function get() { - return _notifications.doError; - } -}); -Object.defineProperty(exports, 'doDismissError', { - enumerable: true, - get: function get() { - return _notifications.doDismissError; - } -}); - -var _claims = __webpack_require__(7); - -Object.defineProperty(exports, 'doFetchClaimsByChannel', { - enumerable: true, - get: function get() { - return _claims.doFetchClaimsByChannel; - } -}); -Object.defineProperty(exports, 'doFetchClaimCountByChannel', { - enumerable: true, - get: function get() { - return _claims.doFetchClaimCountByChannel; - } -}); -Object.defineProperty(exports, 'doFetchClaimListMine', { - enumerable: true, - get: function get() { - return _claims.doFetchClaimListMine; - } -}); -Object.defineProperty(exports, 'doAbandonClaim', { - enumerable: true, - get: function get() { - return _claims.doAbandonClaim; - } -}); -Object.defineProperty(exports, 'doResolveUris', { - enumerable: true, - get: function get() { - return _claims.doResolveUris; - } -}); -Object.defineProperty(exports, 'doResolveUri', { - enumerable: true, - get: function get() { - return _claims.doResolveUri; - } -}); - -var _file_info = __webpack_require__(21); - -Object.defineProperty(exports, 'doFetchFileInfo', { - enumerable: true, - get: function get() { - return _file_info.doFetchFileInfo; - } -}); -Object.defineProperty(exports, 'doFileList', { - enumerable: true, - get: function get() { - return _file_info.doFileList; - } -}); -Object.defineProperty(exports, 'doFetchFileInfosAndPublishedClaims', { - enumerable: true, - get: function get() { - return _file_info.doFetchFileInfosAndPublishedClaims; - } -}); -Object.defineProperty(exports, 'doSetFileListSort', { - enumerable: true, - get: function get() { - return _file_info.doSetFileListSort; - } -}); - -var _search = __webpack_require__(23); - -Object.defineProperty(exports, 'doSearch', { - enumerable: true, - get: function get() { - return _search.doSearch; - } -}); -Object.defineProperty(exports, 'doUpdateSearchQuery', { - enumerable: true, - get: function get() { - return _search.doUpdateSearchQuery; - } -}); -Object.defineProperty(exports, 'doFocusSearchInput', { - enumerable: true, - get: function get() { - return _search.doFocusSearchInput; - } -}); -Object.defineProperty(exports, 'doBlurSearchInput', { - enumerable: true, - get: function get() { - return _search.doBlurSearchInput; - } -}); -Object.defineProperty(exports, 'setSearchApi', { - enumerable: true, - get: function get() { - return _search.setSearchApi; - } -}); -Object.defineProperty(exports, 'doUpdateSearchOptions', { - enumerable: true, - get: function get() { - return _search.doUpdateSearchOptions; - } -}); - -var _content = __webpack_require__(27); - -Object.defineProperty(exports, 'savePosition', { - enumerable: true, - get: function get() { - return _content.savePosition; - } -}); - -var _wallet = __webpack_require__(17); - -Object.defineProperty(exports, 'doUpdateBalance', { - enumerable: true, - get: function get() { - return _wallet.doUpdateBalance; - } -}); -Object.defineProperty(exports, 'doBalanceSubscribe', { - enumerable: true, - get: function get() { - return _wallet.doBalanceSubscribe; - } -}); -Object.defineProperty(exports, 'doUpdateTotalBalance', { - enumerable: true, - get: function get() { - return _wallet.doUpdateTotalBalance; - } -}); -Object.defineProperty(exports, 'doTotalBalanceSubscribe', { - enumerable: true, - get: function get() { - return _wallet.doTotalBalanceSubscribe; - } -}); -Object.defineProperty(exports, 'doFetchTransactions', { - enumerable: true, - get: function get() { - return _wallet.doFetchTransactions; - } -}); -Object.defineProperty(exports, 'doFetchBlock', { - enumerable: true, - get: function get() { - return _wallet.doFetchBlock; - } -}); -Object.defineProperty(exports, 'doGetNewAddress', { - enumerable: true, - get: function get() { - return _wallet.doGetNewAddress; - } -}); -Object.defineProperty(exports, 'doCheckAddressIsMine', { - enumerable: true, - get: function get() { - return _wallet.doCheckAddressIsMine; - } -}); -Object.defineProperty(exports, 'doSendDraftTransaction', { - enumerable: true, - get: function get() { - return _wallet.doSendDraftTransaction; - } -}); -Object.defineProperty(exports, 'doSetDraftTransactionAmount', { - enumerable: true, - get: function get() { - return _wallet.doSetDraftTransactionAmount; - } -}); -Object.defineProperty(exports, 'doSetDraftTransactionAddress', { - enumerable: true, - get: function get() { - return _wallet.doSetDraftTransactionAddress; - } -}); -Object.defineProperty(exports, 'doSendTip', { - enumerable: true, - get: function get() { - return _wallet.doSendTip; - } -}); -Object.defineProperty(exports, 'doWalletEncrypt', { - enumerable: true, - get: function get() { - return _wallet.doWalletEncrypt; - } -}); -Object.defineProperty(exports, 'doWalletDecrypt', { - enumerable: true, - get: function get() { - return _wallet.doWalletDecrypt; - } -}); -Object.defineProperty(exports, 'doWalletUnlock', { - enumerable: true, - get: function get() { - return _wallet.doWalletUnlock; - } -}); -Object.defineProperty(exports, 'doWalletStatus', { - enumerable: true, - get: function get() { - return _wallet.doWalletStatus; - } -}); -Object.defineProperty(exports, 'doSetTransactionListFilter', { - enumerable: true, - get: function get() { - return _wallet.doSetTransactionListFilter; - } -}); -Object.defineProperty(exports, 'doUpdateBlockHeight', { - enumerable: true, - get: function get() { - return _wallet.doUpdateBlockHeight; - } -}); - -var _batchActions = __webpack_require__(24); - -Object.defineProperty(exports, 'batchActions', { - enumerable: true, - get: function get() { - return _batchActions.batchActions; - } -}); - -var _query_params = __webpack_require__(14); - -Object.defineProperty(exports, 'parseQueryParams', { - enumerable: true, - get: function get() { - return _query_params.parseQueryParams; - } -}); -Object.defineProperty(exports, 'toQueryString', { - enumerable: true, - get: function get() { - return _query_params.toQueryString; - } -}); - -var _formatCredits = __webpack_require__(20); - -Object.defineProperty(exports, 'formatCredits', { - enumerable: true, - get: function get() { - return _formatCredits.formatCredits; - } -}); -Object.defineProperty(exports, 'formatFullPrice', { - enumerable: true, - get: function get() { - return _formatCredits.formatFullPrice; - } -}); -Object.defineProperty(exports, 'creditsToString', { - enumerable: true, - get: function get() { - return _formatCredits.creditsToString; - } -}); - -var _claims2 = __webpack_require__(28); - -Object.defineProperty(exports, 'claimsReducer', { - enumerable: true, - get: function get() { - return _claims2.claimsReducer; - } -}); - -var _file_info2 = __webpack_require__(29); - -Object.defineProperty(exports, 'fileInfoReducer', { - enumerable: true, - get: function get() { - return _file_info2.fileInfoReducer; - } -}); - -var _notifications2 = __webpack_require__(32); - -Object.defineProperty(exports, 'notificationsReducer', { - enumerable: true, - get: function get() { - return _notifications2.notificationsReducer; - } -}); - -var _search2 = __webpack_require__(34); - -Object.defineProperty(exports, 'searchReducer', { - enumerable: true, - get: function get() { - return _search2.searchReducer; - } -}); - -var _wallet2 = __webpack_require__(35); - -Object.defineProperty(exports, 'walletReducer', { - enumerable: true, - get: function get() { - return _wallet2.walletReducer; - } -}); - -var _content2 = __webpack_require__(36); - -Object.defineProperty(exports, 'contentReducer', { - enumerable: true, - get: function get() { - return _content2.contentReducer; - } -}); - -var _content3 = __webpack_require__(37); - -Object.defineProperty(exports, 'makeSelectContentPositionForUri', { - enumerable: true, - get: function get() { - return _content3.makeSelectContentPositionForUri; - } -}); - -var _notifications3 = __webpack_require__(38); - -Object.defineProperty(exports, 'selectToast', { - enumerable: true, - get: function get() { - return _notifications3.selectToast; - } -}); -Object.defineProperty(exports, 'selectError', { - enumerable: true, - get: function get() { - return _notifications3.selectError; - } -}); - -var _claims3 = __webpack_require__(11); - -Object.defineProperty(exports, 'makeSelectClaimForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimForUri; - } -}); -Object.defineProperty(exports, 'makeSelectClaimIsMine', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimIsMine; - } -}); -Object.defineProperty(exports, 'makeSelectFetchingChannelClaims', { - enumerable: true, - get: function get() { - return _claims3.makeSelectFetchingChannelClaims; - } -}); -Object.defineProperty(exports, 'makeSelectClaimsInChannelForPage', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimsInChannelForPage; - } -}); -Object.defineProperty(exports, 'makeSelectMetadataForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectMetadataForUri; - } -}); -Object.defineProperty(exports, 'makeSelectTitleForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectTitleForUri; - } -}); -Object.defineProperty(exports, 'makeSelectContentTypeForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectContentTypeForUri; - } -}); -Object.defineProperty(exports, 'makeSelectIsUriResolving', { - enumerable: true, - get: function get() { - return _claims3.makeSelectIsUriResolving; - } -}); -Object.defineProperty(exports, 'makeSelectTotalItemsForChannel', { - enumerable: true, - get: function get() { - return _claims3.makeSelectTotalItemsForChannel; - } -}); -Object.defineProperty(exports, 'makeSelectTotalPagesForChannel', { - enumerable: true, - get: function get() { - return _claims3.makeSelectTotalPagesForChannel; - } -}); -Object.defineProperty(exports, 'makeSelectNsfwCountFromUris', { - enumerable: true, - get: function get() { - return _claims3.makeSelectNsfwCountFromUris; - } -}); -Object.defineProperty(exports, 'makeSelectNsfwCountForChannel', { - enumerable: true, - get: function get() { - return _claims3.makeSelectNsfwCountForChannel; - } -}); -Object.defineProperty(exports, 'makeSelectRecommendedContentForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectRecommendedContentForUri; - } -}); -Object.defineProperty(exports, 'makeSelectFirstRecommendedFileForUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectFirstRecommendedFileForUri; - } -}); -Object.defineProperty(exports, 'makeSelectChannelForClaimUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectChannelForClaimUri; - } -}); -Object.defineProperty(exports, 'makeSelectClaimIsPending', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimIsPending; - } -}); -Object.defineProperty(exports, 'makeSelectPendingByUri', { - enumerable: true, - get: function get() { - return _claims3.makeSelectPendingByUri; - } -}); -Object.defineProperty(exports, 'makeSelectClaimsInChannelForCurrentPageState', { - enumerable: true, - get: function get() { - return _claims3.makeSelectClaimsInChannelForCurrentPageState; - } -}); -Object.defineProperty(exports, 'selectPendingById', { - enumerable: true, - get: function get() { - return _claims3.selectPendingById; - } -}); -Object.defineProperty(exports, 'selectClaimsById', { - enumerable: true, - get: function get() { - return _claims3.selectClaimsById; - } -}); -Object.defineProperty(exports, 'selectClaimsByUri', { - enumerable: true, - get: function get() { - return _claims3.selectClaimsByUri; - } -}); -Object.defineProperty(exports, 'selectAllClaimsByChannel', { - enumerable: true, - get: function get() { - return _claims3.selectAllClaimsByChannel; - } -}); -Object.defineProperty(exports, 'selectMyClaimsRaw', { - enumerable: true, - get: function get() { - return _claims3.selectMyClaimsRaw; - } -}); -Object.defineProperty(exports, 'selectAbandoningIds', { - enumerable: true, - get: function get() { - return _claims3.selectAbandoningIds; - } -}); -Object.defineProperty(exports, 'selectMyActiveClaims', { - enumerable: true, - get: function get() { - return _claims3.selectMyActiveClaims; - } -}); -Object.defineProperty(exports, 'selectAllFetchingChannelClaims', { - enumerable: true, - get: function get() { - return _claims3.selectAllFetchingChannelClaims; - } -}); -Object.defineProperty(exports, 'selectIsFetchingClaimListMine', { - enumerable: true, - get: function get() { - return _claims3.selectIsFetchingClaimListMine; - } -}); -Object.defineProperty(exports, 'selectPendingClaims', { - enumerable: true, - get: function get() { - return _claims3.selectPendingClaims; - } -}); -Object.defineProperty(exports, 'selectMyClaims', { - enumerable: true, - get: function get() { - return _claims3.selectMyClaims; - } -}); -Object.defineProperty(exports, 'selectMyClaimsWithoutChannels', { - enumerable: true, - get: function get() { - return _claims3.selectMyClaimsWithoutChannels; - } -}); -Object.defineProperty(exports, 'selectAllMyClaimsByOutpoint', { - enumerable: true, - get: function get() { - return _claims3.selectAllMyClaimsByOutpoint; - } -}); -Object.defineProperty(exports, 'selectMyClaimsOutpoints', { - enumerable: true, - get: function get() { - return _claims3.selectMyClaimsOutpoints; - } -}); -Object.defineProperty(exports, 'selectFetchingMyChannels', { - enumerable: true, - get: function get() { - return _claims3.selectFetchingMyChannels; - } -}); -Object.defineProperty(exports, 'selectMyChannelClaims', { - enumerable: true, - get: function get() { - return _claims3.selectMyChannelClaims; - } -}); -Object.defineProperty(exports, 'selectResolvingUris', { - enumerable: true, - get: function get() { - return _claims3.selectResolvingUris; - } -}); -Object.defineProperty(exports, 'selectPlayingUri', { - enumerable: true, - get: function get() { - return _claims3.selectPlayingUri; - } -}); -Object.defineProperty(exports, 'selectChannelClaimCounts', { - enumerable: true, - get: function get() { - return _claims3.selectChannelClaimCounts; - } -}); -Object.defineProperty(exports, 'selectCurrentChannelPage', { - enumerable: true, - get: function get() { - return _claims3.selectCurrentChannelPage; - } -}); - -var _file_info3 = __webpack_require__(22); - -Object.defineProperty(exports, 'makeSelectFileInfoForUri', { - enumerable: true, - get: function get() { - return _file_info3.makeSelectFileInfoForUri; - } -}); -Object.defineProperty(exports, 'makeSelectDownloadingForUri', { - enumerable: true, - get: function get() { - return _file_info3.makeSelectDownloadingForUri; - } -}); -Object.defineProperty(exports, 'makeSelectLoadingForUri', { - enumerable: true, - get: function get() { - return _file_info3.makeSelectLoadingForUri; - } -}); -Object.defineProperty(exports, 'selectFileInfosByOutpoint', { - enumerable: true, - get: function get() { - return _file_info3.selectFileInfosByOutpoint; - } -}); -Object.defineProperty(exports, 'selectIsFetchingFileList', { - enumerable: true, - get: function get() { - return _file_info3.selectIsFetchingFileList; - } -}); -Object.defineProperty(exports, 'selectIsFetchingFileListDownloadedOrPublished', { - enumerable: true, - get: function get() { - return _file_info3.selectIsFetchingFileListDownloadedOrPublished; - } -}); -Object.defineProperty(exports, 'selectDownloadingByOutpoint', { - enumerable: true, - get: function get() { - return _file_info3.selectDownloadingByOutpoint; - } -}); -Object.defineProperty(exports, 'selectUrisLoading', { - enumerable: true, - get: function get() { - return _file_info3.selectUrisLoading; - } -}); -Object.defineProperty(exports, 'selectFileInfosDownloaded', { - enumerable: true, - get: function get() { - return _file_info3.selectFileInfosDownloaded; - } -}); -Object.defineProperty(exports, 'selectDownloadingFileInfos', { - enumerable: true, - get: function get() { - return _file_info3.selectDownloadingFileInfos; - } -}); -Object.defineProperty(exports, 'selectTotalDownloadProgress', { - enumerable: true, - get: function get() { - return _file_info3.selectTotalDownloadProgress; - } -}); -Object.defineProperty(exports, 'selectSearchDownloadUris', { - enumerable: true, - get: function get() { - return _file_info3.selectSearchDownloadUris; - } -}); -Object.defineProperty(exports, 'selectFileListDownloadedSort', { - enumerable: true, - get: function get() { - return _file_info3.selectFileListDownloadedSort; - } -}); -Object.defineProperty(exports, 'selectFileListPublishedSort', { - enumerable: true, - get: function get() { - return _file_info3.selectFileListPublishedSort; - } -}); - -var _search3 = __webpack_require__(12); - -Object.defineProperty(exports, 'makeSelectSearchUris', { - enumerable: true, - get: function get() { - return _search3.makeSelectSearchUris; - } -}); -Object.defineProperty(exports, 'selectSearchValue', { - enumerable: true, - get: function get() { - return _search3.selectSearchValue; - } -}); -Object.defineProperty(exports, 'selectSearchOptions', { - enumerable: true, - get: function get() { - return _search3.selectSearchOptions; - } -}); -Object.defineProperty(exports, 'selectIsSearching', { - enumerable: true, - get: function get() { - return _search3.selectIsSearching; - } -}); -Object.defineProperty(exports, 'selectSearchUrisByQuery', { - enumerable: true, - get: function get() { - return _search3.selectSearchUrisByQuery; - } -}); -Object.defineProperty(exports, 'selectSearchBarFocused', { - enumerable: true, - get: function get() { - return _search3.selectSearchBarFocused; - } -}); -Object.defineProperty(exports, 'selectSearchSuggestions', { - enumerable: true, - get: function get() { - return _search3.selectSearchSuggestions; - } -}); -Object.defineProperty(exports, 'makeSelectQueryWithOptions', { - enumerable: true, - get: function get() { - return _search3.makeSelectQueryWithOptions; - } -}); - -var _wallet3 = __webpack_require__(18); - -Object.defineProperty(exports, 'makeSelectBlockDate', { - enumerable: true, - get: function get() { - return _wallet3.makeSelectBlockDate; - } -}); -Object.defineProperty(exports, 'selectBalance', { - enumerable: true, - get: function get() { - return _wallet3.selectBalance; - } -}); -Object.defineProperty(exports, 'selectTotalBalance', { - enumerable: true, - get: function get() { - return _wallet3.selectTotalBalance; - } -}); -Object.defineProperty(exports, 'selectTransactionsById', { - enumerable: true, - get: function get() { - return _wallet3.selectTransactionsById; - } -}); -Object.defineProperty(exports, 'selectTransactionItems', { - enumerable: true, - get: function get() { - return _wallet3.selectTransactionItems; - } -}); -Object.defineProperty(exports, 'selectRecentTransactions', { - enumerable: true, - get: function get() { - return _wallet3.selectRecentTransactions; - } -}); -Object.defineProperty(exports, 'selectHasTransactions', { - enumerable: true, - get: function get() { - return _wallet3.selectHasTransactions; - } -}); -Object.defineProperty(exports, 'selectIsFetchingTransactions', { - enumerable: true, - get: function get() { - return _wallet3.selectIsFetchingTransactions; - } -}); -Object.defineProperty(exports, 'selectIsSendingSupport', { - enumerable: true, - get: function get() { - return _wallet3.selectIsSendingSupport; - } -}); -Object.defineProperty(exports, 'selectReceiveAddress', { - enumerable: true, - get: function get() { - return _wallet3.selectReceiveAddress; - } -}); -Object.defineProperty(exports, 'selectGettingNewAddress', { - enumerable: true, - get: function get() { - return _wallet3.selectGettingNewAddress; - } -}); -Object.defineProperty(exports, 'selectDraftTransaction', { - enumerable: true, - get: function get() { - return _wallet3.selectDraftTransaction; - } -}); -Object.defineProperty(exports, 'selectDraftTransactionAmount', { - enumerable: true, - get: function get() { - return _wallet3.selectDraftTransactionAmount; - } -}); -Object.defineProperty(exports, 'selectDraftTransactionAddress', { - enumerable: true, - get: function get() { - return _wallet3.selectDraftTransactionAddress; - } -}); -Object.defineProperty(exports, 'selectDraftTransactionError', { - enumerable: true, - get: function get() { - return _wallet3.selectDraftTransactionError; - } -}); -Object.defineProperty(exports, 'selectBlocks', { - enumerable: true, - get: function get() { - return _wallet3.selectBlocks; - } -}); -Object.defineProperty(exports, 'selectWalletIsEncrypted', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletIsEncrypted; - } -}); -Object.defineProperty(exports, 'selectWalletState', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletState; - } -}); -Object.defineProperty(exports, 'selectWalletEncryptPending', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletEncryptPending; - } -}); -Object.defineProperty(exports, 'selectWalletEncryptSucceeded', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletEncryptSucceeded; - } -}); -Object.defineProperty(exports, 'selectWalletEncryptResult', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletEncryptResult; - } -}); -Object.defineProperty(exports, 'selectWalletDecryptPending', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletDecryptPending; - } -}); -Object.defineProperty(exports, 'selectWalletDecryptSucceeded', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletDecryptSucceeded; - } -}); -Object.defineProperty(exports, 'selectWalletDecryptResult', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletDecryptResult; - } -}); -Object.defineProperty(exports, 'selectWalletUnlockPending', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletUnlockPending; - } -}); -Object.defineProperty(exports, 'selectWalletUnlockSucceeded', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletUnlockSucceeded; - } -}); -Object.defineProperty(exports, 'selectWalletUnlockResult', { - enumerable: true, - get: function get() { - return _wallet3.selectWalletUnlockResult; - } -}); -Object.defineProperty(exports, 'selectTransactionListFilter', { - enumerable: true, - get: function get() { - return _wallet3.selectTransactionListFilter; - } -}); - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _thumbnail_upload_statuses = __webpack_require__(39); - -var THUMBNAIL_STATUSES = _interopRequireWildcard(_thumbnail_upload_statuses); - -var _settings = __webpack_require__(40); - -var SETTINGS = _interopRequireWildcard(_settings); - -var _transaction_types = __webpack_require__(19); - -var TRANSACTIONS = _interopRequireWildcard(_transaction_types); - -var _sort_options = __webpack_require__(30); - -var SORT_OPTIONS = _interopRequireWildcard(_sort_options); - -var _pages = __webpack_require__(31); - -var PAGES = _interopRequireWildcard(_pages); - -var _search4 = __webpack_require__(13); - -var _lbry = __webpack_require__(8); - -var _lbry2 = _interopRequireDefault(_lbry); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -// types -// export { Toast } from 'types/Notification'; - -// constants -exports.ACTIONS = ACTIONS; -exports.THUMBNAIL_STATUSES = THUMBNAIL_STATUSES; -exports.SEARCH_TYPES = _search4.SEARCH_TYPES; -exports.SEARCH_OPTIONS = _search4.SEARCH_OPTIONS; -exports.SETTINGS = SETTINGS; -exports.TRANSACTIONS = TRANSACTIONS; -exports.SORT_OPTIONS = SORT_OPTIONS; -exports.PAGES = PAGES; - -// common - -exports.Lbry = _lbry2.default; -exports.selectSearchState = _search3.selectState; - -/***/ }), -/* 1 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = 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; }; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -exports.parseURI = parseURI; -exports.buildURI = buildURI; -exports.normalizeURI = normalizeURI; -exports.isURIValid = isURIValid; -exports.isNameValid = isNameValid; -exports.isURIClaimable = isURIClaimable; -exports.convertToShareLink = convertToShareLink; -var channelNameMinLength = 1; -var claimIdMaxLength = 40; - -var regexInvalidURI = exports.regexInvalidURI = /[^A-Za-z0-9-]/g; -var regexAddress = exports.regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; - -/** - * Parses a LBRY name into its component parts. Throws errors with user-friendly - * messages for invalid names. - * - * N.B. that "name" indicates the value in the name position of the URI. For - * claims for channel content, this will actually be the channel name, and - * the content name is in the path (e.g. lbry://@channel/content) - * - * In most situations, you'll want to use the contentName and channelName keys - * and ignore the name key. - * - * Returns a dictionary with keys: - * - name (string): The value in the "name" position in the URI. Note that this - * could be either content name or channel name; see above. - * - path (string, if persent) - * - claimSequence (int, if present) - * - bidPosition (int, if present) - * - claimId (string, if present) - * - isChannel (boolean) - * - contentName (string): For anon claims, the name; for channel claims, the path - * - channelName (string, if present): Channel name without @ - */ -function parseURI(URI) { - var requireProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - // Break into components. Empty sub-matches are converted to null - var componentsRegex = new RegExp('^((?:lbry://)?)' + // protocol - '([^:$#/]*)' + // claim name (stops at the first separator or end) - '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) - '(/?)(.*)' // path separator, path - ); - - var _componentsRegex$exec = componentsRegex.exec(URI).slice(1).map(function (match) { - return match || null; - }), - _componentsRegex$exec2 = _slicedToArray(_componentsRegex$exec, 6), - proto = _componentsRegex$exec2[0], - claimName = _componentsRegex$exec2[1], - modSep = _componentsRegex$exec2[2], - modVal = _componentsRegex$exec2[3], - pathSep = _componentsRegex$exec2[4], - path = _componentsRegex$exec2[5]; - - var contentName = void 0; - - // Validate protocol - if (requireProto && !proto) { - throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); - } - - // Validate and process name - if (!claimName) { - throw new Error(__('URI does not include name.')); - } - - var isChannel = claimName.startsWith('@'); - var channelName = isChannel ? claimName.slice(1) : claimName; - - if (isChannel) { - if (!channelName) { - throw new Error(__('No channel name after @.')); - } - - if (channelName.length < channelNameMinLength) { - throw new Error(__('Channel names must be at least %s characters.', channelNameMinLength)); - } - - contentName = path; - } - - var nameBadChars = (channelName || claimName).match(regexInvalidURI); - if (nameBadChars) { - throw new Error(__('Invalid character %s in name: %s.', nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); - } - - // Validate and process modifier (claim ID, bid position or claim sequence) - var claimId = void 0; - var claimSequence = void 0; - var bidPosition = void 0; - if (modSep) { - if (!modVal) { - throw new Error(__('No modifier provided after separator %s.', modSep)); - } - - if (modSep === '#') { - claimId = modVal; - } else if (modSep === ':') { - claimSequence = modVal; - } else if (modSep === '$') { - bidPosition = modVal; - } - } - - if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__('Invalid claim ID %s.', claimId)); - } - - if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Claim sequence must be a number.')); - } - - if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Bid position must be a number.')); - } - - // Validate and process path - if (path) { - if (!isChannel) { - throw new Error(__('Only channel URIs may have a path.')); - } - - var pathBadChars = path.match(regexInvalidURI); - if (pathBadChars) { - throw new Error(__('Invalid character in path: %s', pathBadChars.join(', '))); - } - - contentName = path; - } else if (pathSep) { - throw new Error(__('No path provided after /')); - } - - return _extends({ - claimName: claimName, - path: path, - isChannel: isChannel - }, contentName ? { contentName: contentName } : {}, channelName ? { channelName: channelName } : {}, claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}, bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}, claimId ? { claimId: claimId } : {}, path ? { path: path } : {}); -} - -/** - * Takes an object in the same format returned by parse() and builds a URI. - * - * The channelName key will accept names with or without the @ prefix. - */ -function buildURI(URIObj) { - var includeProto = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - var protoDefault = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 'lbry://'; - var claimId = URIObj.claimId, - claimSequence = URIObj.claimSequence, - bidPosition = URIObj.bidPosition, - contentName = URIObj.contentName, - channelName = URIObj.channelName; - var claimName = URIObj.claimName, - path = URIObj.path; - - - if (channelName) { - var channelNameFormatted = channelName.startsWith('@') ? channelName : '@' + channelName; - if (!claimName) { - claimName = channelNameFormatted; - } else if (claimName !== channelNameFormatted) { - throw new Error(__('Received a channel content URI, but claim name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.')); - } - } - - if (contentName) { - if (!claimName) { - claimName = contentName; - } else if (!path) { - path = contentName; - } - if (path && path !== contentName) { - throw new Error(__('Path and contentName do not match. Only one is required; most likely you wanted contentName.')); - } - } - - return (includeProto ? protoDefault : '') + claimName + (claimId ? '#' + claimId : '') + (claimSequence ? ':' + claimSequence : '') + (bidPosition ? '' + bidPosition : '') + (path ? '/' + path : ''); -} - -/* Takes a parseable LBRY URI and converts it to standard, canonical format */ -function normalizeURI(URI) { - var _parseURI = parseURI(URI), - claimName = _parseURI.claimName, - path = _parseURI.path, - bidPosition = _parseURI.bidPosition, - claimSequence = _parseURI.claimSequence, - claimId = _parseURI.claimId; - - return buildURI({ claimName: claimName, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }); -} - -function isURIValid(URI) { - var parts = void 0; - try { - parts = parseURI(normalizeURI(URI)); - } catch (error) { - return false; - } - return parts && parts.claimName; -} - -function isNameValid(claimName) { - var checkCase = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; - - var regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); - return regexp.test(claimName); -} - -function isURIClaimable(URI) { - var parts = void 0; - try { - parts = parseURI(normalizeURI(URI)); - } catch (error) { - return false; - } - return parts && parts.claimName && !parts.claimId && !parts.bidPosition && !parts.claimSequence && !parts.isChannel && !parts.path; -} - -function convertToShareLink(URI) { - var _parseURI2 = parseURI(URI), - claimName = _parseURI2.claimName, - path = _parseURI2.path, - bidPosition = _parseURI2.bidPosition, - claimSequence = _parseURI2.claimSequence, - claimId = _parseURI2.claimId; - - return buildURI({ claimName: claimName, path: path, claimSequence: claimSequence, bidPosition: bidPosition, claimId: claimId }, true, 'https://open.lbry.io/'); -} - -/***/ }), -/* 2 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doToast = doToast; -exports.doDismissToast = doDismissToast; -exports.doError = doError; -exports.doDismissError = doDismissError; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _v = __webpack_require__(4); - -var _v2 = _interopRequireDefault(_v); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -// @flow -/*:: import type { ToastParams } from 'types/Notification';*/ -function doToast(params /*: ToastParams*/) { - if (!params) { - throw Error("'params' object is required to create a toast notification"); - } - - return { - type: ACTIONS.CREATE_TOAST, - data: { - id: (0, _v2.default)(), - params: params - } - }; -} - -function doDismissToast() { - return { - type: ACTIONS.DISMISS_TOAST - }; -} - -function doError(error /*: string | {}*/) { - return { - type: ACTIONS.CREATE_ERROR, - data: { - error: error - } - }; -} - -function doDismissError() { - return { - type: ACTIONS.DISMISS_ERROR - }; -} - -/***/ }), -/* 3 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var WINDOW_FOCUSED = exports.WINDOW_FOCUSED = 'WINDOW_FOCUSED'; -var DAEMON_READY = exports.DAEMON_READY = 'DAEMON_READY'; -var DAEMON_VERSION_MATCH = exports.DAEMON_VERSION_MATCH = 'DAEMON_VERSION_MATCH'; -var DAEMON_VERSION_MISMATCH = exports.DAEMON_VERSION_MISMATCH = 'DAEMON_VERSION_MISMATCH'; -var VOLUME_CHANGED = exports.VOLUME_CHANGED = 'VOLUME_CHANGED'; - -// Navigation -var CHANGE_AFTER_AUTH_PATH = exports.CHANGE_AFTER_AUTH_PATH = 'CHANGE_AFTER_AUTH_PATH'; -var WINDOW_SCROLLED = exports.WINDOW_SCROLLED = 'WINDOW_SCROLLED'; -var HISTORY_NAVIGATE = exports.HISTORY_NAVIGATE = 'HISTORY_NAVIGATE'; - -// Upgrades -var UPGRADE_CANCELLED = exports.UPGRADE_CANCELLED = 'UPGRADE_CANCELLED'; -var DOWNLOAD_UPGRADE = exports.DOWNLOAD_UPGRADE = 'DOWNLOAD_UPGRADE'; -var UPGRADE_DOWNLOAD_STARTED = exports.UPGRADE_DOWNLOAD_STARTED = 'UPGRADE_DOWNLOAD_STARTED'; -var UPGRADE_DOWNLOAD_COMPLETED = exports.UPGRADE_DOWNLOAD_COMPLETED = 'UPGRADE_DOWNLOAD_COMPLETED'; -var UPGRADE_DOWNLOAD_PROGRESSED = exports.UPGRADE_DOWNLOAD_PROGRESSED = 'UPGRADE_DOWNLOAD_PROGRESSED'; -var CHECK_UPGRADE_AVAILABLE = exports.CHECK_UPGRADE_AVAILABLE = 'CHECK_UPGRADE_AVAILABLE'; -var CHECK_UPGRADE_START = exports.CHECK_UPGRADE_START = 'CHECK_UPGRADE_START'; -var CHECK_UPGRADE_SUCCESS = exports.CHECK_UPGRADE_SUCCESS = 'CHECK_UPGRADE_SUCCESS'; -var CHECK_UPGRADE_FAIL = exports.CHECK_UPGRADE_FAIL = 'CHECK_UPGRADE_FAIL'; -var CHECK_UPGRADE_SUBSCRIBE = exports.CHECK_UPGRADE_SUBSCRIBE = 'CHECK_UPGRADE_SUBSCRIBE'; -var UPDATE_VERSION = exports.UPDATE_VERSION = 'UPDATE_VERSION'; -var UPDATE_REMOTE_VERSION = exports.UPDATE_REMOTE_VERSION = 'UPDATE_REMOTE_VERSION'; -var SKIP_UPGRADE = exports.SKIP_UPGRADE = 'SKIP_UPGRADE'; -var START_UPGRADE = exports.START_UPGRADE = 'START_UPGRADE'; -var AUTO_UPDATE_DECLINED = exports.AUTO_UPDATE_DECLINED = 'AUTO_UPDATE_DECLINED'; -var AUTO_UPDATE_DOWNLOADED = exports.AUTO_UPDATE_DOWNLOADED = 'AUTO_UPDATE_DOWNLOADED'; -var CLEAR_UPGRADE_TIMER = exports.CLEAR_UPGRADE_TIMER = 'CLEAR_UPGRADE_TIMER'; - -// Wallet -var GET_NEW_ADDRESS_STARTED = exports.GET_NEW_ADDRESS_STARTED = 'GET_NEW_ADDRESS_STARTED'; -var GET_NEW_ADDRESS_COMPLETED = exports.GET_NEW_ADDRESS_COMPLETED = 'GET_NEW_ADDRESS_COMPLETED'; -var FETCH_TRANSACTIONS_STARTED = exports.FETCH_TRANSACTIONS_STARTED = 'FETCH_TRANSACTIONS_STARTED'; -var FETCH_TRANSACTIONS_COMPLETED = exports.FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'; -var UPDATE_BALANCE = exports.UPDATE_BALANCE = 'UPDATE_BALANCE'; -var UPDATE_TOTAL_BALANCE = exports.UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; -var CHECK_ADDRESS_IS_MINE_STARTED = exports.CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; -var CHECK_ADDRESS_IS_MINE_COMPLETED = exports.CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED'; -var SEND_TRANSACTION_STARTED = exports.SEND_TRANSACTION_STARTED = 'SEND_TRANSACTION_STARTED'; -var SEND_TRANSACTION_COMPLETED = exports.SEND_TRANSACTION_COMPLETED = 'SEND_TRANSACTION_COMPLETED'; -var SEND_TRANSACTION_FAILED = exports.SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'; -var FETCH_BLOCK_SUCCESS = exports.FETCH_BLOCK_SUCCESS = 'FETCH_BLOCK_SUCCESS'; -var SUPPORT_TRANSACTION_STARTED = exports.SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED'; -var SUPPORT_TRANSACTION_COMPLETED = exports.SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED'; -var SUPPORT_TRANSACTION_FAILED = exports.SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED'; -var WALLET_ENCRYPT_START = exports.WALLET_ENCRYPT_START = 'WALLET_ENCRYPT_START'; -var WALLET_ENCRYPT_COMPLETED = exports.WALLET_ENCRYPT_COMPLETED = 'WALLET_ENCRYPT_COMPLETED'; -var WALLET_ENCRYPT_FAILED = exports.WALLET_ENCRYPT_FAILED = 'WALLET_ENCRYPT_FAILED'; -var WALLET_UNLOCK_START = exports.WALLET_UNLOCK_START = 'WALLET_UNLOCK_START'; -var WALLET_UNLOCK_COMPLETED = exports.WALLET_UNLOCK_COMPLETED = 'WALLET_UNLOCK_COMPLETED'; -var WALLET_UNLOCK_FAILED = exports.WALLET_UNLOCK_FAILED = 'WALLET_UNLOCK_FAILED'; -var WALLET_DECRYPT_START = exports.WALLET_DECRYPT_START = 'WALLET_DECRYPT_START'; -var WALLET_DECRYPT_COMPLETED = exports.WALLET_DECRYPT_COMPLETED = 'WALLET_DECRYPT_COMPLETED'; -var WALLET_DECRYPT_FAILED = exports.WALLET_DECRYPT_FAILED = 'WALLET_DECRYPT_FAILED'; -var WALLET_LOCK_START = exports.WALLET_LOCK_START = 'WALLET_LOCK_START'; -var WALLET_LOCK_COMPLETED = exports.WALLET_LOCK_COMPLETED = 'WALLET_LOCK_COMPLETED'; -var WALLET_LOCK_FAILED = exports.WALLET_LOCK_FAILED = 'WALLET_LOCK_FAILED'; -var WALLET_STATUS_START = exports.WALLET_STATUS_START = 'WALLET_STATUS_START'; -var WALLET_STATUS_COMPLETED = exports.WALLET_STATUS_COMPLETED = 'WALLET_STATUS_COMPLETED'; -var SET_TRANSACTION_LIST_FILTER = exports.SET_TRANSACTION_LIST_FILTER = 'SET_TRANSACTION_LIST_FILTER'; -var UPDATE_CURRENT_HEIGHT = exports.UPDATE_CURRENT_HEIGHT = 'UPDATE_CURRENT_HEIGHT'; -var SET_DRAFT_TRANSACTION_AMOUNT = exports.SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; -var SET_DRAFT_TRANSACTION_ADDRESS = exports.SET_DRAFT_TRANSACTION_ADDRESS = 'SET_DRAFT_TRANSACTION_ADDRESS'; - -// Claims -var RESOLVE_URIS_STARTED = exports.RESOLVE_URIS_STARTED = 'RESOLVE_URIS_STARTED'; -var RESOLVE_URIS_COMPLETED = exports.RESOLVE_URIS_COMPLETED = 'RESOLVE_URIS_COMPLETED'; -var FETCH_CHANNEL_CLAIMS_STARTED = exports.FETCH_CHANNEL_CLAIMS_STARTED = 'FETCH_CHANNEL_CLAIMS_STARTED'; -var FETCH_CHANNEL_CLAIMS_COMPLETED = exports.FETCH_CHANNEL_CLAIMS_COMPLETED = 'FETCH_CHANNEL_CLAIMS_COMPLETED'; -var FETCH_CHANNEL_CLAIM_COUNT_STARTED = exports.FETCH_CHANNEL_CLAIM_COUNT_STARTED = 'FETCH_CHANNEL_CLAIM_COUNT_STARTED'; -var FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = exports.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED = 'FETCH_CHANNEL_CLAIM_COUNT_COMPLETED'; -var FETCH_CLAIM_LIST_MINE_STARTED = exports.FETCH_CLAIM_LIST_MINE_STARTED = 'FETCH_CLAIM_LIST_MINE_STARTED'; -var FETCH_CLAIM_LIST_MINE_COMPLETED = exports.FETCH_CLAIM_LIST_MINE_COMPLETED = 'FETCH_CLAIM_LIST_MINE_COMPLETED'; -var ABANDON_CLAIM_STARTED = exports.ABANDON_CLAIM_STARTED = 'ABANDON_CLAIM_STARTED'; -var ABANDON_CLAIM_SUCCEEDED = exports.ABANDON_CLAIM_SUCCEEDED = 'ABANDON_CLAIM_SUCCEEDED'; -var FETCH_CHANNEL_LIST_STARTED = exports.FETCH_CHANNEL_LIST_STARTED = 'FETCH_CHANNEL_LIST_STARTED'; -var FETCH_CHANNEL_LIST_COMPLETED = exports.FETCH_CHANNEL_LIST_COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED'; -var CREATE_CHANNEL_STARTED = exports.CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED'; -var CREATE_CHANNEL_COMPLETED = exports.CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; -var PUBLISH_STARTED = exports.PUBLISH_STARTED = 'PUBLISH_STARTED'; -var PUBLISH_COMPLETED = exports.PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; -var PUBLISH_FAILED = exports.PUBLISH_FAILED = 'PUBLISH_FAILED'; -var SET_PLAYING_URI = exports.SET_PLAYING_URI = 'SET_PLAYING_URI'; -var SET_CONTENT_POSITION = exports.SET_CONTENT_POSITION = 'SET_CONTENT_POSITION'; -var SET_CONTENT_LAST_VIEWED = exports.SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED'; -var CLEAR_CONTENT_HISTORY_URI = exports.CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI'; -var CLEAR_CONTENT_HISTORY_ALL = exports.CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL'; - -// Files -var FILE_LIST_STARTED = exports.FILE_LIST_STARTED = 'FILE_LIST_STARTED'; -var FILE_LIST_SUCCEEDED = exports.FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; -var FETCH_FILE_INFO_STARTED = exports.FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'; -var FETCH_FILE_INFO_COMPLETED = exports.FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'; -var LOADING_VIDEO_STARTED = exports.LOADING_VIDEO_STARTED = 'LOADING_VIDEO_STARTED'; -var LOADING_VIDEO_COMPLETED = exports.LOADING_VIDEO_COMPLETED = 'LOADING_VIDEO_COMPLETED'; -var LOADING_VIDEO_FAILED = exports.LOADING_VIDEO_FAILED = 'LOADING_VIDEO_FAILED'; -var DOWNLOADING_STARTED = exports.DOWNLOADING_STARTED = 'DOWNLOADING_STARTED'; -var DOWNLOADING_PROGRESSED = exports.DOWNLOADING_PROGRESSED = 'DOWNLOADING_PROGRESSED'; -var DOWNLOADING_COMPLETED = exports.DOWNLOADING_COMPLETED = 'DOWNLOADING_COMPLETED'; -var DOWNLOADING_CANCELED = exports.DOWNLOADING_CANCELED = 'DOWNLOADING_CANCELED'; -var PLAY_VIDEO_STARTED = exports.PLAY_VIDEO_STARTED = 'PLAY_VIDEO_STARTED'; -var FETCH_AVAILABILITY_STARTED = exports.FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'; -var FETCH_AVAILABILITY_COMPLETED = exports.FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'; -var FILE_DELETE = exports.FILE_DELETE = 'FILE_DELETE'; -var SET_FILE_LIST_SORT = exports.SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; - -// Search -var SEARCH_START = exports.SEARCH_START = 'SEARCH_START'; -var SEARCH_SUCCESS = exports.SEARCH_SUCCESS = 'SEARCH_SUCCESS'; -var SEARCH_FAIL = exports.SEARCH_FAIL = 'SEARCH_FAIL'; -var UPDATE_SEARCH_QUERY = exports.UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY'; -var UPDATE_SEARCH_OPTIONS = exports.UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS'; -var UPDATE_SEARCH_SUGGESTIONS = exports.UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS'; -var SEARCH_FOCUS = exports.SEARCH_FOCUS = 'SEARCH_FOCUS'; -var SEARCH_BLUR = exports.SEARCH_BLUR = 'SEARCH_BLUR'; - -// Settings -var DAEMON_SETTINGS_RECEIVED = exports.DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; -var CLIENT_SETTING_CHANGED = exports.CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; -var UPDATE_IS_NIGHT = exports.UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT'; - -// User -var AUTHENTICATION_STARTED = exports.AUTHENTICATION_STARTED = 'AUTHENTICATION_STARTED'; -var AUTHENTICATION_SUCCESS = exports.AUTHENTICATION_SUCCESS = 'AUTHENTICATION_SUCCESS'; -var AUTHENTICATION_FAILURE = exports.AUTHENTICATION_FAILURE = 'AUTHENTICATION_FAILURE'; -var USER_EMAIL_DECLINE = exports.USER_EMAIL_DECLINE = 'USER_EMAIL_DECLINE'; -var USER_EMAIL_NEW_STARTED = exports.USER_EMAIL_NEW_STARTED = 'USER_EMAIL_NEW_STARTED'; -var USER_EMAIL_NEW_SUCCESS = exports.USER_EMAIL_NEW_SUCCESS = 'USER_EMAIL_NEW_SUCCESS'; -var USER_EMAIL_NEW_EXISTS = exports.USER_EMAIL_NEW_EXISTS = 'USER_EMAIL_NEW_EXISTS'; -var USER_EMAIL_NEW_FAILURE = exports.USER_EMAIL_NEW_FAILURE = 'USER_EMAIL_NEW_FAILURE'; -var USER_EMAIL_VERIFY_SET = exports.USER_EMAIL_VERIFY_SET = 'USER_EMAIL_VERIFY_SET'; -var USER_EMAIL_VERIFY_STARTED = exports.USER_EMAIL_VERIFY_STARTED = 'USER_EMAIL_VERIFY_STARTED'; -var USER_EMAIL_VERIFY_SUCCESS = exports.USER_EMAIL_VERIFY_SUCCESS = 'USER_EMAIL_VERIFY_SUCCESS'; -var USER_EMAIL_VERIFY_FAILURE = exports.USER_EMAIL_VERIFY_FAILURE = 'USER_EMAIL_VERIFY_FAILURE'; -var USER_EMAIL_VERIFY_RETRY = exports.USER_EMAIL_VERIFY_RETRY = 'USER_EMAIL_VERIFY_RETRY'; -var USER_PHONE_RESET = exports.USER_PHONE_RESET = 'USER_PHONE_RESET'; -var USER_PHONE_NEW_STARTED = exports.USER_PHONE_NEW_STARTED = 'USER_PHONE_NEW_STARTED'; -var USER_PHONE_NEW_SUCCESS = exports.USER_PHONE_NEW_SUCCESS = 'USER_PHONE_NEW_SUCCESS'; -var USER_PHONE_NEW_FAILURE = exports.USER_PHONE_NEW_FAILURE = 'USER_PHONE_NEW_FAILURE'; -var USER_PHONE_VERIFY_STARTED = exports.USER_PHONE_VERIFY_STARTED = 'USER_PHONE_VERIFY_STARTED'; -var USER_PHONE_VERIFY_SUCCESS = exports.USER_PHONE_VERIFY_SUCCESS = 'USER_PHONE_VERIFY_SUCCESS'; -var USER_PHONE_VERIFY_FAILURE = exports.USER_PHONE_VERIFY_FAILURE = 'USER_PHONE_VERIFY_FAILURE'; -var USER_IDENTITY_VERIFY_STARTED = exports.USER_IDENTITY_VERIFY_STARTED = 'USER_IDENTITY_VERIFY_STARTED'; -var USER_IDENTITY_VERIFY_SUCCESS = exports.USER_IDENTITY_VERIFY_SUCCESS = 'USER_IDENTITY_VERIFY_SUCCESS'; -var USER_IDENTITY_VERIFY_FAILURE = exports.USER_IDENTITY_VERIFY_FAILURE = 'USER_IDENTITY_VERIFY_FAILURE'; -var USER_FETCH_STARTED = exports.USER_FETCH_STARTED = 'USER_FETCH_STARTED'; -var USER_FETCH_SUCCESS = exports.USER_FETCH_SUCCESS = 'USER_FETCH_SUCCESS'; -var USER_FETCH_FAILURE = exports.USER_FETCH_FAILURE = 'USER_FETCH_FAILURE'; -var USER_INVITE_STATUS_FETCH_STARTED = exports.USER_INVITE_STATUS_FETCH_STARTED = 'USER_INVITE_STATUS_FETCH_STARTED'; -var USER_INVITE_STATUS_FETCH_SUCCESS = exports.USER_INVITE_STATUS_FETCH_SUCCESS = 'USER_INVITE_STATUS_FETCH_SUCCESS'; -var USER_INVITE_STATUS_FETCH_FAILURE = exports.USER_INVITE_STATUS_FETCH_FAILURE = 'USER_INVITE_STATUS_FETCH_FAILURE'; -var USER_INVITE_NEW_STARTED = exports.USER_INVITE_NEW_STARTED = 'USER_INVITE_NEW_STARTED'; -var USER_INVITE_NEW_SUCCESS = exports.USER_INVITE_NEW_SUCCESS = 'USER_INVITE_NEW_SUCCESS'; -var USER_INVITE_NEW_FAILURE = exports.USER_INVITE_NEW_FAILURE = 'USER_INVITE_NEW_FAILURE'; -var FETCH_ACCESS_TOKEN_SUCCESS = exports.FETCH_ACCESS_TOKEN_SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS'; - -// Rewards -var FETCH_REWARDS_STARTED = exports.FETCH_REWARDS_STARTED = 'FETCH_REWARDS_STARTED'; -var FETCH_REWARDS_COMPLETED = exports.FETCH_REWARDS_COMPLETED = 'FETCH_REWARDS_COMPLETED'; -var CLAIM_REWARD_STARTED = exports.CLAIM_REWARD_STARTED = 'CLAIM_REWARD_STARTED'; -var CLAIM_REWARD_SUCCESS = exports.CLAIM_REWARD_SUCCESS = 'CLAIM_REWARD_SUCCESS'; -var CLAIM_REWARD_FAILURE = exports.CLAIM_REWARD_FAILURE = 'CLAIM_REWARD_FAILURE'; -var CLAIM_REWARD_CLEAR_ERROR = exports.CLAIM_REWARD_CLEAR_ERROR = 'CLAIM_REWARD_CLEAR_ERROR'; -var FETCH_REWARD_CONTENT_COMPLETED = exports.FETCH_REWARD_CONTENT_COMPLETED = 'FETCH_REWARD_CONTENT_COMPLETED'; - -// Language -var DOWNLOAD_LANGUAGE_SUCCEEDED = exports.DOWNLOAD_LANGUAGE_SUCCEEDED = 'DOWNLOAD_LANGUAGE_SUCCEEDED'; -var DOWNLOAD_LANGUAGE_FAILED = exports.DOWNLOAD_LANGUAGE_FAILED = 'DOWNLOAD_LANGUAGE_FAILED'; - -// ShapeShift -var GET_SUPPORTED_COINS_START = exports.GET_SUPPORTED_COINS_START = 'GET_SUPPORTED_COINS_START'; -var GET_SUPPORTED_COINS_SUCCESS = exports.GET_SUPPORTED_COINS_SUCCESS = 'GET_SUPPORTED_COINS_SUCCESS'; -var GET_SUPPORTED_COINS_FAIL = exports.GET_SUPPORTED_COINS_FAIL = 'GET_SUPPORTED_COINS_FAIL'; -var GET_COIN_STATS_START = exports.GET_COIN_STATS_START = 'GET_COIN_STATS_START'; -var GET_COIN_STATS_SUCCESS = exports.GET_COIN_STATS_SUCCESS = 'GET_COIN_STATS_SUCCESS'; -var GET_COIN_STATS_FAIL = exports.GET_COIN_STATS_FAIL = 'GET_COIN_STATS_FAIL'; -var PREPARE_SHAPE_SHIFT_START = exports.PREPARE_SHAPE_SHIFT_START = 'PREPARE_SHAPE_SHIFT_START'; -var PREPARE_SHAPE_SHIFT_SUCCESS = exports.PREPARE_SHAPE_SHIFT_SUCCESS = 'PREPARE_SHAPE_SHIFT_SUCCESS'; -var PREPARE_SHAPE_SHIFT_FAIL = exports.PREPARE_SHAPE_SHIFT_FAIL = 'PREPARE_SHAPE_SHIFT_FAIL'; -var GET_ACTIVE_SHIFT_START = exports.GET_ACTIVE_SHIFT_START = 'GET_ACTIVE_SHIFT_START'; -var GET_ACTIVE_SHIFT_SUCCESS = exports.GET_ACTIVE_SHIFT_SUCCESS = 'GET_ACTIVE_SHIFT_SUCCESS'; -var GET_ACTIVE_SHIFT_FAIL = exports.GET_ACTIVE_SHIFT_FAIL = 'GET_ACTIVE_SHIFT_FAIL'; -var CLEAR_SHAPE_SHIFT = exports.CLEAR_SHAPE_SHIFT = 'CLEAR_SHAPE_SHIFT'; - -// Subscriptions -var CHANNEL_SUBSCRIBE = exports.CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE'; -var CHANNEL_UNSUBSCRIBE = exports.CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE'; -var HAS_FETCHED_SUBSCRIPTIONS = exports.HAS_FETCHED_SUBSCRIPTIONS = 'HAS_FETCHED_SUBSCRIPTIONS'; -var SET_SUBSCRIPTION_LATEST = exports.SET_SUBSCRIPTION_LATEST = 'SET_SUBSCRIPTION_LATEST'; -var SET_SUBSCRIPTION_NOTIFICATION = exports.SET_SUBSCRIPTION_NOTIFICATION = 'SET_SUBSCRIPTION_NOTIFICATION'; -var SET_SUBSCRIPTION_NOTIFICATIONS = exports.SET_SUBSCRIPTION_NOTIFICATIONS = 'SET_SUBSCRIPTION_NOTIFICATIONS'; -var CHECK_SUBSCRIPTION_STARTED = exports.CHECK_SUBSCRIPTION_STARTED = 'CHECK_SUBSCRIPTION_STARTED'; -var CHECK_SUBSCRIPTION_COMPLETED = exports.CHECK_SUBSCRIPTION_COMPLETED = 'CHECK_SUBSCRIPTION_COMPLETED'; -var CHECK_SUBSCRIPTIONS_SUBSCRIBE = exports.CHECK_SUBSCRIPTIONS_SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE'; - -// Publishing -var CLEAR_PUBLISH = exports.CLEAR_PUBLISH = 'CLEAR_PUBLISH'; -var UPDATE_PUBLISH_FORM = exports.UPDATE_PUBLISH_FORM = 'UPDATE_PUBLISH_FORM'; -var PUBLISH_START = exports.PUBLISH_START = 'PUBLISH_START'; -var PUBLISH_SUCCESS = exports.PUBLISH_SUCCESS = 'PUBLISH_SUCCESS'; -var PUBLISH_FAIL = exports.PUBLISH_FAIL = 'PUBLISH_FAIL'; -var CLEAR_PUBLISH_ERROR = exports.CLEAR_PUBLISH_ERROR = 'CLEAR_PUBLISH_ERROR'; -var REMOVE_PENDING_PUBLISH = exports.REMOVE_PENDING_PUBLISH = 'REMOVE_PENDING_PUBLISH'; -var DO_PREPARE_EDIT = exports.DO_PREPARE_EDIT = 'DO_PREPARE_EDIT'; - -// Notifications -var CREATE_NOTIFICATION = exports.CREATE_NOTIFICATION = 'CREATE_NOTIFICATION'; -var EDIT_NOTIFICATION = exports.EDIT_NOTIFICATION = 'EDIT_NOTIFICATION'; -var DELETE_NOTIFICATION = exports.DELETE_NOTIFICATION = 'DELETE_NOTIFICATION'; -var DISMISS_NOTIFICATION = exports.DISMISS_NOTIFICATION = 'DISMISS_NOTIFICATION'; -var CREATE_TOAST = exports.CREATE_TOAST = 'CREATE_TOAST'; -var DISMISS_TOAST = exports.DISMISS_TOAST = 'DISMISS_TOAST'; -var CREATE_ERROR = exports.CREATE_ERROR = 'CREATE_ERROR'; -var DISMISS_ERROR = exports.DISMISS_ERROR = 'DISMISS_ERROR'; - -var FETCH_DATE = exports.FETCH_DATE = 'FETCH_DATE'; - -/***/ }), -/* 4 */ -/***/ (function(module, exports, __webpack_require__) { - -var rng = __webpack_require__(5); -var bytesToUuid = __webpack_require__(6); - -function v4(options, buf, offset) { - var i = buf && offset || 0; - - if (typeof(options) == 'string') { - buf = options === 'binary' ? new Array(16) : null; - options = null; - } - options = options || {}; - - var rnds = options.random || (options.rng || rng)(); - - // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` - rnds[6] = (rnds[6] & 0x0f) | 0x40; - rnds[8] = (rnds[8] & 0x3f) | 0x80; - - // Copy bytes to buffer, if provided - if (buf) { - for (var ii = 0; ii < 16; ++ii) { - buf[i + ii] = rnds[ii]; - } - } - - return buf || bytesToUuid(rnds); -} - -module.exports = v4; - - -/***/ }), -/* 5 */ -/***/ (function(module, exports) { - -// Unique ID creation requires a high quality random # generator. In the -// browser this is a little complicated due to unknown quality of Math.random() -// and inconsistent support for the `crypto` API. We do the best we can via -// feature-detection - -// getRandomValues needs to be invoked in a context where "this" is a Crypto -// implementation. Also, find the complete implementation of crypto on IE11. -var getRandomValues = (typeof(crypto) != 'undefined' && crypto.getRandomValues && crypto.getRandomValues.bind(crypto)) || - (typeof(msCrypto) != 'undefined' && typeof window.msCrypto.getRandomValues == 'function' && msCrypto.getRandomValues.bind(msCrypto)); - -if (getRandomValues) { - // WHATWG crypto RNG - http://wiki.whatwg.org/wiki/Crypto - var rnds8 = new Uint8Array(16); // eslint-disable-line no-undef - - module.exports = function whatwgRNG() { - getRandomValues(rnds8); - return rnds8; - }; -} else { - // Math.random()-based (RNG) - // - // If all else fails, use Math.random(). It's fast, but is of unspecified - // quality. - var rnds = new Array(16); - - module.exports = function mathRNG() { - for (var i = 0, r; i < 16; i++) { - if ((i & 0x03) === 0) r = Math.random() * 0x100000000; - rnds[i] = r >>> ((i & 0x03) << 3) & 0xff; - } - - return rnds; - }; -} - - -/***/ }), -/* 6 */ -/***/ (function(module, exports) { - -/** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ -var byteToHex = []; -for (var i = 0; i < 256; ++i) { - byteToHex[i] = (i + 0x100).toString(16).substr(1); -} - -function bytesToUuid(buf, offset) { - var i = offset || 0; - var bth = byteToHex; - // join used to fix memory issue caused by concatenation: https://bugs.chromium.org/p/v8/issues/detail?id=3175#c4 - return ([bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], '-', - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]], - bth[buf[i++]], bth[buf[i++]]]).join(''); -} - -module.exports = bytesToUuid; - - -/***/ }), -/* 7 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -exports.doResolveUris = doResolveUris; -exports.doResolveUri = doResolveUri; -exports.doFetchClaimListMine = doFetchClaimListMine; -exports.doAbandonClaim = doAbandonClaim; -exports.doFetchClaimsByChannel = doFetchClaimsByChannel; -exports.doFetchClaimCountByChannel = doFetchClaimCountByChannel; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbry = __webpack_require__(8); - -var _lbry2 = _interopRequireDefault(_lbry); - -var _lbryURI = __webpack_require__(1); - -var _notifications = __webpack_require__(2); - -var _claims = __webpack_require__(11); - -var _wallet = __webpack_require__(17); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -function doResolveUris(uris) { - var returnCachedClaims = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - return function (dispatch, getState) { - var normalizedUris = uris.map(_lbryURI.normalizeURI); - var state = getState(); - - var resolvingUris = (0, _claims.selectResolvingUris)(state); - var claimsByUri = (0, _claims.selectClaimsByUri)(state); - var urisToResolve = normalizedUris.filter(function (uri) { - if (resolvingUris.includes(uri)) { - return false; - } - - return returnCachedClaims ? !claimsByUri[uri] : true; - }); - - if (urisToResolve.length === 0) { - return; - } - - dispatch({ - type: ACTIONS.RESOLVE_URIS_STARTED, - data: { uris: normalizedUris } - }); - - var resolveInfo = {}; - _lbry2.default.resolve({ urls: urisToResolve }).then(function (result) { - Object.entries(result).forEach(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - uri = _ref2[0], - uriResolveInfo = _ref2[1]; - - var fallbackResolveInfo = { - claim: null, - claimsInChannel: null, - certificate: null - }; - - var _ref3 = uriResolveInfo && !uriResolveInfo.error ? uriResolveInfo : fallbackResolveInfo, - claim = _ref3.claim, - certificate = _ref3.certificate, - claimsInChannel = _ref3.claims_in_channel; - - resolveInfo[uri] = { claim: claim, certificate: certificate, claimsInChannel: claimsInChannel }; - }); - - dispatch({ - type: ACTIONS.RESOLVE_URIS_COMPLETED, - data: { resolveInfo: resolveInfo } - }); - }); - }; -} - -function doResolveUri(uri) { - return doResolveUris([uri]); -} - -function doFetchClaimListMine() { - return function (dispatch) { - dispatch({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED - }); - - _lbry2.default.claim_list_mine().then(function (claims) { - dispatch({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims: claims - } - }); - }); - }; -} - -function doAbandonClaim(txid, nout) { - return function (dispatch, getState) { - var state = getState(); - var myClaims = (0, _claims.selectMyClaimsRaw)(state); - - var _myClaims$find = myClaims.find(function (claim) { - return claim.txid === txid && claim.nout === nout; - }), - claimId = _myClaims$find.claim_id; - - dispatch({ - type: ACTIONS.ABANDON_CLAIM_STARTED, - data: { - claimId: claimId - } - }); - - var errorCallback = function errorCallback() { - dispatch((0, _notifications.doToast)({ - message: 'Transaction failed', - isError: true - })); - }; - - var successCallback = function successCallback(results) { - if (results.success === true) { - dispatch({ - type: ACTIONS.ABANDON_CLAIM_SUCCEEDED, - data: { - claimId: claimId - } - }); - dispatch((0, _notifications.doToast)({ - message: 'Successfully abandoned your claim' - })); - - // After abandoning, call claim_list_mine to show the claim as abandoned - // Also fetch transactions to show the new abandon transaction - dispatch(doFetchClaimListMine()); - dispatch((0, _wallet.doFetchTransactions)()); - } else { - dispatch((0, _notifications.doToast)({ - message: 'Error abandoning claim', - isError: true - })); - } - }; - - _lbry2.default.claim_abandon({ - txid: txid, - nout: nout - }).then(successCallback, errorCallback); - }; -} - -function doFetchClaimsByChannel(uri, page) { - return function (dispatch) { - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIMS_STARTED, - data: { uri: uri, page: page } - }); - - _lbry2.default.claim_list_by_channel({ uri: uri, page: page || 1 }).then(function (result) { - var claimResult = result[uri] || {}; - var claimsInChannel = claimResult.claims_in_channel, - returnedPage = claimResult.returned_page; - - - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, - data: { - uri: uri, - claims: claimsInChannel || [], - page: returnedPage || undefined - } - }); - }); - }; -} - -function doFetchClaimCountByChannel(uri) { - return function (dispatch) { - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_STARTED, - data: { uri: uri } - }); - - _lbry2.default.claim_list_by_channel({ uri: uri }).then(function (result) { - var claimResult = result[uri]; - var totalClaims = claimResult ? claimResult.claims_in_channel : 0; - - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED, - data: { - uri: uri, - totalClaims: totalClaims - } - }); - }); - }; -} - -/***/ }), -/* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; // @flow - - -__webpack_require__(9); - -var CHECK_DAEMON_STARTED_TRY_NUMBER = 200; - -var Lbry = { - isConnected: false, - daemonConnectionString: 'http://localhost:5279', - pendingPublishTimeout: 20 * 60 * 1000 -}; - -function checkAndParse(response) { - if (response.status >= 200 && response.status < 300) { - return response.json(); - } - return response.json().then(function (json) { - var error = void 0; - if (json.error) { - var errorMessage = _typeof(json.error) === 'object' ? json.error.message : json.error; - error = new Error(errorMessage); - } else { - error = new Error('Protocol error with unknown response signature'); - } - return Promise.reject(error); - }); -} - -function apiCall(method /*: string*/, params /*: ?{}*/, resolve /*: Function*/, reject /*: Function*/) { - var counter = new Date().getTime(); - var options = { - method: 'POST', - body: JSON.stringify({ - jsonrpc: '2.0', - method: method, - params: params, - id: counter - }) - }; - - return fetch(Lbry.daemonConnectionString, options).then(checkAndParse).then(function (response) { - var error = response.error || response.result && response.result.error; - - if (error) { - return reject(error); - } - return resolve(response.result); - }).catch(reject); -} - -var daemonCallWithResult = function daemonCallWithResult(name) { - var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - return new Promise(function (resolve, reject) { - apiCall(name, params, function (result) { - resolve(result); - }, reject); - }); -}; - -// blobs -Lbry.blob_delete = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('blob_delete', params); -}; -Lbry.blob_list = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('blob_list', params); -}; - -// core -Lbry.status = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('status', params); -}; -Lbry.version = function () { - return daemonCallWithResult('version', {}); -}; -Lbry.file_delete = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('file_delete', params); -}; -Lbry.file_set_status = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('file_set_status', params); -}; -Lbry.stop = function () { - return daemonCallWithResult('stop', {}); -}; - -// claims -Lbry.claim_list_by_channel = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('claim_list_by_channel', params); -}; - -// wallet -Lbry.account_balance = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('account_balance', params); -}; -Lbry.account_decrypt = function () { - return daemonCallWithResult('account_decrypt', {}); -}; -Lbry.account_encrypt = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('account_encrypt', params); -}; -Lbry.account_list = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('account_list', params); -}; -Lbry.address_is_mine = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('address_is_mine', params); -}; -Lbry.wallet_lock = function () { - return daemonCallWithResult('wallet_lock', {}); -}; -Lbry.address_unused = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('address_unused', params); -}; -Lbry.wallet_send = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('wallet_send', params); -}; -Lbry.account_unlock = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('account_unlock', params); -}; -Lbry.address_unused = function () { - return daemonCallWithResult('address_unused', {}); -}; -Lbry.claim_tip = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('claim_tip', params); -}; - -// transactions -Lbry.transaction_list = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('transaction_list', params); -}; -Lbry.utxo_release = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('utxo_release', params); -}; - -// sync -Lbry.sync_hash = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('sync_hash', params); -}; -Lbry.sync_apply = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return daemonCallWithResult('sync_apply', params); -}; - -Lbry.connectPromise = null; -Lbry.connect = function () { - if (Lbry.connectPromise === null) { - Lbry.connectPromise = new Promise(function (resolve, reject) { - var tryNum = 0; - // Check every half second to see if the daemon is accepting connections - function checkDaemonStarted() { - tryNum += 1; - Lbry.status().then(resolve).catch(function () { - if (tryNum <= CHECK_DAEMON_STARTED_TRY_NUMBER) { - setTimeout(checkDaemonStarted, tryNum < 50 ? 400 : 1000); - } else { - reject(new Error('Unable to connect to LBRY')); - } - }); - } - - checkDaemonStarted(); - }); - } - - return Lbry.connectPromise; -}; - -Lbry.getMediaType = function (contentType, extname) { - if (extname) { - var formats = [[/^(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/^(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/^(html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org)$/i, 'document'], [/^(stl|obj|fbx|gcode)$/i, '3D-file']]; - var res = formats.reduce(function (ret, testpair) { - switch (testpair[0].test(ret)) { - case true: - return testpair[1]; - default: - return ret; - } - }, extname); - return res === extname ? 'unknown' : res; - } else if (contentType) { - return (/^[^/]+/.exec(contentType)[0] - ); - } - return 'unknown'; -}; - -/** - * Wrappers for API methods to simulate missing or future behavior. Unlike the old-style stubs, - * these are designed to be transparent wrappers around the corresponding API methods. - */ - -/** - * Returns results from the file_list API method, plus dummy entries for pending publishes. - * (If a real publish with the same name is found, the pending publish will be ignored and removed.) - */ -Lbry.file_list = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall('file_list', params, function (fileInfos) { - resolve(fileInfos); - }, reject); - }); -}; - -Lbry.claim_list_mine = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall('claim_list_mine', params, function (claims) { - resolve(claims); - }, reject); - }); -}; - -Lbry.get = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall('get', params, function (streamInfo) { - resolve(streamInfo); - }, reject); - }); -}; - -Lbry.resolve = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall('resolve', params, function (data) { - resolve(data || {}); - }, reject); - }); -}; - -Lbry.publish = function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - if (Lbry.overrides.publish) { - Lbry.overrides.publish(params).then(resolve, reject); - } else { - apiCall('publish', params, resolve, reject); - } - }); -}; - -// Allow overriding Lbry methods -Lbry.overrides = {}; -Lbry.setOverride = function (methodName, newMethod) { - Lbry.overrides[methodName] = newMethod; -}; - -// Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) -Lbry.setDaemonConnectionString = function (value) { - Lbry.daemonConnectionString = value; -}; - -var lbryProxy = new Proxy(Lbry, { - get: function get(target, name) { - if (name in target) { - return target[name]; - } - - return function () { - var params = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - return new Promise(function (resolve, reject) { - apiCall(name, params, resolve, reject); - }); - }; - } -}); - -exports.default = lbryProxy; - -/***/ }), -/* 9 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/* WEBPACK VAR INJECTION */(function(global) {/* - * Copyright 2016 Google Inc. All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - - - - -(function(scope) { - if (scope['Proxy']) { - return; - } - let lastRevokeFn = null; - - /** - * @param {*} o - * @return {boolean} whether this is probably a (non-null) Object - */ - function isObject(o) { - return o ? (typeof o == 'object' || typeof o == 'function') : false; - } - - /** - * @constructor - * @param {!Object} target - * @param {{apply, construct, get, set}} handler - */ - scope.Proxy = function(target, handler) { - if (!isObject(target) || !isObject(handler)) { - throw new TypeError('Cannot create proxy with a non-object as target or handler'); - } - - // Construct revoke function, and set lastRevokeFn so that Proxy.revocable can steal it. - // The caller might get the wrong revoke function if a user replaces or wraps scope.Proxy - // to call itself, but that seems unlikely especially when using the polyfill. - let throwRevoked = function() {}; - lastRevokeFn = function() { - throwRevoked = function(trap) { - throw new TypeError(`Cannot perform '${trap}' on a proxy that has been revoked`); - }; - }; - - // Fail on unsupported traps: Chrome doesn't do this, but ensure that users of the polyfill - // are a bit more careful. Copy the internal parts of handler to prevent user changes. - let unsafeHandler = handler; - handler = {'get': null, 'set': null, 'apply': null, 'construct': null}; - for (let k in unsafeHandler) { - if (!(k in handler)) { - throw new TypeError(`Proxy polyfill does not support trap '${k}'`); - } - handler[k] = unsafeHandler[k]; - } - if (typeof unsafeHandler == 'function') { - // Allow handler to be a function (which has an 'apply' method). This matches what is - // probably a bug in native versions. It treats the apply call as a trap to be configured. - handler.apply = unsafeHandler.apply.bind(unsafeHandler); - } - - // Define proxy as this, or a Function (if either it's callable, or apply is set). - // TODO(samthor): Closure compiler doesn't know about 'construct', attempts to rename it. - let proxy = this; - let isMethod = false; - let targetIsFunction = typeof target == 'function'; - if (handler.apply || handler['construct'] || targetIsFunction) { - proxy = function Proxy() { - let usingNew = (this && this.constructor === proxy); - throwRevoked(usingNew ? 'construct' : 'apply'); - - if (usingNew && handler['construct']) { - return handler['construct'].call(this, target, arguments); - } else if (!usingNew && handler.apply) { - return handler.apply(target, this, arguments); - } else if (targetIsFunction) { - // since the target was a function, fallback to calling it directly. - if (usingNew) { - // inspired by answers to https://stackoverflow.com/q/1606797 - let all = Array.prototype.slice.call(arguments); - all.unshift(target); // pass class as first arg to constructor, although irrelevant - // nb. cast to convince Closure compiler that this is a constructor - let f = /** @type {!Function} */ (target.bind.apply(target, all)); - return new f(); - } - return target.apply(this, arguments); - } - throw new TypeError(usingNew ? 'not a constructor' : 'not a function'); - }; - isMethod = true; - } - - // Create default getters/setters. Create different code paths as handler.get/handler.set can't - // change after creation. - let getter = handler.get ? function(prop) { - throwRevoked('get'); - return handler.get(this, prop, proxy); - } : function(prop) { - throwRevoked('get'); - return this[prop]; - }; - let setter = handler.set ? function(prop, value) { - throwRevoked('set'); - let status = handler.set(this, prop, value, proxy); - if (!status) { - // TODO(samthor): If the calling code is in strict mode, throw TypeError. - // It's (sometimes) possible to work this out, if this code isn't strict- try to load the - // callee, and if it's available, that code is non-strict. However, this isn't exhaustive. - } - } : function(prop, value) { - throwRevoked('set'); - this[prop] = value; - }; - - // Clone direct properties (i.e., not part of a prototype). - let propertyNames = Object.getOwnPropertyNames(target); - let propertyMap = {}; - propertyNames.forEach(function(prop) { - if (isMethod && prop in proxy) { - return; // ignore properties already here, e.g. 'bind', 'prototype' etc - } - let real = Object.getOwnPropertyDescriptor(target, prop); - let desc = { - enumerable: !!real.enumerable, - get: getter.bind(target, prop), - set: setter.bind(target, prop), - }; - Object.defineProperty(proxy, prop, desc); - propertyMap[prop] = true; - }); - - // Set the prototype, or clone all prototype methods (always required if a getter is provided). - // TODO(samthor): We don't allow prototype methods to be set. It's (even more) awkward. - // An alternative here would be to _just_ clone methods to keep behavior consistent. - let prototypeOk = true; - if (Object.setPrototypeOf) { - Object.setPrototypeOf(proxy, Object.getPrototypeOf(target)); - } else if (proxy.__proto__) { - proxy.__proto__ = target.__proto__; - } else { - prototypeOk = false; - } - if (handler.get || !prototypeOk) { - for (let k in target) { - if (propertyMap[k]) { - continue; - } - Object.defineProperty(proxy, k, {get: getter.bind(target, k)}); - } - } - - // The Proxy polyfill cannot handle adding new properties. Seal the target and proxy. - Object.seal(target); - Object.seal(proxy); - - return proxy; // nb. if isMethod is true, proxy != this - }; - - scope.Proxy.revocable = function(target, handler) { - let p = new scope.Proxy(target, handler); - return {'proxy': p, 'revoke': lastRevokeFn}; - }; - - scope.Proxy['revocable'] = scope.Proxy.revocable; - scope['Proxy'] = scope.Proxy; -})(typeof module !== 'undefined' && module['exports'] ? global : window); - -/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(10))) - -/***/ }), -/* 10 */ -/***/ (function(module, exports) { - -var g; - -// This works in non-strict mode -g = (function() { - return this; -})(); - -try { - // This works if eval is allowed (see CSP) - g = g || Function("return this")() || (1, eval)("this"); -} catch (e) { - // This works if the window reference is available - if (typeof window === "object") g = window; -} - -// g can still be undefined, but nothing to do about it... -// We return undefined, instead of nothing here, so it's -// easier to handle this case. if(!global) { ...} - -module.exports = g; - - -/***/ }), -/* 11 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.makeSelectChannelForClaimUri = exports.makeSelectFirstRecommendedFileForUri = exports.makeSelectRecommendedContentForUri = exports.makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountFromUris = exports.makeSelectTotalPagesForChannel = exports.makeSelectTotalItemsForChannel = exports.selectChannelClaimCounts = exports.selectPlayingUri = exports.makeSelectIsUriResolving = exports.selectResolvingUris = exports.selectMyChannelClaims = exports.selectFetchingMyChannels = exports.selectMyClaimsOutpoints = exports.selectAllMyClaimsByOutpoint = exports.selectMyClaimsWithoutChannels = exports.selectMyClaims = exports.selectIsFetchingClaimListMine = exports.makeSelectContentTypeForUri = exports.makeSelectTitleForUri = exports.makeSelectMetadataForUri = exports.makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectClaimsInChannelForPage = exports.makeSelectFetchingChannelClaims = exports.selectAllFetchingChannelClaims = exports.makeSelectClaimIsMine = exports.selectMyActiveClaims = exports.selectAbandoningIds = exports.selectMyClaimsRaw = exports.makeSelectClaimForUri = exports.makeSelectPendingByUri = exports.makeSelectClaimIsPending = exports.selectPendingClaims = exports.selectPendingById = exports.selectAllClaimsByChannel = exports.selectClaimsByUri = exports.selectCurrentChannelPage = exports.selectClaimsById = undefined; - -var _lbryURI = __webpack_require__(1); - -var _search = __webpack_require__(12); - -var _reselect = __webpack_require__(15); - -var _claim = __webpack_require__(16); - -var _query_params = __webpack_require__(14); - -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); } } - -var selectState = function selectState(state) { - return state.claims || {}; -}; - -var selectClaimsById = exports.selectClaimsById = (0, _reselect.createSelector)(selectState, function (state) { - return state.byId || {}; -}); - -var selectCurrentChannelPage = exports.selectCurrentChannelPage = (0, _reselect.createSelector)(selectState, function (state) { - return state.currentChannelPage || 1; -}); - -var selectClaimsByUri = exports.selectClaimsByUri = (0, _reselect.createSelector)(selectState, selectClaimsById, function (state, byId) { - var byUri = state.claimsByUri || {}; - var claims = {}; - - Object.keys(byUri).forEach(function (uri) { - var claimId = byUri[uri]; - - // NOTE returning a null claim allows us to differentiate between an - // undefined (never fetched claim) and one which just doesn't exist. Not - // the cleanest solution but couldn't think of anything better right now - if (claimId === null) { - claims[uri] = null; - } else { - claims[uri] = byId[claimId]; - } - }); - - return claims; -}); - -var selectAllClaimsByChannel = exports.selectAllClaimsByChannel = (0, _reselect.createSelector)(selectState, function (state) { - return state.claimsByChannel || {}; -}); - -var selectPendingById = exports.selectPendingById = (0, _reselect.createSelector)(selectState, function (state) { - return state.pendingById || {}; -}); - -var selectPendingClaims = exports.selectPendingClaims = (0, _reselect.createSelector)(selectState, function (state) { - return Object.values(state.pendingById || []); -}); - -var makeSelectClaimIsPending = exports.makeSelectClaimIsPending = function makeSelectClaimIsPending(uri) { - return (0, _reselect.createSelector)(selectPendingById, function (pendingById) { - var _parseURI = (0, _lbryURI.parseURI)(uri), - claimId = _parseURI.claimId; - - return Boolean(pendingById[claimId]); - }); -}; - -var makeSelectPendingByUri = exports.makeSelectPendingByUri = function makeSelectPendingByUri(uri) { - return (0, _reselect.createSelector)(selectPendingById, function (pendingById) { - var _parseURI2 = (0, _lbryURI.parseURI)(uri), - claimId = _parseURI2.claimId; - - return pendingById[claimId]; - }); -}; - -var makeSelectClaimForUri = exports.makeSelectClaimForUri = function makeSelectClaimForUri(uri) { - return (0, _reselect.createSelector)(selectClaimsByUri, selectPendingById, function (byUri, pendingById) { - // Check if a claim is pending first - // It won't be in claimsByUri because resolving it will return nothing - var _parseURI3 = (0, _lbryURI.parseURI)(uri), - claimId = _parseURI3.claimId; - - var pendingClaim = pendingById[claimId]; - if (pendingClaim) { - return pendingClaim; - } - - return byUri && byUri[(0, _lbryURI.normalizeURI)(uri)]; - }); -}; - -var selectMyClaimsRaw = exports.selectMyClaimsRaw = (0, _reselect.createSelector)(selectState, function (state) { - return state.myClaims; -}); - -var selectAbandoningIds = exports.selectAbandoningIds = (0, _reselect.createSelector)(selectState, function (state) { - return Object.keys(state.abandoningById || {}); -}); - -var selectMyActiveClaims = exports.selectMyActiveClaims = (0, _reselect.createSelector)(selectMyClaimsRaw, selectAbandoningIds, function (claims, abandoningIds) { - return new Set(claims && claims.map(function (claim) { - return claim.claim_id; - }).filter(function (claimId) { - return Object.keys(abandoningIds).indexOf(claimId) === -1; - })); -}); - -var makeSelectClaimIsMine = exports.makeSelectClaimIsMine = function makeSelectClaimIsMine(rawUri) { - var uri = (0, _lbryURI.normalizeURI)(rawUri); - return (0, _reselect.createSelector)(selectClaimsByUri, selectMyActiveClaims, function (claims, myClaims) { - return claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); - }); -}; - -var selectAllFetchingChannelClaims = exports.selectAllFetchingChannelClaims = (0, _reselect.createSelector)(selectState, function (state) { - return state.fetchingChannelClaims || {}; -}); - -var makeSelectFetchingChannelClaims = exports.makeSelectFetchingChannelClaims = function makeSelectFetchingChannelClaims(uri) { - return (0, _reselect.createSelector)(selectAllFetchingChannelClaims, function (fetching) { - return fetching && fetching[uri]; - }); -}; - -var makeSelectClaimsInChannelForPage = exports.makeSelectClaimsInChannelForPage = function makeSelectClaimsInChannelForPage(uri, page) { - return (0, _reselect.createSelector)(selectClaimsById, selectAllClaimsByChannel, function (byId, allClaims) { - var byChannel = allClaims[uri] || {}; - var claimIds = byChannel[page || 1]; - - if (!claimIds) return claimIds; - - return claimIds.map(function (claimId) { - return byId[claimId]; - }); - }); -}; - -var makeSelectClaimsInChannelForCurrentPageState = exports.makeSelectClaimsInChannelForCurrentPageState = function makeSelectClaimsInChannelForCurrentPageState(uri) { - return (0, _reselect.createSelector)(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, function (byId, allClaims, page) { - var byChannel = allClaims[uri] || {}; - var claimIds = byChannel[page || 1]; - - if (!claimIds) return claimIds; - - return claimIds.map(function (claimId) { - return byId[claimId]; - }); - }); -}; - -var makeSelectMetadataForUri = exports.makeSelectMetadataForUri = function makeSelectMetadataForUri(uri) { - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { - var metadata = claim && claim.value && claim.value.stream && claim.value.stream.metadata; - - return metadata || (claim === undefined ? undefined : null); - }); -}; - -var makeSelectTitleForUri = exports.makeSelectTitleForUri = function makeSelectTitleForUri(uri) { - return (0, _reselect.createSelector)(makeSelectMetadataForUri(uri), function (metadata) { - return metadata && metadata.title; - }); -}; - -var makeSelectContentTypeForUri = exports.makeSelectContentTypeForUri = function makeSelectContentTypeForUri(uri) { - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { - var source = claim && claim.value && claim.value.stream && claim.value.stream.source; - return source ? source.contentType : undefined; - }); -}; - -var selectIsFetchingClaimListMine = exports.selectIsFetchingClaimListMine = (0, _reselect.createSelector)(selectState, function (state) { - return state.isFetchingClaimListMine; -}); - -var selectMyClaims = exports.selectMyClaims = (0, _reselect.createSelector)(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, function (myClaimIds, byId, abandoningIds, pendingClaims) { - var claims = []; - - myClaimIds.forEach(function (id) { - var claim = byId[id]; - - if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); - }); - - return [].concat(claims, _toConsumableArray(pendingClaims)); -}); - -var selectMyClaimsWithoutChannels = exports.selectMyClaimsWithoutChannels = (0, _reselect.createSelector)(selectMyClaims, function (myClaims) { - return myClaims.filter(function (claim) { - return !claim.name.match(/^@/); - }); -}); - -var selectAllMyClaimsByOutpoint = exports.selectAllMyClaimsByOutpoint = (0, _reselect.createSelector)(selectMyClaimsRaw, function (claims) { - return new Set(claims && claims.length ? claims.map(function (claim) { - return claim.txid + ':' + claim.nout; - }) : null); -}); - -var selectMyClaimsOutpoints = exports.selectMyClaimsOutpoints = (0, _reselect.createSelector)(selectMyClaims, function (myClaims) { - var outpoints = []; - - myClaims.forEach(function (claim) { - return outpoints.push(claim.txid + ':' + claim.nout); - }); - - return outpoints; -}); - -var selectFetchingMyChannels = exports.selectFetchingMyChannels = (0, _reselect.createSelector)(selectState, function (state) { - return state.fetchingMyChannels; -}); - -var selectMyChannelClaims = exports.selectMyChannelClaims = (0, _reselect.createSelector)(selectState, selectClaimsById, function (state, byId) { - var ids = state.myChannelClaims || []; - var claims = []; - - ids.forEach(function (id) { - if (byId[id]) { - // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544 - claims.push(byId[id]); - } - }); - - return claims; -}); - -var selectResolvingUris = exports.selectResolvingUris = (0, _reselect.createSelector)(selectState, function (state) { - return state.resolvingUris || []; -}); - -var makeSelectIsUriResolving = exports.makeSelectIsUriResolving = function makeSelectIsUriResolving(uri) { - return (0, _reselect.createSelector)(selectResolvingUris, function (resolvingUris) { - return resolvingUris && resolvingUris.indexOf(uri) !== -1; - }); -}; - -var selectPlayingUri = exports.selectPlayingUri = (0, _reselect.createSelector)(selectState, function (state) { - return state.playingUri; -}); - -var selectChannelClaimCounts = exports.selectChannelClaimCounts = (0, _reselect.createSelector)(selectState, function (state) { - return state.channelClaimCounts || {}; -}); - -var makeSelectTotalItemsForChannel = exports.makeSelectTotalItemsForChannel = function makeSelectTotalItemsForChannel(uri) { - return (0, _reselect.createSelector)(selectChannelClaimCounts, function (byUri) { - return byUri && byUri[uri]; - }); -}; - -var makeSelectTotalPagesForChannel = exports.makeSelectTotalPagesForChannel = function makeSelectTotalPagesForChannel(uri) { - var pageSize = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 10; - return (0, _reselect.createSelector)(selectChannelClaimCounts, function (byUri) { - return byUri && byUri[uri] && Math.ceil(byUri[uri] / pageSize); - }); -}; - -var makeSelectNsfwCountFromUris = exports.makeSelectNsfwCountFromUris = function makeSelectNsfwCountFromUris(uris) { - return (0, _reselect.createSelector)(selectClaimsByUri, function (claims) { - return uris.reduce(function (acc, uri) { - var claim = claims[uri]; - if ((0, _claim.isClaimNsfw)(claim)) { - return acc + 1; - } - return acc; - }, 0); - }); -}; - -var makeSelectNsfwCountForChannel = exports.makeSelectNsfwCountForChannel = function makeSelectNsfwCountForChannel(uri) { - return (0, _reselect.createSelector)(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, function (byId, allClaims, page) { - var byChannel = allClaims[uri] || {}; - var claimIds = byChannel[page || 1]; - - if (!claimIds) return 0; - - return claimIds.reduce(function (acc, claimId) { - var claim = byId[claimId]; - if ((0, _claim.isClaimNsfw)(claim)) { - return acc + 1; - } - return acc; - }, 0); - }); -}; - -var makeSelectRecommendedContentForUri = exports.makeSelectRecommendedContentForUri = function makeSelectRecommendedContentForUri(uri) { - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), _search.selectSearchUrisByQuery, function (claim, searchUrisByQuery) { - var atVanityURI = !uri.includes('#'); - - var recommendedContent = void 0; - if (claim) { - // If we are at a vanity uri, build the full uri so we can properly filter - var currentUri = atVanityURI ? (0, _lbryURI.buildURI)({ claimId: claim.claim_id, claimName: claim.name }) : uri; - - var title = claim.value.stream.metadata.title; - - - var searchQuery = (0, _query_params.getSearchQueryString)(title.replace(/\//, ' ')); - - var searchUris = searchUrisByQuery[searchQuery]; - if (searchUris) { - searchUris = searchUris.filter(function (searchUri) { - return searchUri !== currentUri; - }); - recommendedContent = searchUris; - } - } - - return recommendedContent; - }); -}; - -var makeSelectFirstRecommendedFileForUri = exports.makeSelectFirstRecommendedFileForUri = function makeSelectFirstRecommendedFileForUri(uri) { - return (0, _reselect.createSelector)(makeSelectRecommendedContentForUri(uri), function (recommendedContent) { - return recommendedContent ? recommendedContent[0] : null; - }); -}; - -// Returns the associated channel uri for a given claim uri -var makeSelectChannelForClaimUri = exports.makeSelectChannelForClaimUri = function makeSelectChannelForClaimUri(uri) { - var includePrefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - return (0, _reselect.createSelector)(makeSelectClaimForUri(uri), function (claim) { - if (!claim) { - return null; - } - - var channelName = claim.channel_name, - value = claim.value; - - var channelClaimId = value && value.publisherSignature && value.publisherSignature.certificateId; - - return channelName && channelClaimId ? (0, _lbryURI.buildURI)({ channelName: channelName, claimId: channelClaimId }, includePrefix) : null; - }); -}; - -/***/ }), -/* 12 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.makeSelectQueryWithOptions = exports.selectSearchSuggestions = exports.selectSearchBarFocused = exports.makeSelectSearchUris = exports.selectSearchUrisByQuery = exports.selectIsSearching = exports.selectSuggestions = exports.selectSearchOptions = exports.selectSearchValue = exports.selectState = undefined; - -var _extends = 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; }; - -var _search = __webpack_require__(13); - -var _query_params = __webpack_require__(14); - -var _lbryURI = __webpack_require__(1); - -var _reselect = __webpack_require__(15); - -// @flow -/*:: import type { SearchState, SearchOptions, SearchSuggestion } from 'types/Search';*/ -/*:: type State = { search: SearchState };*/ -var selectState = exports.selectState = function selectState(state /*: State*/) /*: SearchState*/ { - return state.search; -}; - -var selectSearchValue /*: (state: State) => string*/ = exports.selectSearchValue = (0, _reselect.createSelector)(selectState, function (state) { - return state.searchQuery; -}); - -var selectSearchOptions /*: (state: State) => SearchOptions*/ = exports.selectSearchOptions = (0, _reselect.createSelector)(selectState, function (state) { - return state.options; -}); - -var selectSuggestions /*: ( - state: State - ) => { [string]: Array }*/ = exports.selectSuggestions = (0, _reselect.createSelector)(selectState, function (state) { - return state.suggestions; -}); - -var selectIsSearching /*: (state: State) => boolean*/ = exports.selectIsSearching = (0, _reselect.createSelector)(selectState, function (state) { - return state.searching; -}); - -var selectSearchUrisByQuery /*: ( - state: State - ) => { [string]: Array }*/ = exports.selectSearchUrisByQuery = (0, _reselect.createSelector)(selectState, function (state) { - return state.urisByQuery; -}); - -var makeSelectSearchUris = exports.makeSelectSearchUris = function makeSelectSearchUris(query -// replace statement below is kind of ugly, and repeated in doSearch action -/*: string*/) /*: ((state: State) => Array)*/ { - return (0, _reselect.createSelector)(selectSearchUrisByQuery, function (byQuery) { - return byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]; - }); -}; - -var selectSearchBarFocused /*: boolean*/ = exports.selectSearchBarFocused = (0, _reselect.createSelector)(selectState, function (state) { - return state.focused; -}); - -var selectSearchSuggestions /*: Array*/ = exports.selectSearchSuggestions = (0, _reselect.createSelector)(selectSearchValue, selectSuggestions, function (query /*: string*/, suggestions /*: { [string]: Array }*/) { - 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.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.SEARCH_TYPES.SEARCH - }, { - value: uri, - shorthand: isChannel ? claimName.slice(1) : claimName, - type: isChannel ? _search.SEARCH_TYPES.CHANNEL : _search.SEARCH_TYPES.FILE - }); - } catch (e) { - searchSuggestions.push({ - value: query, - type: _search.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.SEARCH_TYPES.CHANNEL : _search.SEARCH_TYPES.FILE - }; - } catch (e) { - // search result includes some character that isn't valid in claim names - return { - value: suggestion, - type: _search.SEARCH_TYPES.SEARCH - }; - } - })); - } - - return searchSuggestions; -}); - -// Creates a query string based on the state in the search reducer -// Can be overrided by passing in custom sizes/from values for other areas pagination -var makeSelectQueryWithOptions = exports.makeSelectQueryWithOptions = function makeSelectQueryWithOptions(customQuery /*: ?string*/, customSize /*: ?number*/, customFrom // If it's a background search, don't use the users settings -/*: ?number*/) { - var isBackgroundSearch /*: boolean*/ = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - return (0, _reselect.createSelector)(selectSearchValue, selectSearchOptions, function (query, options) { - var size = customSize || options[_search.SEARCH_OPTIONS.RESULT_COUNT]; - - var queryString = (0, _query_params.getSearchQueryString)(customQuery || query, _extends({}, options, { size: size, from: customFrom }), !isBackgroundSearch); - - return queryString; - }); -}; - -/***/ }), -/* 13 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var SEARCH_TYPES = exports.SEARCH_TYPES = { - FILE: 'file', - CHANNEL: 'channel', - SEARCH: 'search' -}; - -var SEARCH_OPTIONS = exports.SEARCH_OPTIONS = { - RESULT_COUNT: 'size', - CLAIM_TYPE: 'claimType', - INCLUDE_FILES: 'file', - INCLUDE_CHANNELS: 'channel', - INCLUDE_FILES_AND_CHANNELS: 'file,channel', - MEDIA_AUDIO: 'audio', - MEDIA_VIDEO: 'video', - MEDIA_TEXT: 'text', - MEDIA_IMAGE: 'image', - MEDIA_APPLICATION: 'application' -}; - -/***/ }), -/* 14 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.getSearchQueryString = undefined; - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); // @flow - - -exports.parseQueryParams = parseQueryParams; -exports.toQueryString = toQueryString; - -var _search = __webpack_require__(13); - -var DEFAULT_SEARCH_RESULT_FROM = 0; -var DEFAULT_SEARCH_SIZE = 20; - -function parseQueryParams(queryString /*: string*/) { - if (queryString === '') return {}; - var parts = queryString.split('?').pop().split('&').map(function (p) { - return p.split('='); - }); - - var params = {}; - parts.forEach(function (array) { - var _array = _slicedToArray(array, 2), - first = _array[0], - second = _array[1]; - - params[first] = second; - }); - return params; -} - -function toQueryString(params /*: { [string]: string | number }*/) { - if (!params) return ''; - - var parts = []; - Object.keys(params).forEach(function (key) { - if (Object.prototype.hasOwnProperty.call(params, key) && params[key]) { - parts.push(key + '=' + params[key]); - } - }); - - return parts.join('&'); -} - -var getSearchQueryString = exports.getSearchQueryString = function getSearchQueryString(query /*: string*/) { - var options /*: any*/ = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var includeUserOptions /*: boolean*/ = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; - - var encodedQuery = encodeURIComponent(query); - var queryParams = ['s=' + encodedQuery, 'size=' + (options.size || DEFAULT_SEARCH_SIZE), 'from=' + (options.from || DEFAULT_SEARCH_RESULT_FROM)]; - - if (includeUserOptions) { - queryParams.push('claimType=' + options[_search.SEARCH_OPTIONS.CLAIM_TYPE]); - - // If they are only searching for channels, strip out the media info - if (options[_search.SEARCH_OPTIONS.CLAIM_TYPE] !== _search.SEARCH_OPTIONS.INCLUDE_CHANNELS) { - queryParams.push('mediaType=' + [_search.SEARCH_OPTIONS.MEDIA_FILE, _search.SEARCH_OPTIONS.MEDIA_AUDIO, _search.SEARCH_OPTIONS.MEDIA_VIDEO, _search.SEARCH_OPTIONS.MEDIA_TEXT, _search.SEARCH_OPTIONS.MEDIA_IMAGE, _search.SEARCH_OPTIONS.MEDIA_APPLICATION].reduce(function (acc, currentOption) { - return options[currentOption] ? '' + acc + currentOption + ',' : acc; - }, '')); - } - } - - return queryParams.join('&'); -}; - -/***/ }), -/* 15 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -exports.__esModule = true; -exports.defaultMemoize = defaultMemoize; -exports.createSelectorCreator = createSelectorCreator; -exports.createStructuredSelector = createStructuredSelector; -function defaultEqualityCheck(a, b) { - return a === b; -} - -function areArgumentsShallowlyEqual(equalityCheck, prev, next) { - if (prev === null || next === null || prev.length !== next.length) { - return false; - } - - // Do this in a for loop (and not a `forEach` or an `every`) so we can determine equality as fast as possible. - var length = prev.length; - for (var i = 0; i < length; i++) { - if (!equalityCheck(prev[i], next[i])) { - return false; - } - } - - return true; -} - -function defaultMemoize(func) { - var equalityCheck = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : defaultEqualityCheck; - - var lastArgs = null; - var lastResult = null; - // we reference arguments instead of spreading them for performance reasons - return function () { - if (!areArgumentsShallowlyEqual(equalityCheck, lastArgs, arguments)) { - // apply arguments instead of spreading for performance. - lastResult = func.apply(null, arguments); - } - - lastArgs = arguments; - return lastResult; - }; -} - -function getDependencies(funcs) { - var dependencies = Array.isArray(funcs[0]) ? funcs[0] : funcs; - - if (!dependencies.every(function (dep) { - return typeof dep === 'function'; - })) { - var dependencyTypes = dependencies.map(function (dep) { - return typeof dep; - }).join(', '); - throw new Error('Selector creators expect all input-selectors to be functions, ' + ('instead received the following types: [' + dependencyTypes + ']')); - } - - return dependencies; -} - -function createSelectorCreator(memoize) { - for (var _len = arguments.length, memoizeOptions = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { - memoizeOptions[_key - 1] = arguments[_key]; - } - - return function () { - for (var _len2 = arguments.length, funcs = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - funcs[_key2] = arguments[_key2]; - } - - var recomputations = 0; - var resultFunc = funcs.pop(); - var dependencies = getDependencies(funcs); - - var memoizedResultFunc = memoize.apply(undefined, [function () { - recomputations++; - // apply arguments instead of spreading for performance. - return resultFunc.apply(null, arguments); - }].concat(memoizeOptions)); - - // If a selector is called with the exact same arguments we don't need to traverse our dependencies again. - var selector = defaultMemoize(function () { - var params = []; - var length = dependencies.length; - - for (var i = 0; i < length; i++) { - // apply arguments instead of spreading and mutate a local list of params for performance. - params.push(dependencies[i].apply(null, arguments)); - } - - // apply arguments instead of spreading for performance. - return memoizedResultFunc.apply(null, params); - }); - - selector.resultFunc = resultFunc; - selector.recomputations = function () { - return recomputations; - }; - selector.resetRecomputations = function () { - return recomputations = 0; - }; - return selector; - }; -} - -var createSelector = exports.createSelector = createSelectorCreator(defaultMemoize); - -function createStructuredSelector(selectors) { - var selectorCreator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : createSelector; - - if (typeof selectors !== 'object') { - throw new Error('createStructuredSelector expects first argument to be an object ' + ('where each property is a selector, instead received a ' + typeof selectors)); - } - var objectKeys = Object.keys(selectors); - return selectorCreator(objectKeys.map(function (key) { - return selectors[key]; - }), function () { - for (var _len3 = arguments.length, values = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) { - values[_key3] = arguments[_key3]; - } - - return values.reduce(function (composition, value, index) { - composition[objectKeys[index]] = value; - return composition; - }, {}); - }); -} - -/***/ }), -/* 16 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var isClaimNsfw = exports.isClaimNsfw = function isClaimNsfw(claim) { - return claim && claim.value && claim.value.stream && claim.value.stream.metadata.nsfw; -}; - -/***/ }), -/* 17 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doUpdateBalance = doUpdateBalance; -exports.doUpdateTotalBalance = doUpdateTotalBalance; -exports.doBalanceSubscribe = doBalanceSubscribe; -exports.doTotalBalanceSubscribe = doTotalBalanceSubscribe; -exports.doFetchTransactions = doFetchTransactions; -exports.doFetchBlock = doFetchBlock; -exports.doGetNewAddress = doGetNewAddress; -exports.doCheckAddressIsMine = doCheckAddressIsMine; -exports.doSendDraftTransaction = doSendDraftTransaction; -exports.doSetDraftTransactionAmount = doSetDraftTransactionAmount; -exports.doSetDraftTransactionAddress = doSetDraftTransactionAddress; -exports.doSendTip = doSendTip; -exports.doWalletEncrypt = doWalletEncrypt; -exports.doWalletUnlock = doWalletUnlock; -exports.doWalletLock = doWalletLock; -exports.doWalletDecrypt = doWalletDecrypt; -exports.doWalletStatus = doWalletStatus; -exports.doSetTransactionListFilter = doSetTransactionListFilter; -exports.doUpdateBlockHeight = doUpdateBlockHeight; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbry = __webpack_require__(8); - -var _lbry2 = _interopRequireDefault(_lbry); - -var _notifications = __webpack_require__(2); - -var _wallet = __webpack_require__(18); - -var _formatCredits = __webpack_require__(20); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -function doUpdateBalance() { - return function (dispatch, getState) { - var _getState = getState(), - balanceInStore = _getState.wallet.balance; - - _lbry2.default.account_balance().then(function (balanceAsString) { - var balance = parseFloat(balanceAsString); - if (balanceInStore !== balance) { - dispatch({ - type: ACTIONS.UPDATE_BALANCE, - data: { - balance: balance - } - }); - } - }); - }; -} - -function doUpdateTotalBalance() { - return function (dispatch, getState) { - var _getState2 = getState(), - totalBalanceInStore = _getState2.wallet.totalBalance; - - _lbry2.default.account_list().then(function (accountList) { - var accounts = accountList.lbc_mainnet; - - var totalSatoshis = accounts.length === 1 ? accounts[0].satoshis : accounts.reduce(function (a, b) { - return a.satoshis + b.satoshis; - }); - var totalBalance = (Number.isNaN(totalSatoshis) ? 0 : totalSatoshis) / Math.pow(10, 8); - if (totalBalanceInStore !== totalBalance) { - dispatch({ - type: ACTIONS.UPDATE_TOTAL_BALANCE, - data: { - totalBalance: totalBalance - } - }); - } - }); - }; -} - -function doBalanceSubscribe() { - return function (dispatch) { - dispatch(doUpdateBalance()); - setInterval(function () { - return dispatch(doUpdateBalance()); - }, 5000); - }; -} - -function doTotalBalanceSubscribe() { - return function (dispatch) { - dispatch(doUpdateTotalBalance()); - setInterval(function () { - return dispatch(doUpdateTotalBalance()); - }, 5000); - }; -} - -function doFetchTransactions() { - return function (dispatch) { - dispatch({ - type: ACTIONS.FETCH_TRANSACTIONS_STARTED - }); - - _lbry2.default.utxo_release().then(function () { - return _lbry2.default.transaction_list(); - }).then(function (results) { - dispatch({ - type: ACTIONS.FETCH_TRANSACTIONS_COMPLETED, - data: { - transactions: results - } - }); - }); - }; -} - -function doFetchBlock(height) { - return function (dispatch) { - _lbry2.default.block_show({ height: height }).then(function (block) { - dispatch({ - type: ACTIONS.FETCH_BLOCK_SUCCESS, - data: { block: block } - }); - }); - }; -} - -function doGetNewAddress() { - return function (dispatch) { - dispatch({ - type: ACTIONS.GET_NEW_ADDRESS_STARTED - }); - - // Removed localStorage use, since address is expected to be stored in redux store - _lbry2.default.address_unused().then(function (address) { - dispatch({ - type: ACTIONS.GET_NEW_ADDRESS_COMPLETED, - data: { address: address } - }); - }); - }; -} - -function doCheckAddressIsMine(address) { - return function (dispatch) { - dispatch({ - type: ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED - }); - - _lbry2.default.address_is_mine({ address: address }).then(function (isMine) { - if (!isMine) dispatch(doGetNewAddress()); - - dispatch({ - type: ACTIONS.CHECK_ADDRESS_IS_MINE_COMPLETED - }); - }); - }; -} - -function doSendDraftTransaction(address, amount) { - return function (dispatch, getState) { - var state = getState(); - var balance = (0, _wallet.selectBalance)(state); - - if (balance - amount <= 0) { - dispatch((0, _notifications.doToast)({ - title: 'Insufficient credits', - message: 'Insufficient credits' - })); - return; - } - - dispatch({ - type: ACTIONS.SEND_TRANSACTION_STARTED - }); - - var successCallback = function successCallback(response) { - if (response.txid) { - dispatch({ - type: ACTIONS.SEND_TRANSACTION_COMPLETED - }); - dispatch((0, _notifications.doToast)({ - message: 'You sent ' + amount + ' LBC', - linkText: 'History', - linkTarget: '/wallet' - })); - } else { - dispatch({ - type: ACTIONS.SEND_TRANSACTION_FAILED, - data: { error: response } - }); - dispatch((0, _notifications.doToast)({ - message: 'Transaction failed', - isError: true - })); - } - }; - - var errorCallback = function errorCallback(error) { - dispatch({ - type: ACTIONS.SEND_TRANSACTION_FAILED, - data: { error: error.message } - }); - dispatch((0, _notifications.doToast)({ - message: 'Transaction failed', - isError: true - })); - }; - - _lbry2.default.wallet_send({ - address: address, - amount: (0, _formatCredits.creditsToString)(amount) - }).then(successCallback, errorCallback); - }; -} - -function doSetDraftTransactionAmount(amount) { - return { - type: ACTIONS.SET_DRAFT_TRANSACTION_AMOUNT, - data: { amount: amount } - }; -} - -function doSetDraftTransactionAddress(address) { - return { - type: ACTIONS.SET_DRAFT_TRANSACTION_ADDRESS, - data: { address: address } - }; -} - -function doSendTip(amount, claimId, uri, successCallback, errorCallback) { - return function (dispatch, getState) { - var state = getState(); - var balance = (0, _wallet.selectBalance)(state); - - if (balance - amount <= 0) { - dispatch((0, _notifications.doToast)({ - message: 'Insufficient credits', - isError: true - })); - return; - } - - var success = function success() { - dispatch((0, _notifications.doToast)({ - message: __('You sent ' + amount + ' LBC as a tip, Mahalo!'), - linkText: __('History'), - linkTarget: __('/wallet') - })); - - dispatch({ - type: ACTIONS.SUPPORT_TRANSACTION_COMPLETED - }); - - if (successCallback) { - successCallback(); - } - }; - - var error = function error(err) { - dispatch((0, _notifications.doToast)({ - message: __('There was an error sending support funds.'), - isError: true - })); - - dispatch({ - type: ACTIONS.SUPPORT_TRANSACTION_FAILED, - data: { - error: err - } - }); - - if (errorCallback) { - errorCallback(); - } - }; - - dispatch({ - type: ACTIONS.SUPPORT_TRANSACTION_STARTED - }); - - _lbry2.default.claim_tip({ - claim_id: claimId, - amount: (0, _formatCredits.creditsToString)(amount) - }).then(success, error); - }; -} - -function doWalletEncrypt(newPassword) { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_ENCRYPT_START - }); - - _lbry2.default.account_encrypt({ new_password: newPassword }).then(function (result) { - if (result === true) { - dispatch({ - type: ACTIONS.WALLET_ENCRYPT_COMPLETED, - result: result - }); - } else { - dispatch({ - type: ACTIONS.WALLET_ENCRYPT_FAILED, - result: result - }); - } - }); - }; -} - -function doWalletUnlock(password) { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_UNLOCK_START - }); - - _lbry2.default.account_unlock({ password: password }).then(function (result) { - if (result === true) { - dispatch({ - type: ACTIONS.WALLET_UNLOCK_COMPLETED, - result: result - }); - } else { - dispatch({ - type: ACTIONS.WALLET_UNLOCK_FAILED, - result: result - }); - } - }); - }; -} - -function doWalletLock() { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_LOCK_START - }); - - _lbry2.default.wallet_lock().then(function (result) { - if (result === true) { - dispatch({ - type: ACTIONS.WALLET_LOCK_COMPLETED, - result: result - }); - } else { - dispatch({ - type: ACTIONS.WALLET_LOCK_FAILED, - result: result - }); - } - }); - }; -} - -function doWalletDecrypt() { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_DECRYPT_START - }); - - _lbry2.default.account_decrypt().then(function (result) { - if (result === true) { - dispatch({ - type: ACTIONS.WALLET_DECRYPT_COMPLETED, - result: result - }); - } else { - dispatch({ - type: ACTIONS.WALLET_DECRYPT_FAILED, - result: result - }); - } - }); - }; -} - -function doWalletStatus() { - return function (dispatch) { - dispatch({ - type: ACTIONS.WALLET_STATUS_START - }); - - _lbry2.default.status().then(function (status) { - if (status && status.wallet) { - dispatch({ - type: ACTIONS.WALLET_STATUS_COMPLETED, - result: status.wallet.is_encrypted - }); - } - }); - }; -} - -function doSetTransactionListFilter(filterOption) { - return { - type: ACTIONS.SET_TRANSACTION_LIST_FILTER, - data: filterOption - }; -} - -function doUpdateBlockHeight() { - return function (dispatch) { - return _lbry2.default.status().then(function (status) { - if (status.wallet) { - dispatch({ - type: ACTIONS.UPDATE_CURRENT_HEIGHT, - data: status.wallet.blocks - }); - } - }); - }; -} - -/***/ }), -/* 18 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.selectTransactionListFilter = exports.makeSelectBlockDate = exports.selectCurrentHeight = 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.selectTotalBalance = exports.selectBalance = exports.selectWalletLockResult = exports.selectWalletLockSucceeded = exports.selectWalletLockPending = exports.selectWalletUnlockResult = exports.selectWalletUnlockSucceeded = exports.selectWalletUnlockPending = exports.selectWalletDecryptResult = exports.selectWalletDecryptSucceeded = exports.selectWalletDecryptPending = exports.selectWalletEncryptResult = exports.selectWalletEncryptSucceeded = exports.selectWalletEncryptPending = exports.selectWalletIsEncrypted = exports.selectWalletState = exports.selectState = undefined; - -var _reselect = __webpack_require__(15); - -var _transaction_types = __webpack_require__(19); - -var TRANSACTIONS = _interopRequireWildcard(_transaction_types); - -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; } } - -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); } } - -var selectState = exports.selectState = function selectState(state) { - return state.wallet || {}; -}; - -var selectWalletState = exports.selectWalletState = selectState; - -var selectWalletIsEncrypted = exports.selectWalletIsEncrypted = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletIsEncrypted; -}); - -var selectWalletEncryptPending = exports.selectWalletEncryptPending = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletEncryptPending; -}); - -var selectWalletEncryptSucceeded = exports.selectWalletEncryptSucceeded = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletEncryptSucceded; -}); - -var selectWalletEncryptResult = exports.selectWalletEncryptResult = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletEncryptResult; -}); - -var selectWalletDecryptPending = exports.selectWalletDecryptPending = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletDecryptPending; -}); - -var selectWalletDecryptSucceeded = exports.selectWalletDecryptSucceeded = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletDecryptSucceded; -}); - -var selectWalletDecryptResult = exports.selectWalletDecryptResult = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletDecryptResult; -}); - -var selectWalletUnlockPending = exports.selectWalletUnlockPending = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletUnlockPending; -}); - -var selectWalletUnlockSucceeded = exports.selectWalletUnlockSucceeded = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletUnlockSucceded; -}); - -var selectWalletUnlockResult = exports.selectWalletUnlockResult = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletUnlockResult; -}); - -var selectWalletLockPending = exports.selectWalletLockPending = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletLockPending; -}); - -var selectWalletLockSucceeded = exports.selectWalletLockSucceeded = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletLockSucceded; -}); - -var selectWalletLockResult = exports.selectWalletLockResult = (0, _reselect.createSelector)(selectState, function (state) { - return state.walletLockResult; -}); - -var selectBalance = exports.selectBalance = (0, _reselect.createSelector)(selectState, function (state) { - return state.balance; -}); - -var selectTotalBalance = exports.selectTotalBalance = (0, _reselect.createSelector)(selectState, function (state) { - return state.totalBalance; -}); - -var selectTransactionsById = exports.selectTransactionsById = (0, _reselect.createSelector)(selectState, function (state) { - return state.transactions; -}); - -var selectTransactionItems = exports.selectTransactionItems = (0, _reselect.createSelector)(selectTransactionsById, function (byId) { - var items = []; - - Object.keys(byId).forEach(function (txid) { - var tx = byId[txid]; - - // ignore dust/fees - // it is fee only txn if all infos are also empty - if (Math.abs(tx.value) === Math.abs(tx.fee) && tx.claim_info.length === 0 && tx.support_info.length === 0 && tx.update_info.length === 0 && tx.abandon_info.length === 0) { - return; - } - - var append = []; - - append.push.apply(append, _toConsumableArray(tx.claim_info.map(function (item) { - return Object.assign({}, tx, item, { - type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH - }); - }))); - append.push.apply(append, _toConsumableArray(tx.support_info.map(function (item) { - return Object.assign({}, tx, item, { - type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP - }); - }))); - append.push.apply(append, _toConsumableArray(tx.update_info.map(function (item) { - return Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE }); - }))); - append.push.apply(append, _toConsumableArray(tx.abandon_info.map(function (item) { - return Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON }); - }))); - - if (!append.length) { - append.push(Object.assign({}, tx, { - type: tx.value < 0 ? TRANSACTIONS.SPEND : TRANSACTIONS.RECEIVE - })); - } - - items.push.apply(items, _toConsumableArray(append.map(function (item) { - // value on transaction, amount on outpoint - // amount is always positive, but should match sign of value - var balanceDelta = parseFloat(item.balance_delta); - var value = parseFloat(item.value); - var amount = balanceDelta || value; - var fee = parseFloat(tx.fee); - - return { - txid: txid, - timestamp: tx.timestamp, - date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, - amount: amount, - fee: fee, - claim_id: item.claim_id, - claim_name: item.claim_name, - type: item.type || TRANSACTIONS.SPEND, - nout: item.nout, - confirmations: tx.confirmations - }; - }))); - }); - - return items.sort(function (tx1, tx2) { - if (!tx1.timestamp && !tx2.timestamp) { - return 0; - } else if (!tx1.timestamp && tx2.timestamp) { - return -1; - } else if (tx1.timestamp && !tx2.timestamp) { - return 1; - } - - return tx2.timestamp - tx1.timestamp; - }); -}); - -var selectRecentTransactions = exports.selectRecentTransactions = (0, _reselect.createSelector)(selectTransactionItems, function (transactions) { - var threshold = new Date(); - threshold.setDate(threshold.getDate() - 7); - return transactions.filter(function (transaction) { - if (!transaction.date) { - return true; // pending transaction - } - - return transaction.date > threshold; - }); -}); - -var selectHasTransactions = exports.selectHasTransactions = (0, _reselect.createSelector)(selectTransactionItems, function (transactions) { - return transactions && transactions.length > 0; -}); - -var selectIsFetchingTransactions = exports.selectIsFetchingTransactions = (0, _reselect.createSelector)(selectState, function (state) { - return state.fetchingTransactions; -}); - -var selectIsSendingSupport = exports.selectIsSendingSupport = (0, _reselect.createSelector)(selectState, function (state) { - return state.sendingSupport; -}); - -var selectReceiveAddress = exports.selectReceiveAddress = (0, _reselect.createSelector)(selectState, function (state) { - return state.receiveAddress; -}); - -var selectGettingNewAddress = exports.selectGettingNewAddress = (0, _reselect.createSelector)(selectState, function (state) { - return state.gettingNewAddress; -}); - -var selectDraftTransaction = exports.selectDraftTransaction = (0, _reselect.createSelector)(selectState, function (state) { - return state.draftTransaction || {}; -}); - -var selectDraftTransactionAmount = exports.selectDraftTransactionAmount = (0, _reselect.createSelector)(selectDraftTransaction, function (draft) { - return draft.amount; -}); - -var selectDraftTransactionAddress = exports.selectDraftTransactionAddress = (0, _reselect.createSelector)(selectDraftTransaction, function (draft) { - return draft.address; -}); - -var selectDraftTransactionError = exports.selectDraftTransactionError = (0, _reselect.createSelector)(selectDraftTransaction, function (draft) { - return draft.error; -}); - -var selectBlocks = exports.selectBlocks = (0, _reselect.createSelector)(selectState, function (state) { - return state.blocks; -}); - -var selectCurrentHeight = exports.selectCurrentHeight = (0, _reselect.createSelector)(selectState, function (state) { - return state.latestBlock; -}); - -var makeSelectBlockDate = exports.makeSelectBlockDate = function makeSelectBlockDate(block) { - return (0, _reselect.createSelector)(selectBlocks, selectCurrentHeight, function (blocks, latestBlock) { - // If we have the block data, look at the actual date, - // If not, try to simulate it based on 2.5 minute blocks - // Adding this on 11/7/2018 because caling block_show for every claim is causing - // performance issues. - if (blocks && blocks[block]) { - return new Date(blocks[block].time * 1000); - } - - // Pending claim - if (block < 1) { - return null; - } - - var difference = latestBlock - block; - var msSincePublish = difference * 2.5 * 60 * 1000; // Number of blocks * 2.5 minutes in ms - var publishDate = Date.now() - msSincePublish; - return new Date(publishDate); - }); -}; - -var selectTransactionListFilter = exports.selectTransactionListFilter = (0, _reselect.createSelector)(selectState, function (state) { - return state.transactionListFilter || ''; -}); - -/***/ }), -/* 19 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -// eslint-disable-next-line import/prefer-default-export -var ALL = exports.ALL = 'all'; -var SPEND = exports.SPEND = 'spend'; -var RECEIVE = exports.RECEIVE = 'receive'; -var PUBLISH = exports.PUBLISH = 'publish'; -var CHANNEL = exports.CHANNEL = 'channel'; -var TIP = exports.TIP = 'tip'; -var SUPPORT = exports.SUPPORT = 'support'; -var UPDATE = exports.UPDATE = 'update'; -var ABANDON = exports.ABANDON = 'abandon'; - -/***/ }), -/* 20 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.formatCredits = formatCredits; -exports.formatFullPrice = formatFullPrice; -exports.creditsToString = creditsToString; -function formatCredits(amount, precision) { - if (Number.isNaN(parseFloat(amount))) return '0'; - return parseFloat(amount).toFixed(precision || 1).replace(/\.?0+$/, ''); -} - -function formatFullPrice(amount) { - var precision = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1; - - var formated = ''; - - var quantity = amount.toString().split('.'); - var fraction = quantity[1]; - - if (fraction) { - var decimals = fraction.split(''); - var first = decimals.filter(function (number) { - return number !== '0'; - })[0]; - var index = decimals.indexOf(first); - - // Set format fraction - formated = '.' + fraction.substring(0, index + precision); - } - - return parseFloat(quantity[0] + formated); -} - -function creditsToString(amount) { - var creditString = parseFloat(amount).toFixed(8); - return creditString; -} - -/***/ }), -/* 21 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doFetchFileInfo = doFetchFileInfo; -exports.doFileList = doFileList; -exports.doFetchFileInfosAndPublishedClaims = doFetchFileInfosAndPublishedClaims; -exports.doSetFileListSort = doSetFileListSort; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbry = __webpack_require__(8); - -var _lbry2 = _interopRequireDefault(_lbry); - -var _claims = __webpack_require__(7); - -var _claims2 = __webpack_require__(11); - -var _file_info = __webpack_require__(22); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -function doFetchFileInfo(uri) { - return function (dispatch, getState) { - var state = getState(); - var claim = (0, _claims2.selectClaimsByUri)(state)[uri]; - var outpoint = claim ? claim.txid + ':' + claim.nout : null; - var alreadyFetching = !!(0, _file_info.selectUrisLoading)(state)[uri]; - - if (!alreadyFetching) { - dispatch({ - type: ACTIONS.FETCH_FILE_INFO_STARTED, - data: { - outpoint: outpoint - } - }); - - _lbry2.default.file_list({ outpoint: outpoint, full_status: true }).then(function (fileInfos) { - dispatch({ - type: ACTIONS.FETCH_FILE_INFO_COMPLETED, - data: { - outpoint: outpoint, - fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null - } - }); - }); - } - }; -} - -function doFileList() { - return function (dispatch, getState) { - var state = getState(); - var isFetching = (0, _file_info.selectIsFetchingFileList)(state); - - if (!isFetching) { - dispatch({ - type: ACTIONS.FILE_LIST_STARTED - }); - - _lbry2.default.file_list().then(function (fileInfos) { - dispatch({ - type: ACTIONS.FILE_LIST_SUCCEEDED, - data: { - fileInfos: fileInfos - } - }); - }); - } - }; -} - -function doFetchFileInfosAndPublishedClaims() { - return function (dispatch, getState) { - var state = getState(); - var isFetchingClaimListMine = (0, _claims2.selectIsFetchingClaimListMine)(state); - var isFetchingFileInfo = (0, _file_info.selectIsFetchingFileList)(state); - - if (!isFetchingClaimListMine) dispatch((0, _claims.doFetchClaimListMine)()); - if (!isFetchingFileInfo) dispatch(doFileList()); - }; -} - -function doSetFileListSort(page, value) { - return { - type: ACTIONS.SET_FILE_LIST_SORT, - data: { page: page, value: value } - }; -} - -/***/ }), -/* 22 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.selectFileListDownloadedSort = exports.selectFileListPublishedSort = exports.selectSearchDownloadUris = exports.selectTotalDownloadProgress = exports.selectDownloadingFileInfos = exports.selectFileInfosDownloaded = exports.makeSelectLoadingForUri = exports.selectUrisLoading = exports.makeSelectDownloadingForUri = exports.selectDownloadingByOutpoint = exports.makeSelectFileInfoForUri = exports.selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileList = exports.selectFileInfosByOutpoint = exports.selectState = undefined; - -var _claims = __webpack_require__(11); - -var _reselect = __webpack_require__(15); - -var _lbryURI = __webpack_require__(1); - -var selectState = exports.selectState = function selectState(state) { - return state.fileInfo || {}; -}; - -var selectFileInfosByOutpoint = exports.selectFileInfosByOutpoint = (0, _reselect.createSelector)(selectState, function (state) { - return state.byOutpoint || {}; -}); - -var selectIsFetchingFileList = exports.selectIsFetchingFileList = (0, _reselect.createSelector)(selectState, function (state) { - return state.isFetchingFileList; -}); - -var selectIsFetchingFileListDownloadedOrPublished = exports.selectIsFetchingFileListDownloadedOrPublished = (0, _reselect.createSelector)(selectIsFetchingFileList, _claims.selectIsFetchingClaimListMine, function (isFetchingFileList, isFetchingClaimListMine) { - return isFetchingFileList || isFetchingClaimListMine; -}); - -var makeSelectFileInfoForUri = exports.makeSelectFileInfoForUri = function makeSelectFileInfoForUri(uri) { - return (0, _reselect.createSelector)(_claims.selectClaimsByUri, selectFileInfosByOutpoint, function (claims, byOutpoint) { - var claim = claims[uri]; - var outpoint = claim ? claim.txid + ':' + claim.nout : undefined; - return outpoint ? byOutpoint[outpoint] : undefined; - }); -}; - -var selectDownloadingByOutpoint = exports.selectDownloadingByOutpoint = (0, _reselect.createSelector)(selectState, function (state) { - return state.downloadingByOutpoint || {}; -}); - -var makeSelectDownloadingForUri = exports.makeSelectDownloadingForUri = function makeSelectDownloadingForUri(uri) { - return (0, _reselect.createSelector)(selectDownloadingByOutpoint, makeSelectFileInfoForUri(uri), function (byOutpoint, fileInfo) { - if (!fileInfo) return false; - return byOutpoint[fileInfo.outpoint]; - }); -}; - -var selectUrisLoading = exports.selectUrisLoading = (0, _reselect.createSelector)(selectState, function (state) { - return state.urisLoading || {}; -}); - -var makeSelectLoadingForUri = exports.makeSelectLoadingForUri = function makeSelectLoadingForUri(uri) { - return (0, _reselect.createSelector)(selectUrisLoading, function (byUri) { - return byUri && byUri[uri]; - }); -}; - -var selectFileInfosDownloaded = exports.selectFileInfosDownloaded = (0, _reselect.createSelector)(selectFileInfosByOutpoint, _claims.selectMyClaims, function (byOutpoint, myClaims) { - return Object.values(byOutpoint).filter(function (fileInfo) { - var myClaimIds = myClaims.map(function (claim) { - return claim.claim_id; - }); - - return fileInfo && myClaimIds.indexOf(fileInfo.claim_id) === -1 && (fileInfo.completed || fileInfo.written_bytes); - }); -}); - -// export const selectFileInfoForUri = (state, props) => { -// const claims = selectClaimsByUri(state), -// claim = claims[props.uri], -// fileInfos = selectAllFileInfos(state), -// outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; - -// return outpoint && fileInfos ? fileInfos[outpoint] : undefined; -// }; - -var selectDownloadingFileInfos = exports.selectDownloadingFileInfos = (0, _reselect.createSelector)(selectDownloadingByOutpoint, selectFileInfosByOutpoint, function (downloadingByOutpoint, fileInfosByOutpoint) { - var outpoints = Object.keys(downloadingByOutpoint); - var fileInfos = []; - - outpoints.forEach(function (outpoint) { - var fileInfo = fileInfosByOutpoint[outpoint]; - - if (fileInfo) fileInfos.push(fileInfo); - }); - - return fileInfos; -}); - -var selectTotalDownloadProgress = exports.selectTotalDownloadProgress = (0, _reselect.createSelector)(selectDownloadingFileInfos, function (fileInfos) { - var progress = []; - - fileInfos.forEach(function (fileInfo) { - progress.push(fileInfo.written_bytes / fileInfo.total_bytes * 100); - }); - - var totalProgress = progress.reduce(function (a, b) { - return a + b; - }, 0); - - if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; - return -1; -}); - -var selectSearchDownloadUris = exports.selectSearchDownloadUris = function selectSearchDownloadUris(query) { - return (0, _reselect.createSelector)(selectFileInfosDownloaded, _claims.selectClaimsById, function (fileInfos, claimsById) { - if (!query || !fileInfos.length) { - return null; - } - - var queryParts = query.toLowerCase().split(' '); - var searchQueryDictionary = {}; - queryParts.forEach(function (subQuery) { - searchQueryDictionary[subQuery] = subQuery; - }); - - var arrayContainsQueryPart = function arrayContainsQueryPart(array) { - for (var i = 0; i < array.length; i += 1) { - var subQuery = array[i]; - if (searchQueryDictionary[subQuery]) { - return true; - } - } - return false; - }; - - var downloadResultsFromQuery = []; - fileInfos.forEach(function (fileInfo) { - var channelName = fileInfo.channel_name, - claimName = fileInfo.claim_name, - metadata = fileInfo.metadata; - var author = metadata.author, - description = metadata.description, - title = metadata.title; - - - if (channelName) { - var lowerCaseChannel = channelName.toLowerCase(); - var strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ - if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - var nameParts = claimName.toLowerCase().split('-'); - if (arrayContainsQueryPart(nameParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - var titleParts = title.toLowerCase().split(' '); - if (arrayContainsQueryPart(titleParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - if (author) { - var authorParts = author.toLowerCase().split(' '); - if (arrayContainsQueryPart(authorParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - if (description) { - var descriptionParts = description.toLowerCase().split(' '); - if (arrayContainsQueryPart(descriptionParts)) { - downloadResultsFromQuery.push(fileInfo); - } - } - }); - - return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(function (fileInfo) { - var channelName = fileInfo.channel_name, - claimId = fileInfo.claim_id, - claimName = fileInfo.claim_name; - - - var uriParams = {}; - - if (channelName) { - var claim = claimsById[claimId]; - if (claim && claim.value) { - uriParams.claimId = claim.value.publisherSignature.certificateId; - } else { - uriParams.claimId = claimId; - } - uriParams.channelName = channelName; - uriParams.contentName = claimName; - } else { - uriParams.claimId = claimId; - uriParams.claimName = claimName; - } - - var uri = (0, _lbryURI.buildURI)(uriParams); - return uri; - }) : null; - }); -}; - -var selectFileListPublishedSort = exports.selectFileListPublishedSort = (0, _reselect.createSelector)(selectState, function (state) { - return state.fileListPublishedSort; -}); - -var selectFileListDownloadedSort = exports.selectFileListDownloadedSort = (0, _reselect.createSelector)(selectState, function (state) { - return state.fileListDownloadedSort; -}); - -/***/ }), -/* 23 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.doUpdateSearchOptions = exports.doBlurSearchInput = exports.doFocusSearchInput = exports.doSearch = exports.doUpdateSearchQuery = exports.getSearchSuggestions = exports.setSearchApi = undefined; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbryURI = __webpack_require__(1); - -var _claims = __webpack_require__(7); - -var _search = __webpack_require__(12); - -var _batchActions = __webpack_require__(24); - -var _debounce = __webpack_require__(25); - -var _debounce2 = _interopRequireDefault(_debounce); - -var _handleFetch = __webpack_require__(26); - -var _handleFetch2 = _interopRequireDefault(_handleFetch); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - -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; } } - -// @flow -/*:: import type { SearchState, SearchOptions } from 'types/Search';*/ - - -var DEBOUNCED_SEARCH_SUGGESTION_MS = 300; -/*:: type Dispatch = (action: any) => any;*/ - - -// We can't use env's because they aren't passed into node_modules -/*:: type GetState = () => { search: SearchState };*/ -var CONNECTION_STRING = 'https://lighthouse.lbry.io/'; - -var setSearchApi = exports.setSearchApi = function setSearchApi(endpoint /*: string*/) { - CONNECTION_STRING = endpoint.replace(/\/*$/, '/'); // exactly one slash at the end; -}; - -var getSearchSuggestions = exports.getSearchSuggestions = function getSearchSuggestions(value /*: string*/) { - return function (dispatch /*: Dispatch*/, getState /*: GetState*/) { - var query = value.trim(); - - // strip out any basic stuff for more accurate search results - 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(CONNECTION_STRING + 'autocomplete?s=' + searchValue).then(_handleFetch2.default).then(function (apiSuggestions) { - dispatch({ - type: ACTIONS.UPDATE_SEARCH_SUGGESTIONS, - data: { - query: searchValue, - suggestions: apiSuggestions - } - }); - }).catch(function () { - // If the fetch fails, do nothing - // Basic search suggestions are already populated at this point - }); - }; -}; - -var throttledSearchSuggestions = (0, _debounce2.default)(function (dispatch, query) { - dispatch(getSearchSuggestions(query)); -}, DEBOUNCED_SEARCH_SUGGESTION_MS); - -var doUpdateSearchQuery = exports.doUpdateSearchQuery = function doUpdateSearchQuery(query /*: string*/, shouldSkipSuggestions /*: ?boolean*/) { - return function (dispatch /*: Dispatch*/) { - dispatch({ - type: ACTIONS.UPDATE_SEARCH_QUERY, - data: { query: query } - }); - - // Don't fetch new suggestions if the user just added a space - if (!query.endsWith(' ') || !shouldSkipSuggestions) { - throttledSearchSuggestions(dispatch, query); - } - }; -}; - -var doSearch = exports.doSearch = function doSearch(rawQuery /*: string*/, size /*: ?number*/, from /*: ?number*/) { - var isBackgroundSearch /*: boolean*/ = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; - return function (dispatch /*: Dispatch*/, getState /*: GetState*/) { - var query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); - - if (!query) { - dispatch({ - type: ACTIONS.SEARCH_FAIL - }); - return; - } - - var state = getState(); - var queryWithOptions = (0, _search.makeSelectQueryWithOptions)(query, size, from, isBackgroundSearch)(state); - - // If we have already searched for something, we don't need to do anything - var urisForQuery = (0, _search.makeSelectSearchUris)(queryWithOptions)(state); - if (urisForQuery && !!urisForQuery.length) { - return; - } - - dispatch({ - type: ACTIONS.SEARCH_START - }); - - // 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 - // isBackgroundSearch means the search is happening in the background, don't update the search query - if (!state.search.searchQuery && !isBackgroundSearch) { - dispatch(doUpdateSearchQuery(query)); - } - - fetch(CONNECTION_STRING + 'search?' + queryWithOptions).then(_handleFetch2.default).then(function (data) { - var uris = []; - var actions = []; - - data.forEach(function (result) { - var uri = (0, _lbryURI.buildURI)({ - claimName: result.name, - claimId: result.claimId - }); - actions.push((0, _claims.doResolveUri)(uri)); - uris.push(uri); - }); - - actions.push({ - type: ACTIONS.SEARCH_SUCCESS, - data: { - query: queryWithOptions, - uris: uris - } - }); - dispatch(_batchActions.batchActions.apply(undefined, actions)); - }).catch(function () { - dispatch({ - type: ACTIONS.SEARCH_FAIL - }); - }); - }; -}; - -var doFocusSearchInput = exports.doFocusSearchInput = function doFocusSearchInput() { - return function (dispatch /*: Dispatch*/) { - return dispatch({ - type: ACTIONS.SEARCH_FOCUS - }); - }; -}; - -var doBlurSearchInput = exports.doBlurSearchInput = function doBlurSearchInput() { - return function (dispatch /*: Dispatch*/) { - return dispatch({ - type: ACTIONS.SEARCH_BLUR - }); - }; -}; - -var doUpdateSearchOptions = exports.doUpdateSearchOptions = function doUpdateSearchOptions(newOptions /*: SearchOptions*/) { - return function (dispatch /*: Dispatch*/, getState /*: GetState*/) { - var state = getState(); - var searchValue = (0, _search.selectSearchValue)(state); - - dispatch({ - type: ACTIONS.UPDATE_SEARCH_OPTIONS, - data: newOptions - }); - - if (searchValue) { - // After updating, perform a search with the new options - dispatch(doSearch(searchValue)); - } - }; -}; - -/***/ }), -/* 24 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.batchActions = batchActions; -// https://github.com/reactjs/redux/issues/911 -function batchActions() { - for (var _len = arguments.length, actions = Array(_len), _key = 0; _key < _len; _key++) { - actions[_key] = arguments[_key]; - } - - return { - type: 'BATCH_ACTIONS', - actions: actions - }; -} - -/***/ }), -/* 25 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = debouce; -// Returns a function, that, as long as it continues to be invoked, will not -// be triggered. The function will be called after it stops being called for -// N milliseconds. If `immediate` is passed, trigger the function on the -// leading edge, instead of the trailing. -function debouce(func, wait, immediate) { - var timeout = void 0; - - return function () { - var context = this; - var args = arguments; - var later = function later() { - timeout = null; - if (!immediate) func.apply(context, args); - }; - - var callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) func.apply(context, args); - }; -} - -/***/ }), -/* 26 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.default = handleFetchResponse; -function handleFetchResponse(response) { - return response.status === 200 ? Promise.resolve(response.json()) : Promise.reject(new Error(response.statusText)); -} - -/***/ }), -/* 27 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.savePosition = savePosition; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -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; } } - -function savePosition(claimId /*: string*/, outpoint /*: string*/, position /*: number*/) { - return function (dispatch) { - dispatch({ - type: ACTIONS.SET_CONTENT_POSITION, - data: { claimId: claimId, outpoint: outpoint, position: position } - }); - }; -} - -/***/ }), -/* 28 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); - -exports.claimsReducer = claimsReducer; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _lbryURI = __webpack_require__(1); - -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 reducers = {}; - -var defaultState = { - channelClaimCounts: {} -}; - -reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = function (state, action) { - var resolveInfo = action.data.resolveInfo; - - var byUri = Object.assign({}, state.claimsByUri); - var byId = Object.assign({}, state.byId); - var channelClaimCounts = Object.assign({}, state.channelClaimCounts); - - Object.entries(resolveInfo).forEach(function (_ref) { - var _ref2 = _slicedToArray(_ref, 2), - uri = _ref2[0], - _ref2$ = _ref2[1], - certificate = _ref2$.certificate, - claimsInChannel = _ref2$.claimsInChannel; - - if (certificate && !Number.isNaN(claimsInChannel)) { - channelClaimCounts[uri] = claimsInChannel; - } - }); - - Object.entries(resolveInfo).forEach(function (_ref3) { - var _ref4 = _slicedToArray(_ref3, 2), - uri = _ref4[0], - _ref4$ = _ref4[1], - certificate = _ref4$.certificate, - claim = _ref4$.claim; - - if (claim) { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; - } else if (claim === undefined && certificate !== undefined) { - byId[certificate.claim_id] = certificate; - // Don't point URI at the channel certificate unless it actually is - // a channel URI. This is brittle. - if (!uri.split(certificate.name)[1].match(/\//)) { - byUri[uri] = certificate.claim_id; - } else { - byUri[uri] = null; - } - } else { - byUri[uri] = null; - } - }); - - return Object.assign({}, state, { - byId: byId, - claimsByUri: byUri, - channelClaimCounts: channelClaimCounts, - resolvingUris: (state.resolvingUris || []).filter(function (uri) { - return !resolveInfo[uri]; - }) - }); -}; - -reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = function (state) { - return Object.assign({}, state, { - isFetchingClaimListMine: true - }); -}; - -reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = function (state, action) { - var claims = action.data.claims; - - var byId = Object.assign({}, state.byId); - var byUri = Object.assign({}, state.claimsByUri); - var pendingById = Object.assign({}, state.pendingById); - - claims.forEach(function (claim) { - var uri = (0, _lbryURI.buildURI)({ claimName: claim.name, claimId: claim.claim_id }); - - if (claim.type && claim.type.match(/claim|update/)) { - if (claim.confirmations < 1) { - pendingById[claim.claim_id] = claim; - delete byId[claim.claim_id]; - delete byUri[claim.claim_id]; - } else { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; - } - } - }); - - // Remove old pending publishes - Object.values(pendingById).filter(function (pendingClaim) { - return byId[pendingClaim.claim_id]; - }).forEach(function (pendingClaim) { - delete pendingById[pendingClaim.claim_id]; - }); - - return Object.assign({}, state, { - isFetchingClaimListMine: false, - myClaims: claims, - byId: byId, - claimsByUri: byUri, - pendingById: pendingById - }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_LIST_STARTED] = function (state) { - return Object.assign({}, state, { fetchingMyChannels: true }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = function (state, action) { - var claims = action.data.claims; - - var myChannelClaims = new Set(state.myChannelClaims); - var byId = Object.assign({}, state.byId); - - claims.forEach(function (claim) { - myChannelClaims.add(claim.claim_id); - byId[claim.claim_id] = claim; - }); - - return Object.assign({}, state, { - byId: byId, - fetchingMyChannels: false, - myChannelClaims: myChannelClaims - }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_STARTED] = function (state, action) { - var _action$data = action.data, - uri = _action$data.uri, - page = _action$data.page; - - var fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); - - fetchingChannelClaims[uri] = page; - - return Object.assign({}, state, { - fetchingChannelClaims: fetchingChannelClaims, - currentChannelPage: page - }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = function (state, action) { - var _action$data2 = action.data, - uri = _action$data2.uri, - claims = _action$data2.claims, - page = _action$data2.page; - - - var claimsByChannel = Object.assign({}, state.claimsByChannel); - var byChannel = Object.assign({}, claimsByChannel[uri]); - var allClaimIds = new Set(byChannel.all); - var currentPageClaimIds = []; - var byId = Object.assign({}, state.byId); - var fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); - var claimsByUri = Object.assign({}, state.claimsByUri); - - if (claims !== undefined) { - claims.forEach(function (claim) { - allClaimIds.add(claim.claim_id); - currentPageClaimIds.push(claim.claim_id); - byId[claim.claim_id] = claim; - claimsByUri['lbry://' + claim.name + '#' + claim.claim_id] = claim.claim_id; - }); - } - - byChannel.all = allClaimIds; - byChannel[page] = currentPageClaimIds; - claimsByChannel[uri] = byChannel; - delete fetchingChannelClaims[uri]; - - return Object.assign({}, state, { - claimsByChannel: claimsByChannel, - byId: byId, - fetchingChannelClaims: fetchingChannelClaims, - claimsByUri: claimsByUri, - currentChannelPage: page - }); -}; - -reducers[ACTIONS.ABANDON_CLAIM_STARTED] = function (state, action) { - var claimId = action.data.claimId; - - var abandoningById = Object.assign({}, state.abandoningById); - - abandoningById[claimId] = true; - - return Object.assign({}, state, { - abandoningById: abandoningById - }); -}; - -reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = function (state, action) { - var claimId = action.data.claimId; - - var byId = Object.assign({}, state.byId); - var claimsByUri = Object.assign({}, state.claimsByUri); - - Object.keys(claimsByUri).forEach(function (uri) { - if (claimsByUri[uri] === claimId) { - delete claimsByUri[uri]; - } - }); - - delete byId[claimId]; - - return Object.assign({}, state, { - byId: byId, - claimsByUri: claimsByUri - }); -}; - -reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = function (state, action) { - var channelClaim = action.data.channelClaim; - - var byId = Object.assign({}, state.byId); - var myChannelClaims = new Set(state.myChannelClaims); - - byId[channelClaim.claim_id] = channelClaim; - myChannelClaims.add(channelClaim.claim_id); - - return Object.assign({}, state, { - byId: byId, - myChannelClaims: myChannelClaims - }); -}; - -reducers[ACTIONS.RESOLVE_URIS_STARTED] = function (state, action) { - var uris = action.data.uris; - - - var oldResolving = state.resolvingUris || []; - var newResolving = Object.assign([], oldResolving); - - uris.forEach(function (uri) { - if (!newResolving.includes(uri)) { - newResolving.push(uri); - } - }); - - return Object.assign({}, state, { - resolvingUris: newResolving - }); -}; - -reducers[ACTIONS.FETCH_CHANNEL_CLAIM_COUNT_COMPLETED] = function (state, action) { - var channelClaimCounts = Object.assign({}, state.channelClaimCounts); - var _action$data3 = action.data, - uri = _action$data3.uri, - totalClaims = _action$data3.totalClaims; - - - channelClaimCounts[uri] = totalClaims; - - return Object.assign({}, state, { - channelClaimCounts: channelClaimCounts - }); -}; - -function claimsReducer() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action = arguments[1]; - - var handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} - -/***/ }), -/* 29 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = 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; }; - -exports.fileInfoReducer = fileInfoReducer; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _sort_options = __webpack_require__(30); - -var SORT_OPTIONS = _interopRequireWildcard(_sort_options); - -var _pages = __webpack_require__(31); - -var PAGES = _interopRequireWildcard(_pages); - -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; } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var reducers = {}; -var defaultState = { - fileListPublishedSort: SORT_OPTIONS.DATE_NEW, - fileListDownloadedSort: SORT_OPTIONS.DATE_NEW -}; - -reducers[ACTIONS.FILE_LIST_STARTED] = function (state) { - return Object.assign({}, state, { - isFetchingFileList: true - }); -}; - -reducers[ACTIONS.FILE_LIST_SUCCEEDED] = function (state, action) { - var fileInfos = action.data.fileInfos; - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var pendingByOutpoint = Object.assign({}, state.pendingByOutpoint); - - fileInfos.forEach(function (fileInfo) { - var outpoint = fileInfo.outpoint; - - - if (outpoint) newByOutpoint[fileInfo.outpoint] = fileInfo; - }); - - return Object.assign({}, state, { - isFetchingFileList: false, - byOutpoint: newByOutpoint, - pendingByOutpoint: pendingByOutpoint - }); -}; - -reducers[ACTIONS.FETCH_FILE_INFO_STARTED] = function (state, action) { - var outpoint = action.data.outpoint; - - var newFetching = Object.assign({}, state.fetching); - - newFetching[outpoint] = true; - - return Object.assign({}, state, { - fetching: newFetching - }); -}; - -reducers[ACTIONS.FETCH_FILE_INFO_COMPLETED] = function (state, action) { - var _action$data = action.data, - fileInfo = _action$data.fileInfo, - outpoint = _action$data.outpoint; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var newFetching = Object.assign({}, state.fetching); - - newByOutpoint[outpoint] = fileInfo; - delete newFetching[outpoint]; - - return Object.assign({}, state, { - byOutpoint: newByOutpoint, - fetching: newFetching - }); -}; - -reducers[ACTIONS.DOWNLOADING_STARTED] = function (state, action) { - var _action$data2 = action.data, - uri = _action$data2.uri, - outpoint = _action$data2.outpoint, - fileInfo = _action$data2.fileInfo; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var newDownloading = Object.assign({}, state.downloadingByOutpoint); - var newLoading = Object.assign({}, state.urisLoading); - - newDownloading[outpoint] = true; - newByOutpoint[outpoint] = fileInfo; - delete newLoading[uri]; - - return Object.assign({}, state, { - downloadingByOutpoint: newDownloading, - urisLoading: newLoading, - byOutpoint: newByOutpoint - }); -}; - -reducers[ACTIONS.DOWNLOADING_PROGRESSED] = function (state, action) { - var _action$data3 = action.data, - outpoint = _action$data3.outpoint, - fileInfo = _action$data3.fileInfo; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var newDownloading = Object.assign({}, state.downloadingByOutpoint); - - newByOutpoint[outpoint] = fileInfo; - newDownloading[outpoint] = true; - - return Object.assign({}, state, { - byOutpoint: newByOutpoint, - downloadingByOutpoint: newDownloading - }); -}; - -reducers[ACTIONS.DOWNLOADING_CANCELED] = function (state, action) { - var outpoint = action.data.outpoint; - - - var newDownloading = Object.assign({}, state.downloadingByOutpoint); - delete newDownloading[outpoint]; - - return Object.assign({}, state, { - downloadingByOutpoint: newDownloading - }); -}; - -reducers[ACTIONS.DOWNLOADING_COMPLETED] = function (state, action) { - var _action$data4 = action.data, - outpoint = _action$data4.outpoint, - fileInfo = _action$data4.fileInfo; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var newDownloading = Object.assign({}, state.downloadingByOutpoint); - - newByOutpoint[outpoint] = fileInfo; - delete newDownloading[outpoint]; - - return Object.assign({}, state, { - byOutpoint: newByOutpoint, - downloadingByOutpoint: newDownloading - }); -}; - -reducers[ACTIONS.FILE_DELETE] = function (state, action) { - var outpoint = action.data.outpoint; - - - var newByOutpoint = Object.assign({}, state.byOutpoint); - var downloadingByOutpoint = Object.assign({}, state.downloadingByOutpoint); - - delete newByOutpoint[outpoint]; - delete downloadingByOutpoint[outpoint]; - - return Object.assign({}, state, { - byOutpoint: newByOutpoint, - downloadingByOutpoint: downloadingByOutpoint - }); -}; - -reducers[ACTIONS.LOADING_VIDEO_STARTED] = function (state, action) { - var uri = action.data.uri; - - - var newLoading = Object.assign({}, state.urisLoading); - newLoading[uri] = true; - - var newErrors = _extends({}, state.errors); - if (uri in newErrors) delete newErrors[uri]; - - return Object.assign({}, state, { - urisLoading: newLoading, - errors: _extends({}, newErrors) - }); -}; - -reducers[ACTIONS.LOADING_VIDEO_FAILED] = function (state, action) { - var uri = action.data.uri; - - - var newLoading = Object.assign({}, state.urisLoading); - delete newLoading[uri]; - - var newErrors = _extends({}, state.errors); - newErrors[uri] = true; - - return Object.assign({}, state, { - urisLoading: newLoading, - errors: _extends({}, newErrors) - }); -}; - -reducers[ACTIONS.FETCH_DATE] = function (state, action) { - var time = action.data.time; - - if (time) { - return Object.assign({}, state, { - publishedDate: time - }); - } - return null; -}; - -reducers[ACTIONS.SET_FILE_LIST_SORT] = function (state, action) { - var _pageSortStates; - - var pageSortStates = (_pageSortStates = {}, _defineProperty(_pageSortStates, PAGES.PUBLISHED, 'fileListPublishedSort'), _defineProperty(_pageSortStates, PAGES.DOWNLOADED, 'fileListDownloadedSort'), _pageSortStates); - var pageSortState = pageSortStates[action.data.page]; - var value = action.data.value; - - - return Object.assign({}, state, _defineProperty({}, pageSortState, value)); -}; - -function fileInfoReducer() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action = arguments[1]; - - var handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} - -/***/ }), -/* 30 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var DATE_NEW = exports.DATE_NEW = 'dateNew'; -var DATE_OLD = exports.DATE_OLD = 'dateOld'; -var TITLE = exports.TITLE = 'title'; -var FILENAME = exports.FILENAME = 'filename'; - -/***/ }), -/* 31 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var AUTH = exports.AUTH = 'auth'; -var BACKUP = exports.BACKUP = 'backup'; -var CHANNEL = exports.CHANNEL = 'channel'; -var DISCOVER = exports.DISCOVER = 'discover'; -var FILE = exports.FILE = 'file'; -var DOWNLOADED = exports.DOWNLOADED = 'downloaded'; -var PUBLISHED = exports.PUBLISHED = 'published'; -var GET_CREDITS = exports.GET_CREDITS = 'getcredits'; -var HELP = exports.HELP = 'help'; -var INVITE = exports.INVITE = 'invite'; -var PUBLISH = exports.PUBLISH = 'publish'; -var REPORT = exports.REPORT = 'report'; -var REWARDS = exports.REWARDS = 'rewards'; -var SEARCH = exports.SEARCH = 'search'; -var SEND_CREDITS = exports.SEND_CREDITS = 'send'; -var SETTINGS = exports.SETTINGS = 'settings'; -var SHOW = exports.SHOW = 'show'; -var SUBSCRIPTIONS = exports.SUBSCRIPTIONS = 'subscriptions'; -var TRANSACTION_HISTORY = exports.TRANSACTION_HISTORY = 'history'; -var HISTORY = exports.HISTORY = 'user_history'; -var WALLET = exports.WALLET = 'wallet'; - -/***/ }), -/* 32 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.notificationsReducer = undefined; - -var _handleActions; - -var _extends = 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; }; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _reduxUtils = __webpack_require__(33); - -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; } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -// @flow -/*:: import type { - NotificationState, - DoToast, - DoError, - DoNotification, - DoEditNotification, - DoDeleteNotification, -} from 'types/Notification';*/ - - -var defaultState /*: NotificationState*/ = { - notifications: [], - toasts: [], - errors: [] -}; - -var notificationsReducer = (0, _reduxUtils.handleActions)((_handleActions = {}, _defineProperty(_handleActions, ACTIONS.CREATE_TOAST, function (state /*: NotificationState*/, action /*: DoToast*/) { - var toast = action.data; - var newToasts = state.toasts.slice(); - newToasts.push(toast); - - return _extends({}, state, { - toasts: newToasts - }); -}), _defineProperty(_handleActions, ACTIONS.DISMISS_TOAST, function (state /*: NotificationState*/) { - var newToasts = state.toasts.slice(); - newToasts.shift(); - - return _extends({}, state, { - toasts: newToasts - }); -}), _defineProperty(_handleActions, ACTIONS.CREATE_NOTIFICATION, function (state /*: NotificationState*/, action /*: DoNotification*/) { - var notification = action.data; - var newNotifications = state.notifications.slice(); - newNotifications.push(notification); - - return _extends({}, state, { - notifications: newNotifications - }); -}), _defineProperty(_handleActions, ACTIONS.EDIT_NOTIFICATION, function (state /*: NotificationState*/, action /*: DoEditNotification*/) { - var notification = action.data.notification; - - var notifications = state.notifications.slice(); - - notifications = notifications.map(function (pastNotification) { - return pastNotification.id === notification.id ? notification : pastNotification; - }); - - return _extends({}, state, { - notifications: notifications - }); -}), _defineProperty(_handleActions, ACTIONS.DELETE_NOTIFICATION, function (state /*: NotificationState*/, action /*: DoDeleteNotification*/) { - var id = action.data.id; - - var newNotifications = state.notifications.slice(); - newNotifications = newNotifications.filter(function (notification) { - return notification.id !== id; - }); - - return _extends({}, state, { - notifications: newNotifications - }); -}), _defineProperty(_handleActions, ACTIONS.CREATE_ERROR, function (state /*: NotificationState*/, action /*: DoError*/) { - var error = action.data; - var newErrors = state.errors.slice(); - newErrors.push(error); - - return _extends({}, state, { - errors: newErrors - }); -}), _defineProperty(_handleActions, ACTIONS.DISMISS_ERROR, function (state /*: NotificationState*/) { - var newErrors = state.errors.slice(); - newErrors.shift(); - - return _extends({}, state, { - errors: newErrors - }); -}), _handleActions), defaultState); - -exports.notificationsReducer = notificationsReducer; - -/***/ }), -/* 33 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -// util for creating reducers -// based off of redux-actions -// https://redux-actions.js.org/docs/api/handleAction.html#handleactions - -// eslint-disable-next-line import/prefer-default-export -var handleActions = exports.handleActions = function handleActions(actionMap, defaultState) { - return function () { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action = arguments[1]; - - var handler = actionMap[action.type]; - - if (handler) { - var newState = handler(state, action); - return Object.assign({}, state, newState); - } - - // just return the original state if no handler - // returning a copy here breaks redux-persist - return state; - }; -}; - -/***/ }), -/* 34 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.searchReducer = undefined; - -var _extends = 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; }; - -var _options, _handleActions; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -var _reduxUtils = __webpack_require__(33); - -var _search = __webpack_require__(13); - -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; } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } // @flow - - -/*:: import type { - SearchState, - SearchSuccess, - UpdateSearchQuery, - UpdateSearchSuggestions, - HistoryNavigate, - UpdateSearchOptions, -} from 'types/Search';*/ - - -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 - options: (_options = {}, _defineProperty(_options, _search.SEARCH_OPTIONS.RESULT_COUNT, 30), _defineProperty(_options, _search.SEARCH_OPTIONS.CLAIM_TYPE, _search.SEARCH_OPTIONS.INCLUDE_FILES_AND_CHANNELS), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_AUDIO, true), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_VIDEO, true), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_TEXT, true), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_IMAGE, true), _defineProperty(_options, _search.SEARCH_OPTIONS.MEDIA_APPLICATION, true), _options), - suggestions: {}, - urisByQuery: {} -}; - -var searchReducer = exports.searchReducer = (0, _reduxUtils.handleActions)((_handleActions = {}, _defineProperty(_handleActions, ACTIONS.SEARCH_START, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - searching: true - }); -}), _defineProperty(_handleActions, ACTIONS.SEARCH_SUCCESS, function (state /*: SearchState*/, action /*: SearchSuccess*/) /*: SearchState*/ { - var _action$data = action.data, - query = _action$data.query, - uris = _action$data.uris; - - - return _extends({}, state, { - searching: false, - urisByQuery: Object.assign({}, state.urisByQuery, _defineProperty({}, query, uris)) - }); -}), _defineProperty(_handleActions, ACTIONS.SEARCH_FAIL, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - searching: false - }); -}), _defineProperty(_handleActions, ACTIONS.UPDATE_SEARCH_QUERY, function (state /*: SearchState*/, action /*: UpdateSearchQuery*/) /*: SearchState*/ { - return _extends({}, state, { - searchQuery: action.data.query, - isActive: true - }); -}), _defineProperty(_handleActions, ACTIONS.UPDATE_SEARCH_SUGGESTIONS, function (state /*: SearchState*/, action /*: UpdateSearchSuggestions*/) /*: SearchState*/ { - return _extends({}, state, { - 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) : '', - isActive: url.indexOf('/search') === 0, - suggestions: {} - }); -}), _defineProperty(_handleActions, ACTIONS.DISMISS_NOTIFICATION, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - isActive: false - }); -}), _defineProperty(_handleActions, ACTIONS.SEARCH_FOCUS, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - focused: true - }); -}), _defineProperty(_handleActions, ACTIONS.SEARCH_BLUR, function (state /*: SearchState*/) /*: SearchState*/ { - return _extends({}, state, { - focused: false - }); -}), _defineProperty(_handleActions, ACTIONS.UPDATE_SEARCH_OPTIONS, function (state /*: SearchState*/, action /*: UpdateSearchOptions*/) /*: SearchState*/ { - var oldOptions = state.options; - - var newOptions = action.data; - var options = _extends({}, oldOptions, newOptions); - return _extends({}, state, { - options: options - }); -}), _handleActions), defaultState); - -/***/ }), -/* 35 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.walletReducer = walletReducer; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -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 reducers = {}; // @flow - -var buildDraftTransaction = function buildDraftTransaction() { - return { - amount: undefined, - address: undefined - }; -}; - -// TODO: Split into common success and failure types -// See details in https://github.com/lbryio/lbry/issues/1307 -/*:: type ActionResult = { - type: any, - result: any, -};*/ -/*:: type WalletState = { - balance: any, - blocks: any, - latestBlock: ?number, - transactions: any, - fetchingTransactions: boolean, - gettingNewAddress: boolean, - draftTransaction: any, - sendingSupport: boolean, - walletIsEncrypted: boolean, - walletEncryptPending: boolean, - walletEncryptSucceded: ?boolean, - walletEncryptResult: ?boolean, - walletDecryptPending: boolean, - walletDecryptSucceded: ?boolean, - walletDecryptResult: ?boolean, - walletUnlockPending: boolean, - walletUnlockSucceded: ?boolean, - walletUnlockResult: ?boolean, - walletLockPending: boolean, - walletLockSucceded: ?boolean, - walletLockResult: ?boolean, -};*/ - - -var defaultState = { - balance: undefined, - totalBalance: undefined, - blocks: {}, - latestBlock: undefined, - transactions: {}, - fetchingTransactions: false, - gettingNewAddress: false, - draftTransaction: buildDraftTransaction(), - sendingSupport: false, - walletIsEncrypted: false, - walletEncryptPending: false, - walletEncryptSucceded: null, - walletEncryptResult: null, - walletDecryptPending: false, - walletDecryptSucceded: null, - walletDecryptResult: null, - walletUnlockPending: false, - walletUnlockSucceded: null, - walletUnlockResult: null, - walletLockPending: false, - walletLockSucceded: null, - walletLockResult: null, - transactionListFilter: 'all' -}; - -reducers[ACTIONS.FETCH_TRANSACTIONS_STARTED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - fetchingTransactions: true - }); -}; - -reducers[ACTIONS.FETCH_TRANSACTIONS_COMPLETED] = function (state /*: WalletState*/, action) { - var byId = Object.assign({}, state.transactions); - - var transactions = action.data.transactions; - - - transactions.forEach(function (transaction) { - byId[transaction.txid] = transaction; - }); - - return Object.assign({}, state, { - transactions: byId, - fetchingTransactions: false - }); -}; - -reducers[ACTIONS.GET_NEW_ADDRESS_STARTED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - gettingNewAddress: true - }); -}; - -reducers[ACTIONS.GET_NEW_ADDRESS_COMPLETED] = function (state /*: WalletState*/, action) { - var address = action.data.address; - - // Say no to localStorage! - - return Object.assign({}, state, { - gettingNewAddress: false, - receiveAddress: address - }); -}; - -reducers[ACTIONS.UPDATE_BALANCE] = function (state /*: WalletState*/, action) { - return Object.assign({}, state, { - balance: action.data.balance - }); -}; - -reducers[ACTIONS.UPDATE_TOTAL_BALANCE] = function (state /*: WalletState*/, action) { - return Object.assign({}, state, { - totalBalance: action.data.totalBalance - }); -}; - -reducers[ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - checkingAddressOwnership: true - }); -}; - -reducers[ACTIONS.CHECK_ADDRESS_IS_MINE_COMPLETED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - checkingAddressOwnership: false - }); -}; - -reducers[ACTIONS.SET_DRAFT_TRANSACTION_AMOUNT] = function (state /*: WalletState*/, action) { - var oldDraft = state.draftTransaction; - var newDraft = Object.assign({}, oldDraft, { - amount: parseFloat(action.data.amount) - }); - - return Object.assign({}, state, { - draftTransaction: newDraft - }); -}; - -reducers[ACTIONS.SET_DRAFT_TRANSACTION_ADDRESS] = function (state /*: WalletState*/, action) { - var oldDraft = state.draftTransaction; - var newDraft = Object.assign({}, oldDraft, { - address: action.data.address - }); - - return Object.assign({}, state, { - draftTransaction: newDraft - }); -}; - -reducers[ACTIONS.SEND_TRANSACTION_STARTED] = function (state /*: WalletState*/) { - var newDraftTransaction = Object.assign({}, state.draftTransaction, { - sending: true - }); - - return Object.assign({}, state, { - draftTransaction: newDraftTransaction - }); -}; - -reducers[ACTIONS.SEND_TRANSACTION_COMPLETED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - draftTransaction: buildDraftTransaction() - }); -}; - -reducers[ACTIONS.SEND_TRANSACTION_FAILED] = function (state /*: WalletState*/, action) { - var newDraftTransaction = Object.assign({}, state.draftTransaction, { - sending: false, - error: action.data.error - }); - - return Object.assign({}, state, { - draftTransaction: newDraftTransaction - }); -}; - -reducers[ACTIONS.SUPPORT_TRANSACTION_STARTED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - sendingSupport: true - }); -}; - -reducers[ACTIONS.SUPPORT_TRANSACTION_COMPLETED] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - sendingSupport: false - }); -}; - -reducers[ACTIONS.SUPPORT_TRANSACTION_FAILED] = function (state /*: WalletState*/, action) { - return Object.assign({}, state, { - error: action.data.error, - sendingSupport: false - }); -}; - -reducers[ACTIONS.FETCH_BLOCK_SUCCESS] = function (state /*: WalletState*/, action) { - var _action$data = action.data, - block = _action$data.block, - height = _action$data.block.height; - - var blocks = Object.assign({}, state.blocks); - - blocks[height] = block; - - return Object.assign({}, state, { blocks: blocks }); -}; - -reducers[ACTIONS.WALLET_STATUS_COMPLETED] = function (state /*: WalletState*/, action) { - return Object.assign({}, state, { - walletIsEncrypted: action.result - }); -}; - -reducers[ACTIONS.WALLET_ENCRYPT_START] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - walletEncryptPending: true, - walletEncryptSucceded: null, - walletEncryptResult: null - }); -}; - -reducers[ACTIONS.WALLET_ENCRYPT_COMPLETED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletEncryptPending: false, - walletEncryptSucceded: true, - walletEncryptResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_ENCRYPT_FAILED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletEncryptPending: false, - walletEncryptSucceded: false, - walletEncryptResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_DECRYPT_START] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - walletDecryptPending: true, - walletDecryptSucceded: null, - walletDecryptResult: null - }); -}; - -reducers[ACTIONS.WALLET_DECRYPT_COMPLETED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletDecryptPending: false, - walletDecryptSucceded: true, - walletDecryptResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_DECRYPT_FAILED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletDecryptPending: false, - walletDecryptSucceded: false, - walletDecryptResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_UNLOCK_START] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - walletUnlockPending: true, - walletUnlockSucceded: null, - walletUnlockResult: null - }); -}; - -reducers[ACTIONS.WALLET_UNLOCK_COMPLETED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletUnlockPending: false, - walletUnlockSucceded: true, - walletUnlockResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_UNLOCK_FAILED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletUnlockPending: false, - walletUnlockSucceded: false, - walletUnlockResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_LOCK_START] = function (state /*: WalletState*/) { - return Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: null, - walletLockResult: null - }); -}; - -reducers[ACTIONS.WALLET_LOCK_COMPLETED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: true, - walletLockResult: action.result - }); -}; - -reducers[ACTIONS.WALLET_LOCK_FAILED] = function (state /*: WalletState*/, action /*: ActionResult*/) { - return Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: false, - walletLockResult: action.result - }); -}; - -reducers[ACTIONS.SET_TRANSACTION_LIST_FILTER] = function (state /*: WalletState*/, action /*: {}*/) { - return Object.assign({}, state, { - transactionListFilter: action.data - }); -}; - -reducers[ACTIONS.UPDATE_CURRENT_HEIGHT] = function (state /*: WalletState*/, action /*: { data: number }*/) { - return Object.assign({}, state, { - latestBlock: action.data - }); -}; - -function walletReducer() { - var state /*: WalletState*/ = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action /*: ActionResult*/ = arguments[1]; - - var handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} - -/***/ }), -/* 36 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); - -var _extends = 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; }; - -exports.contentReducer = contentReducer; - -var _action_types = __webpack_require__(3); - -var ACTIONS = _interopRequireWildcard(_action_types); - -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; } } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var reducers = {}; -var defaultState = { - positions: {} -}; - -reducers[ACTIONS.SET_CONTENT_POSITION] = function (state, action) { - var _action$data = action.data, - claimId = _action$data.claimId, - outpoint = _action$data.outpoint, - position = _action$data.position; - - return _extends({}, state, { - positions: _extends({}, state.positions, _defineProperty({}, claimId, _extends({}, state.positions[claimId], _defineProperty({}, outpoint, position)))) - }); -}; - -function contentReducer() { - var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : defaultState; - var action = arguments[1]; - - var handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} - -/***/ }), -/* 37 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.makeSelectContentPositionForUri = exports.selectState = undefined; - -var _reselect = __webpack_require__(15); - -var _claims = __webpack_require__(11); - -var selectState = exports.selectState = function selectState(state /*: any*/) { - return state.content || {}; -}; - -var makeSelectContentPositionForUri = exports.makeSelectContentPositionForUri = function makeSelectContentPositionForUri(uri /*: string*/) { - return (0, _reselect.createSelector)(selectState, (0, _claims.makeSelectClaimForUri)(uri), function (state, claim) { - if (!claim) { - return null; - } - var outpoint = claim.txid + ':' + claim.nout; - var id = claim.claim_id; - return state.positions[id] ? state.positions[id][outpoint] : null; - }); -}; - -/***/ }), -/* 38 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.selectError = exports.selectToast = exports.selectState = undefined; - -var _extends = 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; }; - -var _reselect = __webpack_require__(15); - -var selectState = exports.selectState = function selectState(state) { - return state.notifications || {}; -}; - -var selectToast = exports.selectToast = (0, _reselect.createSelector)(selectState, function (state) { - if (state.toasts.length) { - var _state$toasts$ = state.toasts[0], - id = _state$toasts$.id, - params = _state$toasts$.params; - - return _extends({ - id: id - }, params); - } - - return null; -}); - -var selectError = exports.selectError = (0, _reselect.createSelector)(selectState, function (state) { - if (state.errors.length) { - var error = state.errors[0].error; - - return { - error: error - }; - } - - return null; -}); - -/***/ }), -/* 39 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -var API_DOWN = exports.API_DOWN = 'apiDown'; -var READY = exports.READY = 'ready'; -var IN_PROGRESS = exports.IN_PROGRESS = 'inProgress'; -var COMPLETE = exports.COMPLETE = 'complete'; -var MANUAL = exports.MANUAL = 'manual'; - -/***/ }), -/* 40 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; - - -Object.defineProperty(exports, "__esModule", { - value: true -}); -/* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ -/* Many SETTINGS are stored in the localStorage by their name - - be careful about changing the value of a SETTINGS constant, as doing so can invalidate existing SETTINGS */ -var CREDIT_REQUIRED_ACKNOWLEDGED = exports.CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged'; -var NEW_USER_ACKNOWLEDGED = exports.NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged'; -var EMAIL_COLLECTION_ACKNOWLEDGED = exports.EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; -var LANGUAGE = exports.LANGUAGE = 'language'; -var SHOW_NSFW = exports.SHOW_NSFW = 'showNsfw'; -var SHOW_UNAVAILABLE = exports.SHOW_UNAVAILABLE = 'showUnavailable'; -var INSTANT_PURCHASE_ENABLED = exports.INSTANT_PURCHASE_ENABLED = 'instantPurchaseEnabled'; -var INSTANT_PURCHASE_MAX = exports.INSTANT_PURCHASE_MAX = 'instantPurchaseMax'; -var THEME = exports.THEME = 'theme'; -var THEMES = exports.THEMES = 'themes'; -var AUTOMATIC_DARK_MODE_ENABLED = exports.AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; - -// mobile settings -var BACKGROUND_PLAY_ENABLED = exports.BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; -var FOREGROUND_NOTIFICATION_ENABLED = exports.FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; -var KEEP_DAEMON_RUNNING = exports.KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; - -/***/ }) -/******/ ]); -}); \ No newline at end of file diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 5541dc0..32318c5 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -1,7 +1,7 @@ // @flow import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; -import { normalizeURI } from 'lbryURI'; +import { normalizeURI, parseURI } from 'lbryURI'; import { doToast } from 'redux/actions/notifications'; import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux/selectors/claims'; import { doFetchTransactions } from 'redux/actions/wallet'; @@ -155,19 +155,22 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { data: { uri, page }, }); - Lbry.claim_search({ uri, page: page || 1 }).then((result: ClaimSearchResponse) => { - const claimResult = result[uri] || {}; - const { claims_in_channel: claimsInChannel, returned_page: returnedPage } = claimResult; + const { claimId } = parseURI(uri); - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, - data: { - uri, - claims: claimsInChannel || [], - page: returnedPage || undefined, - }, - }); - }); + Lbry.claim_search({ channel_id: claimId, page: page || 1 }).then( + (result: ClaimSearchResponse) => { + const { items: claimsInChannel, page: returnedPage } = result; + + dispatch({ + type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, + data: { + uri, + claims: claimsInChannel || [], + page: returnedPage || undefined, + }, + }); + } + ); }; } -- 2.45.2 From faa9d13d609ae94817d3e27fbdb8fa272c2568dc Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 1 May 2019 10:21:51 -0400 Subject: [PATCH 005/371] add cover selector --- dist/bundle.es.js | 6 ++++++ src/index.js | 1 + src/redux/selectors/claims.js | 9 +++++++++ 3 files changed, 16 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 08a1745..459f4c9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1243,6 +1243,11 @@ const makeSelectThumbnailForUri = uri => reselect.createSelector(makeSelectClaim return thumbnail ? thumbnail.url : undefined; }); +const makeSelectCoverForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { + const cover = claim && claim.value && claim.value.cover; + return cover ? cover.url : undefined; +}); + const selectIsFetchingClaimListMine = reselect.createSelector(selectState$1, state => state.isFetchingClaimListMine); const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, (myClaimIds, byId, abandoningIds, pendingClaims) => { @@ -3483,6 +3488,7 @@ exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannel exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; exports.makeSelectContentPositionForUri = makeSelectContentPositionForUri; exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; +exports.makeSelectCoverForUri = makeSelectCoverForUri; exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; diff --git a/src/index.js b/src/index.js index 46467c4..a378626 100644 --- a/src/index.js +++ b/src/index.js @@ -145,6 +145,7 @@ export { selectChannelClaimCounts, selectCurrentChannelPage, makeSelectThumbnailForUri, + makeSelectCoverForUri, } from 'redux/selectors/claims'; export { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 477dfac..5686127 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -196,6 +196,15 @@ export const makeSelectThumbnailForUri = (uri: string) => } ); +export const makeSelectCoverForUri = (uri: string) => + createSelector( + makeSelectClaimForUri(uri), + claim => { + const cover = claim && claim.value && claim.value.cover; + return cover ? cover.url : undefined; + } + ); + export const selectIsFetchingClaimListMine = createSelector( selectState, state => state.isFetchingClaimListMine -- 2.45.2 From 26d68d825951f23f8452f41a598b15be6075b0c7 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 6 May 2019 01:21:24 -0400 Subject: [PATCH 006/371] add email & website_url values to channel metadata types --- dist/flow-typed/Claim.js | 2 ++ flow-typed/Claim.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 49419bc..548000e 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -62,6 +62,8 @@ declare type ChannelMetadata = GenericMetadata & { cover_url?: string, contact_email?: string, homepage_url?: string, + email?: string, + website_url?: string, }; declare type StreamMetadata = GenericMetadata & { diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 49419bc..548000e 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -62,6 +62,8 @@ declare type ChannelMetadata = GenericMetadata & { cover_url?: string, contact_email?: string, homepage_url?: string, + email?: string, + website_url?: string, }; declare type StreamMetadata = GenericMetadata & { -- 2.45.2 From ee2f2093919465b289cb8662fb5e6306d643abba Mon Sep 17 00:00:00 2001 From: Jessop Breth Date: Sun, 5 May 2019 22:00:45 -0400 Subject: [PATCH 007/371] Uses timestamps for dates for Claims and Transactions --- flow-typed/Claim.js | 1 + src/constants/action_types.js | 1 - src/index.js | 3 +- src/redux/actions/wallet.js | 11 -- src/redux/reducers/wallet.js | 12 -- src/redux/selectors/claims.js | 13 ++ src/redux/selectors/wallet.js | 241 ++++++++++++++++++---------------- 7 files changed, 140 insertions(+), 142 deletions(-) diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 49419bc..566e847 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -31,6 +31,7 @@ declare type GenericClaim = { decoded_claim: boolean, // claim made in accordance with sdk protobuf types depth: number, // confirmations since tx effective_amount: number, // bid amount + supports + timestamp?: number, // date of transaction has_signature: boolean, height: number, // block height the tx was confirmed hex: string, // `value` hex encoded diff --git a/src/constants/action_types.js b/src/constants/action_types.js index a01c6ef..37a94cc 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -40,7 +40,6 @@ export const CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED' export const SEND_TRANSACTION_STARTED = 'SEND_TRANSACTION_STARTED'; export const SEND_TRANSACTION_COMPLETED = 'SEND_TRANSACTION_COMPLETED'; export const SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'; -export const FETCH_BLOCK_SUCCESS = 'FETCH_BLOCK_SUCCESS'; export const SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED'; export const SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED'; export const SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED'; diff --git a/src/index.js b/src/index.js index 46467c4..eb27302 100644 --- a/src/index.js +++ b/src/index.js @@ -71,7 +71,6 @@ export { doUpdateTotalBalance, doTotalBalanceSubscribe, doFetchTransactions, - doFetchBlock, doGetNewAddress, doCheckAddressIsMine, doSendDraftTransaction, @@ -111,6 +110,7 @@ export { makeSelectClaimsInChannelForPage, makeSelectMetadataForUri, makeSelectTitleForUri, + makeSelectDateForUri, makeSelectContentTypeForUri, makeSelectIsUriResolving, makeSelectTotalItemsForChannel, @@ -177,7 +177,6 @@ export { } from 'redux/selectors/search'; export { - makeSelectBlockDate, selectBalance, selectTotalBalance, selectTransactionsById, diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 74aa062..cdcd816 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -80,17 +80,6 @@ export function doFetchTransactions() { }; } -export function doFetchBlock(height) { - return dispatch => { - Lbry.block_show({ height }).then(block => { - dispatch({ - type: ACTIONS.FETCH_BLOCK_SUCCESS, - data: { block }, - }); - }); - }; -} - export function doGetNewAddress() { return dispatch => { dispatch({ diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index 308c5e7..5e9061b 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -183,18 +183,6 @@ reducers[ACTIONS.SUPPORT_TRANSACTION_FAILED] = (state: WalletState, action) => sendingSupport: false, }); -reducers[ACTIONS.FETCH_BLOCK_SUCCESS] = (state: WalletState, action) => { - const { - block, - block: { height }, - } = action.data; - const blocks = Object.assign({}, state.blocks); - - blocks[height] = block; - - return Object.assign({}, state, { blocks }); -}; - reducers[ACTIONS.WALLET_STATUS_COMPLETED] = (state: WalletState, action) => Object.assign({}, state, { walletIsEncrypted: action.result, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 477dfac..23b15f9 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -178,6 +178,19 @@ export const makeSelectTitleForUri = (uri: string) => metadata => metadata && metadata.title ); +export const makeSelectDateForUri = (uri: string) => + createSelector( + makeSelectClaimForUri(uri), + claim => { + const timestamp = claim && claim.timestamp ? claim.timestamp * 1000 : undefined; + if (!timestamp) { + return undefined; + } + const dateObj = new Date(timestamp); + return dateObj; + } + ); + export const makeSelectContentTypeForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index af5d340..a79bfc4 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -65,112 +65,130 @@ export const selectWalletLockSucceeded = createSelector( state => state.walletLockSucceded ); -export const selectWalletLockResult = createSelector(selectState, state => state.walletLockResult); +export const selectWalletLockResult = createSelector( + selectState, + state => state.walletLockResult +); -export const selectBalance = createSelector(selectState, state => state.balance); +export const selectBalance = createSelector( + selectState, + state => state.balance +); -export const selectTotalBalance = createSelector(selectState, state => state.totalBalance); +export const selectTotalBalance = createSelector( + selectState, + state => state.totalBalance +); -export const selectTransactionsById = createSelector(selectState, state => state.transactions); +export const selectTransactionsById = createSelector( + selectState, + state => state.transactions +); -export const selectTransactionItems = createSelector(selectTransactionsById, byId => { - const items = []; +export const selectTransactionItems = createSelector( + selectTransactionsById, + byId => { + const items = []; - Object.keys(byId).forEach(txid => { - const tx = byId[txid]; + Object.keys(byId).forEach(txid => { + const tx = byId[txid]; - // ignore dust/fees - // it is fee only txn if all infos are also empty - if ( - Math.abs(tx.value) === Math.abs(tx.fee) && - tx.claim_info.length === 0 && - tx.support_info.length === 0 && - tx.update_info.length === 0 && - tx.abandon_info.length === 0 - ) { - return; - } + // ignore dust/fees + // it is fee only txn if all infos are also empty + if ( + Math.abs(tx.value) === Math.abs(tx.fee) && + tx.claim_info.length === 0 && + tx.support_info.length === 0 && + tx.update_info.length === 0 && + tx.abandon_info.length === 0 + ) { + return; + } - const append = []; + const append = []; - append.push( - ...tx.claim_info.map(item => - Object.assign({}, tx, item, { - type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH, - }) - ) - ); - append.push( - ...tx.support_info.map(item => - Object.assign({}, tx, item, { - type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP, - }) - ) - ); - append.push( - ...tx.update_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE })) - ); - append.push( - ...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON })) - ); - - if (!append.length) { append.push( - Object.assign({}, tx, { - type: tx.value < 0 ? TRANSACTIONS.SPEND : TRANSACTIONS.RECEIVE, + ...tx.claim_info.map(item => + Object.assign({}, tx, item, { + type: item.claim_name[0] === '@' ? TRANSACTIONS.CHANNEL : TRANSACTIONS.PUBLISH, + }) + ) + ); + append.push( + ...tx.support_info.map(item => + Object.assign({}, tx, item, { + type: !item.is_tip ? TRANSACTIONS.SUPPORT : TRANSACTIONS.TIP, + }) + ) + ); + append.push( + ...tx.update_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.UPDATE })) + ); + append.push( + ...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: TRANSACTIONS.ABANDON })) + ); + + if (!append.length) { + append.push( + Object.assign({}, tx, { + type: tx.value < 0 ? TRANSACTIONS.SPEND : TRANSACTIONS.RECEIVE, + }) + ); + } + + items.push( + ...append.map(item => { + // value on transaction, amount on outpoint + // amount is always positive, but should match sign of value + const balanceDelta = parseFloat(item.balance_delta); + const value = parseFloat(item.value); + const amount = balanceDelta || value; + const fee = parseFloat(tx.fee); + + return { + txid, + timestamp: tx.timestamp, + date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, + amount, + fee, + claim_id: item.claim_id, + claim_name: item.claim_name, + type: item.type || TRANSACTIONS.SPEND, + nout: item.nout, + confirmations: tx.confirmations, + }; }) ); - } + }); - items.push( - ...append.map(item => { - // value on transaction, amount on outpoint - // amount is always positive, but should match sign of value - const balanceDelta = parseFloat(item.balance_delta); - const value = parseFloat(item.value); - const amount = balanceDelta || value; - const fee = parseFloat(tx.fee); + return items.sort((tx1, tx2) => { + if (!tx1.timestamp && !tx2.timestamp) { + return 0; + } else if (!tx1.timestamp && tx2.timestamp) { + return -1; + } else if (tx1.timestamp && !tx2.timestamp) { + return 1; + } - return { - txid, - timestamp: tx.timestamp, - date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, - amount, - fee, - claim_id: item.claim_id, - claim_name: item.claim_name, - type: item.type || TRANSACTIONS.SPEND, - nout: item.nout, - confirmations: tx.confirmations, - }; - }) - ); - }); + return tx2.timestamp - tx1.timestamp; + }); + } +); - return items.sort((tx1, tx2) => { - if (!tx1.timestamp && !tx2.timestamp) { - return 0; - } else if (!tx1.timestamp && tx2.timestamp) { - return -1; - } else if (tx1.timestamp && !tx2.timestamp) { - return 1; - } +export const selectRecentTransactions = createSelector( + selectTransactionItems, + transactions => { + const threshold = new Date(); + threshold.setDate(threshold.getDate() - 7); + return transactions.filter(transaction => { + if (!transaction.date) { + return true; // pending transaction + } - return tx2.timestamp - tx1.timestamp; - }); -}); - -export const selectRecentTransactions = createSelector(selectTransactionItems, transactions => { - const threshold = new Date(); - threshold.setDate(threshold.getDate() - 7); - return transactions.filter(transaction => { - if (!transaction.date) { - return true; // pending transaction - } - - return transaction.date > threshold; - }); -}); + return transaction.date > threshold; + }); + } +); export const selectHasTransactions = createSelector( selectTransactionItems, @@ -182,9 +200,15 @@ export const selectIsFetchingTransactions = createSelector( state => state.fetchingTransactions ); -export const selectIsSendingSupport = createSelector(selectState, state => state.sendingSupport); +export const selectIsSendingSupport = createSelector( + selectState, + state => state.sendingSupport +); -export const selectReceiveAddress = createSelector(selectState, state => state.receiveAddress); +export const selectReceiveAddress = createSelector( + selectState, + state => state.receiveAddress +); export const selectGettingNewAddress = createSelector( selectState, @@ -211,30 +235,15 @@ export const selectDraftTransactionError = createSelector( draft => draft.error ); -export const selectBlocks = createSelector(selectState, state => state.blocks); +export const selectBlocks = createSelector( + selectState, + state => state.blocks +); -export const selectCurrentHeight = createSelector(selectState, state => state.latestBlock); - -export const makeSelectBlockDate = block => - createSelector(selectBlocks, selectCurrentHeight, (blocks, latestBlock) => { - // If we have the block data, look at the actual date, - // If not, try to simulate it based on 2.5 minute blocks - // Adding this on 11/7/2018 because caling block_show for every claim is causing - // performance issues. - if (blocks && blocks[block]) { - return new Date(blocks[block].time * 1000); - } - - // Pending claim - if (block < 1) { - return null; - } - - const difference = latestBlock - block; - const msSincePublish = difference * 2.5 * 60 * 1000; // Number of blocks * 2.5 minutes in ms - const publishDate = Date.now() - msSincePublish; - return new Date(publishDate); - }); +export const selectCurrentHeight = createSelector( + selectState, + state => state.latestBlock +); export const selectTransactionListFilter = createSelector( selectState, -- 2.45.2 From 459bea2257d61003e591daf169fefe9624522680 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 6 May 2019 13:57:07 -0400 Subject: [PATCH 008/371] add generic metadata selector --- dist/bundle.es.js | 5 +++++ src/index.js | 5 +++-- src/redux/selectors/claims.js | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 459f4c9..ea149de 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1231,6 +1231,10 @@ const makeSelectMetadataForUri = uri => reselect.createSelector(makeSelectClaimF return metadata || (claim === undefined ? undefined : null); }); +const makeSelectMetadataItemForUri = (uri, key) => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => { + return metadata ? metadata[key] : undefined; +}); + const makeSelectTitleForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); const makeSelectContentTypeForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { @@ -3496,6 +3500,7 @@ exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileFor exports.makeSelectIsUriResolving = makeSelectIsUriResolving; exports.makeSelectLoadingForUri = makeSelectLoadingForUri; exports.makeSelectMetadataForUri = makeSelectMetadataForUri; +exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectPendingByUri = makeSelectPendingByUri; diff --git a/src/index.js b/src/index.js index a378626..30b7cb5 100644 --- a/src/index.js +++ b/src/index.js @@ -110,6 +110,9 @@ export { makeSelectFetchingChannelClaims, makeSelectClaimsInChannelForPage, makeSelectMetadataForUri, + makeSelectMetadataItemForUri, + makeSelectThumbnailForUri, + makeSelectCoverForUri, makeSelectTitleForUri, makeSelectContentTypeForUri, makeSelectIsUriResolving, @@ -144,8 +147,6 @@ export { selectPlayingUri, selectChannelClaimCounts, selectCurrentChannelPage, - makeSelectThumbnailForUri, - makeSelectCoverForUri, } from 'redux/selectors/claims'; export { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 5686127..96e7000 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -172,6 +172,14 @@ export const makeSelectMetadataForUri = (uri: string) => } ); +export const makeSelectMetadataItemForUri = (uri: string, key: string) => + createSelector( + makeSelectMetadataForUri(uri), + (metadata: ChannelMetadata | StreamMetadata) => { + return metadata ? metadata[key] : undefined; + } + ); + export const makeSelectTitleForUri = (uri: string) => createSelector( makeSelectMetadataForUri(uri), -- 2.45.2 From d169b66b0e667437091af047c3322de20e897ecb Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 7 May 2019 00:18:22 -0400 Subject: [PATCH 009/371] fix: remove mediaType when searching for files --- dist/bundle.es.js | 5 +++-- src/util/query_params.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 459f4c9..2855346 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -775,10 +775,11 @@ const getSearchQueryString = (query, options = {}, includeUserOptions = false) = const queryParams = [`s=${encodedQuery}`, `size=${options.size || DEFAULT_SEARCH_SIZE}`, `from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`]; if (includeUserOptions) { - queryParams.push(`claimType=${options[SEARCH_OPTIONS.CLAIM_TYPE]}`); + const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; + queryParams.push(`claimType=${claimType}`); // If they are only searching for channels, strip out the media info - if (options[SEARCH_OPTIONS.CLAIM_TYPE] !== SEARCH_OPTIONS.INCLUDE_CHANNELS) { + if (!claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS)) { queryParams.push(`mediaType=${[SEARCH_OPTIONS.MEDIA_FILE, SEARCH_OPTIONS.MEDIA_AUDIO, SEARCH_OPTIONS.MEDIA_VIDEO, SEARCH_OPTIONS.MEDIA_TEXT, SEARCH_OPTIONS.MEDIA_IMAGE, SEARCH_OPTIONS.MEDIA_APPLICATION].reduce((acc, currentOption) => options[currentOption] ? `${acc}${currentOption},` : acc, '')}`); } } diff --git a/src/util/query_params.js b/src/util/query_params.js index 1e99cb2..9f6ae1f 100644 --- a/src/util/query_params.js +++ b/src/util/query_params.js @@ -46,10 +46,11 @@ export const getSearchQueryString = ( ]; if (includeUserOptions) { - queryParams.push(`claimType=${options[SEARCH_OPTIONS.CLAIM_TYPE]}`); + const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; + queryParams.push(`claimType=${claimType}`); // If they are only searching for channels, strip out the media info - if (options[SEARCH_OPTIONS.CLAIM_TYPE] !== SEARCH_OPTIONS.INCLUDE_CHANNELS) { + if (!claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS)) { queryParams.push( `mediaType=${[ SEARCH_OPTIONS.MEDIA_FILE, -- 2.45.2 From 2b94f516eb3dc6d0599c17758fa1a962df347649 Mon Sep 17 00:00:00 2001 From: Jessop Breth Date: Sun, 5 May 2019 22:00:45 -0400 Subject: [PATCH 010/371] Uses timestamps for dates for Claims and Transactions --- dist/bundle.es.js | 67 ++++--------- dist/flow-typed/Claim.js | 1 + src/redux/selectors/file_info.js | 167 +++++++++++++++++-------------- 3 files changed, 112 insertions(+), 123 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 459f4c9..7435ec7 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -50,7 +50,6 @@ const CHECK_ADDRESS_IS_MINE_COMPLETED = 'CHECK_ADDRESS_IS_MINE_COMPLETED'; const SEND_TRANSACTION_STARTED = 'SEND_TRANSACTION_STARTED'; const SEND_TRANSACTION_COMPLETED = 'SEND_TRANSACTION_COMPLETED'; const SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'; -const FETCH_BLOCK_SUCCESS = 'FETCH_BLOCK_SUCCESS'; const SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED'; const SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED'; const SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED'; @@ -262,7 +261,6 @@ var action_types = /*#__PURE__*/Object.freeze({ SEND_TRANSACTION_STARTED: SEND_TRANSACTION_STARTED, SEND_TRANSACTION_COMPLETED: SEND_TRANSACTION_COMPLETED, SEND_TRANSACTION_FAILED: SEND_TRANSACTION_FAILED, - FETCH_BLOCK_SUCCESS: FETCH_BLOCK_SUCCESS, SUPPORT_TRANSACTION_STARTED: SUPPORT_TRANSACTION_STARTED, SUPPORT_TRANSACTION_COMPLETED: SUPPORT_TRANSACTION_COMPLETED, SUPPORT_TRANSACTION_FAILED: SUPPORT_TRANSACTION_FAILED, @@ -1233,6 +1231,15 @@ const makeSelectMetadataForUri = uri => reselect.createSelector(makeSelectClaimF const makeSelectTitleForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); +const makeSelectDateForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { + const timestamp = claim && claim.timestamp ? claim.timestamp * 1000 : undefined; + if (!timestamp) { + return undefined; + } + const dateObj = new Date(timestamp); + return dateObj; +}); + const makeSelectContentTypeForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { const source = claim && claim.value && claim.value.source; return source ? source.media_type : undefined; @@ -1510,26 +1517,6 @@ const selectBlocks = reselect.createSelector(selectState$2, state => state.block const selectCurrentHeight = reselect.createSelector(selectState$2, state => state.latestBlock); -const makeSelectBlockDate = block => reselect.createSelector(selectBlocks, selectCurrentHeight, (blocks, latestBlock) => { - // If we have the block data, look at the actual date, - // If not, try to simulate it based on 2.5 minute blocks - // Adding this on 11/7/2018 because caling block_show for every claim is causing - // performance issues. - if (blocks && blocks[block]) { - return new Date(blocks[block].time * 1000); - } - - // Pending claim - if (block < 1) { - return null; - } - - const difference = latestBlock - block; - const msSincePublish = difference * 2.5 * 60 * 1000; // Number of blocks * 2.5 minutes in ms - const publishDate = Date.now() - msSincePublish; - return new Date(publishDate); -}); - const selectTransactionListFilter = reselect.createSelector(selectState$2, state => state.transactionListFilter || ''); function formatCredits(amount, precision) { @@ -1631,17 +1618,6 @@ function doFetchTransactions() { }; } -function doFetchBlock(height) { - return dispatch => { - lbryProxy.block_show({ height }).then(block => { - dispatch({ - type: FETCH_BLOCK_SUCCESS, - data: { block } - }); - }); - }; -} - function doGetNewAddress() { return dispatch => { dispatch({ @@ -2235,14 +2211,18 @@ const selectSearchDownloadUris = query => reselect.createSelector(selectFileInfo }); return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(fileInfo => { - const { channel_name: channelName, claim_id: claimId, claim_name: claimName } = fileInfo; + const { + channel_name: channelName, + claim_id: claimId, + claim_name: claimName + } = fileInfo; const uriParams = {}; if (channelName) { const claim = claimsById[claimId]; - if (claim && claim.value) { - uriParams.claimId = claim.value.publisherSignature.certificateId; + if (claim && claim.signing_channel) { + uriParams.claimId = claim.signing_channel.claim_id; } else { uriParams.claimId = claimId; } @@ -3256,18 +3236,6 @@ reducers$2[SUPPORT_TRANSACTION_FAILED] = (state, action) => Object.assign({}, st sendingSupport: false }); -reducers$2[FETCH_BLOCK_SUCCESS] = (state, action) => { - const { - block, - block: { height } - } = action.data; - const blocks = Object.assign({}, state.blocks); - - blocks[height] = block; - - return Object.assign({}, state, { blocks }); -}; - reducers$2[WALLET_STATUS_COMPLETED] = (state, action) => Object.assign({}, state, { walletIsEncrypted: action.result }); @@ -3442,7 +3410,6 @@ exports.doCreateChannel = doCreateChannel; exports.doDismissError = doDismissError; exports.doDismissToast = doDismissToast; exports.doError = doError; -exports.doFetchBlock = doFetchBlock; exports.doFetchChannelListMine = doFetchChannelListMine; exports.doFetchClaimListMine = doFetchClaimListMine; exports.doFetchClaimsByChannel = doFetchClaimsByChannel; @@ -3478,7 +3445,6 @@ exports.formatFullPrice = formatFullPrice; exports.isNameValid = isNameValid; exports.isURIClaimable = isURIClaimable; exports.isURIValid = isURIValid; -exports.makeSelectBlockDate = makeSelectBlockDate; exports.makeSelectChannelForClaimUri = makeSelectChannelForClaimUri; exports.makeSelectClaimForUri = makeSelectClaimForUri; exports.makeSelectClaimIsMine = makeSelectClaimIsMine; @@ -3489,6 +3455,7 @@ exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; exports.makeSelectContentPositionForUri = makeSelectContentPositionForUri; exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; exports.makeSelectCoverForUri = makeSelectCoverForUri; +exports.makeSelectDateForUri = makeSelectDateForUri; exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 548000e..8bdd33c 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -31,6 +31,7 @@ declare type GenericClaim = { decoded_claim: boolean, // claim made in accordance with sdk protobuf types depth: number, // confirmations since tx effective_amount: number, // bid amount + supports + timestamp?: number, // date of transaction has_signature: boolean, height: number, // block height the tx was confirmed hex: string, // `value` hex encoded diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index ac346af..ab941ea 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -26,11 +26,15 @@ export const selectIsFetchingFileListDownloadedOrPublished = createSelector( ); export const makeSelectFileInfoForUri = uri => - createSelector(selectClaimsByUri, selectFileInfosByOutpoint, (claims, byOutpoint) => { - const claim = claims[uri]; - const outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; - return outpoint ? byOutpoint[outpoint] : undefined; - }); + createSelector( + selectClaimsByUri, + selectFileInfosByOutpoint, + (claims, byOutpoint) => { + const claim = claims[uri]; + const outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined; + return outpoint ? byOutpoint[outpoint] : undefined; + } + ); export const selectDownloadingByOutpoint = createSelector( selectState, @@ -47,10 +51,16 @@ export const makeSelectDownloadingForUri = uri => } ); -export const selectUrisLoading = createSelector(selectState, state => state.urisLoading || {}); +export const selectUrisLoading = createSelector( + selectState, + state => state.urisLoading || {} +); export const makeSelectLoadingForUri = uri => - createSelector(selectUrisLoading, byUri => byUri && byUri[uri]); + createSelector( + selectUrisLoading, + byUri => byUri && byUri[uri] + ); export const selectFileInfosDownloaded = createSelector( selectFileInfosByOutpoint, @@ -93,93 +103,103 @@ export const selectDownloadingFileInfos = createSelector( } ); -export const selectTotalDownloadProgress = createSelector(selectDownloadingFileInfos, fileInfos => { - const progress = []; +export const selectTotalDownloadProgress = createSelector( + selectDownloadingFileInfos, + fileInfos => { + const progress = []; - fileInfos.forEach(fileInfo => { - progress.push((fileInfo.written_bytes / fileInfo.total_bytes) * 100); - }); + fileInfos.forEach(fileInfo => { + progress.push((fileInfo.written_bytes / fileInfo.total_bytes) * 100); + }); - const totalProgress = progress.reduce((a, b) => a + b, 0); + const totalProgress = progress.reduce((a, b) => a + b, 0); - if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; - return -1; -}); + if (fileInfos.length > 0) return totalProgress / fileInfos.length / 100.0; + return -1; + } +); export const selectSearchDownloadUris = query => - createSelector(selectFileInfosDownloaded, selectClaimsById, (fileInfos, claimsById) => { - if (!query || !fileInfos.length) { - return null; - } - - const queryParts = query.toLowerCase().split(' '); - const searchQueryDictionary = {}; - queryParts.forEach(subQuery => { - searchQueryDictionary[subQuery] = subQuery; - }); - - const arrayContainsQueryPart = array => { - for (let i = 0; i < array.length; i += 1) { - const subQuery = array[i]; - if (searchQueryDictionary[subQuery]) { - return true; - } + createSelector( + selectFileInfosDownloaded, + selectClaimsById, + (fileInfos, claimsById) => { + if (!query || !fileInfos.length) { + return null; } - return false; - }; - const downloadResultsFromQuery = []; - fileInfos.forEach(fileInfo => { - const { channel_name: channelName, claim_name: claimName, metadata } = fileInfo; - const { author, description, title } = metadata; + const queryParts = query.toLowerCase().split(' '); + const searchQueryDictionary = {}; + queryParts.forEach(subQuery => { + searchQueryDictionary[subQuery] = subQuery; + }); - if (channelName) { - const lowerCaseChannel = channelName.toLowerCase(); - const strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ - if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { + const arrayContainsQueryPart = array => { + for (let i = 0; i < array.length; i += 1) { + const subQuery = array[i]; + if (searchQueryDictionary[subQuery]) { + return true; + } + } + return false; + }; + + const downloadResultsFromQuery = []; + fileInfos.forEach(fileInfo => { + const { channel_name: channelName, claim_name: claimName, metadata } = fileInfo; + const { author, description, title } = metadata; + + if (channelName) { + const lowerCaseChannel = channelName.toLowerCase(); + const strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ + if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { + downloadResultsFromQuery.push(fileInfo); + return; + } + } + + const nameParts = claimName.toLowerCase().split('-'); + if (arrayContainsQueryPart(nameParts)) { downloadResultsFromQuery.push(fileInfo); return; } - } - const nameParts = claimName.toLowerCase().split('-'); - if (arrayContainsQueryPart(nameParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - const titleParts = title.toLowerCase().split(' '); - if (arrayContainsQueryPart(titleParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - if (author) { - const authorParts = author.toLowerCase().split(' '); - if (arrayContainsQueryPart(authorParts)) { + const titleParts = title.toLowerCase().split(' '); + if (arrayContainsQueryPart(titleParts)) { downloadResultsFromQuery.push(fileInfo); return; } - } - if (description) { - const descriptionParts = description.toLowerCase().split(' '); - if (arrayContainsQueryPart(descriptionParts)) { - downloadResultsFromQuery.push(fileInfo); + if (author) { + const authorParts = author.toLowerCase().split(' '); + if (arrayContainsQueryPart(authorParts)) { + downloadResultsFromQuery.push(fileInfo); + return; + } } - } - }); - return downloadResultsFromQuery.length - ? downloadResultsFromQuery.map(fileInfo => { - const { channel_name: channelName, claim_id: claimId, claim_name: claimName } = fileInfo; + if (description) { + const descriptionParts = description.toLowerCase().split(' '); + if (arrayContainsQueryPart(descriptionParts)) { + downloadResultsFromQuery.push(fileInfo); + } + } + }); + + return downloadResultsFromQuery.length + ? downloadResultsFromQuery.map(fileInfo => { + const { + channel_name: channelName, + claim_id: claimId, + claim_name: claimName, + } = fileInfo; const uriParams = {}; if (channelName) { const claim = claimsById[claimId]; - if (claim && claim.value) { - uriParams.claimId = claim.value.publisherSignature.certificateId; + if (claim && claim.signing_channel) { + uriParams.claimId = claim.signing_channel.claim_id; } else { uriParams.claimId = claimId; } @@ -193,8 +213,9 @@ export const selectSearchDownloadUris = query => const uri = buildURI(uriParams); return uri; }) - : null; - }); + : null; + } + ); export const selectFileListPublishedSort = createSelector( selectState, -- 2.45.2 From 423123f1c19e61cead67c745d0892a2e4481cb6a Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 9 May 2019 09:57:58 -0400 Subject: [PATCH 011/371] add: nsfw Also cleaned up some metadata depth is no longer there, replaced by confirmations added city added featured to channel removed email/homepage --- dist/bundle.es.js | 1 + dist/flow-typed/Claim.js | 5 ++--- flow-typed/Claim.js | 5 ++--- src/index.js | 1 + 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e36df2e..ee3aad0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3446,6 +3446,7 @@ exports.doWalletUnlock = doWalletUnlock; exports.fileInfoReducer = fileInfoReducer; exports.formatCredits = formatCredits; exports.formatFullPrice = formatFullPrice; +exports.isClaimNsfw = isClaimNsfw; exports.isNameValid = isNameValid; exports.isURIClaimable = isURIClaimable; exports.isURIValid = isURIValid; diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 8bdd33c..9cbf4da 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -29,7 +29,6 @@ declare type GenericClaim = { claim_op: 'create' | 'update', confirmations: number, // This isn't the most stable atm: https://github.com/lbryio/lbry/issues/2000 decoded_claim: boolean, // claim made in accordance with sdk protobuf types - depth: number, // confirmations since tx effective_amount: number, // bid amount + supports timestamp?: number, // date of transaction has_signature: boolean, @@ -61,10 +60,9 @@ declare type GenericMetadata = { declare type ChannelMetadata = GenericMetadata & { public_key: string, cover_url?: string, - contact_email?: string, - homepage_url?: string, email?: string, website_url?: string, + featured?: Array, }; declare type StreamMetadata = GenericMetadata & { @@ -108,6 +106,7 @@ declare type Location = { longitude?: number, country?: string, state?: string, + city?: string, code?: string, }; diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 8bdd33c..9cbf4da 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -29,7 +29,6 @@ declare type GenericClaim = { claim_op: 'create' | 'update', confirmations: number, // This isn't the most stable atm: https://github.com/lbryio/lbry/issues/2000 decoded_claim: boolean, // claim made in accordance with sdk protobuf types - depth: number, // confirmations since tx effective_amount: number, // bid amount + supports timestamp?: number, // date of transaction has_signature: boolean, @@ -61,10 +60,9 @@ declare type GenericMetadata = { declare type ChannelMetadata = GenericMetadata & { public_key: string, cover_url?: string, - contact_email?: string, - homepage_url?: string, email?: string, website_url?: string, + featured?: Array, }; declare type StreamMetadata = GenericMetadata & { @@ -108,6 +106,7 @@ declare type Location = { longitude?: number, country?: string, state?: string, + city?: string, code?: string, }; diff --git a/src/index.js b/src/index.js index a0ccf45..9c17d2d 100644 --- a/src/index.js +++ b/src/index.js @@ -89,6 +89,7 @@ export { export { batchActions } from 'util/batchActions'; export { parseQueryParams, toQueryString } from 'util/query_params'; export { formatCredits, formatFullPrice, creditsToString } from 'util/formatCredits'; +export { isClaimNsfw } from 'util/claim'; // reducers export { claimsReducer } from 'redux/reducers/claims'; -- 2.45.2 From 391286677f42dea9e6d3725c702bf1be370cb12c Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 9 May 2019 14:13:55 -0400 Subject: [PATCH 012/371] fix: change fee amount to string SDK has updated this amount also. --- dist/flow-typed/Claim.js | 2 +- flow-typed/Claim.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 9cbf4da..69ac31b 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -111,7 +111,7 @@ declare type Location = { }; declare type Fee = { - amount: number, // should be a string https://github.com/lbryio/lbry/issues/1576 + amount: string, currency: string, address: string, }; diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 9cbf4da..69ac31b 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -111,7 +111,7 @@ declare type Location = { }; declare type Fee = { - amount: number, // should be a string https://github.com/lbryio/lbry/issues/1576 + amount: string, currency: string, address: string, }; -- 2.45.2 From c8126ab21792d7a85e1123a2363af285a0263654 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 10 May 2019 01:02:03 -0400 Subject: [PATCH 013/371] store user supports --- dist/bundle.es.js | 438 +++++++++++++++++++-------------- dist/flow-typed/Lbry.js | 3 + dist/flow-typed/Transaction.js | 16 ++ flow-typed/Lbry.js | 3 + flow-typed/Transaction.js | 16 ++ src/constants/action_types.js | 4 + src/index.js | 1 + src/lbry.js | 1 + src/redux/actions/claims.js | 55 +++-- src/redux/actions/wallet.js | 18 ++ src/redux/reducers/wallet.js | 403 ++++++++++++++++-------------- src/redux/selectors/wallet.js | 7 +- 12 files changed, 574 insertions(+), 391 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 172c991..57f1639 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -43,6 +43,10 @@ const GET_NEW_ADDRESS_STARTED = 'GET_NEW_ADDRESS_STARTED'; const GET_NEW_ADDRESS_COMPLETED = 'GET_NEW_ADDRESS_COMPLETED'; const FETCH_TRANSACTIONS_STARTED = 'FETCH_TRANSACTIONS_STARTED'; const FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'; +const FETCH_SUPPORTS_STARTED = 'FETCH_SUPPORTS_STARTED'; +const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED'; +const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED'; +const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED'; const UPDATE_BALANCE = 'UPDATE_BALANCE'; const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; @@ -254,6 +258,10 @@ var action_types = /*#__PURE__*/Object.freeze({ GET_NEW_ADDRESS_COMPLETED: GET_NEW_ADDRESS_COMPLETED, FETCH_TRANSACTIONS_STARTED: FETCH_TRANSACTIONS_STARTED, FETCH_TRANSACTIONS_COMPLETED: FETCH_TRANSACTIONS_COMPLETED, + FETCH_SUPPORTS_STARTED: FETCH_SUPPORTS_STARTED, + FETCH_SUPPORTS_COMPLETED: FETCH_SUPPORTS_COMPLETED, + ABANDON_SUPPORT_STARTED: ABANDON_SUPPORT_STARTED, + ABANDON_SUPPORT_COMPLETED: ABANDON_SUPPORT_COMPLETED, UPDATE_BALANCE: UPDATE_BALANCE, UPDATE_TOTAL_BALANCE: UPDATE_TOTAL_BALANCE, CHECK_ADDRESS_IS_MINE_STARTED: CHECK_ADDRESS_IS_MINE_STARTED, @@ -647,6 +655,7 @@ const Lbry = { address_unused: (params = {}) => daemonCallWithResult('address_unused', params), transaction_list: (params = {}) => daemonCallWithResult('transaction_list', params), utxo_release: (params = {}) => daemonCallWithResult('utxo_release', params), + support_abandon: (params = {}) => daemonCallWithResult('support_abandon', params), sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), @@ -1421,7 +1430,9 @@ const selectBalance = reselect.createSelector(selectState$2, state => state.bala const selectTotalBalance = reselect.createSelector(selectState$2, state => state.totalBalance); -const selectTransactionsById = reselect.createSelector(selectState$2, state => state.transactions); +const selectTransactionsById = reselect.createSelector(selectState$2, state => state.transactions || {}); + +const selectSupportsById = reselect.createSelector(selectState$2, state => state.supports || {}); const selectTransactionItems = reselect.createSelector(selectTransactionsById, byId => { const items = []; @@ -1608,6 +1619,7 @@ function doTotalBalanceSubscribe() { function doFetchTransactions() { return dispatch => { + dispatch(doFetchSupports()); dispatch({ type: FETCH_TRANSACTIONS_STARTED }); @@ -1623,6 +1635,23 @@ function doFetchTransactions() { }; } +function doFetchSupports() { + return dispatch => { + dispatch({ + type: FETCH_SUPPORTS_STARTED + }); + + lbryProxy.support_list().then(results => { + dispatch({ + type: FETCH_SUPPORTS_COMPLETED, + data: { + supports: results + } + }); + }); + }; +} + function doGetNewAddress() { return dispatch => { dispatch({ @@ -1966,39 +1995,43 @@ function doAbandonClaim(txid, nout) { return (dispatch, getState) => { const state = getState(); const myClaims = selectMyClaimsRaw(state); - const claimToAbandon = myClaims.find(claim => claim.txid === txid && claim.nout === nout); + const mySupports = selectSupportsById(state); - if (!claimToAbandon) { - console.error('No associated claim with txid: ', txid); + // A user could be trying to abandon a support or one of their claims + const claimToAbandon = myClaims.find(claim => claim.txid === txid && claim.nout === nout); + const supportToAbandon = mySupports[txid]; + + if (!claimToAbandon && !supportToAbandon) { + console.error('No associated support or claim with txid: ', txid); return; } - const { claim_id: claimId, name: claimName } = claimToAbandon; + const data = claimToAbandon ? { claimId: claimToAbandon.claim_id } : { txid: supportToAbandon.txid }; + + const isClaim = !!claimToAbandon; + const startedActionType = isClaim ? ABANDON_CLAIM_STARTED : ABANDON_SUPPORT_STARTED; + const completedActionType = isClaim ? ABANDON_CLAIM_STARTED : ABANDON_SUPPORT_COMPLETED; dispatch({ - type: ABANDON_CLAIM_STARTED, - data: { - claimId - } + type: startedActionType, + data }); const errorCallback = () => { dispatch(doToast({ - message: 'Error abandoning claim', + message: isClaim ? 'Error abandoning your claim' : 'Error unlocking your tip', isError: true })); }; const successCallback = () => { dispatch({ - type: ABANDON_CLAIM_SUCCEEDED, - data: { - claimId - } + type: completedActionType, + data }); dispatch(doToast({ - message: 'Successfully abandoned your claim' + message: isClaim ? 'Successfully abandoned your claim' : 'Successfully unlocked your tip!' })); // After abandoning, call claim_list to show the claim as abandoned @@ -2013,7 +2046,19 @@ function doAbandonClaim(txid, nout) { blocking: true }; - const method = claimName.startsWith('@') ? 'channel_abandon' : 'stream_abandon'; + let method; + if (supportToAbandon) { + method = 'support_abandon'; + } else if (claimToAbandon) { + const { name: claimName } = claimToAbandon; + method = claimName.startsWith('@') ? 'channel_abandon' : 'stream_abandon'; + } + + if (!method) { + console.error('No "method" chosen for claim or support abandon'); + return; + } + lbryProxy[method](abandonParams).then(successCallback, errorCallback); }; } @@ -3094,9 +3139,8 @@ const searchReducer = handleActions({ } }, defaultState$3); -// +var _extends$7 = 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; }; -const reducers$2 = {}; const buildDraftTransaction = () => ({ amount: undefined, address: undefined @@ -3109,10 +3153,12 @@ const buildDraftTransaction = () => ({ const defaultState$4 = { balance: undefined, totalBalance: undefined, - blocks: {}, latestBlock: undefined, transactions: {}, fetchingTransactions: false, + supports: {}, + fetchingSupports: false, + abandoningSupportsById: {}, gettingNewAddress: false, draftTransaction: buildDraftTransaction(), sendingSupport: false, @@ -3132,217 +3178,234 @@ const defaultState$4 = { transactionListFilter: 'all' }; -reducers$2[FETCH_TRANSACTIONS_STARTED] = state => Object.assign({}, state, { - fetchingTransactions: true -}); +const walletReducer = handleActions({ + [FETCH_TRANSACTIONS_STARTED]: state => _extends$7({}, state, { + fetchingTransactions: true + }), -reducers$2[FETCH_TRANSACTIONS_COMPLETED] = (state, action) => { - const byId = Object.assign({}, state.transactions); + [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { + const byId = _extends$7({}, state.transactions); - const { transactions } = action.data; + const { transactions } = action.data; + transactions.forEach(transaction => { + byId[transaction.txid] = transaction; + }); - transactions.forEach(transaction => { - byId[transaction.txid] = transaction; - }); + return _extends$7({}, state, { + transactions: byId, + fetchingTransactions: false + }); + }, - return Object.assign({}, state, { - transactions: byId, - fetchingTransactions: false - }); -}; + [FETCH_SUPPORTS_STARTED]: state => _extends$7({}, state, { + fetchingSupports: true + }), -reducers$2[GET_NEW_ADDRESS_STARTED] = state => Object.assign({}, state, { - gettingNewAddress: true -}); + [FETCH_SUPPORTS_COMPLETED]: (state, action) => { + const byId = state.supports; + const { supports } = action.data; -reducers$2[GET_NEW_ADDRESS_COMPLETED] = (state, action) => { - const { address } = action.data; + supports.forEach(support => { + byId[support.txid] = support; + }); - // Say no to localStorage! - return Object.assign({}, state, { - gettingNewAddress: false, - receiveAddress: address - }); -}; + return _extends$7({}, state, { supports: byId, fetchingSupports: false }); + }, -reducers$2[UPDATE_BALANCE] = (state, action) => Object.assign({}, state, { - balance: action.data.balance -}); + [ABANDON_SUPPORT_STARTED]: (state, action) => { + const { txid } = action.data; + const abandoningById = state.abandoningSupportsById; -reducers$2[UPDATE_TOTAL_BALANCE] = (state, action) => Object.assign({}, state, { - totalBalance: action.data.totalBalance -}); + abandoningById[txid] = true; -reducers$2[CHECK_ADDRESS_IS_MINE_STARTED] = state => Object.assign({}, state, { - checkingAddressOwnership: true -}); + return _extends$7({}, state, { + abandoningSupportsById: abandoningById + }); + }, -reducers$2[CHECK_ADDRESS_IS_MINE_COMPLETED] = state => Object.assign({}, state, { - checkingAddressOwnership: false -}); + [ABANDON_SUPPORT_COMPLETED]: (state, action) => { + const { txid } = action.data; + const byId = state.supports; + const abandoningById = state.abandoningSupportsById; -reducers$2[SET_DRAFT_TRANSACTION_AMOUNT] = (state, action) => { - const oldDraft = state.draftTransaction; - const newDraft = Object.assign({}, oldDraft, { - amount: parseFloat(action.data.amount) - }); + delete abandoningById[txid]; + delete byId[txid]; - return Object.assign({}, state, { - draftTransaction: newDraft - }); -}; + return _extends$7({}, state, { + supports: byId, + abandoningSupportsById: abandoningById + }); + }, -reducers$2[SET_DRAFT_TRANSACTION_ADDRESS] = (state, action) => { - const oldDraft = state.draftTransaction; - const newDraft = Object.assign({}, oldDraft, { - address: action.data.address - }); + [GET_NEW_ADDRESS_STARTED]: state => _extends$7({}, state, { + gettingNewAddress: true + }), - return Object.assign({}, state, { - draftTransaction: newDraft - }); -}; + [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { + const { address } = action.data; -reducers$2[SEND_TRANSACTION_STARTED] = state => { - const newDraftTransaction = Object.assign({}, state.draftTransaction, { - sending: true - }); + return _extends$7({}, state, { gettingNewAddress: false, receiveAddress: address }); + }, - return Object.assign({}, state, { - draftTransaction: newDraftTransaction - }); -}; + [UPDATE_BALANCE]: (state, action) => _extends$7({}, state, { + balance: action.data.balance + }), -reducers$2[SEND_TRANSACTION_COMPLETED] = state => Object.assign({}, state, { - draftTransaction: buildDraftTransaction() -}); + [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$7({}, state, { + totalBalance: action.data.totalBalance + }), -reducers$2[SEND_TRANSACTION_FAILED] = (state, action) => { - const newDraftTransaction = Object.assign({}, state.draftTransaction, { - sending: false, - error: action.data.error - }); + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$7({}, state, { + checkingAddressOwnership: true + }), - return Object.assign({}, state, { - draftTransaction: newDraftTransaction - }); -}; + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$7({}, state, { + checkingAddressOwnership: false + }), -reducers$2[SUPPORT_TRANSACTION_STARTED] = state => Object.assign({}, state, { - sendingSupport: true -}); + [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { + const oldDraft = state.draftTransaction; + const newDraft = _extends$7({}, oldDraft, { amount: parseFloat(action.data.amount) }); -reducers$2[SUPPORT_TRANSACTION_COMPLETED] = state => Object.assign({}, state, { - sendingSupport: false -}); + return _extends$7({}, state, { draftTransaction: newDraft }); + }, -reducers$2[SUPPORT_TRANSACTION_FAILED] = (state, action) => Object.assign({}, state, { - error: action.data.error, - sendingSupport: false -}); + [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { + const oldDraft = state.draftTransaction; + const newDraft = _extends$7({}, oldDraft, { address: action.data.address }); -reducers$2[WALLET_STATUS_COMPLETED] = (state, action) => Object.assign({}, state, { - walletIsEncrypted: action.result -}); + return _extends$7({}, state, { draftTransaction: newDraft }); + }, -reducers$2[WALLET_ENCRYPT_START] = state => Object.assign({}, state, { - walletEncryptPending: true, - walletEncryptSucceded: null, - walletEncryptResult: null -}); + [SEND_TRANSACTION_STARTED]: state => { + const newDraftTransaction = _extends$7({}, state.draftTransaction, { sending: true }); -reducers$2[WALLET_ENCRYPT_COMPLETED] = (state, action) => Object.assign({}, state, { - walletEncryptPending: false, - walletEncryptSucceded: true, - walletEncryptResult: action.result -}); + return _extends$7({}, state, { draftTransaction: newDraftTransaction }); + }, -reducers$2[WALLET_ENCRYPT_FAILED] = (state, action) => Object.assign({}, state, { - walletEncryptPending: false, - walletEncryptSucceded: false, - walletEncryptResult: action.result -}); + [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { + draftTransaction: buildDraftTransaction() + }), -reducers$2[WALLET_DECRYPT_START] = state => Object.assign({}, state, { - walletDecryptPending: true, - walletDecryptSucceded: null, - walletDecryptResult: null -}); + [SEND_TRANSACTION_FAILED]: (state, action) => { + const newDraftTransaction = Object.assign({}, state.draftTransaction, { + sending: false, + error: action.data.error + }); -reducers$2[WALLET_DECRYPT_COMPLETED] = (state, action) => Object.assign({}, state, { - walletDecryptPending: false, - walletDecryptSucceded: true, - walletDecryptResult: action.result -}); + return _extends$7({}, state, { draftTransaction: newDraftTransaction }); + }, -reducers$2[WALLET_DECRYPT_FAILED] = (state, action) => Object.assign({}, state, { - walletDecryptPending: false, - walletDecryptSucceded: false, - walletDecryptResult: action.result -}); + [SUPPORT_TRANSACTION_STARTED]: state => _extends$7({}, state, { + sendingSupport: true + }), -reducers$2[WALLET_UNLOCK_START] = state => Object.assign({}, state, { - walletUnlockPending: true, - walletUnlockSucceded: null, - walletUnlockResult: null -}); + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$7({}, state, { + sendingSupport: false + }), -reducers$2[WALLET_UNLOCK_COMPLETED] = (state, action) => Object.assign({}, state, { - walletUnlockPending: false, - walletUnlockSucceded: true, - walletUnlockResult: action.result -}); + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$7({}, state, { + error: action.data.error, + sendingSupport: false + }), -reducers$2[WALLET_UNLOCK_FAILED] = (state, action) => Object.assign({}, state, { - walletUnlockPending: false, - walletUnlockSucceded: false, - walletUnlockResult: action.result -}); + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$7({}, state, { + walletIsEncrypted: action.result + }), -reducers$2[WALLET_LOCK_START] = state => Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: null, - walletLockResult: null -}); + [WALLET_ENCRYPT_START]: state => _extends$7({}, state, { + walletEncryptPending: true, + walletEncryptSucceded: null, + walletEncryptResult: null + }), -reducers$2[WALLET_LOCK_COMPLETED] = (state, action) => Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: true, - walletLockResult: action.result -}); + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$7({}, state, { + walletEncryptPending: false, + walletEncryptSucceded: true, + walletEncryptResult: action.result + }), -reducers$2[WALLET_LOCK_FAILED] = (state, action) => Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: false, - walletLockResult: action.result -}); + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$7({}, state, { + walletEncryptPending: false, + walletEncryptSucceded: false, + walletEncryptResult: action.result + }), -reducers$2[SET_TRANSACTION_LIST_FILTER] = (state, action) => Object.assign({}, state, { - transactionListFilter: action.data -}); + [WALLET_DECRYPT_START]: state => _extends$7({}, state, { + walletDecryptPending: true, + walletDecryptSucceded: null, + walletDecryptResult: null + }), -reducers$2[UPDATE_CURRENT_HEIGHT] = (state, action) => Object.assign({}, state, { - latestBlock: action.data -}); + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$7({}, state, { + walletDecryptPending: false, + walletDecryptSucceded: true, + walletDecryptResult: action.result + }), -function walletReducer(state = defaultState$4, action) { - const handler = reducers$2[action.type]; - if (handler) return handler(state, action); - return state; -} + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$7({}, state, { + walletDecryptPending: false, + walletDecryptSucceded: false, + walletDecryptResult: action.result + }), -var _extends$7 = 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; }; + [WALLET_UNLOCK_START]: state => _extends$7({}, state, { + walletUnlockPending: true, + walletUnlockSucceded: null, + walletUnlockResult: null + }), -const reducers$3 = {}; + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$7({}, state, { + walletUnlockPending: false, + walletUnlockSucceded: true, + walletUnlockResult: action.result + }), + + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$7({}, state, { + walletUnlockPending: false, + walletUnlockSucceded: false, + walletUnlockResult: action.result + }), + + [WALLET_LOCK_START]: state => _extends$7({}, state, { + walletLockPending: false, + walletLockSucceded: null, + walletLockResult: null + }), + + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$7({}, state, { + walletLockPending: false, + walletLockSucceded: true, + walletLockResult: action.result + }), + + [WALLET_LOCK_FAILED]: (state, action) => _extends$7({}, state, { + walletLockPending: false, + walletLockSucceded: false, + walletLockResult: action.result + }), + + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$7({}, state, { + transactionListFilter: action.data + }), + + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$7({}, state, { + latestBlock: action.data + }) +}, defaultState$4); + +var _extends$8 = 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; }; + +const reducers$2 = {}; const defaultState$5 = { positions: {} }; -reducers$3[SET_CONTENT_POSITION] = (state, action) => { +reducers$2[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$7({}, state, { - positions: _extends$7({}, state.positions, { - [claimId]: _extends$7({}, state.positions[claimId], { + return _extends$8({}, state, { + positions: _extends$8({}, state.positions, { + [claimId]: _extends$8({}, state.positions[claimId], { [outpoint]: position }) }) @@ -3350,7 +3413,7 @@ reducers$3[SET_CONTENT_POSITION] = (state, action) => { }; function contentReducer(state = defaultState$5, action) { - const handler = reducers$3[action.type]; + const handler = reducers$2[action.type]; if (handler) return handler(state, action); return state; } @@ -3366,14 +3429,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$8 = 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; }; +var _extends$9 = 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; }; const selectState$5 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$5, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$8({ + return _extends$9({ id }, params); } @@ -3537,6 +3600,7 @@ exports.selectSearchState = selectState; exports.selectSearchSuggestions = selectSearchSuggestions; exports.selectSearchUrisByQuery = selectSearchUrisByQuery; exports.selectSearchValue = selectSearchValue; +exports.selectSupportsById = selectSupportsById; exports.selectToast = selectToast; exports.selectTotalBalance = selectTotalBalance; exports.selectTotalDownloadProgress = selectTotalDownloadProgress; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 93ce160..6219328 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -130,6 +130,8 @@ declare type SyncApplyResponse = { data: string, }; +declare type SupportAbandonResponse = GenericTxResponse; + // // Types used in the generic Lbry object that is exported // @@ -175,6 +177,7 @@ declare type LbryTypes = { address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address transaction_list: (params: {}) => Promise, + support_abandon: (params: {}) => Promise, // Sync sync_hash: (params: {}) => Promise, diff --git a/dist/flow-typed/Transaction.js b/dist/flow-typed/Transaction.js index 7953b90..0042576 100644 --- a/dist/flow-typed/Transaction.js +++ b/dist/flow-typed/Transaction.js @@ -9,3 +9,19 @@ declare type Transaction = { type: string, date: Date, }; + +declare type Support = { + address: string, + amount: string, + claim_id: string, + confirmations: number, + height: string, + is_change: string, + is_mine: string, + name: string, + nout: string, + permanent_url: string, + timestamp: number, + txid: string, + type: string, +}; diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 93ce160..6219328 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -130,6 +130,8 @@ declare type SyncApplyResponse = { data: string, }; +declare type SupportAbandonResponse = GenericTxResponse; + // // Types used in the generic Lbry object that is exported // @@ -175,6 +177,7 @@ declare type LbryTypes = { address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address transaction_list: (params: {}) => Promise, + support_abandon: (params: {}) => Promise, // Sync sync_hash: (params: {}) => Promise, diff --git a/flow-typed/Transaction.js b/flow-typed/Transaction.js index 7953b90..0042576 100644 --- a/flow-typed/Transaction.js +++ b/flow-typed/Transaction.js @@ -9,3 +9,19 @@ declare type Transaction = { type: string, date: Date, }; + +declare type Support = { + address: string, + amount: string, + claim_id: string, + confirmations: number, + height: string, + is_change: string, + is_mine: string, + name: string, + nout: string, + permanent_url: string, + timestamp: number, + txid: string, + type: string, +}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 37a94cc..95d4035 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -33,6 +33,10 @@ export const GET_NEW_ADDRESS_STARTED = 'GET_NEW_ADDRESS_STARTED'; export const GET_NEW_ADDRESS_COMPLETED = 'GET_NEW_ADDRESS_COMPLETED'; export const FETCH_TRANSACTIONS_STARTED = 'FETCH_TRANSACTIONS_STARTED'; export const FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'; +export const FETCH_SUPPORTS_STARTED = 'FETCH_SUPPORTS_STARTED'; +export const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED'; +export const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED'; +export const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED'; export const UPDATE_BALANCE = 'UPDATE_BALANCE'; export const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; export const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; diff --git a/src/index.js b/src/index.js index 9c17d2d..cc751c0 100644 --- a/src/index.js +++ b/src/index.js @@ -183,6 +183,7 @@ export { selectBalance, selectTotalBalance, selectTransactionsById, + selectSupportsById, selectTransactionItems, selectRecentTransactions, selectHasTransactions, diff --git a/src/lbry.js b/src/lbry.js index 1d306bb..ec66286 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -86,6 +86,7 @@ const Lbry: LbryTypes = { address_unused: (params = {}) => daemonCallWithResult('address_unused', params), transaction_list: (params = {}) => daemonCallWithResult('transaction_list', params), utxo_release: (params = {}) => daemonCallWithResult('utxo_release', params), + support_abandon: (params = {}) => daemonCallWithResult('support_abandon', params), sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 32318c5..3e2ba1b 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -5,6 +5,7 @@ import { normalizeURI, parseURI } from 'lbryURI'; import { doToast } from 'redux/actions/notifications'; import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux/selectors/claims'; import { doFetchTransactions } from 'redux/actions/wallet'; +import { selectSupportsById } from 'redux/selectors/wallet'; import { creditsToString } from 'util/formatCredits'; export function doResolveUris(uris: Array, returnCachedClaims: boolean = false) { @@ -92,26 +93,38 @@ export function doAbandonClaim(txid: string, nout: number) { return (dispatch: Dispatch, getState: GetState) => { const state = getState(); const myClaims: Array = selectMyClaimsRaw(state); - const claimToAbandon = myClaims.find(claim => claim.txid === txid && claim.nout === nout); + const mySupports: { [string]: Support } = selectSupportsById(state); - if (!claimToAbandon) { - console.error('No associated claim with txid: ', txid); + // A user could be trying to abandon a support or one of their claims + const claimToAbandon = myClaims.find(claim => claim.txid === txid && claim.nout === nout); + const supportToAbandon = mySupports[txid]; + + if (!claimToAbandon && !supportToAbandon) { + console.error('No associated support or claim with txid: ', txid); return; } - const { claim_id: claimId, name: claimName } = claimToAbandon; + const data = claimToAbandon + ? { claimId: claimToAbandon.claim_id } + : { txid: supportToAbandon.txid }; + + const isClaim = !!claimToAbandon; + const startedActionType = isClaim + ? ACTIONS.ABANDON_CLAIM_STARTED + : ACTIONS.ABANDON_SUPPORT_STARTED; + const completedActionType = isClaim + ? ACTIONS.ABANDON_CLAIM_STARTED + : ACTIONS.ABANDON_SUPPORT_COMPLETED; dispatch({ - type: ACTIONS.ABANDON_CLAIM_STARTED, - data: { - claimId, - }, + type: startedActionType, + data, }); const errorCallback = () => { dispatch( doToast({ - message: 'Error abandoning claim', + message: isClaim ? 'Error abandoning your claim' : 'Error unlocking your tip', isError: true, }) ); @@ -119,15 +132,15 @@ export function doAbandonClaim(txid: string, nout: number) { const successCallback = () => { dispatch({ - type: ACTIONS.ABANDON_CLAIM_SUCCEEDED, - data: { - claimId, - }, + type: completedActionType, + data, }); dispatch( doToast({ - message: 'Successfully abandoned your claim', + message: isClaim + ? 'Successfully abandoned your claim' + : 'Successfully unlocked your tip!', }) ); @@ -143,7 +156,19 @@ export function doAbandonClaim(txid: string, nout: number) { blocking: true, }; - const method = claimName.startsWith('@') ? 'channel_abandon' : 'stream_abandon'; + let method; + if (supportToAbandon) { + method = 'support_abandon'; + } else if (claimToAbandon) { + const { name: claimName } = claimToAbandon; + method = claimName.startsWith('@') ? 'channel_abandon' : 'stream_abandon'; + } + + if (!method) { + console.error('No "method" chosen for claim or support abandon'); + return; + } + Lbry[method](abandonParams).then(successCallback, errorCallback); }; } diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index cdcd816..74c9126 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -63,6 +63,7 @@ export function doTotalBalanceSubscribe() { export function doFetchTransactions() { return dispatch => { + dispatch(doFetchSupports()); dispatch({ type: ACTIONS.FETCH_TRANSACTIONS_STARTED, }); @@ -80,6 +81,23 @@ export function doFetchTransactions() { }; } +export function doFetchSupports() { + return dispatch => { + dispatch({ + type: ACTIONS.FETCH_SUPPORTS_STARTED, + }); + + Lbry.support_list().then(results => { + dispatch({ + type: ACTIONS.FETCH_SUPPORTS_COMPLETED, + data: { + supports: results, + }, + }); + }); + }; +} + export function doGetNewAddress() { return dispatch => { dispatch({ diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index 5e9061b..259479d 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -1,7 +1,7 @@ // @flow import * as ACTIONS from 'constants/action_types'; +import { handleActions } from 'util/redux-utils'; -const reducers = {}; const buildDraftTransaction = () => ({ amount: undefined, address: undefined, @@ -16,9 +16,10 @@ type ActionResult = { type WalletState = { balance: any, - blocks: any, latestBlock: ?number, - transactions: any, + transactions: { [string]: Transaction }, + supports: { [string]: Support }, + abandoningSupportsById: { [string]: boolean }, fetchingTransactions: boolean, gettingNewAddress: boolean, draftTransaction: any, @@ -41,10 +42,12 @@ type WalletState = { const defaultState = { balance: undefined, totalBalance: undefined, - blocks: {}, latestBlock: undefined, transactions: {}, fetchingTransactions: false, + supports: {}, + fetchingSupports: false, + abandoningSupportsById: {}, gettingNewAddress: false, draftTransaction: buildDraftTransaction(), sendingSupport: false, @@ -64,226 +67,250 @@ const defaultState = { transactionListFilter: 'all', }; -reducers[ACTIONS.FETCH_TRANSACTIONS_STARTED] = (state: WalletState) => - Object.assign({}, state, { - fetchingTransactions: true, - }); +export const walletReducer = handleActions( + { + [ACTIONS.FETCH_TRANSACTIONS_STARTED]: (state: WalletState) => ({ + ...state, + fetchingTransactions: true, + }), -reducers[ACTIONS.FETCH_TRANSACTIONS_COMPLETED] = (state: WalletState, action) => { - const byId = Object.assign({}, state.transactions); + [ACTIONS.FETCH_TRANSACTIONS_COMPLETED]: (state: WalletState, action) => { + const byId = { ...state.transactions }; - const { transactions } = action.data; + const { transactions } = action.data; + transactions.forEach(transaction => { + byId[transaction.txid] = transaction; + }); - transactions.forEach(transaction => { - byId[transaction.txid] = transaction; - }); + return { + ...state, + transactions: byId, + fetchingTransactions: false, + }; + }, - return Object.assign({}, state, { - transactions: byId, - fetchingTransactions: false, - }); -}; + [ACTIONS.FETCH_SUPPORTS_STARTED]: (state: WalletState) => ({ + ...state, + fetchingSupports: true, + }), -reducers[ACTIONS.GET_NEW_ADDRESS_STARTED] = (state: WalletState) => - Object.assign({}, state, { - gettingNewAddress: true, - }); + [ACTIONS.FETCH_SUPPORTS_COMPLETED]: (state: WalletState, action) => { + const byId = state.supports; + const { supports } = action.data; -reducers[ACTIONS.GET_NEW_ADDRESS_COMPLETED] = (state: WalletState, action) => { - const { address } = action.data; + supports.forEach(support => { + byId[support.txid] = support; + }); - // Say no to localStorage! - return Object.assign({}, state, { - gettingNewAddress: false, - receiveAddress: address, - }); -}; + return { ...state, supports: byId, fetchingSupports: false }; + }, -reducers[ACTIONS.UPDATE_BALANCE] = (state: WalletState, action) => - Object.assign({}, state, { - balance: action.data.balance, - }); + [ACTIONS.ABANDON_SUPPORT_STARTED]: (state: WalletState, action: any): WalletState => { + const { txid }: { txid: string } = action.data; + const abandoningById = state.abandoningSupportsById; -reducers[ACTIONS.UPDATE_TOTAL_BALANCE] = (state: WalletState, action) => - Object.assign({}, state, { - totalBalance: action.data.totalBalance, - }); + abandoningById[txid] = true; -reducers[ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED] = (state: WalletState) => - Object.assign({}, state, { - checkingAddressOwnership: true, - }); + return { + ...state, + abandoningSupportsById: abandoningById, + }; + }, -reducers[ACTIONS.CHECK_ADDRESS_IS_MINE_COMPLETED] = (state: WalletState) => - Object.assign({}, state, { - checkingAddressOwnership: false, - }); + [ACTIONS.ABANDON_SUPPORT_COMPLETED]: (state: WalletState, action: any): WalletState => { + const { txid }: { txid: string } = action.data; + const byId = state.supports; + const abandoningById = state.abandoningSupportsById; -reducers[ACTIONS.SET_DRAFT_TRANSACTION_AMOUNT] = (state: WalletState, action) => { - const oldDraft = state.draftTransaction; - const newDraft = Object.assign({}, oldDraft, { - amount: parseFloat(action.data.amount), - }); + delete abandoningById[txid]; + delete byId[txid]; - return Object.assign({}, state, { - draftTransaction: newDraft, - }); -}; + return { + ...state, + supports: byId, + abandoningSupportsById: abandoningById, + }; + }, -reducers[ACTIONS.SET_DRAFT_TRANSACTION_ADDRESS] = (state: WalletState, action) => { - const oldDraft = state.draftTransaction; - const newDraft = Object.assign({}, oldDraft, { - address: action.data.address, - }); + [ACTIONS.GET_NEW_ADDRESS_STARTED]: (state: WalletState) => ({ + ...state, + gettingNewAddress: true, + }), - return Object.assign({}, state, { - draftTransaction: newDraft, - }); -}; + [ACTIONS.GET_NEW_ADDRESS_COMPLETED]: (state: WalletState, action) => { + const { address } = action.data; -reducers[ACTIONS.SEND_TRANSACTION_STARTED] = (state: WalletState) => { - const newDraftTransaction = Object.assign({}, state.draftTransaction, { - sending: true, - }); + return { ...state, gettingNewAddress: false, receiveAddress: address }; + }, - return Object.assign({}, state, { - draftTransaction: newDraftTransaction, - }); -}; + [ACTIONS.UPDATE_BALANCE]: (state: WalletState, action) => ({ + ...state, + balance: action.data.balance, + }), -reducers[ACTIONS.SEND_TRANSACTION_COMPLETED] = (state: WalletState) => - Object.assign({}, state, { - draftTransaction: buildDraftTransaction(), - }); + [ACTIONS.UPDATE_TOTAL_BALANCE]: (state: WalletState, action) => ({ + ...state, + totalBalance: action.data.totalBalance, + }), -reducers[ACTIONS.SEND_TRANSACTION_FAILED] = (state: WalletState, action) => { - const newDraftTransaction = Object.assign({}, state.draftTransaction, { - sending: false, - error: action.data.error, - }); + [ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED]: (state: WalletState) => ({ + ...state, + checkingAddressOwnership: true, + }), - return Object.assign({}, state, { - draftTransaction: newDraftTransaction, - }); -}; + [ACTIONS.CHECK_ADDRESS_IS_MINE_COMPLETED]: (state: WalletState) => ({ + ...state, + checkingAddressOwnership: false, + }), -reducers[ACTIONS.SUPPORT_TRANSACTION_STARTED] = (state: WalletState) => - Object.assign({}, state, { - sendingSupport: true, - }); + [ACTIONS.SET_DRAFT_TRANSACTION_AMOUNT]: (state: WalletState, action) => { + const oldDraft = state.draftTransaction; + const newDraft = { ...oldDraft, amount: parseFloat(action.data.amount) }; -reducers[ACTIONS.SUPPORT_TRANSACTION_COMPLETED] = (state: WalletState) => - Object.assign({}, state, { - sendingSupport: false, - }); + return { ...state, draftTransaction: newDraft }; + }, -reducers[ACTIONS.SUPPORT_TRANSACTION_FAILED] = (state: WalletState, action) => - Object.assign({}, state, { - error: action.data.error, - sendingSupport: false, - }); + [ACTIONS.SET_DRAFT_TRANSACTION_ADDRESS]: (state: WalletState, action) => { + const oldDraft = state.draftTransaction; + const newDraft = { ...oldDraft, address: action.data.address }; -reducers[ACTIONS.WALLET_STATUS_COMPLETED] = (state: WalletState, action) => - Object.assign({}, state, { - walletIsEncrypted: action.result, - }); + return { ...state, draftTransaction: newDraft }; + }, -reducers[ACTIONS.WALLET_ENCRYPT_START] = (state: WalletState) => - Object.assign({}, state, { - walletEncryptPending: true, - walletEncryptSucceded: null, - walletEncryptResult: null, - }); + [ACTIONS.SEND_TRANSACTION_STARTED]: (state: WalletState) => { + const newDraftTransaction = { ...state.draftTransaction, sending: true }; -reducers[ACTIONS.WALLET_ENCRYPT_COMPLETED] = (state: WalletState, action: ActionResult) => - Object.assign({}, state, { - walletEncryptPending: false, - walletEncryptSucceded: true, - walletEncryptResult: action.result, - }); + return { ...state, draftTransaction: newDraftTransaction }; + }, -reducers[ACTIONS.WALLET_ENCRYPT_FAILED] = (state: WalletState, action: ActionResult) => - Object.assign({}, state, { - walletEncryptPending: false, - walletEncryptSucceded: false, - walletEncryptResult: action.result, - }); + [ACTIONS.SEND_TRANSACTION_COMPLETED]: (state: WalletState) => + Object.assign({}, state, { + draftTransaction: buildDraftTransaction(), + }), -reducers[ACTIONS.WALLET_DECRYPT_START] = (state: WalletState) => - Object.assign({}, state, { - walletDecryptPending: true, - walletDecryptSucceded: null, - walletDecryptResult: null, - }); + [ACTIONS.SEND_TRANSACTION_FAILED]: (state: WalletState, action) => { + const newDraftTransaction = Object.assign({}, state.draftTransaction, { + sending: false, + error: action.data.error, + }); -reducers[ACTIONS.WALLET_DECRYPT_COMPLETED] = (state: WalletState, action: ActionResult) => - Object.assign({}, state, { - walletDecryptPending: false, - walletDecryptSucceded: true, - walletDecryptResult: action.result, - }); + return { ...state, draftTransaction: newDraftTransaction }; + }, -reducers[ACTIONS.WALLET_DECRYPT_FAILED] = (state: WalletState, action: ActionResult) => - Object.assign({}, state, { - walletDecryptPending: false, - walletDecryptSucceded: false, - walletDecryptResult: action.result, - }); + [ACTIONS.SUPPORT_TRANSACTION_STARTED]: (state: WalletState) => ({ + ...state, + sendingSupport: true, + }), -reducers[ACTIONS.WALLET_UNLOCK_START] = (state: WalletState) => - Object.assign({}, state, { - walletUnlockPending: true, - walletUnlockSucceded: null, - walletUnlockResult: null, - }); + [ACTIONS.SUPPORT_TRANSACTION_COMPLETED]: (state: WalletState) => ({ + ...state, + sendingSupport: false, + }), -reducers[ACTIONS.WALLET_UNLOCK_COMPLETED] = (state: WalletState, action: ActionResult) => - Object.assign({}, state, { - walletUnlockPending: false, - walletUnlockSucceded: true, - walletUnlockResult: action.result, - }); + [ACTIONS.SUPPORT_TRANSACTION_FAILED]: (state: WalletState, action) => ({ + ...state, + error: action.data.error, + sendingSupport: false, + }), -reducers[ACTIONS.WALLET_UNLOCK_FAILED] = (state: WalletState, action: ActionResult) => - Object.assign({}, state, { - walletUnlockPending: false, - walletUnlockSucceded: false, - walletUnlockResult: action.result, - }); + [ACTIONS.WALLET_STATUS_COMPLETED]: (state: WalletState, action) => ({ + ...state, + walletIsEncrypted: action.result, + }), -reducers[ACTIONS.WALLET_LOCK_START] = (state: WalletState) => - Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: null, - walletLockResult: null, - }); + [ACTIONS.WALLET_ENCRYPT_START]: (state: WalletState) => ({ + ...state, + walletEncryptPending: true, + walletEncryptSucceded: null, + walletEncryptResult: null, + }), -reducers[ACTIONS.WALLET_LOCK_COMPLETED] = (state: WalletState, action: ActionResult) => - Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: true, - walletLockResult: action.result, - }); + [ACTIONS.WALLET_ENCRYPT_COMPLETED]: (state: WalletState, action: ActionResult) => ({ + ...state, + walletEncryptPending: false, + walletEncryptSucceded: true, + walletEncryptResult: action.result, + }), -reducers[ACTIONS.WALLET_LOCK_FAILED] = (state: WalletState, action: ActionResult) => - Object.assign({}, state, { - walletLockPending: false, - walletLockSucceded: false, - walletLockResult: action.result, - }); + [ACTIONS.WALLET_ENCRYPT_FAILED]: (state: WalletState, action: ActionResult) => ({ + ...state, + walletEncryptPending: false, + walletEncryptSucceded: false, + walletEncryptResult: action.result, + }), -reducers[ACTIONS.SET_TRANSACTION_LIST_FILTER] = (state: WalletState, action: { data: string }) => - Object.assign({}, state, { - transactionListFilter: action.data, - }); + [ACTIONS.WALLET_DECRYPT_START]: (state: WalletState) => ({ + ...state, + walletDecryptPending: true, + walletDecryptSucceded: null, + walletDecryptResult: null, + }), -reducers[ACTIONS.UPDATE_CURRENT_HEIGHT] = (state: WalletState, action: { data: number }) => - Object.assign({}, state, { - latestBlock: action.data, - }); + [ACTIONS.WALLET_DECRYPT_COMPLETED]: (state: WalletState, action: ActionResult) => ({ + ...state, + walletDecryptPending: false, + walletDecryptSucceded: true, + walletDecryptResult: action.result, + }), -export function walletReducer(state: WalletState = defaultState, action: ActionResult) { - const handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} + [ACTIONS.WALLET_DECRYPT_FAILED]: (state: WalletState, action: ActionResult) => ({ + ...state, + walletDecryptPending: false, + walletDecryptSucceded: false, + walletDecryptResult: action.result, + }), + + [ACTIONS.WALLET_UNLOCK_START]: (state: WalletState) => ({ + ...state, + walletUnlockPending: true, + walletUnlockSucceded: null, + walletUnlockResult: null, + }), + + [ACTIONS.WALLET_UNLOCK_COMPLETED]: (state: WalletState, action: ActionResult) => ({ + ...state, + walletUnlockPending: false, + walletUnlockSucceded: true, + walletUnlockResult: action.result, + }), + + [ACTIONS.WALLET_UNLOCK_FAILED]: (state: WalletState, action: ActionResult) => ({ + ...state, + walletUnlockPending: false, + walletUnlockSucceded: false, + walletUnlockResult: action.result, + }), + + [ACTIONS.WALLET_LOCK_START]: (state: WalletState) => ({ + ...state, + walletLockPending: false, + walletLockSucceded: null, + walletLockResult: null, + }), + + [ACTIONS.WALLET_LOCK_COMPLETED]: (state: WalletState, action: ActionResult) => ({ + ...state, + walletLockPending: false, + walletLockSucceded: true, + walletLockResult: action.result, + }), + + [ACTIONS.WALLET_LOCK_FAILED]: (state: WalletState, action: ActionResult) => ({ + ...state, + walletLockPending: false, + walletLockSucceded: false, + walletLockResult: action.result, + }), + + [ACTIONS.SET_TRANSACTION_LIST_FILTER]: (state: WalletState, action: { data: string }) => ({ + ...state, + transactionListFilter: action.data, + }), + + [ACTIONS.UPDATE_CURRENT_HEIGHT]: (state: WalletState, action: { data: number }) => ({ + ...state, + latestBlock: action.data, + }), + }, + defaultState +); diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index a79bfc4..8e80ca0 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -82,7 +82,12 @@ export const selectTotalBalance = createSelector( export const selectTransactionsById = createSelector( selectState, - state => state.transactions + state => state.transactions || {} +); + +export const selectSupportsById = createSelector( + selectState, + state => state.supports || {} ); export const selectTransactionItems = createSelector( -- 2.45.2 From 231d51832a66274b62d697e9b662a30deb9b3f58 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 10 May 2019 13:29:51 -0400 Subject: [PATCH 014/371] lbry.io => lbry.com --- dist/bundle.es.js | 4 ++-- package.json | 4 ++-- src/lbryURI.js | 2 +- src/redux/actions/search.js | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 57f1639..d1e7bdd 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -984,7 +984,7 @@ function isURIClaimable(URI) { function convertToShareLink(URI) { const { claimName, path, bidPosition, claimSequence, claimId } = parseURI(URI); - return buildURI({ claimName, path, claimSequence, bidPosition, claimId }, true, 'https://open.lbry.io/'); + return buildURI({ claimName, path, claimSequence, bidPosition, claimId }, true, 'https://open.lbry.com/'); } var _extends$1 = 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; }; @@ -2400,7 +2400,7 @@ function handleFetchResponse(response) { const DEBOUNCED_SEARCH_SUGGESTION_MS = 300; // We can't use env's because they aren't passed into node_modules -let CONNECTION_STRING = 'https://lighthouse.lbry.io/'; +let CONNECTION_STRING = 'https://lighthouse.lbry.com/'; const setSearchApi = endpoint => { CONNECTION_STRING = endpoint.replace(/\/*$/, '/'); // exactly one slash at the end; diff --git a/package.json b/package.json index 4d15c96..21b595f 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "lbry" ], "license": "MIT", - "homepage": "https://lbry.io/", + "homepage": "https://lbry.com/", "bugs": { "url": "https://github.com/lbryio/lbry-redux/issues" }, @@ -16,7 +16,7 @@ }, "author": { "name": "LBRY Inc.", - "email": "hello@lbry.io" + "email": "hello@lbry.com" }, "main": "dist/bundle.es.js", "module": "dist/bundle.es.js", diff --git a/src/lbryURI.js b/src/lbryURI.js index 260df9a..fd07213 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -228,6 +228,6 @@ export function convertToShareLink(URI) { return buildURI( { claimName, path, claimSequence, bidPosition, claimId }, true, - 'https://open.lbry.io/' + 'https://open.lbry.com/' ); } diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index d81c592..6844a80 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -17,7 +17,7 @@ type Dispatch = (action: any) => any; type GetState = () => { search: SearchState }; // We can't use env's because they aren't passed into node_modules -let CONNECTION_STRING = 'https://lighthouse.lbry.io/'; +let CONNECTION_STRING = 'https://lighthouse.lbry.com/'; export const setSearchApi = (endpoint: string) => { CONNECTION_STRING = endpoint.replace(/\/*$/, '/'); // exactly one slash at the end; -- 2.45.2 From 02f6918238110726c0b3b4248c61a84ac0b969e3 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 14 May 2019 00:50:21 -0400 Subject: [PATCH 015/371] store supports by outpoint in redux --- dist/bundle.es.js | 45 +++++++++++++++++++---------------- src/index.js | 2 +- src/redux/actions/claims.js | 10 ++++---- src/redux/reducers/wallet.js | 35 ++++++++++++++------------- src/redux/selectors/wallet.js | 2 +- 5 files changed, 50 insertions(+), 44 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d1e7bdd..9a913dd 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1432,7 +1432,7 @@ const selectTotalBalance = reselect.createSelector(selectState$2, state => state const selectTransactionsById = reselect.createSelector(selectState$2, state => state.transactions || {}); -const selectSupportsById = reselect.createSelector(selectState$2, state => state.supports || {}); +const selectSupportsByOutpoint = reselect.createSelector(selectState$2, state => state.supports || {}); const selectTransactionItems = reselect.createSelector(selectTransactionsById, byId => { const items = []; @@ -1992,21 +1992,23 @@ function doFetchClaimListMine() { } function doAbandonClaim(txid, nout) { + const outpoint = `${txid}:${nout}`; + return (dispatch, getState) => { const state = getState(); const myClaims = selectMyClaimsRaw(state); - const mySupports = selectSupportsById(state); + const mySupports = selectSupportsByOutpoint(state); // A user could be trying to abandon a support or one of their claims const claimToAbandon = myClaims.find(claim => claim.txid === txid && claim.nout === nout); - const supportToAbandon = mySupports[txid]; + const supportToAbandon = mySupports[outpoint]; if (!claimToAbandon && !supportToAbandon) { console.error('No associated support or claim with txid: ', txid); return; } - const data = claimToAbandon ? { claimId: claimToAbandon.claim_id } : { txid: supportToAbandon.txid }; + const data = claimToAbandon ? { claimId: claimToAbandon.claim_id } : { outpoint: `${supportToAbandon.txid}:${supportToAbandon.nout}` }; const isClaim = !!claimToAbandon; const startedActionType = isClaim ? ABANDON_CLAIM_STARTED : ABANDON_SUPPORT_STARTED; @@ -3158,7 +3160,7 @@ const defaultState$4 = { fetchingTransactions: false, supports: {}, fetchingSupports: false, - abandoningSupportsById: {}, + abandoningSupportsByOutpoint: {}, gettingNewAddress: false, draftTransaction: buildDraftTransaction(), sendingSupport: false, @@ -3202,38 +3204,39 @@ const walletReducer = handleActions({ }), [FETCH_SUPPORTS_COMPLETED]: (state, action) => { - const byId = state.supports; + const byOutpoint = state.supports; const { supports } = action.data; - supports.forEach(support => { - byId[support.txid] = support; + supports.forEach(transaction => { + const { txid, nout } = transaction; + byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$7({}, state, { supports: byId, fetchingSupports: false }); + return _extends$7({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { - const { txid } = action.data; - const abandoningById = state.abandoningSupportsById; + const { outpoint } = action.data; + const currentlyAbandoning = state.abandoningSupportsByOutpoint; - abandoningById[txid] = true; + currentlyAbandoning[outpoint] = true; return _extends$7({}, state, { - abandoningSupportsById: abandoningById + abandoningSupportsByOutpoint: currentlyAbandoning }); }, [ABANDON_SUPPORT_COMPLETED]: (state, action) => { - const { txid } = action.data; - const byId = state.supports; - const abandoningById = state.abandoningSupportsById; + const { outpoint } = action.data; + const byOutpoint = state.supports; + const currentlyAbandoning = state.abandoningSupportsByOutpoint; - delete abandoningById[txid]; - delete byId[txid]; + delete currentlyAbandoning[outpoint]; + delete byOutpoint[outpoint]; return _extends$7({}, state, { - supports: byId, - abandoningSupportsById: abandoningById + supports: byOutpoint, + abandoningSupportsById: currentlyAbandoning }); }, @@ -3600,7 +3603,7 @@ exports.selectSearchState = selectState; exports.selectSearchSuggestions = selectSearchSuggestions; exports.selectSearchUrisByQuery = selectSearchUrisByQuery; exports.selectSearchValue = selectSearchValue; -exports.selectSupportsById = selectSupportsById; +exports.selectSupportsByOutpoint = selectSupportsByOutpoint; exports.selectToast = selectToast; exports.selectTotalBalance = selectTotalBalance; exports.selectTotalDownloadProgress = selectTotalDownloadProgress; diff --git a/src/index.js b/src/index.js index cc751c0..9fa1fff 100644 --- a/src/index.js +++ b/src/index.js @@ -183,7 +183,7 @@ export { selectBalance, selectTotalBalance, selectTransactionsById, - selectSupportsById, + selectSupportsByOutpoint, selectTransactionItems, selectRecentTransactions, selectHasTransactions, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 3e2ba1b..54bc7c9 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -5,7 +5,7 @@ import { normalizeURI, parseURI } from 'lbryURI'; import { doToast } from 'redux/actions/notifications'; import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux/selectors/claims'; import { doFetchTransactions } from 'redux/actions/wallet'; -import { selectSupportsById } from 'redux/selectors/wallet'; +import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { creditsToString } from 'util/formatCredits'; export function doResolveUris(uris: Array, returnCachedClaims: boolean = false) { @@ -90,14 +90,16 @@ export function doFetchClaimListMine() { } export function doAbandonClaim(txid: string, nout: number) { + const outpoint = `${txid}:${nout}`; + return (dispatch: Dispatch, getState: GetState) => { const state = getState(); const myClaims: Array = selectMyClaimsRaw(state); - const mySupports: { [string]: Support } = selectSupportsById(state); + const mySupports: { [string]: Support } = selectSupportsByOutpoint(state); // A user could be trying to abandon a support or one of their claims const claimToAbandon = myClaims.find(claim => claim.txid === txid && claim.nout === nout); - const supportToAbandon = mySupports[txid]; + const supportToAbandon = mySupports[outpoint]; if (!claimToAbandon && !supportToAbandon) { console.error('No associated support or claim with txid: ', txid); @@ -106,7 +108,7 @@ export function doAbandonClaim(txid: string, nout: number) { const data = claimToAbandon ? { claimId: claimToAbandon.claim_id } - : { txid: supportToAbandon.txid }; + : { outpoint: `${supportToAbandon.txid}:${supportToAbandon.nout}` }; const isClaim = !!claimToAbandon; const startedActionType = isClaim diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index 259479d..9d6762d 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -19,7 +19,7 @@ type WalletState = { latestBlock: ?number, transactions: { [string]: Transaction }, supports: { [string]: Support }, - abandoningSupportsById: { [string]: boolean }, + abandoningSupportsByOutpoint: { [string]: boolean }, fetchingTransactions: boolean, gettingNewAddress: boolean, draftTransaction: any, @@ -47,7 +47,7 @@ const defaultState = { fetchingTransactions: false, supports: {}, fetchingSupports: false, - abandoningSupportsById: {}, + abandoningSupportsByOutpoint: {}, gettingNewAddress: false, draftTransaction: buildDraftTransaction(), sendingSupport: false, @@ -95,40 +95,41 @@ export const walletReducer = handleActions( }), [ACTIONS.FETCH_SUPPORTS_COMPLETED]: (state: WalletState, action) => { - const byId = state.supports; + const byOutpoint = state.supports; const { supports } = action.data; - supports.forEach(support => { - byId[support.txid] = support; + supports.forEach(transaction => { + const { txid, nout } = transaction; + byOutpoint[`${txid}:${nout}`] = transaction; }); - return { ...state, supports: byId, fetchingSupports: false }; + return { ...state, supports: byOutpoint, fetchingSupports: false }; }, [ACTIONS.ABANDON_SUPPORT_STARTED]: (state: WalletState, action: any): WalletState => { - const { txid }: { txid: string } = action.data; - const abandoningById = state.abandoningSupportsById; + const { outpoint }: { outpoint: string } = action.data; + const currentlyAbandoning = state.abandoningSupportsByOutpoint; - abandoningById[txid] = true; + currentlyAbandoning[outpoint] = true; return { ...state, - abandoningSupportsById: abandoningById, + abandoningSupportsByOutpoint: currentlyAbandoning, }; }, [ACTIONS.ABANDON_SUPPORT_COMPLETED]: (state: WalletState, action: any): WalletState => { - const { txid }: { txid: string } = action.data; - const byId = state.supports; - const abandoningById = state.abandoningSupportsById; + const { outpoint }: { outpoint: string } = action.data; + const byOutpoint = state.supports; + const currentlyAbandoning = state.abandoningSupportsByOutpoint; - delete abandoningById[txid]; - delete byId[txid]; + delete currentlyAbandoning[outpoint]; + delete byOutpoint[outpoint]; return { ...state, - supports: byId, - abandoningSupportsById: abandoningById, + supports: byOutpoint, + abandoningSupportsById: currentlyAbandoning, }; }, diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 8e80ca0..654836d 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -85,7 +85,7 @@ export const selectTransactionsById = createSelector( state => state.transactions || {} ); -export const selectSupportsById = createSelector( +export const selectSupportsByOutpoint = createSelector( selectState, state => state.supports || {} ); -- 2.45.2 From 29c7a4b8326a0dc8bd006208f6f860cad9e7270d Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 15 May 2019 10:58:36 +0100 Subject: [PATCH 016/371] add account_set sdk call (#146) --- dist/bundle.es.js | 1 + dist/flow-typed/Lbry.js | 14 ++++++++++++++ flow-typed/Lbry.js | 14 ++++++++++++++ src/lbry.js | 1 + 4 files changed, 30 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9a913dd..9512952 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -651,6 +651,7 @@ const Lbry = { account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), account_list: (params = {}) => daemonCallWithResult('account_list', params), account_send: (params = {}) => daemonCallWithResult('account_send', params), + account_set: (params = {}) => daemonCallWithResult('account_set', params), address_is_mine: (params = {}) => daemonCallWithResult('address_is_mine', params), address_unused: (params = {}) => daemonCallWithResult('address_unused', params), transaction_list: (params = {}) => daemonCallWithResult('transaction_list', params), diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 6219328..303de6f 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -130,6 +130,19 @@ declare type SyncApplyResponse = { data: string, }; +declare type AccountSetResponse = Array<{ + id: string, + is_default: string, + ledger: string, + name: string, + seed: string, + encrypted: string, + private_key: string, + public_key: string, + address_generator: string, + modified_on: string, +}>; + declare type SupportAbandonResponse = GenericTxResponse; // @@ -174,6 +187,7 @@ declare type LbryTypes = { account_unlock: (params: {}) => Promise, account_list: (params: {}) => Promise, account_send: (params: {}) => Promise, + account_set: (params: {}) => Promise, address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address transaction_list: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 6219328..303de6f 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -130,6 +130,19 @@ declare type SyncApplyResponse = { data: string, }; +declare type AccountSetResponse = Array<{ + id: string, + is_default: string, + ledger: string, + name: string, + seed: string, + encrypted: string, + private_key: string, + public_key: string, + address_generator: string, + modified_on: string, +}>; + declare type SupportAbandonResponse = GenericTxResponse; // @@ -174,6 +187,7 @@ declare type LbryTypes = { account_unlock: (params: {}) => Promise, account_list: (params: {}) => Promise, account_send: (params: {}) => Promise, + account_set: (params: {}) => Promise, address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address transaction_list: (params: {}) => Promise, diff --git a/src/lbry.js b/src/lbry.js index ec66286..03e7451 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -82,6 +82,7 @@ const Lbry: LbryTypes = { account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), account_list: (params = {}) => daemonCallWithResult('account_list', params), account_send: (params = {}) => daemonCallWithResult('account_send', params), + account_set: (params = {}) => daemonCallWithResult('account_set', params), address_is_mine: (params = {}) => daemonCallWithResult('address_is_mine', params), address_unused: (params = {}) => daemonCallWithResult('address_unused', params), transaction_list: (params = {}) => daemonCallWithResult('transaction_list', params), -- 2.45.2 From 1fe1f6a1883937e372bd211ee478be929c2918ac Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 21 May 2019 20:18:07 +0100 Subject: [PATCH 017/371] refactor doPurchaseUri (#149) --- dist/bundle.es.js | 382 +++++++++++++++++++++++++--------- dist/flow-typed/File.js | 22 ++ flow-typed/File.js | 22 ++ src/constants/action_types.js | 11 + src/index.js | 11 + src/redux/actions/file.js | 104 +++++++++ src/redux/reducers/file.js | 58 ++++++ src/redux/selectors/file.js | 33 +++ 8 files changed, 542 insertions(+), 101 deletions(-) create mode 100644 src/redux/actions/file.js create mode 100644 src/redux/reducers/file.js create mode 100644 src/redux/selectors/file.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9512952..4bbe81d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -116,6 +116,12 @@ const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'; const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'; const FILE_DELETE = 'FILE_DELETE'; const SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; +const PURCHASE_URI_STARTED = 'PURCHASE_URI_STARTED'; +const PURCHASE_URI_COMPLETED = 'PURCHASE_URI_COMPLETED'; +const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; +const LOADING_FILE_STARTED = 'LOADING_FILE_STARTED'; +const LOADING_FILE_COMPLETED = 'LOADING_FILE_COMPLETED'; +const LOADING_FILE_FAILED = 'LOADING_FILE_FAILED'; // Search const SEARCH_START = 'SEARCH_START'; @@ -228,6 +234,11 @@ const DISMISS_ERROR = 'DISMISS_ERROR'; const FETCH_DATE = 'FETCH_DATE'; +// Cost info +const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'; +const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'; +const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; + var action_types = /*#__PURE__*/Object.freeze({ WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, @@ -327,6 +338,12 @@ var action_types = /*#__PURE__*/Object.freeze({ FETCH_AVAILABILITY_COMPLETED: FETCH_AVAILABILITY_COMPLETED, FILE_DELETE: FILE_DELETE, SET_FILE_LIST_SORT: SET_FILE_LIST_SORT, + PURCHASE_URI_STARTED: PURCHASE_URI_STARTED, + PURCHASE_URI_COMPLETED: PURCHASE_URI_COMPLETED, + PURCHASE_URI_FAILED: PURCHASE_URI_FAILED, + LOADING_FILE_STARTED: LOADING_FILE_STARTED, + LOADING_FILE_COMPLETED: LOADING_FILE_COMPLETED, + LOADING_FILE_FAILED: LOADING_FILE_FAILED, SEARCH_START: SEARCH_START, SEARCH_SUCCESS: SEARCH_SUCCESS, SEARCH_FAIL: SEARCH_FAIL, @@ -418,7 +435,10 @@ var action_types = /*#__PURE__*/Object.freeze({ DISMISS_TOAST: DISMISS_TOAST, CREATE_ERROR: CREATE_ERROR, DISMISS_ERROR: DISMISS_ERROR, - FETCH_DATE: FETCH_DATE + FETCH_DATE: FETCH_DATE, + FETCH_COST_INFO_STARTED: FETCH_COST_INFO_STARTED, + FETCH_COST_INFO_COMPLETED: FETCH_COST_INFO_COMPLETED, + FETCH_COST_INFO_FAILED: FETCH_COST_INFO_FAILED }); const API_DOWN = 'apiDown'; @@ -2295,6 +2315,108 @@ const selectFileListPublishedSort = reselect.createSelector(selectState$3, state const selectFileListDownloadedSort = reselect.createSelector(selectState$3, state => state.fileListDownloadedSort); +// + +const selectState$4 = state => state.file || {}; + +const selectFailedPurchaseUris = reselect.createSelector(selectState$4, state => state.failedPurchaseUris); + +const selectPurchasedUris = reselect.createSelector(selectState$4, state => state.purchasedUris); + +const selectPurchasedStreamingUrls = reselect.createSelector(selectState$4, state => state.purchasedStreamingUrls); + +const selectLastPurchasedUri = reselect.createSelector(selectState$4, state => state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null); + +const makeSelectStreamingUrlForUri = uri => reselect.createSelector(selectPurchasedStreamingUrls, streamingUrls => streamingUrls && streamingUrls[uri]); + +// + +function doFileGet(uri, saveFile = true) { + return dispatch => { + dispatch({ + type: LOADING_FILE_STARTED, + data: { + uri + } + }); + + // set save_file argument to True to save the file (old behaviour) + lbryProxy.get({ uri, save_file: saveFile }).then(streamInfo => { + const timeout = streamInfo === null || typeof streamInfo !== 'object'; + + if (timeout) { + dispatch({ + type: LOADING_FILE_FAILED, + data: { uri } + }); + dispatch({ + type: PURCHASE_URI_FAILED, + data: { uri } + }); + + dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); + } else { + // purchase was completed successfully + const { streaming_url: streamingUrl } = streamInfo; + dispatch({ + type: PURCHASE_URI_COMPLETED, + data: { uri, streamingUrl: !saveFile && streamingUrl ? streamingUrl : null } + }); + } + }).catch(() => { + dispatch({ + type: LOADING_FILE_FAILED, + data: { uri } + }); + dispatch({ + type: PURCHASE_URI_FAILED, + data: { uri } + }); + + dispatch(doToast({ + message: `Failed to download ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`, + isError: true + })); + }); + }; +} + +function doPurchaseUri(uri, costInfo, saveFile = true) { + return (dispatch, getState) => { + dispatch({ + type: PURCHASE_URI_STARTED, + data: { uri } + }); + + const state = getState(); + const balance = selectBalance(state); + const fileInfo = makeSelectFileInfoForUri(uri)(state); + const downloadingByOutpoint = selectDownloadingByOutpoint(state); + const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint]; + const alreadyStreaming = makeSelectStreamingUrlForUri(uri)(state); + + if (alreadyDownloading || alreadyStreaming) { + dispatch({ + type: PURCHASE_URI_FAILED, + data: { uri, error: `Already fetching uri: ${uri}` } + }); + return; + } + + const { cost } = costInfo; + + if (cost > balance) { + dispatch({ + type: PURCHASE_URI_FAILED, + data: { uri, error: 'Insufficient credits' } + }); + return; + } + + dispatch(doFileGet(uri, saveFile)); + }; +} + function doFetchFileInfo(uri) { return (dispatch, getState) => { const state = getState(); @@ -2790,15 +2912,65 @@ var _extends$4 = Object.assign || function (target) { for (var i = 1; i < argume const reducers$1 = {}; const defaultState$1 = { + failedPurchaseUris: [], + purchasedUris: [], + purchasedStreamingUrls: {} +}; + +reducers$1[PURCHASE_URI_COMPLETED] = (state, action) => { + const { uri, streamingUrl } = action.data; + const newPurchasedUris = state.purchasedUris.slice(); + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + const newPurchasedStreamingUrls = Object.assign({}, state.purchasedStreamingUrls); + + if (!newPurchasedUris.includes(uri)) { + newPurchasedUris.push(uri); + } + if (newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); + } + if (streamingUrl) { + newPurchasedStreamingUrls[uri] = streamingUrl; + } + + return _extends$4({}, state, { + failedPurchaseUris: newFailedPurchaseUris, + purchasedUris: newPurchasedUris, + purchasedStreamingUrls: newPurchasedStreamingUrls + }); +}; + +reducers$1[PURCHASE_URI_FAILED] = (state, action) => { + const { uri } = action.data; + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + if (!newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.push(uri); + } + + return _extends$4({}, state, { + failedPurchaseUris: newFailedPurchaseUris + }); +}; + +function fileReducer(state = defaultState$1, action) { + const handler = reducers$1[action.type]; + if (handler) return handler(state, action); + return state; +} + +var _extends$5 = 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; }; + +const reducers$2 = {}; +const defaultState$2 = { fileListPublishedSort: DATE_NEW, fileListDownloadedSort: DATE_NEW }; -reducers$1[FILE_LIST_STARTED] = state => Object.assign({}, state, { +reducers$2[FILE_LIST_STARTED] = state => Object.assign({}, state, { isFetchingFileList: true }); -reducers$1[FILE_LIST_SUCCEEDED] = (state, action) => { +reducers$2[FILE_LIST_SUCCEEDED] = (state, action) => { const { fileInfos } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); const pendingByOutpoint = Object.assign({}, state.pendingByOutpoint); @@ -2816,7 +2988,7 @@ reducers$1[FILE_LIST_SUCCEEDED] = (state, action) => { }); }; -reducers$1[FETCH_FILE_INFO_STARTED] = (state, action) => { +reducers$2[FETCH_FILE_INFO_STARTED] = (state, action) => { const { outpoint } = action.data; const newFetching = Object.assign({}, state.fetching); @@ -2827,7 +2999,7 @@ reducers$1[FETCH_FILE_INFO_STARTED] = (state, action) => { }); }; -reducers$1[FETCH_FILE_INFO_COMPLETED] = (state, action) => { +reducers$2[FETCH_FILE_INFO_COMPLETED] = (state, action) => { const { fileInfo, outpoint } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); @@ -2842,7 +3014,7 @@ reducers$1[FETCH_FILE_INFO_COMPLETED] = (state, action) => { }); }; -reducers$1[DOWNLOADING_STARTED] = (state, action) => { +reducers$2[DOWNLOADING_STARTED] = (state, action) => { const { uri, outpoint, fileInfo } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); @@ -2860,7 +3032,7 @@ reducers$1[DOWNLOADING_STARTED] = (state, action) => { }); }; -reducers$1[DOWNLOADING_PROGRESSED] = (state, action) => { +reducers$2[DOWNLOADING_PROGRESSED] = (state, action) => { const { outpoint, fileInfo } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); @@ -2875,7 +3047,7 @@ reducers$1[DOWNLOADING_PROGRESSED] = (state, action) => { }); }; -reducers$1[DOWNLOADING_CANCELED] = (state, action) => { +reducers$2[DOWNLOADING_CANCELED] = (state, action) => { const { outpoint } = action.data; const newDownloading = Object.assign({}, state.downloadingByOutpoint); @@ -2886,7 +3058,7 @@ reducers$1[DOWNLOADING_CANCELED] = (state, action) => { }); }; -reducers$1[DOWNLOADING_COMPLETED] = (state, action) => { +reducers$2[DOWNLOADING_COMPLETED] = (state, action) => { const { outpoint, fileInfo } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); @@ -2901,7 +3073,7 @@ reducers$1[DOWNLOADING_COMPLETED] = (state, action) => { }); }; -reducers$1[FILE_DELETE] = (state, action) => { +reducers$2[FILE_DELETE] = (state, action) => { const { outpoint } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); @@ -2916,37 +3088,37 @@ reducers$1[FILE_DELETE] = (state, action) => { }); }; -reducers$1[LOADING_VIDEO_STARTED] = (state, action) => { +reducers$2[LOADING_VIDEO_STARTED] = (state, action) => { const { uri } = action.data; const newLoading = Object.assign({}, state.urisLoading); newLoading[uri] = true; - const newErrors = _extends$4({}, state.errors); + const newErrors = _extends$5({}, state.errors); if (uri in newErrors) delete newErrors[uri]; return Object.assign({}, state, { urisLoading: newLoading, - errors: _extends$4({}, newErrors) + errors: _extends$5({}, newErrors) }); }; -reducers$1[LOADING_VIDEO_FAILED] = (state, action) => { +reducers$2[LOADING_VIDEO_FAILED] = (state, action) => { const { uri } = action.data; const newLoading = Object.assign({}, state.urisLoading); delete newLoading[uri]; - const newErrors = _extends$4({}, state.errors); + const newErrors = _extends$5({}, state.errors); newErrors[uri] = true; return Object.assign({}, state, { urisLoading: newLoading, - errors: _extends$4({}, newErrors) + errors: _extends$5({}, newErrors) }); }; -reducers$1[FETCH_DATE] = (state, action) => { +reducers$2[FETCH_DATE] = (state, action) => { const { time } = action.data; if (time) { return Object.assign({}, state, { @@ -2956,7 +3128,7 @@ reducers$1[FETCH_DATE] = (state, action) => { return null; }; -reducers$1[SET_FILE_LIST_SORT] = (state, action) => { +reducers$2[SET_FILE_LIST_SORT] = (state, action) => { const pageSortStates = { [PUBLISHED]: 'fileListPublishedSort', [DOWNLOADED]: 'fileListDownloadedSort' @@ -2969,8 +3141,8 @@ reducers$1[SET_FILE_LIST_SORT] = (state, action) => { }); }; -function fileInfoReducer(state = defaultState$1, action) { - const handler = reducers$1[action.type]; +function fileInfoReducer(state = defaultState$2, action) { + const handler = reducers$2[action.type]; if (handler) return handler(state, action); return state; } @@ -2993,9 +3165,9 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -var _extends$5 = 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; }; +var _extends$6 = 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; }; -const defaultState$2 = { +const defaultState$3 = { notifications: [], toasts: [], errors: [] @@ -3008,7 +3180,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$5({}, state, { + return _extends$6({}, state, { toasts: newToasts }); }, @@ -3016,7 +3188,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$5({}, state, { + return _extends$6({}, state, { toasts: newToasts }); }, @@ -3027,7 +3199,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$5({}, state, { + return _extends$6({}, state, { notifications: newNotifications }); }, @@ -3038,7 +3210,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$5({}, state, { + return _extends$6({}, state, { notifications }); }, @@ -3047,7 +3219,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$5({}, state, { + return _extends$6({}, state, { notifications: newNotifications }); }, @@ -3058,7 +3230,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$5({}, state, { + return _extends$6({}, state, { errors: newErrors }); }, @@ -3066,15 +3238,15 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$5({}, state, { + return _extends$6({}, state, { errors: newErrors }); } -}, defaultState$2); +}, defaultState$3); -var _extends$6 = 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; }; +var _extends$7 = 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; }; -const defaultState$3 = { +const defaultState$4 = { 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 @@ -3092,29 +3264,29 @@ const defaultState$3 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$6({}, state, { + [SEARCH_START]: state => _extends$7({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$6({}, state, { + return _extends$7({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$6({}, state, { + [SEARCH_FAIL]: state => _extends$7({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$6({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$7({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$6({}, state, { - suggestions: _extends$6({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$7({}, state, { + suggestions: _extends$7({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -3122,27 +3294,27 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$6({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$7({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$6({}, state, { + [SEARCH_FOCUS]: state => _extends$7({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$6({}, state, { + [SEARCH_BLUR]: state => _extends$7({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$6({}, oldOptions, newOptions); - return _extends$6({}, state, { + const options = _extends$7({}, oldOptions, newOptions); + return _extends$7({}, state, { options }); } -}, defaultState$3); +}, defaultState$4); -var _extends$7 = 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; }; +var _extends$8 = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -3153,7 +3325,7 @@ const buildDraftTransaction = () => ({ // See details in https://github.com/lbryio/lbry/issues/1307 -const defaultState$4 = { +const defaultState$5 = { balance: undefined, totalBalance: undefined, latestBlock: undefined, @@ -3182,25 +3354,25 @@ const defaultState$4 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$7({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$8({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$7({}, state.transactions); + const byId = _extends$8({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$7({}, state, { + return _extends$8({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$7({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$8({}, state, { fetchingSupports: true }), @@ -3213,7 +3385,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$7({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$8({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -3222,7 +3394,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$7({}, state, { + return _extends$8({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -3235,56 +3407,56 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$7({}, state, { + return _extends$8({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$7({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$8({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$7({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$8({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$7({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$8({}, state, { balance: action.data.balance }), - [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$7({}, state, { + [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$8({}, state, { totalBalance: action.data.totalBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$7({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$8({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$7({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$8({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$7({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$8({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$7({}, state, { draftTransaction: newDraft }); + return _extends$8({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$7({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$8({}, oldDraft, { address: action.data.address }); - return _extends$7({}, state, { draftTransaction: newDraft }); + return _extends$8({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$7({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$8({}, state.draftTransaction, { sending: true }); - return _extends$7({}, state, { draftTransaction: newDraftTransaction }); + return _extends$8({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -3297,134 +3469,134 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$7({}, state, { draftTransaction: newDraftTransaction }); + return _extends$8({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$7({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$8({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$7({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$8({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$7({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$8({}, state, { error: action.data.error, sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$7({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$8({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$7({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$8({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$7({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$8({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$7({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$8({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$7({}, state, { + [WALLET_DECRYPT_START]: state => _extends$8({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$7({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$8({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$7({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$8({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$7({}, state, { + [WALLET_UNLOCK_START]: state => _extends$8({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$7({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$8({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$7({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$8({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$7({}, state, { + [WALLET_LOCK_START]: state => _extends$8({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$7({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$8({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$7({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$8({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$7({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$8({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$7({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$8({}, state, { latestBlock: action.data }) -}, defaultState$4); +}, defaultState$5); -var _extends$8 = 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; }; +var _extends$9 = 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; }; -const reducers$2 = {}; -const defaultState$5 = { +const reducers$3 = {}; +const defaultState$6 = { positions: {} }; -reducers$2[SET_CONTENT_POSITION] = (state, action) => { +reducers$3[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$8({}, state, { - positions: _extends$8({}, state.positions, { - [claimId]: _extends$8({}, state.positions[claimId], { + return _extends$9({}, state, { + positions: _extends$9({}, state.positions, { + [claimId]: _extends$9({}, state.positions[claimId], { [outpoint]: position }) }) }); }; -function contentReducer(state = defaultState$5, action) { - const handler = reducers$2[action.type]; +function contentReducer(state = defaultState$6, action) { + const handler = reducers$3[action.type]; if (handler) return handler(state, action); return state; } -const selectState$4 = state => state.content || {}; +const selectState$5 = state => state.content || {}; -const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$4, makeSelectClaimForUri(uri), (state, claim) => { +const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$5, makeSelectClaimForUri(uri), (state, claim) => { if (!claim) { return null; } @@ -3433,14 +3605,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$9 = 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; }; +var _extends$a = 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; }; -const selectState$5 = state => state.notifications || {}; +const selectState$6 = state => state.notifications || {}; -const selectToast = reselect.createSelector(selectState$5, state => { +const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$9({ + return _extends$a({ id }, params); } @@ -3448,7 +3620,7 @@ const selectToast = reselect.createSelector(selectState$5, state => { return null; }); -const selectError = reselect.createSelector(selectState$5, state => { +const selectError = reselect.createSelector(selectState$6, state => { if (state.errors.length) { const { error } = state.errors[0]; return { @@ -3488,9 +3660,11 @@ exports.doFetchClaimsByChannel = doFetchClaimsByChannel; exports.doFetchFileInfo = doFetchFileInfo; exports.doFetchFileInfosAndPublishedClaims = doFetchFileInfosAndPublishedClaims; exports.doFetchTransactions = doFetchTransactions; +exports.doFileGet = doFileGet; exports.doFileList = doFileList; exports.doFocusSearchInput = doFocusSearchInput; exports.doGetNewAddress = doGetNewAddress; +exports.doPurchaseUri = doPurchaseUri; exports.doResolveUri = doResolveUri; exports.doResolveUris = doResolveUris; exports.doSearch = doSearch; @@ -3512,6 +3686,7 @@ exports.doWalletEncrypt = doWalletEncrypt; exports.doWalletStatus = doWalletStatus; exports.doWalletUnlock = doWalletUnlock; exports.fileInfoReducer = fileInfoReducer; +exports.fileReducer = fileReducer; exports.formatCredits = formatCredits; exports.formatFullPrice = formatFullPrice; exports.isClaimNsfw = isClaimNsfw; @@ -3543,6 +3718,7 @@ exports.makeSelectPendingByUri = makeSelectPendingByUri; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; exports.makeSelectSearchUris = makeSelectSearchUris; +exports.makeSelectStreamingUrlForUri = makeSelectStreamingUrlForUri; exports.makeSelectThumbnailForUri = makeSelectThumbnailForUri; exports.makeSelectTitleForUri = makeSelectTitleForUri; exports.makeSelectTotalItemsForChannel = makeSelectTotalItemsForChannel; @@ -3572,6 +3748,7 @@ exports.selectDraftTransactionAddress = selectDraftTransactionAddress; exports.selectDraftTransactionAmount = selectDraftTransactionAmount; exports.selectDraftTransactionError = selectDraftTransactionError; exports.selectError = selectError; +exports.selectFailedPurchaseUris = selectFailedPurchaseUris; exports.selectFetchingMyChannels = selectFetchingMyChannels; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; @@ -3585,6 +3762,7 @@ exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileList exports.selectIsFetchingTransactions = selectIsFetchingTransactions; exports.selectIsSearching = selectIsSearching; exports.selectIsSendingSupport = selectIsSendingSupport; +exports.selectLastPurchasedUri = selectLastPurchasedUri; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; exports.selectMyClaims = selectMyClaims; @@ -3594,6 +3772,8 @@ exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; exports.selectPendingById = selectPendingById; exports.selectPendingClaims = selectPendingClaims; exports.selectPlayingUri = selectPlayingUri; +exports.selectPurchasedStreamingUrls = selectPurchasedStreamingUrls; +exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; exports.selectResolvingUris = selectResolvingUris; diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index a4f8a60..4384d3f 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -24,6 +24,7 @@ declare type FileListItem = { stopped: false, stream_hash: string, stream_name: string, + streaming_url: string, suggested_file_name: string, total_bytes: number, total_bytes_lower_bound: number, @@ -33,3 +34,24 @@ declare type FileListItem = { txid: string, written_bytes: number, }; + +declare type FileState = { + failedPurchaseUris: Array, + purchasedUris: Array, + purchasedStreamingUrls: {}, +}; + +declare type PurchaseUriCompleted = { + type: ACTIONS.PURCHASE_URI_COMPLETED, + data: { + uri: string, + streamingUrl: string, + }, +}; + +declare type PurchaseUriFailed = { + type: ACTIONS.PURCHASE_URI_FAILED, + data: { + uri: string + }, +}; diff --git a/flow-typed/File.js b/flow-typed/File.js index a4f8a60..4384d3f 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -24,6 +24,7 @@ declare type FileListItem = { stopped: false, stream_hash: string, stream_name: string, + streaming_url: string, suggested_file_name: string, total_bytes: number, total_bytes_lower_bound: number, @@ -33,3 +34,24 @@ declare type FileListItem = { txid: string, written_bytes: number, }; + +declare type FileState = { + failedPurchaseUris: Array, + purchasedUris: Array, + purchasedStreamingUrls: {}, +}; + +declare type PurchaseUriCompleted = { + type: ACTIONS.PURCHASE_URI_COMPLETED, + data: { + uri: string, + streamingUrl: string, + }, +}; + +declare type PurchaseUriFailed = { + type: ACTIONS.PURCHASE_URI_FAILED, + data: { + uri: string + }, +}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 95d4035..9582f77 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -106,6 +106,12 @@ export const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'; export const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'; export const FILE_DELETE = 'FILE_DELETE'; export const SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; +export const PURCHASE_URI_STARTED = 'PURCHASE_URI_STARTED'; +export const PURCHASE_URI_COMPLETED = 'PURCHASE_URI_COMPLETED'; +export const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; +export const LOADING_FILE_STARTED = 'LOADING_FILE_STARTED'; +export const LOADING_FILE_COMPLETED = 'LOADING_FILE_COMPLETED'; +export const LOADING_FILE_FAILED = 'LOADING_FILE_FAILED'; // Search export const SEARCH_START = 'SEARCH_START'; @@ -217,3 +223,8 @@ export const CREATE_ERROR = 'CREATE_ERROR'; export const DISMISS_ERROR = 'DISMISS_ERROR'; export const FETCH_DATE = 'FETCH_DATE'; + +// Cost info +export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'; +export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'; +export const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; diff --git a/src/index.js b/src/index.js index 9fa1fff..9265f41 100644 --- a/src/index.js +++ b/src/index.js @@ -47,6 +47,8 @@ export { doCreateChannel, } from 'redux/actions/claims'; +export { doPurchaseUri, doFileGet } from 'redux/actions/file'; + export { doFetchFileInfo, doFileList, @@ -93,6 +95,7 @@ export { isClaimNsfw } from 'util/claim'; // reducers export { claimsReducer } from 'redux/reducers/claims'; +export { fileReducer } from 'redux/reducers/file'; export { fileInfoReducer } from 'redux/reducers/file_info'; export { notificationsReducer } from 'redux/reducers/notifications'; export { searchReducer } from 'redux/reducers/search'; @@ -104,6 +107,14 @@ export { makeSelectContentPositionForUri } from 'redux/selectors/content'; export { selectToast, selectError } from 'redux/selectors/notifications'; +export { + selectFailedPurchaseUris, + selectPurchasedUris, + selectPurchasedStreamingUrls, + selectLastPurchasedUri, + makeSelectStreamingUrlForUri, +} from 'redux/selectors/file'; + export { makeSelectClaimForUri, makeSelectClaimIsMine, diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js new file mode 100644 index 0000000..6d7bb37 --- /dev/null +++ b/src/redux/actions/file.js @@ -0,0 +1,104 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; +import Lbry from 'lbry'; +import { doToast } from 'redux/actions/notifications'; +import { selectBalance } from 'redux/selectors/wallet'; +import { makeSelectFileInfoForUri, selectDownloadingByOutpoint } from 'redux/selectors/file_info'; +import { makeSelectStreamingUrlForUri } from 'redux/selectors/file'; + +type Dispatch = (action: any) => any; +type GetState = () => { file: FileState }; + +export function doFileGet(uri: string, saveFile: boolean = true) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.LOADING_FILE_STARTED, + data: { + uri, + }, + }); + + // set save_file argument to True to save the file (old behaviour) + Lbry.get({ uri, save_file: saveFile }) + .then((streamInfo: GetResponse) => { + const timeout = streamInfo === null || typeof streamInfo !== 'object'; + + if (timeout) { + dispatch({ + type: ACTIONS.LOADING_FILE_FAILED, + data: { uri }, + }); + dispatch({ + type: ACTIONS.PURCHASE_URI_FAILED, + data: { uri }, + }); + + dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); + } else { + // purchase was completed successfully + const { streaming_url: streamingUrl } = streamInfo; + dispatch({ + type: ACTIONS.PURCHASE_URI_COMPLETED, + data: { uri, streamingUrl: !saveFile && streamingUrl ? streamingUrl : null }, + }); + } + }) + .catch(() => { + dispatch({ + type: ACTIONS.LOADING_FILE_FAILED, + data: { uri }, + }); + dispatch({ + type: ACTIONS.PURCHASE_URI_FAILED, + data: { uri }, + }); + + dispatch( + doToast({ + message: `Failed to download ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`, + isError: true, + }) + ); + }); + }; +} + +export function doPurchaseUri(uri: string, costInfo: { cost: number }, saveFile: boolean = true) { + return (dispatch: Dispatch, getState: GetState) => { + dispatch({ + type: ACTIONS.PURCHASE_URI_STARTED, + data: { uri }, + }); + + const state = getState(); + const balance = selectBalance(state); + const fileInfo = makeSelectFileInfoForUri(uri)(state); + const downloadingByOutpoint = selectDownloadingByOutpoint(state); + const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint]; + const alreadyStreaming = makeSelectStreamingUrlForUri(uri)(state); + + if (alreadyDownloading || alreadyStreaming) { + dispatch({ + type: ACTIONS.PURCHASE_URI_FAILED, + data: { uri, error: `Already fetching uri: ${uri}` }, + }); + + Promise.resolve(); + return; + } + + const { cost } = costInfo; + + if (cost > balance) { + dispatch({ + type: ACTIONS.PURCHASE_URI_FAILED, + data: { uri, error: 'Insufficient credits' }, + }); + + Promise.resolve(); + return; + } + + dispatch(doFileGet(uri, saveFile)); + }; +} diff --git a/src/redux/reducers/file.js b/src/redux/reducers/file.js new file mode 100644 index 0000000..2e593fa --- /dev/null +++ b/src/redux/reducers/file.js @@ -0,0 +1,58 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; + +const reducers = {}; +const defaultState = { + failedPurchaseUris: [], + purchasedUris: [], + purchasedStreamingUrls: {}, +}; + +reducers[ACTIONS.PURCHASE_URI_COMPLETED] = ( + state: FileState, + action: PurchaseUriCompleted +): FileState => { + const { uri, streamingUrl } = action.data; + const newPurchasedUris = state.purchasedUris.slice(); + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + const newPurchasedStreamingUrls = Object.assign({}, state.purchasedStreamingUrls); + + if (!newPurchasedUris.includes(uri)) { + newPurchasedUris.push(uri); + } + if (newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); + } + if (streamingUrl) { + newPurchasedStreamingUrls[uri] = streamingUrl; + } + + return { + ...state, + failedPurchaseUris: newFailedPurchaseUris, + purchasedUris: newPurchasedUris, + purchasedStreamingUrls: newPurchasedStreamingUrls, + }; +}; + +reducers[ACTIONS.PURCHASE_URI_FAILED] = ( + state: FileState, + action: PurchaseUriFailed +): FileState => { + const { uri } = action.data; + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + if (!newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.push(uri); + } + + return { + ...state, + failedPurchaseUris: newFailedPurchaseUris, + }; +}; + +export function fileReducer(state: FileState = defaultState, action: any) { + const handler = reducers[action.type]; + if (handler) return handler(state, action); + return state; +} diff --git a/src/redux/selectors/file.js b/src/redux/selectors/file.js new file mode 100644 index 0000000..11caee5 --- /dev/null +++ b/src/redux/selectors/file.js @@ -0,0 +1,33 @@ +// @flow +import { createSelector } from 'reselect'; + +type State = { file: FileState }; + +export const selectState = (state: State): FileState => state.file || {}; + +export const selectFailedPurchaseUris: (state: State) => Array = createSelector( + selectState, + state => state.failedPurchaseUris +); + +export const selectPurchasedUris: (state: State) => Array = createSelector( + selectState, + state => state.purchasedUris +); + +export const selectPurchasedStreamingUrls: (state: State) => {} = createSelector( + selectState, + state => state.purchasedStreamingUrls +); + +export const selectLastPurchasedUri: (state: State) => string = createSelector( + selectState, + state => + state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null +); + +export const makeSelectStreamingUrlForUri = (uri: string): ((state: State) => {}) => + createSelector( + selectPurchasedStreamingUrls, + streamingUrls => streamingUrls && streamingUrls[uri] + ); -- 2.45.2 From 6ce6a494e45f6a3516711d2020bafbee7e9f9018 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 21 May 2019 16:10:41 -0400 Subject: [PATCH 018/371] fix: claim search to use channel uri instead of claim id (support for vanity resolution) I did not test this locally - would need to bring it into an Android build. The --winning parameter is required so that only the winning channel's claims are returned. --- dist/bundle.es.js | 4 +--- src/redux/actions/claims.js | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4bbe81d..5ee8ee8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2093,9 +2093,7 @@ function doFetchClaimsByChannel(uri, page = 1) { data: { uri, page } }); - const { claimId } = parseURI(uri); - - lbryProxy.claim_search({ channel_id: claimId, page: page || 1 }).then(result => { + lbryProxy.claim_search({ channel_name: uri, page: page || 1, winning: true }).then(result => { const { items: claimsInChannel, page: returnedPage } = result; dispatch({ diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 54bc7c9..33dd119 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -182,9 +182,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { data: { uri, page }, }); - const { claimId } = parseURI(uri); - - Lbry.claim_search({ channel_id: claimId, page: page || 1 }).then( + Lbry.claim_search({ channel_name: uri, page: page || 1, winning: true }).then( (result: ClaimSearchResponse) => { const { items: claimsInChannel, page: returnedPage } = result; -- 2.45.2 From a01b919c72139d82fa981df6be4e0fe902ff8f70 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 27 May 2019 14:59:21 +0100 Subject: [PATCH 019/371] remove the uri from the failed list if the user reattempts getting the same uri (#151) * remove uri from failed purchase uris for a new purchase * add doDeletePurchasedUri action * add parseFloat for costInfo.cost * add purhcaseUriErrorMessage and more failure handling --- dist/bundle.es.js | 53 +++++++++++++++++++++++++++++++---- dist/flow-typed/File.js | 16 +++++++++++ flow-typed/File.js | 16 +++++++++++ src/constants/action_types.js | 1 + src/index.js | 3 +- src/redux/actions/file.js | 10 +++++-- src/redux/reducers/file.js | 39 +++++++++++++++++++++++++- src/redux/selectors/file.js | 5 ++++ 8 files changed, 133 insertions(+), 10 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 5ee8ee8..2977116 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -119,6 +119,7 @@ const SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; const PURCHASE_URI_STARTED = 'PURCHASE_URI_STARTED'; const PURCHASE_URI_COMPLETED = 'PURCHASE_URI_COMPLETED'; const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; +const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; const LOADING_FILE_STARTED = 'LOADING_FILE_STARTED'; const LOADING_FILE_COMPLETED = 'LOADING_FILE_COMPLETED'; const LOADING_FILE_FAILED = 'LOADING_FILE_FAILED'; @@ -341,6 +342,7 @@ var action_types = /*#__PURE__*/Object.freeze({ PURCHASE_URI_STARTED: PURCHASE_URI_STARTED, PURCHASE_URI_COMPLETED: PURCHASE_URI_COMPLETED, PURCHASE_URI_FAILED: PURCHASE_URI_FAILED, + DELETE_PURCHASED_URI: DELETE_PURCHASED_URI, LOADING_FILE_STARTED: LOADING_FILE_STARTED, LOADING_FILE_COMPLETED: LOADING_FILE_COMPLETED, LOADING_FILE_FAILED: LOADING_FILE_FAILED, @@ -2317,6 +2319,8 @@ const selectFileListDownloadedSort = reselect.createSelector(selectState$3, stat const selectState$4 = state => state.file || {}; +const selectPurchaseUriErrorMessage = reselect.createSelector(selectState$4, state => state.purchaseUriErrorMessage); + const selectFailedPurchaseUris = reselect.createSelector(selectState$4, state => state.failedPurchaseUris); const selectPurchasedUris = reselect.createSelector(selectState$4, state => state.purchasedUris); @@ -2402,8 +2406,7 @@ function doPurchaseUri(uri, costInfo, saveFile = true) { } const { cost } = costInfo; - - if (cost > balance) { + if (parseFloat(cost) > balance) { dispatch({ type: PURCHASE_URI_FAILED, data: { uri, error: 'Insufficient credits' } @@ -2415,6 +2418,13 @@ function doPurchaseUri(uri, costInfo, saveFile = true) { }; } +function doDeletePurchasedUri(uri) { + return { + type: DELETE_PURCHASED_URI, + data: { uri } + }; +} + function doFetchFileInfo(uri) { return (dispatch, getState) => { const state = getState(); @@ -2912,7 +2922,21 @@ const reducers$1 = {}; const defaultState$1 = { failedPurchaseUris: [], purchasedUris: [], - purchasedStreamingUrls: {} + purchasedStreamingUrls: {}, + purchaseUriErrorMessage: '' +}; + +reducers$1[PURCHASE_URI_STARTED] = (state, action) => { + const { uri } = action.data; + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + if (newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); + } + + return _extends$4({}, state, { + failedPurchaseUris: newFailedPurchaseUris, + purchaseUriErrorMessage: '' + }); }; reducers$1[PURCHASE_URI_COMPLETED] = (state, action) => { @@ -2934,19 +2958,34 @@ reducers$1[PURCHASE_URI_COMPLETED] = (state, action) => { return _extends$4({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, - purchasedStreamingUrls: newPurchasedStreamingUrls + purchasedStreamingUrls: newPurchasedStreamingUrls, + purchaseUriErrorMessage: '' }); }; reducers$1[PURCHASE_URI_FAILED] = (state, action) => { - const { uri } = action.data; + const { uri, error } = action.data; const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + if (!newFailedPurchaseUris.includes(uri)) { newFailedPurchaseUris.push(uri); } return _extends$4({}, state, { - failedPurchaseUris: newFailedPurchaseUris + failedPurchaseUris: newFailedPurchaseUris, + purchaseUriErrorMessage: error + }); +}; + +reducers$1[DELETE_PURCHASED_URI] = (state, action) => { + const { uri } = action.data; + const newPurchasedUris = state.purchasedUris.slice(); + if (newPurchasedUris.includes(uri)) { + newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); + } + + return _extends$4({}, state, { + purchasedUris: newPurchasedUris }); }; @@ -3649,6 +3688,7 @@ exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCreateChannel = doCreateChannel; +exports.doDeletePurchasedUri = doDeletePurchasedUri; exports.doDismissError = doDismissError; exports.doDismissToast = doDismissToast; exports.doError = doError; @@ -3770,6 +3810,7 @@ exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; exports.selectPendingById = selectPendingById; exports.selectPendingClaims = selectPendingClaims; exports.selectPlayingUri = selectPlayingUri; +exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchasedStreamingUrls = selectPurchasedStreamingUrls; exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index 4384d3f..42c9b16 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -51,6 +51,22 @@ declare type PurchaseUriCompleted = { declare type PurchaseUriFailed = { type: ACTIONS.PURCHASE_URI_FAILED, + data: { + uri: string, + error: any + }, +}; + +declare type PurchaseUriStarted = { + type: ACTIONS.PURCHASE_URI_STARTED, + data: { + uri: string, + streamingUrl: string, + }, +}; + +declare type DeletePurchasedUri = { + type: ACTIONS.DELETE_PURCHASED_URI, data: { uri: string }, diff --git a/flow-typed/File.js b/flow-typed/File.js index 4384d3f..42c9b16 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -51,6 +51,22 @@ declare type PurchaseUriCompleted = { declare type PurchaseUriFailed = { type: ACTIONS.PURCHASE_URI_FAILED, + data: { + uri: string, + error: any + }, +}; + +declare type PurchaseUriStarted = { + type: ACTIONS.PURCHASE_URI_STARTED, + data: { + uri: string, + streamingUrl: string, + }, +}; + +declare type DeletePurchasedUri = { + type: ACTIONS.DELETE_PURCHASED_URI, data: { uri: string }, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 9582f77..cb1cdd0 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -109,6 +109,7 @@ export const SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; export const PURCHASE_URI_STARTED = 'PURCHASE_URI_STARTED'; export const PURCHASE_URI_COMPLETED = 'PURCHASE_URI_COMPLETED'; export const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; +export const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; export const LOADING_FILE_STARTED = 'LOADING_FILE_STARTED'; export const LOADING_FILE_COMPLETED = 'LOADING_FILE_COMPLETED'; export const LOADING_FILE_FAILED = 'LOADING_FILE_FAILED'; diff --git a/src/index.js b/src/index.js index 9265f41..848d0e5 100644 --- a/src/index.js +++ b/src/index.js @@ -47,7 +47,7 @@ export { doCreateChannel, } from 'redux/actions/claims'; -export { doPurchaseUri, doFileGet } from 'redux/actions/file'; +export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; export { doFetchFileInfo, @@ -111,6 +111,7 @@ export { selectFailedPurchaseUris, selectPurchasedUris, selectPurchasedStreamingUrls, + selectPurchaseUriErrorMessage, selectLastPurchasedUri, makeSelectStreamingUrlForUri, } from 'redux/selectors/file'; diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 6d7bb37..337f85f 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -88,8 +88,7 @@ export function doPurchaseUri(uri: string, costInfo: { cost: number }, saveFile: } const { cost } = costInfo; - - if (cost > balance) { + if (parseFloat(cost) > balance) { dispatch({ type: ACTIONS.PURCHASE_URI_FAILED, data: { uri, error: 'Insufficient credits' }, @@ -102,3 +101,10 @@ export function doPurchaseUri(uri: string, costInfo: { cost: number }, saveFile: dispatch(doFileGet(uri, saveFile)); }; } + +export function doDeletePurchasedUri(uri: string) { + return { + type: ACTIONS.DELETE_PURCHASED_URI, + data: { uri }, + }; +} diff --git a/src/redux/reducers/file.js b/src/redux/reducers/file.js index 2e593fa..95a3b7e 100644 --- a/src/redux/reducers/file.js +++ b/src/redux/reducers/file.js @@ -6,6 +6,24 @@ const defaultState = { failedPurchaseUris: [], purchasedUris: [], purchasedStreamingUrls: {}, + purchaseUriErrorMessage: '', +}; + +reducers[ACTIONS.PURCHASE_URI_STARTED] = ( + state: FileState, + action: PurchaseUriStarted +): FileState => { + const { uri } = action.data; + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + if (newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); + } + + return { + ...state, + failedPurchaseUris: newFailedPurchaseUris, + purchaseUriErrorMessage: '', + }; }; reducers[ACTIONS.PURCHASE_URI_COMPLETED] = ( @@ -32,6 +50,7 @@ reducers[ACTIONS.PURCHASE_URI_COMPLETED] = ( failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, purchasedStreamingUrls: newPurchasedStreamingUrls, + purchaseUriErrorMessage: '', }; }; @@ -39,8 +58,9 @@ reducers[ACTIONS.PURCHASE_URI_FAILED] = ( state: FileState, action: PurchaseUriFailed ): FileState => { - const { uri } = action.data; + const { uri, error } = action.data; const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + if (!newFailedPurchaseUris.includes(uri)) { newFailedPurchaseUris.push(uri); } @@ -48,6 +68,23 @@ reducers[ACTIONS.PURCHASE_URI_FAILED] = ( return { ...state, failedPurchaseUris: newFailedPurchaseUris, + purchaseUriErrorMessage: error, + }; +}; + +reducers[ACTIONS.DELETE_PURCHASED_URI] = ( + state: FileState, + action: DeletePurchasedUri +): FileState => { + const { uri } = action.data; + const newPurchasedUris = state.purchasedUris.slice(); + if (newPurchasedUris.includes(uri)) { + newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); + } + + return { + ...state, + purchasedUris: newPurchasedUris, }; }; diff --git a/src/redux/selectors/file.js b/src/redux/selectors/file.js index 11caee5..7e0a1a1 100644 --- a/src/redux/selectors/file.js +++ b/src/redux/selectors/file.js @@ -5,6 +5,11 @@ type State = { file: FileState }; export const selectState = (state: State): FileState => state.file || {}; +export const selectPurchaseUriErrorMessage: (state: State) => string = createSelector( + selectState, + state => state.purchaseUriErrorMessage +); + export const selectFailedPurchaseUris: (state: State) => Array = createSelector( selectState, state => state.failedPurchaseUris -- 2.45.2 From bd26d7ba441849cfe3ced3cfcbc8871178c5d70f Mon Sep 17 00:00:00 2001 From: Upsided Date: Thu, 28 Mar 2019 19:40:40 -0500 Subject: [PATCH 020/371] Allow unicode characters in claim names. See https://spec.lbry.com/#urls --- src/lbryURI.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/lbryURI.js b/src/lbryURI.js index fd07213..3415b26 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -1,7 +1,8 @@ const channelNameMinLength = 1; const claimIdMaxLength = 40; -export const regexInvalidURI = /[^A-Za-z0-9-]/g; +// see https://spec.lbry.com/#urls +const regexInvalidURI = (exports.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}$/; /** -- 2.45.2 From b427ccfedea881bd5582f6e095d2d9f407691e74 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Sun, 2 Jun 2019 22:55:52 -0400 Subject: [PATCH 021/371] fix unicode regex Add /g option like before. Remove manual export. Actually use it in the isNameValid function. --- dist/bundle.es.js | 9 ++++----- src/index.js | 1 - src/lbryURI.js | 7 +++---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2977116..fb5eae1 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -822,7 +822,8 @@ var _extends = Object.assign || function (target) { for (var i = 1; i < argument const channelNameMinLength = 1; const claimIdMaxLength = 40; -const regexInvalidURI = /[^A-Za-z0-9-]/g; +// see https://spec.lbry.com/#urls +const regexInvalidURI = exports.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}$/; /** @@ -990,9 +991,8 @@ function isURIValid(URI) { return parts && parts.claimName; } -function isNameValid(claimName, checkCase = true) { - const regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); - return regexp.test(claimName); +function isNameValid(claimName) { + return !regexInvalidURI.test(claimName); } function isURIClaimable(URI) { @@ -3766,7 +3766,6 @@ exports.notificationsReducer = notificationsReducer; exports.parseQueryParams = parseQueryParams; exports.parseURI = parseURI; exports.regexAddress = regexAddress; -exports.regexInvalidURI = regexInvalidURI; exports.savePosition = savePosition; exports.searchReducer = searchReducer; exports.selectAbandoningIds = selectAbandoningIds; diff --git a/src/index.js b/src/index.js index 848d0e5..a85a007 100644 --- a/src/index.js +++ b/src/index.js @@ -23,7 +23,6 @@ export { // common export { Lbry }; export { - regexInvalidURI, regexAddress, parseURI, buildURI, diff --git a/src/lbryURI.js b/src/lbryURI.js index 3415b26..8292606 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 -const regexInvalidURI = (exports.regexInvalidURI = /[=&#:$@%?\u{0000}-\u{0008}\u{000b}-\u{000c}\u{000e}-\u{001F}\u{D800}-\u{DFFF}\u{FFFE}-\u{FFFF}]/u); +const regexInvalidURI = (exports.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}$/; /** @@ -201,9 +201,8 @@ export function isURIValid(URI) { return parts && parts.claimName; } -export function isNameValid(claimName, checkCase = true) { - const regexp = new RegExp('^[a-z0-9-]+$', checkCase ? '' : 'i'); - return regexp.test(claimName); +export function isNameValid(claimName) { + return !regexInvalidURI.test(claimName); } export function isURIClaimable(URI) { -- 2.45.2 From e883f8172203d77ab09d79679bea0256906ed9a5 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Mon, 3 Jun 2019 10:24:46 -0400 Subject: [PATCH 022/371] Fix export --- dist/bundle.es.js | 1 + src/index.js | 1 + src/lbryURI.js | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index fb5eae1..7039cf4 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3766,6 +3766,7 @@ exports.notificationsReducer = notificationsReducer; exports.parseQueryParams = parseQueryParams; exports.parseURI = parseURI; exports.regexAddress = regexAddress; +exports.regexInvalidURI = regexInvalidURI; exports.savePosition = savePosition; exports.searchReducer = searchReducer; exports.selectAbandoningIds = selectAbandoningIds; diff --git a/src/index.js b/src/index.js index a85a007..848d0e5 100644 --- a/src/index.js +++ b/src/index.js @@ -23,6 +23,7 @@ export { // common export { Lbry }; export { + regexInvalidURI, regexAddress, parseURI, buildURI, diff --git a/src/lbryURI.js b/src/lbryURI.js index 8292606..9b805f7 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 -const regexInvalidURI = (exports.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 = (exports.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}$/; /** -- 2.45.2 From ed94218cdb3409b963aec136ffe3c11c9e3bc875 Mon Sep 17 00:00:00 2001 From: Jessop Breth Date: Thu, 30 May 2019 11:24:46 -0400 Subject: [PATCH 023/371] adds headers and means to set them to Lbry --- .gitignore | 6 +++++- dist/bundle.es.js | 9 +++++++++ dist/flow-typed/Lbry.js | 3 +++ flow-typed/Lbry.js | 3 +++ src/lbry.js | 9 +++++++++ 5 files changed, 29 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index f495bd8..cb86625 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ /node_modules yarn-error.log -package-lock.json \ No newline at end of file +package-lock.json + +# Jetbrains +.idea/ + diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2977116..78f961a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -606,12 +606,20 @@ const Lbry = { isConnected: false, connectPromise: null, daemonConnectionString: 'http://localhost:5279', + apiRequestHeaders: { 'Content-Type': 'application/json-rpc' }, // Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) setDaemonConnectionString: value => { Lbry.daemonConnectionString = value; }, + setApiHeader: (key, value) => { + Lbry.apiRequestHeaders = Object.assign(Lbry.apiRequestHeaders, { [key]: value }); + }, + + unsetApiHeader: key => { + Object.keys(Lbry.apiRequestHeaders).includes(key) && delete Lbry.apiRequestHeaders['key']; + }, // Allow overriding Lbry methods overrides: {}, setOverride: (methodName, newMethod) => { @@ -730,6 +738,7 @@ function apiCall(method, params, resolve, reject) { const counter = new Date().getTime(); const options = { method: 'POST', + headers: Lbry.apiRequestHeaders, body: JSON.stringify({ jsonrpc: '2.0', method, diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 303de6f..e4d9090 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -153,7 +153,10 @@ declare type LbryTypes = { connectPromise: ?Promise, connect: () => void, daemonConnectionString: string, + apiRequestHeaders: {[key: string]: string}, setDaemonConnectionString: string => void, + setApiHeader: (string, string) => void, + unsetApiHeader: (string) => void, overrides: { [string]: ?Function }, setOverride: (string, Function) => void, getMediaType: (string, ?string) => string, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 303de6f..e4d9090 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -153,7 +153,10 @@ declare type LbryTypes = { connectPromise: ?Promise, connect: () => void, daemonConnectionString: string, + apiRequestHeaders: {[key: string]: string}, setDaemonConnectionString: string => void, + setApiHeader: (string, string) => void, + unsetApiHeader: (string) => void, overrides: { [string]: ?Function }, setOverride: (string, Function) => void, getMediaType: (string, ?string) => string, diff --git a/src/lbry.js b/src/lbry.js index 03e7451..3ac88ad 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -11,12 +11,20 @@ const Lbry: LbryTypes = { isConnected: false, connectPromise: null, daemonConnectionString: 'http://localhost:5279', + apiRequestHeaders: { 'Content-Type': 'application/json-rpc' }, // Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) setDaemonConnectionString: (value: string) => { Lbry.daemonConnectionString = value; }, + setApiHeader: (key: string, value: string) => { + Lbry.apiRequestHeaders = Object.assign(Lbry.apiRequestHeaders, { [key]: value }); + }, + + unsetApiHeader: key => { + Object.keys(Lbry.apiRequestHeaders).includes(key) && delete Lbry.apiRequestHeaders['key']; + }, // Allow overriding Lbry methods overrides: {}, setOverride: (methodName, newMethod) => { @@ -141,6 +149,7 @@ function apiCall(method: string, params: ?{}, resolve: Function, reject: Functio const counter = new Date().getTime(); const options = { method: 'POST', + headers: Lbry.apiRequestHeaders, body: JSON.stringify({ jsonrpc: '2.0', method, -- 2.45.2 From 1b98a1308270087cc1a8abac357d7f61ae35c587 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 4 Jun 2019 12:06:19 -0400 Subject: [PATCH 024/371] changes for 38 --- dist/bundle.es.js | 35 ++++++++++++++++----------------- dist/flow-typed/Claim.js | 14 +++++++++++++ dist/flow-typed/Lbry.js | 4 +++- flow-typed/Claim.js | 14 +++++++++++++ flow-typed/Lbry.js | 4 +++- src/redux/actions/claims.js | 25 +++++++++++++++-------- src/redux/reducers/file_info.js | 10 ---------- 7 files changed, 68 insertions(+), 38 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2977116..e706f2a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1975,13 +1975,22 @@ function doResolveUris(uris, returnCachedClaims = false) { // Flow has terrible Object.entries support // https://github.com/facebook/flow/issues/2221 - // $FlowFixMe - if (uriResolveInfo.error) { - resolveInfo[uri] = _extends$3({}, fallbackResolveInfo); - } else { - // $FlowFixMe - const { claim, certificate, claims_in_channel: claimsInChannel } = uriResolveInfo; - resolveInfo[uri] = { claim, certificate, claimsInChannel }; + if (uriResolveInfo) { + if (uriResolveInfo.error) { + resolveInfo[uri] = _extends$3({}, fallbackResolveInfo); + } else { + let result = {}; + if (uriResolveInfo.value_type === 'channel') { + result.certificate = uriResolveInfo; + // $FlowFixMe + result.claimsInChannel = uriResolveInfo.meta.claims_in_channel; + } else { + result.claim = uriResolveInfo; + } + + // $FlowFixMe + resolveInfo[uri] = result; + } } }); @@ -2095,7 +2104,7 @@ function doFetchClaimsByChannel(uri, page = 1) { data: { uri, page } }); - lbryProxy.claim_search({ channel_name: uri, page: page || 1, winning: true }).then(result => { + lbryProxy.claim_search({ channel: uri, controlling: true, page: page || 1 }).then(result => { const { items: claimsInChannel, page: returnedPage } = result; dispatch({ @@ -3155,16 +3164,6 @@ reducers$2[LOADING_VIDEO_FAILED] = (state, action) => { }); }; -reducers$2[FETCH_DATE] = (state, action) => { - const { time } = action.data; - if (time) { - return Object.assign({}, state, { - publishedDate: time - }); - } - return null; -}; - reducers$2[SET_FILE_LIST_SORT] = (state, action) => { const pageSortStates = { [PUBLISHED]: 'fileListPublishedSort', diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 69ac31b..0cb2167 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -44,6 +44,20 @@ declare type GenericClaim = { type: 'claim' | 'update' | 'support', valid_at_height?: number, // BUG: this should always exist https://github.com/lbryio/lbry/issues/1728 value_type: 'stream' | 'channel', + meta: { + activation_height: number, + creation_height: number, + creation_timestamp: number, + effective_amount: string, + expiration_height: number, + is_controlling: boolean, + support_amount: string, + trending_global: number, + trending_group: number, + trending_local: number, + trending_mixed: number, + claims_in_channel?: number, + }, }; declare type GenericMetadata = { diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 303de6f..d9ff6f3 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -67,7 +67,9 @@ declare type ResolveResponse = { // Keys are the url(s) passed to resolve [string]: | { error: {}, certificate: ChannelClaim, claims_in_channel: number } - | { error?: {}, claim: StreamClaim, certificate?: ChannelClaim }, + | StreamClaim + | ChannelClaim + | { error?: {} }, }; declare type GetResponse = FileListItem; diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 69ac31b..0cb2167 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -44,6 +44,20 @@ declare type GenericClaim = { type: 'claim' | 'update' | 'support', valid_at_height?: number, // BUG: this should always exist https://github.com/lbryio/lbry/issues/1728 value_type: 'stream' | 'channel', + meta: { + activation_height: number, + creation_height: number, + creation_timestamp: number, + effective_amount: string, + expiration_height: number, + is_controlling: boolean, + support_amount: string, + trending_global: number, + trending_group: number, + trending_local: number, + trending_mixed: number, + claims_in_channel?: number, + }, }; declare type GenericMetadata = { diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 303de6f..d9ff6f3 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -67,7 +67,9 @@ declare type ResolveResponse = { // Keys are the url(s) passed to resolve [string]: | { error: {}, certificate: ChannelClaim, claims_in_channel: number } - | { error?: {}, claim: StreamClaim, certificate?: ChannelClaim }, + | StreamClaim + | ChannelClaim + | { error?: {} }, }; declare type GetResponse = FileListItem; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 33dd119..51c2712 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -50,13 +50,22 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = // Flow has terrible Object.entries support // https://github.com/facebook/flow/issues/2221 - // $FlowFixMe - if (uriResolveInfo.error) { - resolveInfo[uri] = { ...fallbackResolveInfo }; - } else { - // $FlowFixMe - const { claim, certificate, claims_in_channel: claimsInChannel } = uriResolveInfo; - resolveInfo[uri] = { claim, certificate, claimsInChannel }; + if (uriResolveInfo) { + if (uriResolveInfo.error) { + resolveInfo[uri] = { ...fallbackResolveInfo }; + } else { + let result = {}; + if (uriResolveInfo.value_type === 'channel') { + result.certificate = uriResolveInfo; + // $FlowFixMe + result.claimsInChannel = uriResolveInfo.meta.claims_in_channel; + } else { + result.claim = uriResolveInfo; + } + + // $FlowFixMe + resolveInfo[uri] = result; + } } }); @@ -182,7 +191,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { data: { uri, page }, }); - Lbry.claim_search({ channel_name: uri, page: page || 1, winning: true }).then( + Lbry.claim_search({ channel: uri, controlling: true, page: page || 1 }).then( (result: ClaimSearchResponse) => { const { items: claimsInChannel, page: returnedPage } = result; diff --git a/src/redux/reducers/file_info.js b/src/redux/reducers/file_info.js index 1d9f950..dbc5e86 100644 --- a/src/redux/reducers/file_info.js +++ b/src/redux/reducers/file_info.js @@ -161,16 +161,6 @@ reducers[ACTIONS.LOADING_VIDEO_FAILED] = (state, action) => { }); }; -reducers[ACTIONS.FETCH_DATE] = (state, action) => { - const { time } = action.data; - if (time) { - return Object.assign({}, state, { - publishedDate: time, - }); - } - return null; -}; - reducers[ACTIONS.SET_FILE_LIST_SORT] = (state, action) => { const pageSortStates = { [PAGES.PUBLISHED]: 'fileListPublishedSort', -- 2.45.2 From 5c8d3b414301f36e3af246e8093b988e3e81aa2f Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 6 Jun 2019 12:02:43 -0400 Subject: [PATCH 025/371] fix: crash on blank title --- dist/bundle.es.js | 10 ++++++---- src/redux/selectors/file_info.js | 10 ++++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e706f2a..96257e9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2270,10 +2270,12 @@ const selectSearchDownloadUris = query => reselect.createSelector(selectFileInfo return; } - const titleParts = title.toLowerCase().split(' '); - if (arrayContainsQueryPart(titleParts)) { - downloadResultsFromQuery.push(fileInfo); - return; + if (title) { + const titleParts = title.toLowerCase().split(' '); + if (arrayContainsQueryPart(titleParts)) { + downloadResultsFromQuery.push(fileInfo); + return; + } } if (author) { diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index ab941ea..4718cd8 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -164,10 +164,12 @@ export const selectSearchDownloadUris = query => return; } - const titleParts = title.toLowerCase().split(' '); - if (arrayContainsQueryPart(titleParts)) { - downloadResultsFromQuery.push(fileInfo); - return; + if (title) { + const titleParts = title.toLowerCase().split(' '); + if (arrayContainsQueryPart(titleParts)) { + downloadResultsFromQuery.push(fileInfo); + return; + } } if (author) { -- 2.45.2 From b419a1bfa9a5833083b2a587eaad0672100d9e87 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 6 Jun 2019 17:37:36 -0400 Subject: [PATCH 026/371] fix: more 38 changes Fixed resolving by signed_channel, order for claim search and timestamp to use release date / creation date (to match sorting). We'll probably want to show updated_date somewhere in advanced section eventually. Needs some flow love --- dist/bundle.es.js | 48 +++++++++++++++------------ dist/flow-typed/Claim.js | 36 ++++++++------------- dist/flow-typed/Lbry.js | 13 ++++---- flow-typed/Claim.js | 36 ++++++++------------- flow-typed/Lbry.js | 13 ++++---- src/redux/actions/claims.js | 22 +++++++------ src/redux/reducers/claims.js | 61 ++++++++++++++++++----------------- src/redux/selectors/claims.js | 6 ++-- src/util/claim.js | 2 +- 9 files changed, 114 insertions(+), 123 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 96257e9..1e03922 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1269,7 +1269,7 @@ const makeSelectMetadataItemForUri = (uri, key) => reselect.createSelector(makeS const makeSelectTitleForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); const makeSelectDateForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { - const timestamp = claim && claim.timestamp ? claim.timestamp * 1000 : undefined; + const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.value.meta.creation_timestamp * 1000); if (!timestamp) { return undefined; } @@ -1968,9 +1968,9 @@ function doResolveUris(uris, returnCachedClaims = false) { lbryProxy.resolve({ urls: urisToResolve }).then(result => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { - claim: null, + stream: null, claimsInChannel: null, - certificate: null + channel: null }; // Flow has terrible Object.entries support @@ -1981,11 +1981,15 @@ function doResolveUris(uris, returnCachedClaims = false) { } else { let result = {}; if (uriResolveInfo.value_type === 'channel') { - result.certificate = uriResolveInfo; + result.channel = uriResolveInfo; // $FlowFixMe result.claimsInChannel = uriResolveInfo.meta.claims_in_channel; } else { - result.claim = uriResolveInfo; + result.stream = uriResolveInfo; + if (uriResolveInfo.signing_channel) { + result.channel = uriResolveInfo.signing_channel; + result.claimsInChannel = uriResolveInfo.signing_channel.meta.claims_in_channel; + } } // $FlowFixMe @@ -2104,7 +2108,7 @@ function doFetchClaimsByChannel(uri, page = 1) { data: { uri, page } }); - lbryProxy.claim_search({ channel: uri, controlling: true, page: page || 1 }).then(result => { + lbryProxy.claim_search({ channel: uri, is_controlling: true, page: page || 1, order_by: ['release_time'] }).then(result => { const { items: claimsInChannel, page: returnedPage } = result; dispatch({ @@ -2708,34 +2712,36 @@ const defaultState = { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - const { resolveInfo } = action.data; + const { + resolveInfo + } = action.data; const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); Object.entries(resolveInfo).forEach(([uri, resolveResponse]) => { // $FlowFixMe - if (resolveResponse.certificate && !Number.isNaN(resolveResponse.claimsInChannel)) { + if (resolveResponse.claimsInChannel) { // $FlowFixMe channelClaimCounts[uri] = resolveResponse.claimsInChannel; } }); // $FlowFixMe - Object.entries(resolveInfo).forEach(([uri, { certificate, claim }]) => { - if (claim && !certificate) { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; - } else if (claim && certificate) { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; + Object.entries(resolveInfo).forEach(([uri, { channel, stream }]) => { + if (stream && !channel) { + byId[stream.claim_id] = stream; + byUri[uri] = stream.claim_id; + } else if (stream && channel) { + byId[stream.claim_id] = stream; + byUri[uri] = stream.claim_id; - byId[certificate.claim_id] = certificate; - const channelUri = `lbry://${certificate.name}#${certificate.claim_id}`; - byUri[channelUri] = certificate.claim_id; - } else if (!claim && certificate) { - byId[certificate.claim_id] = certificate; - byUri[uri] = certificate.claim_id; + byId[channel.claim_id] = channel; + const channelUri = channel.permanent_url; + byUri[channelUri] = channel.claim_id; + } else if (!stream && channel) { + byId[channel.claim_id] = channel; + byUri[uri] = channel.claim_id; } else { byUri[uri] = null; } diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 0cb2167..e8744f5 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -1,51 +1,41 @@ // @flow -declare type ClaimWithPossibleCertificate = { - certificate?: ChannelClaim, - claim: StreamClaim, -}; +declare type Claim = StreamClaim | ChannelClaim; declare type ChannelClaim = GenericClaim & { + is_channel_signature_valid?: boolean, // we may have signed channels in the future, fixes some flow issues for now. + signing_channel?: ChannelMetadata, value: ChannelMetadata, }; declare type StreamClaim = GenericClaim & { is_channel_signature_valid?: boolean, - signing_channel?: { - claim_id: string, - name: string, - value: { - public_key: string, - }, - }, + signing_channel?: ChannelMetadata, value: StreamMetadata, }; declare type GenericClaim = { address: string, // address associated with tx - amount: number, // bid amount at time of tx + amount: string, // bid amount at time of tx + canonical_url: string, // URL with short id, includes channel with short id claim_id: string, // unique claim identifier - claim_sequence: number, + claim_sequence: number, // not being used currently claim_op: 'create' | 'update', - confirmations: number, // This isn't the most stable atm: https://github.com/lbryio/lbry/issues/2000 - decoded_claim: boolean, // claim made in accordance with sdk protobuf types - effective_amount: number, // bid amount + supports - timestamp?: number, // date of transaction - has_signature: boolean, + confirmations: number, + decoded_claim: boolean, // Not available currently https://github.com/lbryio/lbry/issues/2044 + timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed - hex: string, // `value` hex encoded name: string, - channel_name?: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx permanent_url: string, // name + claim_id - supports: Array<{}>, // TODO: add support type once we start using it + short_url: string, // permanent_url with short id, no channel txid: string, // unique tx id type: 'claim' | 'update' | 'support', - valid_at_height?: number, // BUG: this should always exist https://github.com/lbryio/lbry/issues/1728 value_type: 'stream' | 'channel', meta: { activation_height: number, + claims_in_channel?: number, creation_height: number, creation_timestamp: number, effective_amount: string, @@ -56,7 +46,6 @@ declare type GenericClaim = { trending_group: number, trending_local: number, trending_mixed: number, - claims_in_channel?: number, }, }; @@ -73,6 +62,7 @@ declare type GenericMetadata = { declare type ChannelMetadata = GenericMetadata & { public_key: string, + public_key_id: string, cover_url?: string, email?: string, website_url?: string, diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index d9ff6f3..dae9168 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -66,9 +66,7 @@ declare type VersionResponse = { declare type ResolveResponse = { // Keys are the url(s) passed to resolve [string]: - | { error: {}, certificate: ChannelClaim, claims_in_channel: number } - | StreamClaim - | ChannelClaim + | Claim | { error?: {} }, }; @@ -88,18 +86,19 @@ declare type GenericTxResponse = { declare type PublishResponse = GenericTxResponse & { // Only first value in outputs is a claim // That's the only value we care about - outputs: Array, + outputs: Array, }; declare type ClaimSearchResponse = { - items: Array, + items: Array, page: number, page_size: number, - page_number: number, + total_items: number, + total_pages: number, }; declare type ClaimListResponse = { - claims: Array, + claims: Array, }; declare type ChannelCreateResponse = GenericTxResponse & { diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 0cb2167..e8744f5 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -1,51 +1,41 @@ // @flow -declare type ClaimWithPossibleCertificate = { - certificate?: ChannelClaim, - claim: StreamClaim, -}; +declare type Claim = StreamClaim | ChannelClaim; declare type ChannelClaim = GenericClaim & { + is_channel_signature_valid?: boolean, // we may have signed channels in the future, fixes some flow issues for now. + signing_channel?: ChannelMetadata, value: ChannelMetadata, }; declare type StreamClaim = GenericClaim & { is_channel_signature_valid?: boolean, - signing_channel?: { - claim_id: string, - name: string, - value: { - public_key: string, - }, - }, + signing_channel?: ChannelMetadata, value: StreamMetadata, }; declare type GenericClaim = { address: string, // address associated with tx - amount: number, // bid amount at time of tx + amount: string, // bid amount at time of tx + canonical_url: string, // URL with short id, includes channel with short id claim_id: string, // unique claim identifier - claim_sequence: number, + claim_sequence: number, // not being used currently claim_op: 'create' | 'update', - confirmations: number, // This isn't the most stable atm: https://github.com/lbryio/lbry/issues/2000 - decoded_claim: boolean, // claim made in accordance with sdk protobuf types - effective_amount: number, // bid amount + supports - timestamp?: number, // date of transaction - has_signature: boolean, + confirmations: number, + decoded_claim: boolean, // Not available currently https://github.com/lbryio/lbry/issues/2044 + timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed - hex: string, // `value` hex encoded name: string, - channel_name?: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx permanent_url: string, // name + claim_id - supports: Array<{}>, // TODO: add support type once we start using it + short_url: string, // permanent_url with short id, no channel txid: string, // unique tx id type: 'claim' | 'update' | 'support', - valid_at_height?: number, // BUG: this should always exist https://github.com/lbryio/lbry/issues/1728 value_type: 'stream' | 'channel', meta: { activation_height: number, + claims_in_channel?: number, creation_height: number, creation_timestamp: number, effective_amount: string, @@ -56,7 +46,6 @@ declare type GenericClaim = { trending_group: number, trending_local: number, trending_mixed: number, - claims_in_channel?: number, }, }; @@ -73,6 +62,7 @@ declare type GenericMetadata = { declare type ChannelMetadata = GenericMetadata & { public_key: string, + public_key_id: string, cover_url?: string, email?: string, website_url?: string, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index d9ff6f3..dae9168 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -66,9 +66,7 @@ declare type VersionResponse = { declare type ResolveResponse = { // Keys are the url(s) passed to resolve [string]: - | { error: {}, certificate: ChannelClaim, claims_in_channel: number } - | StreamClaim - | ChannelClaim + | Claim | { error?: {} }, }; @@ -88,18 +86,19 @@ declare type GenericTxResponse = { declare type PublishResponse = GenericTxResponse & { // Only first value in outputs is a claim // That's the only value we care about - outputs: Array, + outputs: Array, }; declare type ClaimSearchResponse = { - items: Array, + items: Array, page: number, page_size: number, - page_number: number, + total_items: number, + total_pages: number, }; declare type ClaimListResponse = { - claims: Array, + claims: Array, }; declare type ChannelCreateResponse = GenericTxResponse & { diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 51c2712..d7a0ff9 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -34,8 +34,8 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = const resolveInfo: { [string]: { - claim: ?StreamClaim, - certificate: ?ChannelClaim, + stream: ?StreamClaim, + channel: ?ChannelClaim, claimsInChannel: ?number, }, } = {}; @@ -43,9 +43,9 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = Lbry.resolve({ urls: urisToResolve }).then((result: ResolveResponse) => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { - claim: null, + stream: null, claimsInChannel: null, - certificate: null, + channel: null, }; // Flow has terrible Object.entries support @@ -55,12 +55,16 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = resolveInfo[uri] = { ...fallbackResolveInfo }; } else { let result = {}; - if (uriResolveInfo.value_type === 'channel') { - result.certificate = uriResolveInfo; + if (uriResolveInfo.value_type === 'channel' ) { + result.channel = uriResolveInfo; // $FlowFixMe result.claimsInChannel = uriResolveInfo.meta.claims_in_channel; } else { - result.claim = uriResolveInfo; + result.stream = uriResolveInfo; + if (uriResolveInfo.signing_channel) { + result.channel = uriResolveInfo.signing_channel; + result.claimsInChannel = uriResolveInfo.signing_channel.meta.claims_in_channel; + } } // $FlowFixMe @@ -103,7 +107,7 @@ export function doAbandonClaim(txid: string, nout: number) { return (dispatch: Dispatch, getState: GetState) => { const state = getState(); - const myClaims: Array = selectMyClaimsRaw(state); + const myClaims: Array = selectMyClaimsRaw(state); const mySupports: { [string]: Support } = selectSupportsByOutpoint(state); // A user could be trying to abandon a support or one of their claims @@ -191,7 +195,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { data: { uri, page }, }); - Lbry.claim_search({ channel: uri, controlling: true, page: page || 1 }).then( + Lbry.claim_search({ channel: uri, is_controlling: true, page: page || 1, order_by: ['release_time'] }).then( (result: ClaimSearchResponse) => { const { items: claimsInChannel, page: returnedPage } = result; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index b4a81e9..59fb1b9 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -14,9 +14,9 @@ import { buildURI, parseURI } from 'lbryURI'; type State = { channelClaimCounts: { [string]: number }, claimsByUri: { [string]: string }, - byId: { [string]: StreamClaim | ChannelClaim }, + byId: { [string]: Claim }, resolvingUris: Array, - pendingById: { [string]: StreamClaim | ChannelClaim }, + pendingById: { [string]: Claim }, myChannelClaims: Set, abandoningById: { [string]: boolean }, fetchingChannelClaims: { [string]: number }, @@ -46,36 +46,42 @@ const defaultState = { }; reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => { - const { resolveInfo }: { [string]: ClaimWithPossibleCertificate } = action.data; + const { + resolveInfo, + }: { + [string]: { + stream: ?StreamClaim, + channel: ?ChannelClaim, + claimsInChannel: ?number, + }, + } = action.data; const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - Object.entries(resolveInfo).forEach( - ([uri: string, resolveResponse: ClaimWithPossibleCertificate]) => { + Object.entries(resolveInfo).forEach(([uri: string, resolveResponse: Claim]) => { + // $FlowFixMe + if (resolveResponse.claimsInChannel) { // $FlowFixMe - if (resolveResponse.certificate && !Number.isNaN(resolveResponse.claimsInChannel)) { - // $FlowFixMe - channelClaimCounts[uri] = resolveResponse.claimsInChannel; - } + channelClaimCounts[uri] = resolveResponse.claimsInChannel; } - ); + }); // $FlowFixMe - Object.entries(resolveInfo).forEach(([uri, { certificate, claim }]) => { - if (claim && !certificate) { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; - } else if (claim && certificate) { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; + Object.entries(resolveInfo).forEach(([uri, { channel, stream }]) => { + if (stream && !channel) { + byId[stream.claim_id] = stream; + byUri[uri] = stream.claim_id; + } else if (stream && channel) { + byId[stream.claim_id] = stream; + byUri[uri] = stream.claim_id; - byId[certificate.claim_id] = certificate; - const channelUri = `lbry://${certificate.name}#${certificate.claim_id}`; - byUri[channelUri] = certificate.claim_id; - } else if (!claim && certificate) { - byId[certificate.claim_id] = certificate; - byUri[uri] = certificate.claim_id; + byId[channel.claim_id] = channel; + const channelUri = channel.permanent_url; + byUri[channelUri] = channel.claim_id; + } else if (!stream && channel) { + byId[channel.claim_id] = channel; + byUri[uri] = channel.claim_id; } else { byUri[uri] = null; } @@ -95,15 +101,12 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State => }); reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): State => { - const { claims }: { claims: Array } = action.data; + const { claims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById: { [string]: StreamClaim | ChannelClaim } = Object.assign( - {}, - state.pendingById - ); + const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); - claims.forEach((claim: StreamClaim | ChannelClaim) => { + claims.forEach((claim: Claim) => { const uri = buildURI({ claimName: claim.name, claimId: claim.claim_id }); if (claim.type && claim.type.match(/claim|update/)) { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 7a1808f..da48735 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -190,7 +190,7 @@ export const makeSelectDateForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), claim => { - const timestamp = claim && claim.timestamp ? claim.timestamp * 1000 : undefined; + const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.value.meta.creation_timestamp * 1000); if (!timestamp) { return undefined; } @@ -368,7 +368,7 @@ export const makeSelectClaimIsNsfw = (uri: string): boolean => // Or possibly come from users settings of what tags they want to hide // For now, there is just a hard coded list of tags inside `isClaimNsfw` // selectNaughtyTags(), - (claim: StreamClaim) => { + (claim: Claim) => { if (!claim) { return false; } @@ -418,7 +418,7 @@ export const makeSelectFirstRecommendedFileForUri = (uri: string) => export const makeSelectChannelForClaimUri = (uri: string, includePrefix: boolean = false) => createSelector( makeSelectClaimForUri(uri), - (claim: ?StreamClaim) => { + (claim: ?Claim) => { if (!claim || !claim.signing_channel) { return null; } diff --git a/src/util/claim.js b/src/util/claim.js index 0e56ce3..73adb7a 100644 --- a/src/util/claim.js +++ b/src/util/claim.js @@ -5,7 +5,7 @@ const naughtyTags = ['porn', 'nsfw', 'mature', 'xxx'].reduce( {} ); -export const isClaimNsfw = (claim: StreamClaim): boolean => { +export const isClaimNsfw = (claim: Claim): boolean => { if (!claim) { throw new Error('No claim passed to isClaimNsfw()'); } -- 2.45.2 From 85c24ae37d09666d19c238be33ee836476e62a2b Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Fri, 7 Jun 2019 13:16:50 -0400 Subject: [PATCH 027/371] fix: sorting param It's claim.meta, not claim.value.meta. --- 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 1e03922..15984e3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1269,7 +1269,7 @@ const makeSelectMetadataItemForUri = (uri, key) => reselect.createSelector(makeS const makeSelectTitleForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); const makeSelectDateForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { - const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.value.meta.creation_timestamp * 1000); + const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta.creation_timestamp * 1000); if (!timestamp) { return undefined; } diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index da48735..7abe3c8 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -190,7 +190,7 @@ export const makeSelectDateForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), claim => { - const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.value.meta.creation_timestamp * 1000); + const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta.creation_timestamp * 1000); if (!timestamp) { return undefined; } -- 2.45.2 From 50d1b166f50ca7db8e23832917c45542a26888e2 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Sun, 9 Jun 2019 21:25:55 -0400 Subject: [PATCH 028/371] simplify claims resolve reducer --- flow-typed/Claim.js | 4 ++-- src/redux/actions/claims.js | 34 +++++++++++++++++++--------------- src/redux/reducers/claims.js | 17 ++++++----------- src/redux/selectors/claims.js | 9 +++++++-- 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index e8744f5..f18b128 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -4,13 +4,13 @@ declare type Claim = StreamClaim | ChannelClaim; declare type ChannelClaim = GenericClaim & { is_channel_signature_valid?: boolean, // we may have signed channels in the future, fixes some flow issues for now. - signing_channel?: ChannelMetadata, + signing_channel?: ChannelClaim, value: ChannelMetadata, }; declare type StreamClaim = GenericClaim & { is_channel_signature_valid?: boolean, - signing_channel?: ChannelMetadata, + signing_channel?: ChannelClaim, value: StreamMetadata, }; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index d7a0ff9..3cbffcd 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -55,7 +55,7 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = resolveInfo[uri] = { ...fallbackResolveInfo }; } else { let result = {}; - if (uriResolveInfo.value_type === 'channel' ) { + if (uriResolveInfo.value_type === 'channel') { result.channel = uriResolveInfo; // $FlowFixMe result.claimsInChannel = uriResolveInfo.meta.claims_in_channel; @@ -63,7 +63,8 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = result.stream = uriResolveInfo; if (uriResolveInfo.signing_channel) { result.channel = uriResolveInfo.signing_channel; - result.claimsInChannel = uriResolveInfo.signing_channel.meta.claims_in_channel; + result.claimsInChannel = + (uriResolveInfo.meta && uriResolveInfo.meta.claims_in_channel) || 0; } } @@ -195,20 +196,23 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { data: { uri, page }, }); - Lbry.claim_search({ channel: uri, is_controlling: true, page: page || 1, order_by: ['release_time'] }).then( - (result: ClaimSearchResponse) => { - const { items: claimsInChannel, page: returnedPage } = result; + Lbry.claim_search({ + channel: uri, + is_controlling: true, + page: page || 1, + order_by: ['release_time'], + }).then((result: ClaimSearchResponse) => { + const { items: claimsInChannel, page: returnedPage } = result; - dispatch({ - type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, - data: { - uri, - claims: claimsInChannel || [], - page: returnedPage || undefined, - }, - }); - } - ); + dispatch({ + type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, + data: { + uri, + claims: claimsInChannel || [], + page: returnedPage || undefined, + }, + }); + }); }; } diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 59fb1b9..cd50cd6 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -69,20 +69,15 @@ reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => // $FlowFixMe Object.entries(resolveInfo).forEach(([uri, { channel, stream }]) => { - if (stream && !channel) { + if (stream) { byId[stream.claim_id] = stream; byUri[uri] = stream.claim_id; - } else if (stream && channel) { - byId[stream.claim_id] = stream; - byUri[uri] = stream.claim_id; - + } + if (channel) { byId[channel.claim_id] = channel; - const channelUri = channel.permanent_url; - byUri[channelUri] = channel.claim_id; - } else if (!stream && channel) { - byId[channel.claim_id] = channel; - byUri[uri] = channel.claim_id; - } else { + byUri[stream ? channel.permanent_url : uri] = channel.claim_id; + } + if (!stream && !channel) { byUri[uri] = null; } }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 7abe3c8..0cf4bdf 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -190,7 +190,12 @@ export const makeSelectDateForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), claim => { - const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta.creation_timestamp * 1000); + const timestamp = + claim && + claim.value && + (claim.value.release_time + ? claim.value.release_time * 1000 + : claim.meta.creation_timestamp * 1000); if (!timestamp) { return undefined; } @@ -418,7 +423,7 @@ export const makeSelectFirstRecommendedFileForUri = (uri: string) => export const makeSelectChannelForClaimUri = (uri: string, includePrefix: boolean = false) => createSelector( makeSelectClaimForUri(uri), - (claim: ?Claim) => { + (claim: ?StreamClaim) => { if (!claim || !claim.signing_channel) { return null; } -- 2.45.2 From c73ea0094179dfe3a2e5385ea03d771367e02d97 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 11 Jun 2019 12:22:44 -0400 Subject: [PATCH 029/371] fix: controlling and channel claim count meta Controlling means controlling claims, not channels. Added so we only return claims with valid signatures (safer for now, can add options to show invalid later). Also, the claim count in channel is in the signed channel meta object, not the high level one. --- dist/bundle.es.js | 26 +++++++++++++------------- dist/flow-typed/Claim.js | 4 ++-- src/redux/actions/claims.js | 6 ++++-- 3 files changed, 19 insertions(+), 17 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 87cf4e4..536e4f0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1997,7 +1997,7 @@ function doResolveUris(uris, returnCachedClaims = false) { result.stream = uriResolveInfo; if (uriResolveInfo.signing_channel) { result.channel = uriResolveInfo.signing_channel; - result.claimsInChannel = uriResolveInfo.signing_channel.meta.claims_in_channel; + result.claimsInChannel = uriResolveInfo.signing_channel.meta && uriResolveInfo.signing_channel.meta.claims_in_channel || 0; } } @@ -2117,7 +2117,12 @@ function doFetchClaimsByChannel(uri, page = 1) { data: { uri, page } }); - lbryProxy.claim_search({ channel: uri, is_controlling: true, page: page || 1, order_by: ['release_time'] }).then(result => { + lbryProxy.claim_search({ + channel: uri, + valid_channel_signatures: true, + page: page || 1, + order_by: ['release_time'] + }).then(result => { const { items: claimsInChannel, page: returnedPage } = result; dispatch({ @@ -2738,20 +2743,15 @@ reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { // $FlowFixMe Object.entries(resolveInfo).forEach(([uri, { channel, stream }]) => { - if (stream && !channel) { + if (stream) { byId[stream.claim_id] = stream; byUri[uri] = stream.claim_id; - } else if (stream && channel) { - byId[stream.claim_id] = stream; - byUri[uri] = stream.claim_id; - + } + if (channel) { byId[channel.claim_id] = channel; - const channelUri = channel.permanent_url; - byUri[channelUri] = channel.claim_id; - } else if (!stream && channel) { - byId[channel.claim_id] = channel; - byUri[uri] = channel.claim_id; - } else { + byUri[stream ? channel.permanent_url : uri] = channel.claim_id; + } + if (!stream && !channel) { byUri[uri] = null; } }); diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index e8744f5..f18b128 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -4,13 +4,13 @@ declare type Claim = StreamClaim | ChannelClaim; declare type ChannelClaim = GenericClaim & { is_channel_signature_valid?: boolean, // we may have signed channels in the future, fixes some flow issues for now. - signing_channel?: ChannelMetadata, + signing_channel?: ChannelClaim, value: ChannelMetadata, }; declare type StreamClaim = GenericClaim & { is_channel_signature_valid?: boolean, - signing_channel?: ChannelMetadata, + signing_channel?: ChannelClaim, value: StreamMetadata, }; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 3cbffcd..5248309 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -64,7 +64,9 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = if (uriResolveInfo.signing_channel) { result.channel = uriResolveInfo.signing_channel; result.claimsInChannel = - (uriResolveInfo.meta && uriResolveInfo.meta.claims_in_channel) || 0; + (uriResolveInfo.signing_channel.meta && + uriResolveInfo.signing_channel.meta.claims_in_channel) || + 0; } } @@ -198,7 +200,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { Lbry.claim_search({ channel: uri, - is_controlling: true, + valid_channel_signatures: true, page: page || 1, order_by: ['release_time'], }).then((result: ClaimSearchResponse) => { -- 2.45.2 From 8fba180923d5bf8c45ad98a82fa99db5f1d75d78 Mon Sep 17 00:00:00 2001 From: zxawry Date: Wed, 12 Jun 2019 15:30:08 +0100 Subject: [PATCH 030/371] set correct suggestion type for lbry URIs --- src/redux/selectors/search.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index b519425..e2f1c1a 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -57,20 +57,21 @@ export const selectSearchSuggestions: Array = createSelector( return []; } - const queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://'; + const queryIsPrefix = + query === 'lbry:' || query === 'lbry:/' || query === 'lbry://' || query === 'lbry://@'; - if (query.startsWith('lbry://') && query !== 'lbry://') { + if (queryIsPrefix) { + // If it is a prefix, wait until something else comes to figure out what to do + return []; + } else if (query.startsWith('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, + type: query[7] === '@' ? SEARCH_TYPES.CHANNEL : 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 = []; -- 2.45.2 From f435dc4600e0aa03a22f49d4f0a70cb9f85afc57 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 18 Jun 2019 12:59:04 -0400 Subject: [PATCH 031/371] update build --- dist/bundle.es.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 536e4f0..b2f04b7 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1044,18 +1044,18 @@ const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selec return []; } - const queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://'; + const queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://' || query === 'lbry://@'; - if (query.startsWith('lbry://') && query !== 'lbry://') { + if (queryIsPrefix) { + // If it is a prefix, wait until something else comes to figure out what to do + return []; + } else if (query.startsWith('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 + type: query[7] === '@' ? SEARCH_TYPES.CHANNEL : 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 = []; -- 2.45.2 From a22d0270d08cc87f647bdc6eae61a14ff5bba2aa Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Sun, 9 Jun 2019 22:45:47 -0400 Subject: [PATCH 032/371] add tags --- .eslintrc.json | 1 + dist/bundle.es.js | 453 +++++++++++++++++++++++-------- dist/flow-typed/Tags.js | 30 ++ flow-typed/Claim.js | 3 +- flow-typed/Tags.js | 30 ++ src/constants/action_types.js | 25 +- src/constants/tags.js | 21 ++ src/index.js | 12 + src/redux/actions/claims.js | 47 +++- src/redux/actions/tags.js | 51 ++++ src/redux/reducers/claims.js | 20 +- src/redux/reducers/tags.js | 84 ++++++ src/redux/selectors/claims.js | 8 + src/redux/selectors/file_info.js | 6 + src/redux/selectors/tags.js | 47 ++++ 15 files changed, 705 insertions(+), 133 deletions(-) create mode 100644 dist/flow-typed/Tags.js create mode 100644 flow-typed/Tags.js create mode 100644 src/constants/tags.js create mode 100644 src/redux/actions/tags.js create mode 100644 src/redux/reducers/tags.js create mode 100644 src/redux/selectors/tags.js diff --git a/.eslintrc.json b/.eslintrc.json index 9ac4855..1860ea4 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -10,6 +10,7 @@ "__": true }, "rules": { + "camelcase": 0, "no-multi-spaces": 0, "new-cap": 0, "prefer-promise-reject-errors": 0, diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b2f04b7..129ae72 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -98,6 +98,9 @@ const SET_CONTENT_POSITION = 'SET_CONTENT_POSITION'; const SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED'; const CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI'; const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL'; +const CLAIM_SEARCH_STARTED = 'CLAIM_SEARCH_STARTED'; +const CLAIM_SEARCH_COMPLETED = 'CLAIM_SEARCH_COMPLETED'; +const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; // Files const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; @@ -187,21 +190,6 @@ const FETCH_REWARD_CONTENT_COMPLETED = 'FETCH_REWARD_CONTENT_COMPLETED'; const DOWNLOAD_LANGUAGE_SUCCEEDED = 'DOWNLOAD_LANGUAGE_SUCCEEDED'; const DOWNLOAD_LANGUAGE_FAILED = 'DOWNLOAD_LANGUAGE_FAILED'; -// ShapeShift -const GET_SUPPORTED_COINS_START = 'GET_SUPPORTED_COINS_START'; -const GET_SUPPORTED_COINS_SUCCESS = 'GET_SUPPORTED_COINS_SUCCESS'; -const GET_SUPPORTED_COINS_FAIL = 'GET_SUPPORTED_COINS_FAIL'; -const GET_COIN_STATS_START = 'GET_COIN_STATS_START'; -const GET_COIN_STATS_SUCCESS = 'GET_COIN_STATS_SUCCESS'; -const GET_COIN_STATS_FAIL = 'GET_COIN_STATS_FAIL'; -const PREPARE_SHAPE_SHIFT_START = 'PREPARE_SHAPE_SHIFT_START'; -const PREPARE_SHAPE_SHIFT_SUCCESS = 'PREPARE_SHAPE_SHIFT_SUCCESS'; -const PREPARE_SHAPE_SHIFT_FAIL = 'PREPARE_SHAPE_SHIFT_FAIL'; -const GET_ACTIVE_SHIFT_START = 'GET_ACTIVE_SHIFT_START'; -const GET_ACTIVE_SHIFT_SUCCESS = 'GET_ACTIVE_SHIFT_SUCCESS'; -const GET_ACTIVE_SHIFT_FAIL = 'GET_ACTIVE_SHIFT_FAIL'; -const CLEAR_SHAPE_SHIFT = 'CLEAR_SHAPE_SHIFT'; - // Subscriptions const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE'; const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE'; @@ -239,6 +227,13 @@ const FETCH_DATE = 'FETCH_DATE'; const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'; const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'; const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; +// Tags +const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; +const TAG_ADD = 'TAG_ADD'; +const TAG_DELETE = 'TAG_DELETE'; +const FETCH_TRENDING_STARTED = 'FETCH_TRENDING_STARTED'; +const FETCH_TRENDING_COMPLETED = 'FETCH_TRENDING_COMPLETED'; +const FETCH_TRENDING_FAILED = 'FETCH_TRENDING_FAILED'; var action_types = /*#__PURE__*/Object.freeze({ WINDOW_FOCUSED: WINDOW_FOCUSED, @@ -323,6 +318,9 @@ var action_types = /*#__PURE__*/Object.freeze({ SET_CONTENT_LAST_VIEWED: SET_CONTENT_LAST_VIEWED, CLEAR_CONTENT_HISTORY_URI: CLEAR_CONTENT_HISTORY_URI, CLEAR_CONTENT_HISTORY_ALL: CLEAR_CONTENT_HISTORY_ALL, + CLAIM_SEARCH_STARTED: CLAIM_SEARCH_STARTED, + CLAIM_SEARCH_COMPLETED: CLAIM_SEARCH_COMPLETED, + CLAIM_SEARCH_FAILED: CLAIM_SEARCH_FAILED, FILE_LIST_STARTED: FILE_LIST_STARTED, FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, @@ -399,19 +397,6 @@ var action_types = /*#__PURE__*/Object.freeze({ FETCH_REWARD_CONTENT_COMPLETED: FETCH_REWARD_CONTENT_COMPLETED, DOWNLOAD_LANGUAGE_SUCCEEDED: DOWNLOAD_LANGUAGE_SUCCEEDED, DOWNLOAD_LANGUAGE_FAILED: DOWNLOAD_LANGUAGE_FAILED, - GET_SUPPORTED_COINS_START: GET_SUPPORTED_COINS_START, - GET_SUPPORTED_COINS_SUCCESS: GET_SUPPORTED_COINS_SUCCESS, - GET_SUPPORTED_COINS_FAIL: GET_SUPPORTED_COINS_FAIL, - GET_COIN_STATS_START: GET_COIN_STATS_START, - GET_COIN_STATS_SUCCESS: GET_COIN_STATS_SUCCESS, - GET_COIN_STATS_FAIL: GET_COIN_STATS_FAIL, - PREPARE_SHAPE_SHIFT_START: PREPARE_SHAPE_SHIFT_START, - PREPARE_SHAPE_SHIFT_SUCCESS: PREPARE_SHAPE_SHIFT_SUCCESS, - PREPARE_SHAPE_SHIFT_FAIL: PREPARE_SHAPE_SHIFT_FAIL, - GET_ACTIVE_SHIFT_START: GET_ACTIVE_SHIFT_START, - GET_ACTIVE_SHIFT_SUCCESS: GET_ACTIVE_SHIFT_SUCCESS, - GET_ACTIVE_SHIFT_FAIL: GET_ACTIVE_SHIFT_FAIL, - CLEAR_SHAPE_SHIFT: CLEAR_SHAPE_SHIFT, CHANNEL_SUBSCRIBE: CHANNEL_SUBSCRIBE, CHANNEL_UNSUBSCRIBE: CHANNEL_UNSUBSCRIBE, HAS_FETCHED_SUBSCRIPTIONS: HAS_FETCHED_SUBSCRIPTIONS, @@ -440,7 +425,13 @@ var action_types = /*#__PURE__*/Object.freeze({ FETCH_DATE: FETCH_DATE, FETCH_COST_INFO_STARTED: FETCH_COST_INFO_STARTED, FETCH_COST_INFO_COMPLETED: FETCH_COST_INFO_COMPLETED, - FETCH_COST_INFO_FAILED: FETCH_COST_INFO_FAILED + FETCH_COST_INFO_FAILED: FETCH_COST_INFO_FAILED, + TOGGLE_TAG_FOLLOW: TOGGLE_TAG_FOLLOW, + TAG_ADD: TAG_ADD, + TAG_DELETE: TAG_DELETE, + FETCH_TRENDING_STARTED: FETCH_TRENDING_STARTED, + FETCH_TRENDING_COMPLETED: FETCH_TRENDING_COMPLETED, + FETCH_TRENDING_FAILED: FETCH_TRENDING_FAILED }); const API_DOWN = 'apiDown'; @@ -1428,6 +1419,10 @@ const makeSelectChannelForClaimUri = (uri, includePrefix = false) => reselect.cr return includePrefix ? `lbry://${channel}` : channel; }); +const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => { + return metadata && metadata.tags || []; +}); + const selectState$2 = state => state.wallet || {}; const selectWalletState = selectState$2; @@ -1946,6 +1941,14 @@ function doUpdateBlockHeight() { }); } +// https://github.com/reactjs/redux/issues/911 +function batchActions(...actions) { + return { + type: 'BATCH_ACTIONS', + actions + }; +} + 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) { @@ -1997,10 +2000,13 @@ function doResolveUris(uris, returnCachedClaims = false) { result.stream = uriResolveInfo; if (uriResolveInfo.signing_channel) { result.channel = uriResolveInfo.signing_channel; +<<<<<<< HEAD result.claimsInChannel = uriResolveInfo.signing_channel.meta && uriResolveInfo.signing_channel.meta.claims_in_channel || 0; +======= + result.claimsInChannel = uriResolveInfo.meta && uriResolveInfo.meta.claims_in_channel || 0; +>>>>>>> add tags } } - // $FlowFixMe resolveInfo[uri] = result; } @@ -2119,7 +2125,11 @@ function doFetchClaimsByChannel(uri, page = 1) { lbryProxy.claim_search({ channel: uri, +<<<<<<< HEAD valid_channel_signatures: true, +======= + is_controlling: true, +>>>>>>> add tags page: page || 1, order_by: ['release_time'] }).then(result => { @@ -2181,6 +2191,46 @@ function doFetchChannelListMine() { }; } +function doClaimSearch(amount = 20, options = {}, cb) { + return dispatch => { + dispatch({ + type: CLAIM_SEARCH_STARTED + }); + + 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_COMPLETED, + data: { resolveInfo } + }); + + if (cb) { + cb(null, uris); + } + }; + + const failure = err => { + dispatch({ + type: CLAIM_SEARCH_FAILED, + error: err + }); + if (cb) { + cb(err); + } + }; + + lbryProxy.claim_search(_extends$3({ + page_size: amount + }, options)).then(success, failure); + }; +} + const selectState$3 = state => state.fileInfo || {}; const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); @@ -2344,6 +2394,10 @@ const selectFileListPublishedSort = reselect.createSelector(selectState$3, state const selectFileListDownloadedSort = reselect.createSelector(selectState$3, state => state.fileListDownloadedSort); +const selectDownloadedUris = reselect.createSelector(selectFileInfosDownloaded, +// We should use permament_url but it doesn't exist in file_list +info => info.map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)); + // const selectState$4 = state => state.file || {}; @@ -2522,14 +2576,6 @@ function doSetFileListSort(page, value) { }; } -// https://github.com/reactjs/redux/issues/911 -function batchActions(...actions) { - return { - type: 'BATCH_ACTIONS', - actions - }; -} - // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the @@ -2709,6 +2755,55 @@ function savePosition(claimId, outpoint, position) { // +const doToggleTagFollow = name => ({ + type: TOGGLE_TAG_FOLLOW, + data: { + name + } +}); + +const doAddTag = name => ({ + type: TAG_ADD, + data: { + name + } +}); + +const doDeleteTag = name => ({ + type: TAG_DELETE, + data: { + name + } +}); + +const doFetchByTags = (amount = 10, options = {}) => { + return dispatch => { + dispatch({ + type: FETCH_TRENDING_STARTED + }); + + const callback = (error, uris = []) => { + if (error) { + return dispatch({ + type: FETCH_TRENDING_FAILED, + error + }); + } + + dispatch({ + type: FETCH_TRENDING_COMPLETED, + data: { + uris + } + }); + }; + + dispatch(doClaimSearch(amount, options, callback)); + }; +}; + +var _extends$4 = 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; }; + const reducers = {}; const defaultState = { byId: {}, @@ -2725,7 +2820,7 @@ const defaultState = { pendingById: {} }; -reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { +function handleClaimAction(state, action) { const { resolveInfo } = action.data; @@ -2762,6 +2857,10 @@ reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { channelClaimCounts, resolvingUris: (state.resolvingUris || []).filter(uri => !resolveInfo[uri]) }); +} + +reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { + return handleClaimAction(state, action); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -2936,13 +3035,27 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }); }; +reducers[CLAIM_SEARCH_STARTED] = state => { + return Object.assign({}, state, { + fetchingClaimSearch: true + }); +}; +reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { + return _extends$4({}, handleClaimAction(state, action), { fetchingClaimSearch: false }); +}; +reducers[CLAIM_SEARCH_FAILED] = state => { + return Object.assign({}, state, { + fetchingClaimSearch: false + }); +}; + function claimsReducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); return state; } -var _extends$4 = 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; }; +var _extends$5 = 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; }; const reducers$1 = {}; const defaultState$1 = { @@ -2959,7 +3072,7 @@ reducers$1[PURCHASE_URI_STARTED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$4({}, state, { + return _extends$5({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: '' }); @@ -2981,7 +3094,7 @@ reducers$1[PURCHASE_URI_COMPLETED] = (state, action) => { newPurchasedStreamingUrls[uri] = streamingUrl; } - return _extends$4({}, state, { + return _extends$5({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, purchasedStreamingUrls: newPurchasedStreamingUrls, @@ -2997,7 +3110,7 @@ reducers$1[PURCHASE_URI_FAILED] = (state, action) => { newFailedPurchaseUris.push(uri); } - return _extends$4({}, state, { + return _extends$5({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: error }); @@ -3010,7 +3123,7 @@ reducers$1[DELETE_PURCHASED_URI] = (state, action) => { newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); } - return _extends$4({}, state, { + return _extends$5({}, state, { purchasedUris: newPurchasedUris }); }; @@ -3021,7 +3134,7 @@ function fileReducer(state = defaultState$1, action) { return state; } -var _extends$5 = 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; }; +var _extends$6 = 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; }; const reducers$2 = {}; const defaultState$2 = { @@ -3157,12 +3270,12 @@ reducers$2[LOADING_VIDEO_STARTED] = (state, action) => { const newLoading = Object.assign({}, state.urisLoading); newLoading[uri] = true; - const newErrors = _extends$5({}, state.errors); + const newErrors = _extends$6({}, state.errors); if (uri in newErrors) delete newErrors[uri]; return Object.assign({}, state, { urisLoading: newLoading, - errors: _extends$5({}, newErrors) + errors: _extends$6({}, newErrors) }); }; @@ -3172,12 +3285,12 @@ reducers$2[LOADING_VIDEO_FAILED] = (state, action) => { const newLoading = Object.assign({}, state.urisLoading); delete newLoading[uri]; - const newErrors = _extends$5({}, state.errors); + const newErrors = _extends$6({}, state.errors); newErrors[uri] = true; return Object.assign({}, state, { urisLoading: newLoading, - errors: _extends$5({}, newErrors) + errors: _extends$6({}, newErrors) }); }; @@ -3218,7 +3331,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -var _extends$6 = 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; }; +var _extends$7 = 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; }; const defaultState$3 = { notifications: [], @@ -3233,7 +3346,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$6({}, state, { + return _extends$7({}, state, { toasts: newToasts }); }, @@ -3241,7 +3354,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$6({}, state, { + return _extends$7({}, state, { toasts: newToasts }); }, @@ -3252,7 +3365,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$6({}, state, { + return _extends$7({}, state, { notifications: newNotifications }); }, @@ -3263,7 +3376,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$6({}, state, { + return _extends$7({}, state, { notifications }); }, @@ -3272,7 +3385,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$6({}, state, { + return _extends$7({}, state, { notifications: newNotifications }); }, @@ -3283,7 +3396,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$6({}, state, { + return _extends$7({}, state, { errors: newErrors }); }, @@ -3291,13 +3404,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$6({}, state, { + return _extends$7({}, state, { errors: newErrors }); } }, defaultState$3); -var _extends$7 = 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; }; +var _extends$8 = 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; }; const defaultState$4 = { isActive: false, // does the user have any typed text in the search input @@ -3317,29 +3430,29 @@ const defaultState$4 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$7({}, state, { + [SEARCH_START]: state => _extends$8({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$7({}, state, { + return _extends$8({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$7({}, state, { + [SEARCH_FAIL]: state => _extends$8({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$7({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$8({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$7({}, state, { - suggestions: _extends$7({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$8({}, state, { + suggestions: _extends$8({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -3347,27 +3460,27 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$7({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$8({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$7({}, state, { + [SEARCH_FOCUS]: state => _extends$8({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$7({}, state, { + [SEARCH_BLUR]: state => _extends$8({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$7({}, oldOptions, newOptions); - return _extends$7({}, state, { + const options = _extends$8({}, oldOptions, newOptions); + return _extends$8({}, state, { options }); } }, defaultState$4); -var _extends$8 = 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; }; +var _extends$9 = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -3407,25 +3520,25 @@ const defaultState$5 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$8({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$9({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$8({}, state.transactions); + const byId = _extends$9({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$8({}, state, { + return _extends$9({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$8({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$9({}, state, { fetchingSupports: true }), @@ -3438,7 +3551,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$8({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$9({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -3447,7 +3560,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$8({}, state, { + return _extends$9({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -3460,56 +3573,56 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$8({}, state, { + return _extends$9({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$8({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$9({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$8({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$9({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$8({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$9({}, state, { balance: action.data.balance }), - [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$8({}, state, { + [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$9({}, state, { totalBalance: action.data.totalBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$8({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$9({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$8({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$9({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$8({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$9({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$8({}, state, { draftTransaction: newDraft }); + return _extends$9({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$8({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$9({}, oldDraft, { address: action.data.address }); - return _extends$8({}, state, { draftTransaction: newDraft }); + return _extends$9({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$8({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$9({}, state.draftTransaction, { sending: true }); - return _extends$8({}, state, { draftTransaction: newDraftTransaction }); + return _extends$9({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -3522,108 +3635,108 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$8({}, state, { draftTransaction: newDraftTransaction }); + return _extends$9({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$8({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$9({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$8({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$9({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$8({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$9({}, state, { error: action.data.error, sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$8({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$9({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$8({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$9({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$8({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$9({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$8({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$9({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$8({}, state, { + [WALLET_DECRYPT_START]: state => _extends$9({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$8({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$9({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$8({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$9({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$8({}, state, { + [WALLET_UNLOCK_START]: state => _extends$9({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$8({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$9({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$8({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$9({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$8({}, state, { + [WALLET_LOCK_START]: state => _extends$9({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$8({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$9({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$8({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$9({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$8({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$9({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$8({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$9({}, state, { latestBlock: action.data }) }, defaultState$5); -var _extends$9 = 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; }; +var _extends$a = 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; }; const reducers$3 = {}; const defaultState$6 = { @@ -3632,9 +3745,9 @@ const defaultState$6 = { reducers$3[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$9({}, state, { - positions: _extends$9({}, state.positions, { - [claimId]: _extends$9({}, state.positions[claimId], { + return _extends$a({}, state, { + positions: _extends$a({}, state.positions, { + [claimId]: _extends$a({}, state.positions[claimId], { [outpoint]: position }) }) @@ -3647,6 +3760,79 @@ function contentReducer(state = defaultState$6, action) { return state; } +const defaultFollowedTags = ['gaming', 'blockchain', 'news', 'learning', 'funny', 'technology', 'automotive', 'economics', 'sports', 'food', 'science', 'art', 'nature', 'beliefs', 'music', 'pop culture', 'weapons']; + +const defaultRecommendedTags = []; + +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 getDefaultRecommendedTags() { + return defaultFollowedTags.concat(defaultRecommendedTags).reduce((tagsMap, tag) => _extends$b({}, tagsMap, { + [tag]: { name: tag } + }), {}); +} + +const defaultState$7 = { + followedTags: defaultFollowedTags, + knownTags: getDefaultRecommendedTags(), + trending: [], + fetchingTrending: false +}; + +const tagsReducer = handleActions({ + [TOGGLE_TAG_FOLLOW]: (state, action) => { + const { followedTags } = state; + const { name } = action.data; + + let newFollowedTags = followedTags.slice(); + + if (newFollowedTags.includes(name)) { + newFollowedTags = newFollowedTags.filter(tag => tag !== name); + } else { + newFollowedTags.push(name); + } + + return _extends$b({}, state, { + followedTags: newFollowedTags + }); + }, + + [TAG_ADD]: (state, action) => { + const { knownTags } = state; + const { name } = action.data; + + let newKnownTags = _extends$b({}, knownTags); + newKnownTags[name] = { name }; + + return _extends$b({}, state, { + knownTags: newKnownTags + }); + }, + + [TAG_DELETE]: (state, action) => { + const { knownTags, followedTags } = state; + const { name } = action.data; + + let newKnownTags = _extends$b({}, knownTags); + delete newKnownTags[name]; + + return _extends$b({}, state, { + knownTags: newKnownTags + }); + }, + [FETCH_TRENDING_STARTED]: state => _extends$b({}, state, { + fetchingTrending: true + }), + [FETCH_TRENDING_COMPLETED]: (state, action) => _extends$b({}, state, { + trending: action.data.uris, + fetchingTrending: false + }), + [FETCH_TRENDING_FAILED]: state => _extends$b({}, state, { + trending: [], + fetchingTrending: false + }) +}, defaultState$7); + const selectState$5 = state => state.content || {}; const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$5, makeSelectClaimForUri(uri), (state, claim) => { @@ -3658,14 +3844,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$a = 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; }; +var _extends$c = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$a({ + return _extends$c({ id }, params); } @@ -3684,6 +3870,34 @@ const selectError = reselect.createSelector(selectState$6, state => { return null; }); +// + +const selectState$7 = state => state.tags || {}; + +const selectKnownTagsByName = reselect.createSelector(selectState$7, state => state.knownTags); + +const selectFollowedTagsList = reselect.createSelector(selectState$7, state => state.followedTags); + +const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag }))); + +const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, selectFollowedTagsList, (tagsByName, followedTags) => { + const followedTagsSet = new Set(followedTags); + let tagsToReturn = []; + + Object.keys(tagsByName).forEach(key => { + if (!followedTagsSet.has(key)) { + const { name } = tagsByName[key]; + tagsToReturn.push({ name }); + } + }); + + return tagsToReturn; +}); + +const selectTrendingUris = reselect.createSelector(selectState$7, state => state.trending || []); + +const selectFetchingTrending = reselect.createSelector(selectState$7, state => state.fetchingTrending); + exports.ACTIONS = action_types; exports.Lbry = lbryProxy; exports.PAGES = pages; @@ -3700,14 +3914,17 @@ exports.contentReducer = contentReducer; exports.convertToShareLink = convertToShareLink; exports.creditsToString = creditsToString; exports.doAbandonClaim = doAbandonClaim; +exports.doAddTag = doAddTag; exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCreateChannel = doCreateChannel; exports.doDeletePurchasedUri = doDeletePurchasedUri; +exports.doDeleteTag = doDeleteTag; exports.doDismissError = doDismissError; exports.doDismissToast = doDismissToast; exports.doError = doError; +exports.doFetchByTags = doFetchByTags; exports.doFetchChannelListMine = doFetchChannelListMine; exports.doFetchClaimListMine = doFetchClaimListMine; exports.doFetchClaimsByChannel = doFetchClaimsByChannel; @@ -3729,6 +3946,7 @@ exports.doSetDraftTransactionAmount = doSetDraftTransactionAmount; exports.doSetFileListSort = doSetFileListSort; exports.doSetTransactionListFilter = doSetTransactionListFilter; exports.doToast = doToast; +exports.doToggleTagFollow = doToggleTagFollow; exports.doTotalBalanceSubscribe = doTotalBalanceSubscribe; exports.doUpdateBalance = doUpdateBalance; exports.doUpdateBlockHeight = doUpdateBlockHeight; @@ -3773,6 +3991,7 @@ exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; exports.makeSelectSearchUris = makeSelectSearchUris; exports.makeSelectStreamingUrlForUri = makeSelectStreamingUrlForUri; +exports.makeSelectTagsForUri = makeSelectTagsForUri; exports.makeSelectThumbnailForUri = makeSelectThumbnailForUri; exports.makeSelectTitleForUri = makeSelectTitleForUri; exports.makeSelectTotalItemsForChannel = makeSelectTotalItemsForChannel; @@ -3795,6 +4014,7 @@ exports.selectChannelClaimCounts = selectChannelClaimCounts; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; exports.selectCurrentChannelPage = selectCurrentChannelPage; +exports.selectDownloadedUris = selectDownloadedUris; exports.selectDownloadingByOutpoint = selectDownloadingByOutpoint; exports.selectDownloadingFileInfos = selectDownloadingFileInfos; exports.selectDraftTransaction = selectDraftTransaction; @@ -3804,10 +4024,12 @@ exports.selectDraftTransactionError = selectDraftTransactionError; exports.selectError = selectError; exports.selectFailedPurchaseUris = selectFailedPurchaseUris; exports.selectFetchingMyChannels = selectFetchingMyChannels; +exports.selectFetchingTrending = selectFetchingTrending; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; exports.selectFileListDownloadedSort = selectFileListDownloadedSort; exports.selectFileListPublishedSort = selectFileListPublishedSort; +exports.selectFollowedTags = selectFollowedTags; exports.selectGettingNewAddress = selectGettingNewAddress; exports.selectHasTransactions = selectHasTransactions; exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; @@ -3846,6 +4068,8 @@ exports.selectTotalDownloadProgress = selectTotalDownloadProgress; exports.selectTransactionItems = selectTransactionItems; exports.selectTransactionListFilter = selectTransactionListFilter; exports.selectTransactionsById = selectTransactionsById; +exports.selectTrendingUris = selectTrendingUris; +exports.selectUnfollowedTags = selectUnfollowedTags; exports.selectUrisLoading = selectUrisLoading; exports.selectWalletDecryptPending = selectWalletDecryptPending; exports.selectWalletDecryptResult = selectWalletDecryptResult; @@ -3859,5 +4083,6 @@ exports.selectWalletUnlockPending = selectWalletUnlockPending; exports.selectWalletUnlockResult = selectWalletUnlockResult; exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded; exports.setSearchApi = setSearchApi; +exports.tagsReducer = tagsReducer; exports.toQueryString = toQueryString; exports.walletReducer = walletReducer; diff --git a/dist/flow-typed/Tags.js b/dist/flow-typed/Tags.js new file mode 100644 index 0000000..d6b4510 --- /dev/null +++ b/dist/flow-typed/Tags.js @@ -0,0 +1,30 @@ +declare type TagState = { + followedTags: FollowedTags, + knownTags: KnownTags, + trending: Array, + fetchingTrending: boolean, +}; + +declare type Tag = { + name: string, +}; + +declare type KnownTags = { + [string]: Tag, +}; + +declare type FollowedTags = Array; + +declare type TagAction = { + type: string, + data: { + name: string, + }, +}; + +declare type TrendingTagAction = { + type: string, + data: { + uris: Array, + }, +}; diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index f18b128..d5ca709 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -3,8 +3,7 @@ declare type Claim = StreamClaim | ChannelClaim; declare type ChannelClaim = GenericClaim & { - is_channel_signature_valid?: boolean, // we may have signed channels in the future, fixes some flow issues for now. - signing_channel?: ChannelClaim, + is_channel_signature_valid?: boolean, // we may have signed channels in the future value: ChannelMetadata, }; diff --git a/flow-typed/Tags.js b/flow-typed/Tags.js new file mode 100644 index 0000000..d6b4510 --- /dev/null +++ b/flow-typed/Tags.js @@ -0,0 +1,30 @@ +declare type TagState = { + followedTags: FollowedTags, + knownTags: KnownTags, + trending: Array, + fetchingTrending: boolean, +}; + +declare type Tag = { + name: string, +}; + +declare type KnownTags = { + [string]: Tag, +}; + +declare type FollowedTags = Array; + +declare type TagAction = { + type: string, + data: { + name: string, + }, +}; + +declare type TrendingTagAction = { + type: string, + data: { + uris: Array, + }, +}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index cb1cdd0..7a303f9 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -88,6 +88,9 @@ export const SET_CONTENT_POSITION = 'SET_CONTENT_POSITION'; export const SET_CONTENT_LAST_VIEWED = 'SET_CONTENT_LAST_VIEWED'; export const CLEAR_CONTENT_HISTORY_URI = 'CLEAR_CONTENT_HISTORY_URI'; export const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL'; +export const CLAIM_SEARCH_STARTED = 'CLAIM_SEARCH_STARTED'; +export const CLAIM_SEARCH_COMPLETED = 'CLAIM_SEARCH_COMPLETED'; +export const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; // Files export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; @@ -177,21 +180,6 @@ export const FETCH_REWARD_CONTENT_COMPLETED = 'FETCH_REWARD_CONTENT_COMPLETED'; export const DOWNLOAD_LANGUAGE_SUCCEEDED = 'DOWNLOAD_LANGUAGE_SUCCEEDED'; export const DOWNLOAD_LANGUAGE_FAILED = 'DOWNLOAD_LANGUAGE_FAILED'; -// ShapeShift -export const GET_SUPPORTED_COINS_START = 'GET_SUPPORTED_COINS_START'; -export const GET_SUPPORTED_COINS_SUCCESS = 'GET_SUPPORTED_COINS_SUCCESS'; -export const GET_SUPPORTED_COINS_FAIL = 'GET_SUPPORTED_COINS_FAIL'; -export const GET_COIN_STATS_START = 'GET_COIN_STATS_START'; -export const GET_COIN_STATS_SUCCESS = 'GET_COIN_STATS_SUCCESS'; -export const GET_COIN_STATS_FAIL = 'GET_COIN_STATS_FAIL'; -export const PREPARE_SHAPE_SHIFT_START = 'PREPARE_SHAPE_SHIFT_START'; -export const PREPARE_SHAPE_SHIFT_SUCCESS = 'PREPARE_SHAPE_SHIFT_SUCCESS'; -export const PREPARE_SHAPE_SHIFT_FAIL = 'PREPARE_SHAPE_SHIFT_FAIL'; -export const GET_ACTIVE_SHIFT_START = 'GET_ACTIVE_SHIFT_START'; -export const GET_ACTIVE_SHIFT_SUCCESS = 'GET_ACTIVE_SHIFT_SUCCESS'; -export const GET_ACTIVE_SHIFT_FAIL = 'GET_ACTIVE_SHIFT_FAIL'; -export const CLEAR_SHAPE_SHIFT = 'CLEAR_SHAPE_SHIFT'; - // Subscriptions export const CHANNEL_SUBSCRIBE = 'CHANNEL_SUBSCRIBE'; export const CHANNEL_UNSUBSCRIBE = 'CHANNEL_UNSUBSCRIBE'; @@ -229,3 +217,10 @@ export const FETCH_DATE = 'FETCH_DATE'; export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'; export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'; export const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; +// Tags +export const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; +export const TAG_ADD = 'TAG_ADD'; +export const TAG_DELETE = 'TAG_DELETE'; +export const FETCH_TRENDING_STARTED = 'FETCH_TRENDING_STARTED'; +export const FETCH_TRENDING_COMPLETED = 'FETCH_TRENDING_COMPLETED'; +export const FETCH_TRENDING_FAILED = 'FETCH_TRENDING_FAILED'; diff --git a/src/constants/tags.js b/src/constants/tags.js new file mode 100644 index 0000000..7f00bd2 --- /dev/null +++ b/src/constants/tags.js @@ -0,0 +1,21 @@ +export const defaultFollowedTags = [ + 'gaming', + 'blockchain', + 'news', + 'learning', + 'funny', + 'technology', + 'automotive', + 'economics', + 'sports', + 'food', + 'science', + 'art', + 'nature', + 'beliefs', + 'music', + 'pop culture', + 'weapons', +]; + +export const defaultRecommendedTags = []; diff --git a/src/index.js b/src/index.js index 848d0e5..6e40213 100644 --- a/src/index.js +++ b/src/index.js @@ -87,6 +87,8 @@ export { doUpdateBlockHeight, } from 'redux/actions/wallet'; +export { doToggleTagFollow, doAddTag, doDeleteTag, doFetchByTags } from 'redux/actions/tags'; + // utils export { batchActions } from 'util/batchActions'; export { parseQueryParams, toQueryString } from 'util/query_params'; @@ -101,6 +103,7 @@ export { notificationsReducer } from 'redux/reducers/notifications'; export { searchReducer } from 'redux/reducers/search'; export { walletReducer } from 'redux/reducers/wallet'; export { contentReducer } from 'redux/reducers/content'; +export { tagsReducer } from 'redux/reducers/tags'; // selectors export { makeSelectContentPositionForUri } from 'redux/selectors/content'; @@ -127,6 +130,7 @@ export { makeSelectCoverForUri, makeSelectTitleForUri, makeSelectDateForUri, + makeSelectTagsForUri, makeSelectContentTypeForUri, makeSelectIsUriResolving, makeSelectTotalItemsForChannel, @@ -177,6 +181,7 @@ export { selectSearchDownloadUris, selectFileListDownloadedSort, selectFileListPublishedSort, + selectDownloadedUris, } from 'redux/selectors/file_info'; export { selectSearchState }; @@ -221,3 +226,10 @@ export { selectWalletUnlockResult, selectTransactionListFilter, } from 'redux/selectors/wallet'; + +export { + selectFollowedTags, + selectUnfollowedTags, + selectTrendingUris, + selectFetchingTrending, +} from 'redux/selectors/tags'; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 5248309..ea3da1f 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -7,6 +7,7 @@ import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux import { doFetchTransactions } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { creditsToString } from 'util/formatCredits'; +import { batchActions } from 'util/batchActions'; export function doResolveUris(uris: Array, returnCachedClaims: boolean = false) { return (dispatch: Dispatch, getState: GetState) => { @@ -69,7 +70,6 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = 0; } } - // $FlowFixMe resolveInfo[uri] = result; } @@ -264,3 +264,48 @@ export function doFetchChannelListMine() { Lbry.channel_list().then(callback); }; } + +export function doClaimSearch( + amount: number = 20, + options: {} = {}, + cb: (?Error, ?Array) => void +) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.CLAIM_SEARCH_STARTED, + }); + + 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_COMPLETED, + data: { resolveInfo }, + }); + + if (cb) { + cb(null, uris); + } + }; + + const failure = err => { + dispatch({ + type: ACTIONS.CLAIM_SEARCH_FAILED, + error: err, + }); + if (cb) { + cb(err); + } + }; + + Lbry.claim_search({ + page_size: amount, + ...options, + }).then(success, failure); + }; +} diff --git a/src/redux/actions/tags.js b/src/redux/actions/tags.js new file mode 100644 index 0000000..28bb7c8 --- /dev/null +++ b/src/redux/actions/tags.js @@ -0,0 +1,51 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; +import Lbry from 'lbry'; +import { doClaimSearch } from 'redux/actions/claims'; + +export const doToggleTagFollow = (name: string) => ({ + type: ACTIONS.TOGGLE_TAG_FOLLOW, + data: { + name, + }, +}); + +export const doAddTag = (name: string) => ({ + type: ACTIONS.TAG_ADD, + data: { + name, + }, +}); + +export const doDeleteTag = (name: string) => ({ + type: ACTIONS.TAG_DELETE, + data: { + name, + }, +}); + +export const doFetchByTags = (amount: number = 10, options: Object = {}) => { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.FETCH_TRENDING_STARTED, + }); + + const callback = (error: ?Error, uris: ?Array = []) => { + if (error) { + return dispatch({ + type: ACTIONS.FETCH_TRENDING_FAILED, + error, + }); + } + + dispatch({ + type: ACTIONS.FETCH_TRENDING_COMPLETED, + data: { + uris, + }, + }); + }; + + dispatch(doClaimSearch(amount, options, callback)); + }; +}; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index cd50cd6..92c5f99 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -45,7 +45,7 @@ const defaultState = { pendingById: {}, }; -reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => { +function handleClaimAction(state: State, action: any): State { const { resolveInfo, }: { @@ -88,6 +88,10 @@ reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => channelClaimCounts, resolvingUris: (state.resolvingUris || []).filter(uri => !resolveInfo[uri]), }); +} + +reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => { + return handleClaimAction(state, action); }; reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State => @@ -265,6 +269,20 @@ reducers[ACTIONS.RESOLVE_URIS_STARTED] = (state: State, action: any): State => { }); }; +reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State): State => { + return Object.assign({}, state, { + fetchingClaimSearch: true, + }); +}; +reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => { + return { ...handleClaimAction(state, action), fetchingClaimSearch: false }; +}; +reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State): State => { + return Object.assign({}, state, { + fetchingClaimSearch: false, + }); +}; + export function claimsReducer(state: State = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js new file mode 100644 index 0000000..eb11692 --- /dev/null +++ b/src/redux/reducers/tags.js @@ -0,0 +1,84 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; +import { handleActions } from 'util/redux-utils'; +import { defaultRecommendedTags, defaultFollowedTags } from 'constants/tags'; + +function getDefaultRecommendedTags() { + return defaultFollowedTags.concat(defaultRecommendedTags).reduce( + (tagsMap, tag) => ({ + ...tagsMap, + [tag]: { name: tag }, + }), + {} + ); +} + +const defaultState: TagState = { + followedTags: defaultFollowedTags, + knownTags: getDefaultRecommendedTags(), + trending: [], + fetchingTrending: false, +}; + +export const tagsReducer = handleActions( + { + [ACTIONS.TOGGLE_TAG_FOLLOW]: (state: TagState, action: TagAction): TagState => { + const { followedTags } = state; + const { name } = action.data; + + let newFollowedTags = followedTags.slice(); + + if (newFollowedTags.includes(name)) { + newFollowedTags = newFollowedTags.filter(tag => tag !== name); + } else { + newFollowedTags.push(name); + } + + return { + ...state, + followedTags: newFollowedTags, + }; + }, + + [ACTIONS.TAG_ADD]: (state: TagState, action: TagAction) => { + const { knownTags } = state; + const { name } = action.data; + + let newKnownTags = { ...knownTags }; + newKnownTags[name] = { name }; + + return { + ...state, + knownTags: newKnownTags, + }; + }, + + [ACTIONS.TAG_DELETE]: (state: TagState, action: TagAction) => { + const { knownTags, followedTags } = state; + const { name } = action.data; + + let newKnownTags = { ...knownTags }; + delete newKnownTags[name]; + + return { + ...state, + knownTags: newKnownTags, + }; + }, + [ACTIONS.FETCH_TRENDING_STARTED]: (state: TagState) => ({ + ...state, + fetchingTrending: true, + }), + [ACTIONS.FETCH_TRENDING_COMPLETED]: (state: TagState, action: TrendingTagAction) => ({ + ...state, + trending: action.data.uris, + fetchingTrending: false, + }), + [ACTIONS.FETCH_TRENDING_FAILED]: (state: TagState) => ({ + ...state, + trending: [], + fetchingTrending: false, + }), + }, + defaultState +); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 0cf4bdf..0a0efc3 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -433,3 +433,11 @@ export const makeSelectChannelForClaimUri = (uri: string, includePrefix: boolean return includePrefix ? `lbry://${channel}` : channel; } ); + +export const makeSelectTagsForUri = (uri: string) => + createSelector( + makeSelectMetadataForUri(uri), + (metadata: ?GenericMetadata) => { + return (metadata && metadata.tags) || []; + } + ); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 4718cd8..fbfc023 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -228,3 +228,9 @@ export const selectFileListDownloadedSort = createSelector( selectState, state => state.fileListDownloadedSort ); + +export const selectDownloadedUris = createSelector( + selectFileInfosDownloaded, + // We should use permament_url but it doesn't exist in file_list + info => info.map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) +); diff --git a/src/redux/selectors/tags.js b/src/redux/selectors/tags.js new file mode 100644 index 0000000..20f88f9 --- /dev/null +++ b/src/redux/selectors/tags.js @@ -0,0 +1,47 @@ +// @flow +import { createSelector } from 'reselect'; + +const selectState = (state: { tags: TagState }) => state.tags || {}; + +export const selectKnownTagsByName = createSelector( + selectState, + (state: TagState): KnownTags => state.knownTags +); + +export const selectFollowedTagsList = createSelector( + selectState, + (state: TagState): Array => state.followedTags +); + +export const selectFollowedTags = createSelector( + selectFollowedTagsList, + (followedTags: Array): Array => followedTags.map(tag => ({ name: tag })) +); + +export const selectUnfollowedTags = createSelector( + selectKnownTagsByName, + selectFollowedTagsList, + (tagsByName: KnownTags, followedTags: Array): Array => { + const followedTagsSet = new Set(followedTags); + let tagsToReturn = []; + + Object.keys(tagsByName).forEach(key => { + if (!followedTagsSet.has(key)) { + const { name } = tagsByName[key]; + tagsToReturn.push({ name }); + } + }); + + return tagsToReturn; + } +); + +export const selectTrendingUris = createSelector( + selectState, + state => state.trending || [] +); + +export const selectFetchingTrending = createSelector( + selectState, + state => state.fetchingTrending +); -- 2.45.2 From 478251f9005f380ae4405f063ee7dbd39556af21 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 10 Jun 2019 12:58:39 -0400 Subject: [PATCH 033/371] sort followed tags alphabetically --- dist/bundle.es.js | 2 +- src/redux/selectors/tags.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 129ae72..903f824 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3878,7 +3878,7 @@ const selectKnownTagsByName = reselect.createSelector(selectState$7, state => st const selectFollowedTagsList = reselect.createSelector(selectState$7, state => state.followedTags); -const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag }))); +const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag })).sort((a, b) => a.name.localeCompare(b.name))); const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, selectFollowedTagsList, (tagsByName, followedTags) => { const followedTagsSet = new Set(followedTags); diff --git a/src/redux/selectors/tags.js b/src/redux/selectors/tags.js index 20f88f9..c6b9889 100644 --- a/src/redux/selectors/tags.js +++ b/src/redux/selectors/tags.js @@ -15,7 +15,8 @@ export const selectFollowedTagsList = createSelector( export const selectFollowedTags = createSelector( selectFollowedTagsList, - (followedTags: Array): Array => followedTags.map(tag => ({ name: tag })) + (followedTags: Array): Array => + followedTags.map(tag => ({ name: tag })).sort((a, b) => a.name.localeCompare(b.name)) ); export const selectUnfollowedTags = createSelector( -- 2.45.2 From 12f4c032b8c6d8d08da87a7e64412855e7b5ae40 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 10 Jun 2019 14:38:53 -0400 Subject: [PATCH 034/371] unfollow tag on delete --- dist/bundle.es.js | 4 +++- src/redux/reducers/tags.js | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 903f824..64ae791 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3815,9 +3815,11 @@ const tagsReducer = handleActions({ let newKnownTags = _extends$b({}, knownTags); delete newKnownTags[name]; + const newFollowedTags = followedTags.filter(tag => tag !== name); return _extends$b({}, state, { - knownTags: newKnownTags + knownTags: newKnownTags, + followedTags: newFollowedTags }); }, [FETCH_TRENDING_STARTED]: state => _extends$b({}, state, { diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index eb11692..38c3d09 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -59,10 +59,12 @@ export const tagsReducer = handleActions( let newKnownTags = { ...knownTags }; delete newKnownTags[name]; + const newFollowedTags = followedTags.filter(tag => tag !== name); return { ...state, knownTags: newKnownTags, + followedTags: newFollowedTags, }; }, [ACTIONS.FETCH_TRENDING_STARTED]: (state: TagState) => ({ -- 2.45.2 From e8466bbeeca1778476e6c9b262ffa98882b45bb2 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 11 Jun 2019 14:11:18 -0400 Subject: [PATCH 035/371] remove trending in favor of lastClaimSearchUris --- dist/bundle.es.js | 87 ++++++++--------------------------- dist/flow-typed/Claim.js | 2 +- dist/flow-typed/Tags.js | 9 ---- flow-typed/Claim.js | 2 +- flow-typed/Tags.js | 9 ---- src/constants/action_types.js | 3 -- src/index.js | 12 ++--- src/redux/actions/claims.js | 15 +----- src/redux/actions/tags.js | 27 ----------- src/redux/reducers/claims.js | 12 ++++- src/redux/reducers/tags.js | 16 ------- src/redux/selectors/claims.js | 10 ++++ src/redux/selectors/tags.js | 10 ---- 13 files changed, 49 insertions(+), 165 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 64ae791..2dd0112 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -231,9 +231,6 @@ const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; const TAG_ADD = 'TAG_ADD'; const TAG_DELETE = 'TAG_DELETE'; -const FETCH_TRENDING_STARTED = 'FETCH_TRENDING_STARTED'; -const FETCH_TRENDING_COMPLETED = 'FETCH_TRENDING_COMPLETED'; -const FETCH_TRENDING_FAILED = 'FETCH_TRENDING_FAILED'; var action_types = /*#__PURE__*/Object.freeze({ WINDOW_FOCUSED: WINDOW_FOCUSED, @@ -428,10 +425,7 @@ var action_types = /*#__PURE__*/Object.freeze({ FETCH_COST_INFO_FAILED: FETCH_COST_INFO_FAILED, TOGGLE_TAG_FOLLOW: TOGGLE_TAG_FOLLOW, TAG_ADD: TAG_ADD, - TAG_DELETE: TAG_DELETE, - FETCH_TRENDING_STARTED: FETCH_TRENDING_STARTED, - FETCH_TRENDING_COMPLETED: FETCH_TRENDING_COMPLETED, - FETCH_TRENDING_FAILED: FETCH_TRENDING_FAILED + TAG_DELETE: TAG_DELETE }); const API_DOWN = 'apiDown'; @@ -1423,6 +1417,10 @@ const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataFo return metadata && metadata.tags || []; }); +const selectFetchingClaimSearch = reselect.createSelector(selectState$1, state => state.fetchingClaimSearch); + +const selectLastClaimSearchUris = reselect.createSelector(selectState$1, state => state.lastClaimSearchUris); + const selectState$2 = state => state.wallet || {}; const selectWalletState = selectState$2; @@ -2191,7 +2189,7 @@ function doFetchChannelListMine() { }; } -function doClaimSearch(amount = 20, options = {}, cb) { +function doClaimSearch(amount = 20, options = {}) { return dispatch => { dispatch({ type: CLAIM_SEARCH_STARTED @@ -2207,12 +2205,8 @@ function doClaimSearch(amount = 20, options = {}, cb) { dispatch({ type: CLAIM_SEARCH_COMPLETED, - data: { resolveInfo } + data: { resolveInfo, uris } }); - - if (cb) { - cb(null, uris); - } }; const failure = err => { @@ -2220,9 +2214,6 @@ function doClaimSearch(amount = 20, options = {}, cb) { type: CLAIM_SEARCH_FAILED, error: err }); - if (cb) { - cb(err); - } }; lbryProxy.claim_search(_extends$3({ @@ -2776,32 +2767,6 @@ const doDeleteTag = name => ({ } }); -const doFetchByTags = (amount = 10, options = {}) => { - return dispatch => { - dispatch({ - type: FETCH_TRENDING_STARTED - }); - - const callback = (error, uris = []) => { - if (error) { - return dispatch({ - type: FETCH_TRENDING_FAILED, - error - }); - } - - dispatch({ - type: FETCH_TRENDING_COMPLETED, - data: { - uris - } - }); - }; - - dispatch(doClaimSearch(amount, options, callback)); - }; -}; - var _extends$4 = 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; }; const reducers = {}; @@ -2817,7 +2782,9 @@ const defaultState = { myChannelClaims: new Set(), fetchingMyChannels: false, abandoningById: {}, - pendingById: {} + pendingById: {}, + fetchingClaimSearch: false, + lastClaimSearchUris: [] }; function handleClaimAction(state, action) { @@ -2860,7 +2827,7 @@ function handleClaimAction(state, action) { } reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return handleClaimAction(state, action); + return _extends$4({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -3041,7 +3008,10 @@ reducers[CLAIM_SEARCH_STARTED] = state => { }); }; reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { - return _extends$4({}, handleClaimAction(state, action), { fetchingClaimSearch: false }); + return _extends$4({}, handleClaimAction(state, action), { + fetchingClaimSearch: false, + lastClaimSearchUris: action.data.uris + }); }; reducers[CLAIM_SEARCH_FAILED] = state => { return Object.assign({}, state, { @@ -3774,9 +3744,7 @@ function getDefaultRecommendedTags() { const defaultState$7 = { followedTags: defaultFollowedTags, - knownTags: getDefaultRecommendedTags(), - trending: [], - fetchingTrending: false + knownTags: getDefaultRecommendedTags() }; const tagsReducer = handleActions({ @@ -3821,18 +3789,7 @@ const tagsReducer = handleActions({ knownTags: newKnownTags, followedTags: newFollowedTags }); - }, - [FETCH_TRENDING_STARTED]: state => _extends$b({}, state, { - fetchingTrending: true - }), - [FETCH_TRENDING_COMPLETED]: (state, action) => _extends$b({}, state, { - trending: action.data.uris, - fetchingTrending: false - }), - [FETCH_TRENDING_FAILED]: state => _extends$b({}, state, { - trending: [], - fetchingTrending: false - }) + } }, defaultState$7); const selectState$5 = state => state.content || {}; @@ -3896,10 +3853,6 @@ const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, sele return tagsToReturn; }); -const selectTrendingUris = reselect.createSelector(selectState$7, state => state.trending || []); - -const selectFetchingTrending = reselect.createSelector(selectState$7, state => state.fetchingTrending); - exports.ACTIONS = action_types; exports.Lbry = lbryProxy; exports.PAGES = pages; @@ -3920,13 +3873,13 @@ exports.doAddTag = doAddTag; exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; +exports.doClaimSearch = doClaimSearch; exports.doCreateChannel = doCreateChannel; exports.doDeletePurchasedUri = doDeletePurchasedUri; exports.doDeleteTag = doDeleteTag; exports.doDismissError = doDismissError; exports.doDismissToast = doDismissToast; exports.doError = doError; -exports.doFetchByTags = doFetchByTags; exports.doFetchChannelListMine = doFetchChannelListMine; exports.doFetchClaimListMine = doFetchClaimListMine; exports.doFetchClaimsByChannel = doFetchClaimsByChannel; @@ -4025,8 +3978,8 @@ exports.selectDraftTransactionAmount = selectDraftTransactionAmount; exports.selectDraftTransactionError = selectDraftTransactionError; exports.selectError = selectError; exports.selectFailedPurchaseUris = selectFailedPurchaseUris; +exports.selectFetchingClaimSearch = selectFetchingClaimSearch; exports.selectFetchingMyChannels = selectFetchingMyChannels; -exports.selectFetchingTrending = selectFetchingTrending; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; exports.selectFileListDownloadedSort = selectFileListDownloadedSort; @@ -4040,6 +3993,7 @@ exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileList exports.selectIsFetchingTransactions = selectIsFetchingTransactions; exports.selectIsSearching = selectIsSearching; exports.selectIsSendingSupport = selectIsSendingSupport; +exports.selectLastClaimSearchUris = selectLastClaimSearchUris; exports.selectLastPurchasedUri = selectLastPurchasedUri; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; @@ -4070,7 +4024,6 @@ exports.selectTotalDownloadProgress = selectTotalDownloadProgress; exports.selectTransactionItems = selectTransactionItems; exports.selectTransactionListFilter = selectTransactionListFilter; exports.selectTransactionsById = selectTransactionsById; -exports.selectTrendingUris = selectTrendingUris; exports.selectUnfollowedTags = selectUnfollowedTags; exports.selectUrisLoading = selectUrisLoading; exports.selectWalletDecryptPending = selectWalletDecryptPending; diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index f18b128..20b8ff0 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -10,7 +10,6 @@ declare type ChannelClaim = GenericClaim & { declare type StreamClaim = GenericClaim & { is_channel_signature_valid?: boolean, - signing_channel?: ChannelClaim, value: StreamMetadata, }; @@ -33,6 +32,7 @@ declare type GenericClaim = { txid: string, // unique tx id type: 'claim' | 'update' | 'support', value_type: 'stream' | 'channel', + signing_channel?: ChannelClaim, meta: { activation_height: number, claims_in_channel?: number, diff --git a/dist/flow-typed/Tags.js b/dist/flow-typed/Tags.js index d6b4510..01c58ac 100644 --- a/dist/flow-typed/Tags.js +++ b/dist/flow-typed/Tags.js @@ -1,8 +1,6 @@ declare type TagState = { followedTags: FollowedTags, knownTags: KnownTags, - trending: Array, - fetchingTrending: boolean, }; declare type Tag = { @@ -21,10 +19,3 @@ declare type TagAction = { name: string, }, }; - -declare type TrendingTagAction = { - type: string, - data: { - uris: Array, - }, -}; diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index d5ca709..1c61c10 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -9,7 +9,6 @@ declare type ChannelClaim = GenericClaim & { declare type StreamClaim = GenericClaim & { is_channel_signature_valid?: boolean, - signing_channel?: ChannelClaim, value: StreamMetadata, }; @@ -32,6 +31,7 @@ declare type GenericClaim = { txid: string, // unique tx id type: 'claim' | 'update' | 'support', value_type: 'stream' | 'channel', + signing_channel?: ChannelClaim, meta: { activation_height: number, claims_in_channel?: number, diff --git a/flow-typed/Tags.js b/flow-typed/Tags.js index d6b4510..01c58ac 100644 --- a/flow-typed/Tags.js +++ b/flow-typed/Tags.js @@ -1,8 +1,6 @@ declare type TagState = { followedTags: FollowedTags, knownTags: KnownTags, - trending: Array, - fetchingTrending: boolean, }; declare type Tag = { @@ -21,10 +19,3 @@ declare type TagAction = { name: string, }, }; - -declare type TrendingTagAction = { - type: string, - data: { - uris: Array, - }, -}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 7a303f9..80acf3f 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -221,6 +221,3 @@ export const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; export const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; export const TAG_ADD = 'TAG_ADD'; export const TAG_DELETE = 'TAG_DELETE'; -export const FETCH_TRENDING_STARTED = 'FETCH_TRENDING_STARTED'; -export const FETCH_TRENDING_COMPLETED = 'FETCH_TRENDING_COMPLETED'; -export const FETCH_TRENDING_FAILED = 'FETCH_TRENDING_FAILED'; diff --git a/src/index.js b/src/index.js index 6e40213..6ed5cd7 100644 --- a/src/index.js +++ b/src/index.js @@ -45,6 +45,7 @@ export { doResolveUri, doFetchChannelListMine, doCreateChannel, + doClaimSearch, } from 'redux/actions/claims'; export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -87,7 +88,7 @@ export { doUpdateBlockHeight, } from 'redux/actions/wallet'; -export { doToggleTagFollow, doAddTag, doDeleteTag, doFetchByTags } from 'redux/actions/tags'; +export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; // utils export { batchActions } from 'util/batchActions'; @@ -164,6 +165,8 @@ export { selectPlayingUri, selectChannelClaimCounts, selectCurrentChannelPage, + selectFetchingClaimSearch, + selectLastClaimSearchUris, } from 'redux/selectors/claims'; export { @@ -227,9 +230,4 @@ export { selectTransactionListFilter, } from 'redux/selectors/wallet'; -export { - selectFollowedTags, - selectUnfollowedTags, - selectTrendingUris, - selectFetchingTrending, -} from 'redux/selectors/tags'; +export { selectFollowedTags, selectUnfollowedTags } from 'redux/selectors/tags'; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index ea3da1f..4ad3728 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -265,11 +265,7 @@ export function doFetchChannelListMine() { }; } -export function doClaimSearch( - amount: number = 20, - options: {} = {}, - cb: (?Error, ?Array) => void -) { +export function doClaimSearch(amount: number = 20, options: {} = {}) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CLAIM_SEARCH_STARTED, @@ -285,12 +281,8 @@ export function doClaimSearch( dispatch({ type: ACTIONS.CLAIM_SEARCH_COMPLETED, - data: { resolveInfo }, + data: { resolveInfo, uris }, }); - - if (cb) { - cb(null, uris); - } }; const failure = err => { @@ -298,9 +290,6 @@ export function doClaimSearch( type: ACTIONS.CLAIM_SEARCH_FAILED, error: err, }); - if (cb) { - cb(err); - } }; Lbry.claim_search({ diff --git a/src/redux/actions/tags.js b/src/redux/actions/tags.js index 28bb7c8..cd7568b 100644 --- a/src/redux/actions/tags.js +++ b/src/redux/actions/tags.js @@ -1,7 +1,6 @@ // @flow import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; -import { doClaimSearch } from 'redux/actions/claims'; export const doToggleTagFollow = (name: string) => ({ type: ACTIONS.TOGGLE_TAG_FOLLOW, @@ -23,29 +22,3 @@ export const doDeleteTag = (name: string) => ({ name, }, }); - -export const doFetchByTags = (amount: number = 10, options: Object = {}) => { - return (dispatch: Dispatch) => { - dispatch({ - type: ACTIONS.FETCH_TRENDING_STARTED, - }); - - const callback = (error: ?Error, uris: ?Array = []) => { - if (error) { - return dispatch({ - type: ACTIONS.FETCH_TRENDING_FAILED, - error, - }); - } - - dispatch({ - type: ACTIONS.FETCH_TRENDING_COMPLETED, - data: { - uris, - }, - }); - }; - - dispatch(doClaimSearch(amount, options, callback)); - }; -}; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 92c5f99..fd57b99 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -43,6 +43,8 @@ const defaultState = { fetchingMyChannels: false, abandoningById: {}, pendingById: {}, + fetchingClaimSearch: false, + lastClaimSearchUris: [], }; function handleClaimAction(state: State, action: any): State { @@ -91,7 +93,9 @@ function handleClaimAction(state: State, action: any): State { } reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => { - return handleClaimAction(state, action); + return { + ...handleClaimAction(state, action), + }; }; reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State => @@ -275,7 +279,11 @@ reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State): State => { }); }; reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => { - return { ...handleClaimAction(state, action), fetchingClaimSearch: false }; + return { + ...handleClaimAction(state, action), + fetchingClaimSearch: false, + lastClaimSearchUris: action.data.uris, + }; }; reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State): State => { return Object.assign({}, state, { diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index 38c3d09..fb01577 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -16,8 +16,6 @@ function getDefaultRecommendedTags() { const defaultState: TagState = { followedTags: defaultFollowedTags, knownTags: getDefaultRecommendedTags(), - trending: [], - fetchingTrending: false, }; export const tagsReducer = handleActions( @@ -67,20 +65,6 @@ export const tagsReducer = handleActions( followedTags: newFollowedTags, }; }, - [ACTIONS.FETCH_TRENDING_STARTED]: (state: TagState) => ({ - ...state, - fetchingTrending: true, - }), - [ACTIONS.FETCH_TRENDING_COMPLETED]: (state: TagState, action: TrendingTagAction) => ({ - ...state, - trending: action.data.uris, - fetchingTrending: false, - }), - [ACTIONS.FETCH_TRENDING_FAILED]: (state: TagState) => ({ - ...state, - trending: [], - fetchingTrending: false, - }), }, defaultState ); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 0a0efc3..d699d0d 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -441,3 +441,13 @@ export const makeSelectTagsForUri = (uri: string) => return (metadata && metadata.tags) || []; } ); + +export const selectFetchingClaimSearch = createSelector( + selectState, + state => state.fetchingClaimSearch +); + +export const selectLastClaimSearchUris = createSelector( + selectState, + state => state.lastClaimSearchUris +); diff --git a/src/redux/selectors/tags.js b/src/redux/selectors/tags.js index c6b9889..e3bbe4c 100644 --- a/src/redux/selectors/tags.js +++ b/src/redux/selectors/tags.js @@ -36,13 +36,3 @@ export const selectUnfollowedTags = createSelector( return tagsToReturn; } ); - -export const selectTrendingUris = createSelector( - selectState, - state => state.trending || [] -); - -export const selectFetchingTrending = createSelector( - selectState, - state => state.fetchingTrending -); -- 2.45.2 From 82a5f242d09685b9f3b7e4022e9b42833d3d3dfb Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 11 Jun 2019 14:36:01 -0400 Subject: [PATCH 036/371] add my publishes uri selector --- dist/bundle.es.js | 3 +++ src/index.js | 1 + src/redux/selectors/claims.js | 5 +++++ 3 files changed, 9 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2dd0112..4b0de17 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1302,6 +1302,8 @@ const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaim const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/))); +const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => myClaims.map(claim => `lbry://${claim.name}#${claim.claim_id}`)); + const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); const selectMyClaimsOutpoints = reselect.createSelector(selectMyClaims, myClaims => { @@ -3997,6 +3999,7 @@ exports.selectLastClaimSearchUris = selectLastClaimSearchUris; exports.selectLastPurchasedUri = selectLastPurchasedUri; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; +exports.selectMyClaimUrisWithoutChannels = selectMyClaimUrisWithoutChannels; exports.selectMyClaims = selectMyClaims; exports.selectMyClaimsOutpoints = selectMyClaimsOutpoints; exports.selectMyClaimsRaw = selectMyClaimsRaw; diff --git a/src/index.js b/src/index.js index 6ed5cd7..e3d84b0 100644 --- a/src/index.js +++ b/src/index.js @@ -157,6 +157,7 @@ export { selectPendingClaims, selectMyClaims, selectMyClaimsWithoutChannels, + selectMyClaimUrisWithoutChannels, selectAllMyClaimsByOutpoint, selectMyClaimsOutpoints, selectFetchingMyChannels, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index d699d0d..8fcfff6 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -259,6 +259,11 @@ export const selectMyClaimsWithoutChannels = createSelector( myClaims => myClaims.filter(claim => !claim.name.match(/^@/)) ); +export const selectMyClaimUrisWithoutChannels = createSelector( + selectMyClaimsWithoutChannels, + myClaims => myClaims.map(claim => `lbry://${claim.name}#${claim.claim_id}`) +); + export const selectAllMyClaimsByOutpoint = createSelector( selectMyClaimsRaw, claims => -- 2.45.2 From ae2f720d1da430c6b931a02ee821799270dff5d7 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 13 Jun 2019 12:10:27 -0400 Subject: [PATCH 037/371] allow apps to set their own default followed tags --- dist/bundle.es.js | 21 +------ src/constants/tags.js | 21 ------- src/index.js | 2 +- src/redux/reducers/tags.js | 115 ++++++++++++++++--------------------- 4 files changed, 54 insertions(+), 105 deletions(-) delete mode 100644 src/constants/tags.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4b0de17..bc5368f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3732,24 +3732,9 @@ function contentReducer(state = defaultState$6, action) { return state; } -const defaultFollowedTags = ['gaming', 'blockchain', 'news', 'learning', 'funny', 'technology', 'automotive', 'economics', 'sports', 'food', 'science', 'art', 'nature', 'beliefs', 'music', 'pop culture', 'weapons']; - -const defaultRecommendedTags = []; - 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 getDefaultRecommendedTags() { - return defaultFollowedTags.concat(defaultRecommendedTags).reduce((tagsMap, tag) => _extends$b({}, tagsMap, { - [tag]: { name: tag } - }), {}); -} - -const defaultState$7 = { - followedTags: defaultFollowedTags, - knownTags: getDefaultRecommendedTags() -}; - -const tagsReducer = handleActions({ +const tagsReducerBuilder = defaultState => handleActions({ [TOGGLE_TAG_FOLLOW]: (state, action) => { const { followedTags } = state; const { name } = action.data; @@ -3792,7 +3777,7 @@ const tagsReducer = handleActions({ followedTags: newFollowedTags }); } -}, defaultState$7); +}, defaultState); const selectState$5 = state => state.content || {}; @@ -4041,6 +4026,6 @@ exports.selectWalletUnlockPending = selectWalletUnlockPending; exports.selectWalletUnlockResult = selectWalletUnlockResult; exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded; exports.setSearchApi = setSearchApi; -exports.tagsReducer = tagsReducer; +exports.tagsReducerBuilder = tagsReducerBuilder; exports.toQueryString = toQueryString; exports.walletReducer = walletReducer; diff --git a/src/constants/tags.js b/src/constants/tags.js deleted file mode 100644 index 7f00bd2..0000000 --- a/src/constants/tags.js +++ /dev/null @@ -1,21 +0,0 @@ -export const defaultFollowedTags = [ - 'gaming', - 'blockchain', - 'news', - 'learning', - 'funny', - 'technology', - 'automotive', - 'economics', - 'sports', - 'food', - 'science', - 'art', - 'nature', - 'beliefs', - 'music', - 'pop culture', - 'weapons', -]; - -export const defaultRecommendedTags = []; diff --git a/src/index.js b/src/index.js index e3d84b0..4ae019e 100644 --- a/src/index.js +++ b/src/index.js @@ -104,7 +104,7 @@ export { notificationsReducer } from 'redux/reducers/notifications'; export { searchReducer } from 'redux/reducers/search'; export { walletReducer } from 'redux/reducers/wallet'; export { contentReducer } from 'redux/reducers/content'; -export { tagsReducer } from 'redux/reducers/tags'; +export { tagsReducerBuilder } from 'redux/reducers/tags'; // selectors export { makeSelectContentPositionForUri } from 'redux/selectors/content'; diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index fb01577..aca5976 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -1,70 +1,55 @@ // @flow import * as ACTIONS from 'constants/action_types'; import { handleActions } from 'util/redux-utils'; -import { defaultRecommendedTags, defaultFollowedTags } from 'constants/tags'; -function getDefaultRecommendedTags() { - return defaultFollowedTags.concat(defaultRecommendedTags).reduce( - (tagsMap, tag) => ({ - ...tagsMap, - [tag]: { name: tag }, - }), - {} +export const tagsReducerBuilder = (defaultState: TagState) => + handleActions( + { + [ACTIONS.TOGGLE_TAG_FOLLOW]: (state: TagState, action: TagAction): TagState => { + const { followedTags } = state; + const { name } = action.data; + + let newFollowedTags = followedTags.slice(); + + if (newFollowedTags.includes(name)) { + newFollowedTags = newFollowedTags.filter(tag => tag !== name); + } else { + newFollowedTags.push(name); + } + + return { + ...state, + followedTags: newFollowedTags, + }; + }, + + [ACTIONS.TAG_ADD]: (state: TagState, action: TagAction) => { + const { knownTags } = state; + const { name } = action.data; + + let newKnownTags = { ...knownTags }; + newKnownTags[name] = { name }; + + return { + ...state, + knownTags: newKnownTags, + }; + }, + + [ACTIONS.TAG_DELETE]: (state: TagState, action: TagAction) => { + const { knownTags, followedTags } = state; + const { name } = action.data; + + let newKnownTags = { ...knownTags }; + delete newKnownTags[name]; + const newFollowedTags = followedTags.filter(tag => tag !== name); + + return { + ...state, + knownTags: newKnownTags, + followedTags: newFollowedTags, + }; + }, + }, + defaultState ); -} - -const defaultState: TagState = { - followedTags: defaultFollowedTags, - knownTags: getDefaultRecommendedTags(), -}; - -export const tagsReducer = handleActions( - { - [ACTIONS.TOGGLE_TAG_FOLLOW]: (state: TagState, action: TagAction): TagState => { - const { followedTags } = state; - const { name } = action.data; - - let newFollowedTags = followedTags.slice(); - - if (newFollowedTags.includes(name)) { - newFollowedTags = newFollowedTags.filter(tag => tag !== name); - } else { - newFollowedTags.push(name); - } - - return { - ...state, - followedTags: newFollowedTags, - }; - }, - - [ACTIONS.TAG_ADD]: (state: TagState, action: TagAction) => { - const { knownTags } = state; - const { name } = action.data; - - let newKnownTags = { ...knownTags }; - newKnownTags[name] = { name }; - - return { - ...state, - knownTags: newKnownTags, - }; - }, - - [ACTIONS.TAG_DELETE]: (state: TagState, action: TagAction) => { - const { knownTags, followedTags } = state; - const { name } = action.data; - - let newKnownTags = { ...knownTags }; - delete newKnownTags[name]; - const newFollowedTags = followedTags.filter(tag => tag !== name); - - return { - ...state, - knownTags: newKnownTags, - followedTags: newFollowedTags, - }; - }, - }, - defaultState -); -- 2.45.2 From cfbf86e95d5e9183588015281f2eccc29003e24b Mon Sep 17 00:00:00 2001 From: Lex Berezhny Date: Mon, 24 Jun 2019 15:42:53 -0400 Subject: [PATCH 038/371] claim_search --valid_channel_signatures was renamed to --valid_channel_signature --- src/redux/actions/claims.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 4ad3728..518f02e 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -200,7 +200,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { Lbry.claim_search({ channel: uri, - valid_channel_signatures: true, + valid_channel_signature: true, page: page || 1, order_by: ['release_time'], }).then((result: ClaimSearchResponse) => { -- 2.45.2 From 9b6912e51f478382d2193ee0d55869c68ed9f23c Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 25 Jun 2019 02:37:31 -0400 Subject: [PATCH 039/371] run build --- dist/bundle.es.js | 10 +--------- dist/flow-typed/Claim.js | 3 +-- 2 files changed, 2 insertions(+), 11 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index bc5368f..71bf2e5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2000,11 +2000,7 @@ function doResolveUris(uris, returnCachedClaims = false) { result.stream = uriResolveInfo; if (uriResolveInfo.signing_channel) { result.channel = uriResolveInfo.signing_channel; -<<<<<<< HEAD result.claimsInChannel = uriResolveInfo.signing_channel.meta && uriResolveInfo.signing_channel.meta.claims_in_channel || 0; -======= - result.claimsInChannel = uriResolveInfo.meta && uriResolveInfo.meta.claims_in_channel || 0; ->>>>>>> add tags } } // $FlowFixMe @@ -2125,11 +2121,7 @@ function doFetchClaimsByChannel(uri, page = 1) { lbryProxy.claim_search({ channel: uri, -<<<<<<< HEAD - valid_channel_signatures: true, -======= - is_controlling: true, ->>>>>>> add tags + valid_channel_signature: true, page: page || 1, order_by: ['release_time'] }).then(result => { diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 20b8ff0..1c61c10 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -3,8 +3,7 @@ declare type Claim = StreamClaim | ChannelClaim; declare type ChannelClaim = GenericClaim & { - is_channel_signature_valid?: boolean, // we may have signed channels in the future, fixes some flow issues for now. - signing_channel?: ChannelClaim, + is_channel_signature_valid?: boolean, // we may have signed channels in the future value: ChannelMetadata, }; -- 2.45.2 From 862ea676804708c46bf4ad59806c6ca8e5157c71 Mon Sep 17 00:00:00 2001 From: Jessop Breth Date: Tue, 11 Jun 2019 21:14:37 -0400 Subject: [PATCH 040/371] changes for comments --- dist/bundle.es.js | 184 +++++++++++++++++++++++++++++++- dist/flow-typed/Comment.js | 18 ++++ dist/flow-typed/Lbry.js | 6 ++ flow-typed/Comment.js | 18 ++++ flow-typed/Lbry.js | 6 ++ src/constants/action_types.js | 8 ++ src/index.js | 5 + src/lbry.js | 3 + src/redux/actions/comments.js | 82 ++++++++++++++ src/redux/reducers/comments.js | 66 ++++++++++++ src/redux/selectors/comments.js | 36 +++++++ 11 files changed, 429 insertions(+), 3 deletions(-) create mode 100644 dist/flow-typed/Comment.js create mode 100644 flow-typed/Comment.js create mode 100644 src/redux/actions/comments.js create mode 100644 src/redux/reducers/comments.js create mode 100644 src/redux/selectors/comments.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 71bf2e5..e4cc141 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -102,6 +102,14 @@ const CLAIM_SEARCH_STARTED = 'CLAIM_SEARCH_STARTED'; const CLAIM_SEARCH_COMPLETED = 'CLAIM_SEARCH_COMPLETED'; const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; +// Comments +const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; +const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED'; +const COMMENT_LIST_UPDATED = 'COMMENT_LIST_UPDATED'; +const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; +const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; +const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; + // Files const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; @@ -318,6 +326,12 @@ var action_types = /*#__PURE__*/Object.freeze({ CLAIM_SEARCH_STARTED: CLAIM_SEARCH_STARTED, CLAIM_SEARCH_COMPLETED: CLAIM_SEARCH_COMPLETED, CLAIM_SEARCH_FAILED: CLAIM_SEARCH_FAILED, + COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, + COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, + COMMENT_LIST_UPDATED: COMMENT_LIST_UPDATED, + COMMENT_CREATE_STARTED: COMMENT_CREATE_STARTED, + COMMENT_CREATE_COMPLETED: COMMENT_CREATE_COMPLETED, + COMMENT_CREATE_FAILED: COMMENT_CREATE_FAILED, FILE_LIST_STARTED: FILE_LIST_STARTED, FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, @@ -676,6 +690,9 @@ const Lbry = { sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), + // Comments + comment_list: (params = {}) => daemonCallWithResult('comment_list', params), + comment_create: (params = {}) => daemonCallWithResult('comment_create', params), // Connect to the sdk connect: () => { if (Lbry.connectPromise === null) { @@ -2761,6 +2778,74 @@ const doDeleteTag = name => ({ } }); +// + +function doCommentList(uri) { + return (dispatch, getState) => { + const state = getState(); + const claim = selectClaimsByUri(state)[uri]; + const claimId = claim ? claim.claim_id : null; + + dispatch({ + type: COMMENT_LIST_STARTED + }); + lbryProxy.comment_list({ + claim_id: claimId + }).then(results => { + dispatch({ + type: COMMENT_LIST_COMPLETED, + data: { + comments: results, + claimId: claimId, + uri: uri + } + }); + }).catch(error => { + console.log(error); + }); + }; +} + +function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { + return (dispatch, getState) => { + const state = getState(); + dispatch({ + type: COMMENT_CREATE_STARTED + }); + const myChannels = selectMyChannelClaims(state); + const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); + const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null; + return lbryProxy.comment_create({ + comment, + claim_id, + channel_id + }).then(result => { + dispatch({ + type: COMMENT_CREATE_COMPLETED, + data: { + response: result + } + }); + dispatch({ + type: COMMENT_LIST_UPDATED, + data: { + comment: result, + claimId: claim_id + } + }); + }).catch(error => { + dispatch({ + type: COMMENT_CREATE_FAILED, + data: error + }); + dispatch(doToast({ + message: 'Oops, someone broke comments.', + isError: true + })); + }); + }; +} + var _extends$4 = 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; }; const reducers = {}; @@ -3724,6 +3809,70 @@ function contentReducer(state = defaultState$6, action) { return state; } +// + +// TODO change to handleActions() +// const commentsReducer = handleActions( { +const reducers$4 = {}; + +const defaultState$7 = { + byId: {}, + commentsByUri: {}, + isLoading: false +}; + +reducers$4[COMMENT_CREATE_STARTED] = (state, action) => Object.assign({}, state, { + isLoading: true +}); + +reducers$4[COMMENT_CREATE_FAILED] = (state, action) => { + // TODO: handle error.. what else? + return state; +}; + +reducers$4[COMMENT_CREATE_COMPLETED] = (state, action) => { + const { comments } = action.data; + return state; +}; + +reducers$4[COMMENT_LIST_UPDATED] = (state, action) => { + const { comment, claimId } = action.data; + const byId = Object.assign({}, state.byId); + const comments = byId[claimId]; + const newComments = comments.slice(); + newComments.unshift(comment); + byId[claimId] = newComments; + return Object.assign({}, state, { + byId + }); +}; + +reducers$4[COMMENT_LIST_STARTED] = state => Object.assign({}, state, { + isLoading: true +}); + +reducers$4[COMMENT_LIST_COMPLETED] = (state, action) => { + const { comments, claimId, uri } = action.data; + const byId = Object.assign({}, state.byId); + const commentsByUri = Object.assign({}, state.commentsByUri); + + if (comments['items']) { + byId[claimId] = comments['items']; + commentsByUri[uri] = claimId; + } + return Object.assign({}, state, { + byId, + commentsByUri, + isLoading: false + }); +}; + +function commentReducer(state = defaultState$7, action) { + const handler = reducers$4[action.type]; + if (handler) return handler(state, action); + return state; +} + 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; }; const tagsReducerBuilder = defaultState => handleActions({ @@ -3810,11 +3959,36 @@ const selectError = reselect.createSelector(selectState$6, state => { // -const selectState$7 = state => state.tags || {}; +const selectState$7 = state => state.comments || {}; -const selectKnownTagsByName = reselect.createSelector(selectState$7, state => state.knownTags); +const selectCommentsById = reselect.createSelector(selectState$7, state => state.byId || {}); -const selectFollowedTagsList = reselect.createSelector(selectState$7, state => state.followedTags); +const selectCommentsByUri = reselect.createSelector(selectState$7, state => { + const byUri = state.commentsByUri || {}; + const comments = {}; + Object.keys(byUri).forEach(uri => { + const claimId = byUri[uri]; + if (claimId === null) { + comments[uri] = null; + } else { + comments[uri] = claimId; + } + }); + return comments; +}); + +const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsById, selectCommentsByUri, (byId, byUri) => { + const claimId = byUri[uri]; + return byId && byId[claimId]; +}); + +// + +const selectState$8 = state => state.tags || {}; + +const selectKnownTagsByName = reselect.createSelector(selectState$8, state => state.knownTags); + +const selectFollowedTagsList = reselect.createSelector(selectState$8, state => state.followedTags); const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag })).sort((a, b) => a.name.localeCompare(b.name))); @@ -3844,6 +4018,7 @@ exports.TRANSACTIONS = transaction_types; exports.batchActions = batchActions; exports.buildURI = buildURI; exports.claimsReducer = claimsReducer; +exports.commentReducer = commentReducer; exports.contentReducer = contentReducer; exports.convertToShareLink = convertToShareLink; exports.creditsToString = creditsToString; @@ -3853,6 +4028,8 @@ exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doClaimSearch = doClaimSearch; +exports.doCommentCreate = doCommentCreate; +exports.doCommentList = doCommentList; exports.doCreateChannel = doCreateChannel; exports.doDeletePurchasedUri = doDeletePurchasedUri; exports.doDeleteTag = doDeleteTag; @@ -3906,6 +4083,7 @@ exports.makeSelectClaimIsNsfw = makeSelectClaimIsNsfw; exports.makeSelectClaimIsPending = makeSelectClaimIsPending; exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannelForCurrentPageState; exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; +exports.makeSelectCommentsForUri = makeSelectCommentsForUri; exports.makeSelectContentPositionForUri = makeSelectContentPositionForUri; exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; exports.makeSelectCoverForUri = makeSelectCoverForUri; diff --git a/dist/flow-typed/Comment.js b/dist/flow-typed/Comment.js new file mode 100644 index 0000000..808dda8 --- /dev/null +++ b/dist/flow-typed/Comment.js @@ -0,0 +1,18 @@ +declare type Comment = { + author: string, + claim_index?: number, + comment_id?: number, + downvotes?: number, + message: string, + omitted?: number, + reply_count?: number, + time_posted?: number, + upvotes?: number, + parent_id?: number, +}; + +declare type CommentsState = { + byId: {}, + isLoading: boolean, + commentsByUri: { [string]: string }, +} diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index d67a17d..9931f68 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -105,6 +105,9 @@ declare type ChannelCreateResponse = GenericTxResponse & { outputs: Array, }; +declare type CommentCreateResponse = Comment; +declare type CommentListResponse = Array; + declare type ChannelListResponse = Array; declare type FileListResponse = Array; @@ -184,6 +187,9 @@ declare type LbryTypes = { blob_delete: (params: {}) => Promise, blob_list: (params: {}) => Promise, + // Commenting + comment_list: (params: {}) => Promise, + comment_create: (params: {}) => Promise, // Wallet utilities account_balance: (params: {}) => Promise, account_decrypt: (prams: {}) => Promise, diff --git a/flow-typed/Comment.js b/flow-typed/Comment.js new file mode 100644 index 0000000..808dda8 --- /dev/null +++ b/flow-typed/Comment.js @@ -0,0 +1,18 @@ +declare type Comment = { + author: string, + claim_index?: number, + comment_id?: number, + downvotes?: number, + message: string, + omitted?: number, + reply_count?: number, + time_posted?: number, + upvotes?: number, + parent_id?: number, +}; + +declare type CommentsState = { + byId: {}, + isLoading: boolean, + commentsByUri: { [string]: string }, +} diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index d67a17d..9931f68 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -105,6 +105,9 @@ declare type ChannelCreateResponse = GenericTxResponse & { outputs: Array, }; +declare type CommentCreateResponse = Comment; +declare type CommentListResponse = Array; + declare type ChannelListResponse = Array; declare type FileListResponse = Array; @@ -184,6 +187,9 @@ declare type LbryTypes = { blob_delete: (params: {}) => Promise, blob_list: (params: {}) => Promise, + // Commenting + comment_list: (params: {}) => Promise, + comment_create: (params: {}) => Promise, // Wallet utilities account_balance: (params: {}) => Promise, account_decrypt: (prams: {}) => Promise, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 80acf3f..c1427fb 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -92,6 +92,14 @@ export const CLAIM_SEARCH_STARTED = 'CLAIM_SEARCH_STARTED'; export const CLAIM_SEARCH_COMPLETED = 'CLAIM_SEARCH_COMPLETED'; export const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; +// Comments +export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; +export const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED'; +export const COMMENT_LIST_UPDATED = 'COMMENT_LIST_UPDATED'; +export const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; +export const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; +export const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; + // Files export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; export const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; diff --git a/src/index.js b/src/index.js index 4ae019e..0e88ed3 100644 --- a/src/index.js +++ b/src/index.js @@ -90,6 +90,8 @@ export { 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'; @@ -104,6 +106,7 @@ export { notificationsReducer } from 'redux/reducers/notifications'; export { searchReducer } from 'redux/reducers/search'; export { walletReducer } from 'redux/reducers/wallet'; export { contentReducer } from 'redux/reducers/content'; +export { commentReducer } from 'redux/reducers/comments'; export { tagsReducerBuilder } from 'redux/reducers/tags'; // selectors @@ -170,6 +173,8 @@ export { selectLastClaimSearchUris, } from 'redux/selectors/claims'; +export { makeSelectCommentsForUri } from 'redux/selectors/comments'; + export { makeSelectFileInfoForUri, makeSelectDownloadingForUri, diff --git a/src/lbry.js b/src/lbry.js index 3ac88ad..617b24b 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -100,6 +100,9 @@ const Lbry: LbryTypes = { sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), + // Comments + comment_list: (params = {}) => daemonCallWithResult('comment_list', params), + comment_create: (params = {}) => daemonCallWithResult('comment_create', params), // Connect to the sdk connect: () => { if (Lbry.connectPromise === null) { diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js new file mode 100644 index 0000000..6d48802 --- /dev/null +++ b/src/redux/actions/comments.js @@ -0,0 +1,82 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; +import Lbry from 'lbry'; +import { selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims'; +import { doToast } from 'redux/actions/notifications'; + +export function doCommentList(uri: string) { + return (dispatch: Dispatch, getState: GetState) => { + const state = getState(); + const claim = selectClaimsByUri(state)[uri]; + const claimId = claim ? claim.claim_id : null; + + dispatch({ + type: ACTIONS.COMMENT_LIST_STARTED, + }); + Lbry.comment_list({ + claim_id: claimId, + }) + .then(results => { + dispatch({ + type: ACTIONS.COMMENT_LIST_COMPLETED, + data: { + comments: results, + claimId: claimId, + uri: uri, + }, + }); + }) + .catch(error => { + console.log(error); + }); + }; +} + +export function doCommentCreate( + comment: string = '', + claim_id: string = '', + channel: ?string, + parent_id?: number +) { + return (dispatch: Dispatch, getState: GetState) => { + const state = getState(); + dispatch({ + type: ACTIONS.COMMENT_CREATE_STARTED, + }); + const myChannels = selectMyChannelClaims(state); + const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); + const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null; + return Lbry.comment_create({ + comment, + claim_id, + channel_id, + }) + .then((result: Comment) => { + dispatch({ + type: ACTIONS.COMMENT_CREATE_COMPLETED, + data: { + response: result, + }, + }); + dispatch({ + type: ACTIONS.COMMENT_LIST_UPDATED, + data: { + comment: result, + claimId: claim_id, + }, + }); + }) + .catch(error => { + dispatch({ + type: ACTIONS.COMMENT_CREATE_FAILED, + data: error, + }); + dispatch( + doToast({ + message: 'Oops, someone broke comments.', + isError: true, + }) + ); + }); + }; +} diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js new file mode 100644 index 0000000..06895a3 --- /dev/null +++ b/src/redux/reducers/comments.js @@ -0,0 +1,66 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; + +// TODO change to handleActions() +// const commentsReducer = handleActions( { +const reducers = {}; + +const defaultState: CommentsState = { + byId: {}, + commentsByUri: {}, + isLoading: false, +}; + +reducers[ACTIONS.COMMENT_CREATE_STARTED] = (state: CommentsState, action: any): CommentsState => + Object.assign({}, state, { + isLoading: true, + }); + +reducers[ACTIONS.COMMENT_CREATE_FAILED] = (state: CommentsState, action: any): CommentsState => { + // TODO: handle error.. what else? + return state; +}; + +reducers[ACTIONS.COMMENT_CREATE_COMPLETED] = (state: CommentsState, action: any): CommentsState => { + const { comments }: any = action.data; + return state; +}; + +reducers[ACTIONS.COMMENT_LIST_UPDATED] = (state: CommentsState, action: any): CommentsState => { + const { comment, claimId }: any = action.data; + const byId = Object.assign({}, state.byId); + const comments = byId[claimId]; + const newComments = comments.slice(); + newComments.unshift(comment); + byId[claimId] = newComments; + return Object.assign({}, state, { + byId, + }); +}; + +reducers[ACTIONS.COMMENT_LIST_STARTED] = state => + Object.assign({}, state, { + isLoading: true, + }); + +reducers[ACTIONS.COMMENT_LIST_COMPLETED] = (state: CommentsState, action: any) => { + const { comments, claimId, uri } = action.data; + const byId = Object.assign({}, state.byId); + const commentsByUri = Object.assign({}, state.commentsByUri); + + if (comments['items']) { + byId[claimId] = comments['items']; + commentsByUri[uri] = claimId; + } + return Object.assign({}, state, { + byId, + commentsByUri, + isLoading: false, + }); +}; + +export function commentReducer(state: CommentsState = defaultState, action: any) { + const handler = reducers[action.type]; + if (handler) return handler(state, action); + return state; +} diff --git a/src/redux/selectors/comments.js b/src/redux/selectors/comments.js new file mode 100644 index 0000000..c391a5c --- /dev/null +++ b/src/redux/selectors/comments.js @@ -0,0 +1,36 @@ +// @flow +import { createSelector } from 'reselect'; + +const selectState = state => state.comments || {}; + +export const selectCommentsById = createSelector( + selectState, + state => state.byId || {} +); + +export const selectCommentsByUri = createSelector( + selectState, + state => { + const byUri = state.commentsByUri || {}; + const comments = {}; + Object.keys(byUri).forEach(uri => { + const claimId = byUri[uri]; + if (claimId === null) { + comments[uri] = null; + } else { + comments[uri] = claimId; + } + }); + return comments; + } +); + +export const makeSelectCommentsForUri = (uri: string) => + createSelector( + selectCommentsById, + selectCommentsByUri, + (byId, byUri) => { + const claimId = byUri[uri]; + return byId && byId[claimId]; + } + ); -- 2.45.2 From cd642e39a4e29811e0a5ee616a6104a34c7ac327 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 26 Jun 2019 19:13:29 -0400 Subject: [PATCH 041/371] respond to PR comments --- dist/bundle.es.js | 126 +++++++++++++++------------------ src/constants/action_types.js | 2 +- src/redux/actions/comments.js | 12 ++-- src/redux/reducers/comments.js | 97 ++++++++++++------------- 4 files changed, 110 insertions(+), 127 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e4cc141..8abd424 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -105,7 +105,7 @@ const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; // Comments const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED'; -const COMMENT_LIST_UPDATED = 'COMMENT_LIST_UPDATED'; +const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED'; const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; @@ -328,7 +328,7 @@ var action_types = /*#__PURE__*/Object.freeze({ CLAIM_SEARCH_FAILED: CLAIM_SEARCH_FAILED, COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, - COMMENT_LIST_UPDATED: COMMENT_LIST_UPDATED, + COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, COMMENT_CREATE_STARTED: COMMENT_CREATE_STARTED, COMMENT_CREATE_COMPLETED: COMMENT_CREATE_COMPLETED, COMMENT_CREATE_FAILED: COMMENT_CREATE_FAILED, @@ -2802,6 +2802,10 @@ function doCommentList(uri) { }); }).catch(error => { console.log(error); + dispatch({ + type: COMMENT_LIST_FAILED, + data: error + }); }); }; } @@ -2822,12 +2826,6 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { }).then(result => { dispatch({ type: COMMENT_CREATE_COMPLETED, - data: { - response: result - } - }); - dispatch({ - type: COMMENT_LIST_UPDATED, data: { comment: result, claimId: claim_id @@ -3809,11 +3807,7 @@ function contentReducer(state = defaultState$6, action) { return state; } -// - -// TODO change to handleActions() -// const commentsReducer = handleActions( { -const reducers$4 = {}; +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; }; const defaultState$7 = { byId: {}, @@ -3821,59 +3815,53 @@ const defaultState$7 = { isLoading: false }; -reducers$4[COMMENT_CREATE_STARTED] = (state, action) => Object.assign({}, state, { - isLoading: true -}); +const commentReducer = handleActions({ + [COMMENT_CREATE_STARTED]: (state, action) => _extends$b({}, state, { + isLoading: true + }), -reducers$4[COMMENT_CREATE_FAILED] = (state, action) => { - // TODO: handle error.. what else? - return state; -}; - -reducers$4[COMMENT_CREATE_COMPLETED] = (state, action) => { - const { comments } = action.data; - return state; -}; - -reducers$4[COMMENT_LIST_UPDATED] = (state, action) => { - const { comment, claimId } = action.data; - const byId = Object.assign({}, state.byId); - const comments = byId[claimId]; - const newComments = comments.slice(); - newComments.unshift(comment); - byId[claimId] = newComments; - return Object.assign({}, state, { - byId - }); -}; - -reducers$4[COMMENT_LIST_STARTED] = state => Object.assign({}, state, { - isLoading: true -}); - -reducers$4[COMMENT_LIST_COMPLETED] = (state, action) => { - const { comments, claimId, uri } = action.data; - const byId = Object.assign({}, state.byId); - const commentsByUri = Object.assign({}, state.commentsByUri); - - if (comments['items']) { - byId[claimId] = comments['items']; - commentsByUri[uri] = claimId; - } - return Object.assign({}, state, { - byId, - commentsByUri, + [COMMENT_CREATE_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false - }); -}; + }), -function commentReducer(state = defaultState$7, action) { - const handler = reducers$4[action.type]; - if (handler) return handler(state, action); - return state; -} + [COMMENT_CREATE_COMPLETED]: (state, action) => { + const { comment, claimId } = action.data; + const byId = Object.assign({}, state.byId); + const comments = byId[claimId]; + const newComments = comments.slice(); -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; }; + newComments.unshift(comment); + byId[claimId] = newComments; + + return _extends$b({}, state, { + byId + }); + }, + + [COMMENT_LIST_STARTED]: state => _extends$b({}, state, { isLoading: true }), + + [COMMENT_LIST_COMPLETED]: (state, action) => { + const { comments, claimId, uri } = action.data; + const byId = Object.assign({}, state.byId); + const commentsByUri = Object.assign({}, state.commentsByUri); + + if (comments['items']) { + byId[claimId] = comments['items']; + commentsByUri[uri] = claimId; + } + return _extends$b({}, state, { + byId, + commentsByUri, + isLoading: false + }); + }, + + [COMMENT_LIST_FAILED]: (state, action) => _extends$b({}, state, { + isLoading: false + }) +}, defaultState$7); + +var _extends$c = 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; }; const tagsReducerBuilder = defaultState => handleActions({ [TOGGLE_TAG_FOLLOW]: (state, action) => { @@ -3888,7 +3876,7 @@ const tagsReducerBuilder = defaultState => handleActions({ newFollowedTags.push(name); } - return _extends$b({}, state, { + return _extends$c({}, state, { followedTags: newFollowedTags }); }, @@ -3897,10 +3885,10 @@ const tagsReducerBuilder = defaultState => handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$b({}, knownTags); + let newKnownTags = _extends$c({}, knownTags); newKnownTags[name] = { name }; - return _extends$b({}, state, { + return _extends$c({}, state, { knownTags: newKnownTags }); }, @@ -3909,11 +3897,11 @@ const tagsReducerBuilder = defaultState => handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$b({}, knownTags); + let newKnownTags = _extends$c({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$b({}, state, { + return _extends$c({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -3931,14 +3919,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$c = 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; }; +var _extends$d = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$c({ + return _extends$d({ id }, params); } diff --git a/src/constants/action_types.js b/src/constants/action_types.js index c1427fb..3fa9547 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -95,7 +95,7 @@ export const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; // Comments export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; export const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED'; -export const COMMENT_LIST_UPDATED = 'COMMENT_LIST_UPDATED'; +export const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED'; export const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; export const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; export const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 6d48802..3de70e6 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -16,7 +16,7 @@ export function doCommentList(uri: string) { Lbry.comment_list({ claim_id: claimId, }) - .then(results => { + .then((results: CommentListResponse) => { dispatch({ type: ACTIONS.COMMENT_LIST_COMPLETED, data: { @@ -28,6 +28,10 @@ export function doCommentList(uri: string) { }) .catch(error => { console.log(error); + dispatch({ + type: ACTIONS.COMMENT_LIST_FAILED, + data: error, + }); }); }; } @@ -54,12 +58,6 @@ export function doCommentCreate( .then((result: Comment) => { dispatch({ type: ACTIONS.COMMENT_CREATE_COMPLETED, - data: { - response: result, - }, - }); - dispatch({ - type: ACTIONS.COMMENT_LIST_UPDATED, data: { comment: result, claimId: claim_id, diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js index 06895a3..1f99467 100644 --- a/src/redux/reducers/comments.js +++ b/src/redux/reducers/comments.js @@ -1,9 +1,6 @@ // @flow import * as ACTIONS from 'constants/action_types'; - -// TODO change to handleActions() -// const commentsReducer = handleActions( { -const reducers = {}; +import { handleActions } from 'util/redux-utils'; const defaultState: CommentsState = { byId: {}, @@ -11,56 +8,56 @@ const defaultState: CommentsState = { isLoading: false, }; -reducers[ACTIONS.COMMENT_CREATE_STARTED] = (state: CommentsState, action: any): CommentsState => - Object.assign({}, state, { - isLoading: true, - }); +export const commentReducer = handleActions( + { + [ACTIONS.COMMENT_CREATE_STARTED]: (state: CommentsState, action: any): CommentsState => ({ + ...state, + isLoading: true, + }), -reducers[ACTIONS.COMMENT_CREATE_FAILED] = (state: CommentsState, action: any): CommentsState => { - // TODO: handle error.. what else? - return state; -}; + [ACTIONS.COMMENT_CREATE_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), -reducers[ACTIONS.COMMENT_CREATE_COMPLETED] = (state: CommentsState, action: any): CommentsState => { - const { comments }: any = action.data; - return state; -}; + [ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => { + const { comment, claimId }: any = action.data; + const byId = Object.assign({}, state.byId); + const comments = byId[claimId]; + const newComments = comments.slice(); -reducers[ACTIONS.COMMENT_LIST_UPDATED] = (state: CommentsState, action: any): CommentsState => { - const { comment, claimId }: any = action.data; - const byId = Object.assign({}, state.byId); - const comments = byId[claimId]; - const newComments = comments.slice(); - newComments.unshift(comment); - byId[claimId] = newComments; - return Object.assign({}, state, { - byId, - }); -}; + newComments.unshift(comment); + byId[claimId] = newComments; -reducers[ACTIONS.COMMENT_LIST_STARTED] = state => - Object.assign({}, state, { - isLoading: true, - }); + return { + ...state, + byId, + }; + }, -reducers[ACTIONS.COMMENT_LIST_COMPLETED] = (state: CommentsState, action: any) => { - const { comments, claimId, uri } = action.data; - const byId = Object.assign({}, state.byId); - const commentsByUri = Object.assign({}, state.commentsByUri); + [ACTIONS.COMMENT_LIST_STARTED]: state => ({ ...state, isLoading: true }), - if (comments['items']) { - byId[claimId] = comments['items']; - commentsByUri[uri] = claimId; - } - return Object.assign({}, state, { - byId, - commentsByUri, - isLoading: false, - }); -}; + [ACTIONS.COMMENT_LIST_COMPLETED]: (state: CommentsState, action: any) => { + const { comments, claimId, uri } = action.data; + const byId = Object.assign({}, state.byId); + const commentsByUri = Object.assign({}, state.commentsByUri); -export function commentReducer(state: CommentsState = defaultState, action: any) { - const handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} + if (comments['items']) { + byId[claimId] = comments['items']; + commentsByUri[uri] = claimId; + } + return { + ...state, + byId, + commentsByUri, + isLoading: false, + }; + }, + + [ACTIONS.COMMENT_LIST_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + }, + defaultState +); -- 2.45.2 From 99e08fc7332c2e6e3eb261cccb372984c0160c62 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 1 Jul 2019 20:49:51 +0100 Subject: [PATCH 042/371] Publishing (#158) * add actions, selectors and reducer for publishing * add publish types * support thumbnail uploads for mobile * update publishSuccess value in reducer --- dist/bundle.es.js | 1731 +++++++++++++++++++++----------- dist/flow-typed/Publish.js | 51 + flow-typed/Publish.js | 51 + src/constants/claim.js | 5 + src/constants/licenses.js | 31 + src/index.js | 43 +- src/redux/actions/publish.js | 404 ++++++++ src/redux/reducers/publish.js | 107 ++ src/redux/selectors/publish.js | 105 ++ src/util/uri.js | 13 + 10 files changed, 1949 insertions(+), 592 deletions(-) create mode 100644 dist/flow-typed/Publish.js create mode 100644 flow-typed/Publish.js create mode 100644 src/constants/claim.js create mode 100644 src/constants/licenses.js create mode 100644 src/redux/actions/publish.js create mode 100644 src/redux/reducers/publish.js create mode 100644 src/redux/selectors/publish.js create mode 100644 src/util/uri.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8abd424..f29e5ca 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -8,6 +8,19 @@ require('proxy-polyfill'); var reselect = require('reselect'); var uuid = _interopDefault(require('uuid/v4')); +const MINIMUM_PUBLISH_BID = 0.00000001; + +const CHANNEL_ANONYMOUS = 'anonymous'; +const CHANNEL_NEW = 'new'; +const PAGE_SIZE = 20; + +var claim = /*#__PURE__*/Object.freeze({ + MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, + CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, + CHANNEL_NEW: CHANNEL_NEW, + PAGE_SIZE: PAGE_SIZE +}); + const WINDOW_FOCUSED = 'WINDOW_FOCUSED'; const DAEMON_READY = 'DAEMON_READY'; const DAEMON_VERSION_MATCH = 'DAEMON_VERSION_MATCH'; @@ -241,219 +254,284 @@ const TAG_ADD = 'TAG_ADD'; const TAG_DELETE = 'TAG_DELETE'; var action_types = /*#__PURE__*/Object.freeze({ - WINDOW_FOCUSED: WINDOW_FOCUSED, - DAEMON_READY: DAEMON_READY, - DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, - DAEMON_VERSION_MISMATCH: DAEMON_VERSION_MISMATCH, - VOLUME_CHANGED: VOLUME_CHANGED, - CHANGE_AFTER_AUTH_PATH: CHANGE_AFTER_AUTH_PATH, - WINDOW_SCROLLED: WINDOW_SCROLLED, - HISTORY_NAVIGATE: HISTORY_NAVIGATE, - UPGRADE_CANCELLED: UPGRADE_CANCELLED, - DOWNLOAD_UPGRADE: DOWNLOAD_UPGRADE, - UPGRADE_DOWNLOAD_STARTED: UPGRADE_DOWNLOAD_STARTED, - UPGRADE_DOWNLOAD_COMPLETED: UPGRADE_DOWNLOAD_COMPLETED, - UPGRADE_DOWNLOAD_PROGRESSED: UPGRADE_DOWNLOAD_PROGRESSED, - CHECK_UPGRADE_AVAILABLE: CHECK_UPGRADE_AVAILABLE, - CHECK_UPGRADE_START: CHECK_UPGRADE_START, - CHECK_UPGRADE_SUCCESS: CHECK_UPGRADE_SUCCESS, - CHECK_UPGRADE_FAIL: CHECK_UPGRADE_FAIL, - CHECK_UPGRADE_SUBSCRIBE: CHECK_UPGRADE_SUBSCRIBE, - UPDATE_VERSION: UPDATE_VERSION, - UPDATE_REMOTE_VERSION: UPDATE_REMOTE_VERSION, - SKIP_UPGRADE: SKIP_UPGRADE, - START_UPGRADE: START_UPGRADE, - AUTO_UPDATE_DECLINED: AUTO_UPDATE_DECLINED, - AUTO_UPDATE_DOWNLOADED: AUTO_UPDATE_DOWNLOADED, - CLEAR_UPGRADE_TIMER: CLEAR_UPGRADE_TIMER, - GET_NEW_ADDRESS_STARTED: GET_NEW_ADDRESS_STARTED, - GET_NEW_ADDRESS_COMPLETED: GET_NEW_ADDRESS_COMPLETED, - FETCH_TRANSACTIONS_STARTED: FETCH_TRANSACTIONS_STARTED, - FETCH_TRANSACTIONS_COMPLETED: FETCH_TRANSACTIONS_COMPLETED, - FETCH_SUPPORTS_STARTED: FETCH_SUPPORTS_STARTED, - FETCH_SUPPORTS_COMPLETED: FETCH_SUPPORTS_COMPLETED, - ABANDON_SUPPORT_STARTED: ABANDON_SUPPORT_STARTED, - ABANDON_SUPPORT_COMPLETED: ABANDON_SUPPORT_COMPLETED, - UPDATE_BALANCE: UPDATE_BALANCE, - UPDATE_TOTAL_BALANCE: UPDATE_TOTAL_BALANCE, - CHECK_ADDRESS_IS_MINE_STARTED: CHECK_ADDRESS_IS_MINE_STARTED, - CHECK_ADDRESS_IS_MINE_COMPLETED: CHECK_ADDRESS_IS_MINE_COMPLETED, - SEND_TRANSACTION_STARTED: SEND_TRANSACTION_STARTED, - SEND_TRANSACTION_COMPLETED: SEND_TRANSACTION_COMPLETED, - SEND_TRANSACTION_FAILED: SEND_TRANSACTION_FAILED, - SUPPORT_TRANSACTION_STARTED: SUPPORT_TRANSACTION_STARTED, - SUPPORT_TRANSACTION_COMPLETED: SUPPORT_TRANSACTION_COMPLETED, - SUPPORT_TRANSACTION_FAILED: SUPPORT_TRANSACTION_FAILED, - WALLET_ENCRYPT_START: WALLET_ENCRYPT_START, - WALLET_ENCRYPT_COMPLETED: WALLET_ENCRYPT_COMPLETED, - WALLET_ENCRYPT_FAILED: WALLET_ENCRYPT_FAILED, - WALLET_UNLOCK_START: WALLET_UNLOCK_START, - WALLET_UNLOCK_COMPLETED: WALLET_UNLOCK_COMPLETED, - WALLET_UNLOCK_FAILED: WALLET_UNLOCK_FAILED, - WALLET_DECRYPT_START: WALLET_DECRYPT_START, - WALLET_DECRYPT_COMPLETED: WALLET_DECRYPT_COMPLETED, - WALLET_DECRYPT_FAILED: WALLET_DECRYPT_FAILED, - WALLET_LOCK_START: WALLET_LOCK_START, - WALLET_LOCK_COMPLETED: WALLET_LOCK_COMPLETED, - WALLET_LOCK_FAILED: WALLET_LOCK_FAILED, - WALLET_STATUS_START: WALLET_STATUS_START, - WALLET_STATUS_COMPLETED: WALLET_STATUS_COMPLETED, - SET_TRANSACTION_LIST_FILTER: SET_TRANSACTION_LIST_FILTER, - UPDATE_CURRENT_HEIGHT: UPDATE_CURRENT_HEIGHT, - SET_DRAFT_TRANSACTION_AMOUNT: SET_DRAFT_TRANSACTION_AMOUNT, - SET_DRAFT_TRANSACTION_ADDRESS: SET_DRAFT_TRANSACTION_ADDRESS, - RESOLVE_URIS_STARTED: RESOLVE_URIS_STARTED, - RESOLVE_URIS_COMPLETED: RESOLVE_URIS_COMPLETED, - FETCH_CHANNEL_CLAIMS_STARTED: FETCH_CHANNEL_CLAIMS_STARTED, - FETCH_CHANNEL_CLAIMS_COMPLETED: FETCH_CHANNEL_CLAIMS_COMPLETED, - FETCH_CLAIM_LIST_MINE_STARTED: FETCH_CLAIM_LIST_MINE_STARTED, - FETCH_CLAIM_LIST_MINE_COMPLETED: FETCH_CLAIM_LIST_MINE_COMPLETED, - ABANDON_CLAIM_STARTED: ABANDON_CLAIM_STARTED, - ABANDON_CLAIM_SUCCEEDED: ABANDON_CLAIM_SUCCEEDED, - FETCH_CHANNEL_LIST_STARTED: FETCH_CHANNEL_LIST_STARTED, - FETCH_CHANNEL_LIST_COMPLETED: FETCH_CHANNEL_LIST_COMPLETED, - CREATE_CHANNEL_STARTED: CREATE_CHANNEL_STARTED, - CREATE_CHANNEL_COMPLETED: CREATE_CHANNEL_COMPLETED, - CREATE_CHANNEL_FAILED: CREATE_CHANNEL_FAILED, - PUBLISH_STARTED: PUBLISH_STARTED, - PUBLISH_COMPLETED: PUBLISH_COMPLETED, - PUBLISH_FAILED: PUBLISH_FAILED, - SET_PLAYING_URI: SET_PLAYING_URI, - SET_CONTENT_POSITION: SET_CONTENT_POSITION, - SET_CONTENT_LAST_VIEWED: SET_CONTENT_LAST_VIEWED, - CLEAR_CONTENT_HISTORY_URI: CLEAR_CONTENT_HISTORY_URI, - CLEAR_CONTENT_HISTORY_ALL: CLEAR_CONTENT_HISTORY_ALL, - CLAIM_SEARCH_STARTED: CLAIM_SEARCH_STARTED, - CLAIM_SEARCH_COMPLETED: CLAIM_SEARCH_COMPLETED, - CLAIM_SEARCH_FAILED: CLAIM_SEARCH_FAILED, - COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, - COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, - COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, - COMMENT_CREATE_STARTED: COMMENT_CREATE_STARTED, - COMMENT_CREATE_COMPLETED: COMMENT_CREATE_COMPLETED, - COMMENT_CREATE_FAILED: COMMENT_CREATE_FAILED, - FILE_LIST_STARTED: FILE_LIST_STARTED, - FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, - FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, - FETCH_FILE_INFO_COMPLETED: FETCH_FILE_INFO_COMPLETED, - LOADING_VIDEO_STARTED: LOADING_VIDEO_STARTED, - LOADING_VIDEO_COMPLETED: LOADING_VIDEO_COMPLETED, - LOADING_VIDEO_FAILED: LOADING_VIDEO_FAILED, - DOWNLOADING_STARTED: DOWNLOADING_STARTED, - DOWNLOADING_PROGRESSED: DOWNLOADING_PROGRESSED, - DOWNLOADING_COMPLETED: DOWNLOADING_COMPLETED, - DOWNLOADING_CANCELED: DOWNLOADING_CANCELED, - PLAY_VIDEO_STARTED: PLAY_VIDEO_STARTED, - FETCH_AVAILABILITY_STARTED: FETCH_AVAILABILITY_STARTED, - FETCH_AVAILABILITY_COMPLETED: FETCH_AVAILABILITY_COMPLETED, - FILE_DELETE: FILE_DELETE, - SET_FILE_LIST_SORT: SET_FILE_LIST_SORT, - PURCHASE_URI_STARTED: PURCHASE_URI_STARTED, - PURCHASE_URI_COMPLETED: PURCHASE_URI_COMPLETED, - PURCHASE_URI_FAILED: PURCHASE_URI_FAILED, - DELETE_PURCHASED_URI: DELETE_PURCHASED_URI, - LOADING_FILE_STARTED: LOADING_FILE_STARTED, - LOADING_FILE_COMPLETED: LOADING_FILE_COMPLETED, - LOADING_FILE_FAILED: LOADING_FILE_FAILED, - SEARCH_START: SEARCH_START, - SEARCH_SUCCESS: SEARCH_SUCCESS, - SEARCH_FAIL: SEARCH_FAIL, - UPDATE_SEARCH_QUERY: UPDATE_SEARCH_QUERY, - UPDATE_SEARCH_OPTIONS: UPDATE_SEARCH_OPTIONS, - UPDATE_SEARCH_SUGGESTIONS: UPDATE_SEARCH_SUGGESTIONS, - SEARCH_FOCUS: SEARCH_FOCUS, - SEARCH_BLUR: SEARCH_BLUR, - DAEMON_SETTINGS_RECEIVED: DAEMON_SETTINGS_RECEIVED, - CLIENT_SETTING_CHANGED: CLIENT_SETTING_CHANGED, - UPDATE_IS_NIGHT: UPDATE_IS_NIGHT, - AUTHENTICATION_STARTED: AUTHENTICATION_STARTED, - AUTHENTICATION_SUCCESS: AUTHENTICATION_SUCCESS, - AUTHENTICATION_FAILURE: AUTHENTICATION_FAILURE, - USER_EMAIL_DECLINE: USER_EMAIL_DECLINE, - USER_EMAIL_NEW_STARTED: USER_EMAIL_NEW_STARTED, - USER_EMAIL_NEW_SUCCESS: USER_EMAIL_NEW_SUCCESS, - USER_EMAIL_NEW_EXISTS: USER_EMAIL_NEW_EXISTS, - USER_EMAIL_NEW_FAILURE: USER_EMAIL_NEW_FAILURE, - USER_EMAIL_VERIFY_SET: USER_EMAIL_VERIFY_SET, - USER_EMAIL_VERIFY_STARTED: USER_EMAIL_VERIFY_STARTED, - USER_EMAIL_VERIFY_SUCCESS: USER_EMAIL_VERIFY_SUCCESS, - USER_EMAIL_VERIFY_FAILURE: USER_EMAIL_VERIFY_FAILURE, - USER_EMAIL_VERIFY_RETRY: USER_EMAIL_VERIFY_RETRY, - USER_PHONE_RESET: USER_PHONE_RESET, - USER_PHONE_NEW_STARTED: USER_PHONE_NEW_STARTED, - USER_PHONE_NEW_SUCCESS: USER_PHONE_NEW_SUCCESS, - USER_PHONE_NEW_FAILURE: USER_PHONE_NEW_FAILURE, - USER_PHONE_VERIFY_STARTED: USER_PHONE_VERIFY_STARTED, - USER_PHONE_VERIFY_SUCCESS: USER_PHONE_VERIFY_SUCCESS, - USER_PHONE_VERIFY_FAILURE: USER_PHONE_VERIFY_FAILURE, - USER_IDENTITY_VERIFY_STARTED: USER_IDENTITY_VERIFY_STARTED, - USER_IDENTITY_VERIFY_SUCCESS: USER_IDENTITY_VERIFY_SUCCESS, - USER_IDENTITY_VERIFY_FAILURE: USER_IDENTITY_VERIFY_FAILURE, - USER_FETCH_STARTED: USER_FETCH_STARTED, - USER_FETCH_SUCCESS: USER_FETCH_SUCCESS, - USER_FETCH_FAILURE: USER_FETCH_FAILURE, - USER_INVITE_STATUS_FETCH_STARTED: USER_INVITE_STATUS_FETCH_STARTED, - USER_INVITE_STATUS_FETCH_SUCCESS: USER_INVITE_STATUS_FETCH_SUCCESS, - USER_INVITE_STATUS_FETCH_FAILURE: USER_INVITE_STATUS_FETCH_FAILURE, - USER_INVITE_NEW_STARTED: USER_INVITE_NEW_STARTED, - USER_INVITE_NEW_SUCCESS: USER_INVITE_NEW_SUCCESS, - USER_INVITE_NEW_FAILURE: USER_INVITE_NEW_FAILURE, - FETCH_ACCESS_TOKEN_SUCCESS: FETCH_ACCESS_TOKEN_SUCCESS, - FETCH_REWARDS_STARTED: FETCH_REWARDS_STARTED, - FETCH_REWARDS_COMPLETED: FETCH_REWARDS_COMPLETED, - CLAIM_REWARD_STARTED: CLAIM_REWARD_STARTED, - CLAIM_REWARD_SUCCESS: CLAIM_REWARD_SUCCESS, - CLAIM_REWARD_FAILURE: CLAIM_REWARD_FAILURE, - CLAIM_REWARD_CLEAR_ERROR: CLAIM_REWARD_CLEAR_ERROR, - FETCH_REWARD_CONTENT_COMPLETED: FETCH_REWARD_CONTENT_COMPLETED, - DOWNLOAD_LANGUAGE_SUCCEEDED: DOWNLOAD_LANGUAGE_SUCCEEDED, - DOWNLOAD_LANGUAGE_FAILED: DOWNLOAD_LANGUAGE_FAILED, - CHANNEL_SUBSCRIBE: CHANNEL_SUBSCRIBE, - CHANNEL_UNSUBSCRIBE: CHANNEL_UNSUBSCRIBE, - HAS_FETCHED_SUBSCRIPTIONS: HAS_FETCHED_SUBSCRIPTIONS, - SET_SUBSCRIPTION_LATEST: SET_SUBSCRIPTION_LATEST, - SET_SUBSCRIPTION_NOTIFICATION: SET_SUBSCRIPTION_NOTIFICATION, - SET_SUBSCRIPTION_NOTIFICATIONS: SET_SUBSCRIPTION_NOTIFICATIONS, - CHECK_SUBSCRIPTION_STARTED: CHECK_SUBSCRIPTION_STARTED, - CHECK_SUBSCRIPTION_COMPLETED: CHECK_SUBSCRIPTION_COMPLETED, - CHECK_SUBSCRIPTIONS_SUBSCRIBE: CHECK_SUBSCRIPTIONS_SUBSCRIBE, - CLEAR_PUBLISH: CLEAR_PUBLISH, - UPDATE_PUBLISH_FORM: UPDATE_PUBLISH_FORM, - PUBLISH_START: PUBLISH_START, - PUBLISH_SUCCESS: PUBLISH_SUCCESS, - PUBLISH_FAIL: PUBLISH_FAIL, - CLEAR_PUBLISH_ERROR: CLEAR_PUBLISH_ERROR, - REMOVE_PENDING_PUBLISH: REMOVE_PENDING_PUBLISH, - DO_PREPARE_EDIT: DO_PREPARE_EDIT, - CREATE_NOTIFICATION: CREATE_NOTIFICATION, - EDIT_NOTIFICATION: EDIT_NOTIFICATION, - DELETE_NOTIFICATION: DELETE_NOTIFICATION, - DISMISS_NOTIFICATION: DISMISS_NOTIFICATION, - CREATE_TOAST: CREATE_TOAST, - DISMISS_TOAST: DISMISS_TOAST, - CREATE_ERROR: CREATE_ERROR, - DISMISS_ERROR: DISMISS_ERROR, - FETCH_DATE: FETCH_DATE, - FETCH_COST_INFO_STARTED: FETCH_COST_INFO_STARTED, - FETCH_COST_INFO_COMPLETED: FETCH_COST_INFO_COMPLETED, - FETCH_COST_INFO_FAILED: FETCH_COST_INFO_FAILED, - TOGGLE_TAG_FOLLOW: TOGGLE_TAG_FOLLOW, - TAG_ADD: TAG_ADD, - TAG_DELETE: TAG_DELETE + WINDOW_FOCUSED: WINDOW_FOCUSED, + DAEMON_READY: DAEMON_READY, + DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, + DAEMON_VERSION_MISMATCH: DAEMON_VERSION_MISMATCH, + VOLUME_CHANGED: VOLUME_CHANGED, + CHANGE_AFTER_AUTH_PATH: CHANGE_AFTER_AUTH_PATH, + WINDOW_SCROLLED: WINDOW_SCROLLED, + HISTORY_NAVIGATE: HISTORY_NAVIGATE, + UPGRADE_CANCELLED: UPGRADE_CANCELLED, + DOWNLOAD_UPGRADE: DOWNLOAD_UPGRADE, + UPGRADE_DOWNLOAD_STARTED: UPGRADE_DOWNLOAD_STARTED, + UPGRADE_DOWNLOAD_COMPLETED: UPGRADE_DOWNLOAD_COMPLETED, + UPGRADE_DOWNLOAD_PROGRESSED: UPGRADE_DOWNLOAD_PROGRESSED, + CHECK_UPGRADE_AVAILABLE: CHECK_UPGRADE_AVAILABLE, + CHECK_UPGRADE_START: CHECK_UPGRADE_START, + CHECK_UPGRADE_SUCCESS: CHECK_UPGRADE_SUCCESS, + CHECK_UPGRADE_FAIL: CHECK_UPGRADE_FAIL, + CHECK_UPGRADE_SUBSCRIBE: CHECK_UPGRADE_SUBSCRIBE, + UPDATE_VERSION: UPDATE_VERSION, + UPDATE_REMOTE_VERSION: UPDATE_REMOTE_VERSION, + SKIP_UPGRADE: SKIP_UPGRADE, + START_UPGRADE: START_UPGRADE, + AUTO_UPDATE_DECLINED: AUTO_UPDATE_DECLINED, + AUTO_UPDATE_DOWNLOADED: AUTO_UPDATE_DOWNLOADED, + CLEAR_UPGRADE_TIMER: CLEAR_UPGRADE_TIMER, + GET_NEW_ADDRESS_STARTED: GET_NEW_ADDRESS_STARTED, + GET_NEW_ADDRESS_COMPLETED: GET_NEW_ADDRESS_COMPLETED, + FETCH_TRANSACTIONS_STARTED: FETCH_TRANSACTIONS_STARTED, + FETCH_TRANSACTIONS_COMPLETED: FETCH_TRANSACTIONS_COMPLETED, + FETCH_SUPPORTS_STARTED: FETCH_SUPPORTS_STARTED, + FETCH_SUPPORTS_COMPLETED: FETCH_SUPPORTS_COMPLETED, + ABANDON_SUPPORT_STARTED: ABANDON_SUPPORT_STARTED, + ABANDON_SUPPORT_COMPLETED: ABANDON_SUPPORT_COMPLETED, + UPDATE_BALANCE: UPDATE_BALANCE, + UPDATE_TOTAL_BALANCE: UPDATE_TOTAL_BALANCE, + CHECK_ADDRESS_IS_MINE_STARTED: CHECK_ADDRESS_IS_MINE_STARTED, + CHECK_ADDRESS_IS_MINE_COMPLETED: CHECK_ADDRESS_IS_MINE_COMPLETED, + SEND_TRANSACTION_STARTED: SEND_TRANSACTION_STARTED, + SEND_TRANSACTION_COMPLETED: SEND_TRANSACTION_COMPLETED, + SEND_TRANSACTION_FAILED: SEND_TRANSACTION_FAILED, + SUPPORT_TRANSACTION_STARTED: SUPPORT_TRANSACTION_STARTED, + SUPPORT_TRANSACTION_COMPLETED: SUPPORT_TRANSACTION_COMPLETED, + SUPPORT_TRANSACTION_FAILED: SUPPORT_TRANSACTION_FAILED, + WALLET_ENCRYPT_START: WALLET_ENCRYPT_START, + WALLET_ENCRYPT_COMPLETED: WALLET_ENCRYPT_COMPLETED, + WALLET_ENCRYPT_FAILED: WALLET_ENCRYPT_FAILED, + WALLET_UNLOCK_START: WALLET_UNLOCK_START, + WALLET_UNLOCK_COMPLETED: WALLET_UNLOCK_COMPLETED, + WALLET_UNLOCK_FAILED: WALLET_UNLOCK_FAILED, + WALLET_DECRYPT_START: WALLET_DECRYPT_START, + WALLET_DECRYPT_COMPLETED: WALLET_DECRYPT_COMPLETED, + WALLET_DECRYPT_FAILED: WALLET_DECRYPT_FAILED, + WALLET_LOCK_START: WALLET_LOCK_START, + WALLET_LOCK_COMPLETED: WALLET_LOCK_COMPLETED, + WALLET_LOCK_FAILED: WALLET_LOCK_FAILED, + WALLET_STATUS_START: WALLET_STATUS_START, + WALLET_STATUS_COMPLETED: WALLET_STATUS_COMPLETED, + SET_TRANSACTION_LIST_FILTER: SET_TRANSACTION_LIST_FILTER, + UPDATE_CURRENT_HEIGHT: UPDATE_CURRENT_HEIGHT, + SET_DRAFT_TRANSACTION_AMOUNT: SET_DRAFT_TRANSACTION_AMOUNT, + SET_DRAFT_TRANSACTION_ADDRESS: SET_DRAFT_TRANSACTION_ADDRESS, + RESOLVE_URIS_STARTED: RESOLVE_URIS_STARTED, + RESOLVE_URIS_COMPLETED: RESOLVE_URIS_COMPLETED, + FETCH_CHANNEL_CLAIMS_STARTED: FETCH_CHANNEL_CLAIMS_STARTED, + FETCH_CHANNEL_CLAIMS_COMPLETED: FETCH_CHANNEL_CLAIMS_COMPLETED, + FETCH_CLAIM_LIST_MINE_STARTED: FETCH_CLAIM_LIST_MINE_STARTED, + FETCH_CLAIM_LIST_MINE_COMPLETED: FETCH_CLAIM_LIST_MINE_COMPLETED, + ABANDON_CLAIM_STARTED: ABANDON_CLAIM_STARTED, + ABANDON_CLAIM_SUCCEEDED: ABANDON_CLAIM_SUCCEEDED, + FETCH_CHANNEL_LIST_STARTED: FETCH_CHANNEL_LIST_STARTED, + FETCH_CHANNEL_LIST_COMPLETED: FETCH_CHANNEL_LIST_COMPLETED, + CREATE_CHANNEL_STARTED: CREATE_CHANNEL_STARTED, + CREATE_CHANNEL_COMPLETED: CREATE_CHANNEL_COMPLETED, + CREATE_CHANNEL_FAILED: CREATE_CHANNEL_FAILED, + PUBLISH_STARTED: PUBLISH_STARTED, + PUBLISH_COMPLETED: PUBLISH_COMPLETED, + PUBLISH_FAILED: PUBLISH_FAILED, + SET_PLAYING_URI: SET_PLAYING_URI, + SET_CONTENT_POSITION: SET_CONTENT_POSITION, + SET_CONTENT_LAST_VIEWED: SET_CONTENT_LAST_VIEWED, + CLEAR_CONTENT_HISTORY_URI: CLEAR_CONTENT_HISTORY_URI, + CLEAR_CONTENT_HISTORY_ALL: CLEAR_CONTENT_HISTORY_ALL, + CLAIM_SEARCH_STARTED: CLAIM_SEARCH_STARTED, + CLAIM_SEARCH_COMPLETED: CLAIM_SEARCH_COMPLETED, + CLAIM_SEARCH_FAILED: CLAIM_SEARCH_FAILED, + COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, + COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, + COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, + COMMENT_CREATE_STARTED: COMMENT_CREATE_STARTED, + COMMENT_CREATE_COMPLETED: COMMENT_CREATE_COMPLETED, + COMMENT_CREATE_FAILED: COMMENT_CREATE_FAILED, + FILE_LIST_STARTED: FILE_LIST_STARTED, + FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, + FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, + FETCH_FILE_INFO_COMPLETED: FETCH_FILE_INFO_COMPLETED, + LOADING_VIDEO_STARTED: LOADING_VIDEO_STARTED, + LOADING_VIDEO_COMPLETED: LOADING_VIDEO_COMPLETED, + LOADING_VIDEO_FAILED: LOADING_VIDEO_FAILED, + DOWNLOADING_STARTED: DOWNLOADING_STARTED, + DOWNLOADING_PROGRESSED: DOWNLOADING_PROGRESSED, + DOWNLOADING_COMPLETED: DOWNLOADING_COMPLETED, + DOWNLOADING_CANCELED: DOWNLOADING_CANCELED, + PLAY_VIDEO_STARTED: PLAY_VIDEO_STARTED, + FETCH_AVAILABILITY_STARTED: FETCH_AVAILABILITY_STARTED, + FETCH_AVAILABILITY_COMPLETED: FETCH_AVAILABILITY_COMPLETED, + FILE_DELETE: FILE_DELETE, + SET_FILE_LIST_SORT: SET_FILE_LIST_SORT, + PURCHASE_URI_STARTED: PURCHASE_URI_STARTED, + PURCHASE_URI_COMPLETED: PURCHASE_URI_COMPLETED, + PURCHASE_URI_FAILED: PURCHASE_URI_FAILED, + DELETE_PURCHASED_URI: DELETE_PURCHASED_URI, + LOADING_FILE_STARTED: LOADING_FILE_STARTED, + LOADING_FILE_COMPLETED: LOADING_FILE_COMPLETED, + LOADING_FILE_FAILED: LOADING_FILE_FAILED, + SEARCH_START: SEARCH_START, + SEARCH_SUCCESS: SEARCH_SUCCESS, + SEARCH_FAIL: SEARCH_FAIL, + UPDATE_SEARCH_QUERY: UPDATE_SEARCH_QUERY, + UPDATE_SEARCH_OPTIONS: UPDATE_SEARCH_OPTIONS, + UPDATE_SEARCH_SUGGESTIONS: UPDATE_SEARCH_SUGGESTIONS, + SEARCH_FOCUS: SEARCH_FOCUS, + SEARCH_BLUR: SEARCH_BLUR, + DAEMON_SETTINGS_RECEIVED: DAEMON_SETTINGS_RECEIVED, + CLIENT_SETTING_CHANGED: CLIENT_SETTING_CHANGED, + UPDATE_IS_NIGHT: UPDATE_IS_NIGHT, + AUTHENTICATION_STARTED: AUTHENTICATION_STARTED, + AUTHENTICATION_SUCCESS: AUTHENTICATION_SUCCESS, + AUTHENTICATION_FAILURE: AUTHENTICATION_FAILURE, + USER_EMAIL_DECLINE: USER_EMAIL_DECLINE, + USER_EMAIL_NEW_STARTED: USER_EMAIL_NEW_STARTED, + USER_EMAIL_NEW_SUCCESS: USER_EMAIL_NEW_SUCCESS, + USER_EMAIL_NEW_EXISTS: USER_EMAIL_NEW_EXISTS, + USER_EMAIL_NEW_FAILURE: USER_EMAIL_NEW_FAILURE, + USER_EMAIL_VERIFY_SET: USER_EMAIL_VERIFY_SET, + USER_EMAIL_VERIFY_STARTED: USER_EMAIL_VERIFY_STARTED, + USER_EMAIL_VERIFY_SUCCESS: USER_EMAIL_VERIFY_SUCCESS, + USER_EMAIL_VERIFY_FAILURE: USER_EMAIL_VERIFY_FAILURE, + USER_EMAIL_VERIFY_RETRY: USER_EMAIL_VERIFY_RETRY, + USER_PHONE_RESET: USER_PHONE_RESET, + USER_PHONE_NEW_STARTED: USER_PHONE_NEW_STARTED, + USER_PHONE_NEW_SUCCESS: USER_PHONE_NEW_SUCCESS, + USER_PHONE_NEW_FAILURE: USER_PHONE_NEW_FAILURE, + USER_PHONE_VERIFY_STARTED: USER_PHONE_VERIFY_STARTED, + USER_PHONE_VERIFY_SUCCESS: USER_PHONE_VERIFY_SUCCESS, + USER_PHONE_VERIFY_FAILURE: USER_PHONE_VERIFY_FAILURE, + USER_IDENTITY_VERIFY_STARTED: USER_IDENTITY_VERIFY_STARTED, + USER_IDENTITY_VERIFY_SUCCESS: USER_IDENTITY_VERIFY_SUCCESS, + USER_IDENTITY_VERIFY_FAILURE: USER_IDENTITY_VERIFY_FAILURE, + USER_FETCH_STARTED: USER_FETCH_STARTED, + USER_FETCH_SUCCESS: USER_FETCH_SUCCESS, + USER_FETCH_FAILURE: USER_FETCH_FAILURE, + USER_INVITE_STATUS_FETCH_STARTED: USER_INVITE_STATUS_FETCH_STARTED, + USER_INVITE_STATUS_FETCH_SUCCESS: USER_INVITE_STATUS_FETCH_SUCCESS, + USER_INVITE_STATUS_FETCH_FAILURE: USER_INVITE_STATUS_FETCH_FAILURE, + USER_INVITE_NEW_STARTED: USER_INVITE_NEW_STARTED, + USER_INVITE_NEW_SUCCESS: USER_INVITE_NEW_SUCCESS, + USER_INVITE_NEW_FAILURE: USER_INVITE_NEW_FAILURE, + FETCH_ACCESS_TOKEN_SUCCESS: FETCH_ACCESS_TOKEN_SUCCESS, + FETCH_REWARDS_STARTED: FETCH_REWARDS_STARTED, + FETCH_REWARDS_COMPLETED: FETCH_REWARDS_COMPLETED, + CLAIM_REWARD_STARTED: CLAIM_REWARD_STARTED, + CLAIM_REWARD_SUCCESS: CLAIM_REWARD_SUCCESS, + CLAIM_REWARD_FAILURE: CLAIM_REWARD_FAILURE, + CLAIM_REWARD_CLEAR_ERROR: CLAIM_REWARD_CLEAR_ERROR, + FETCH_REWARD_CONTENT_COMPLETED: FETCH_REWARD_CONTENT_COMPLETED, + DOWNLOAD_LANGUAGE_SUCCEEDED: DOWNLOAD_LANGUAGE_SUCCEEDED, + DOWNLOAD_LANGUAGE_FAILED: DOWNLOAD_LANGUAGE_FAILED, + CHANNEL_SUBSCRIBE: CHANNEL_SUBSCRIBE, + CHANNEL_UNSUBSCRIBE: CHANNEL_UNSUBSCRIBE, + HAS_FETCHED_SUBSCRIPTIONS: HAS_FETCHED_SUBSCRIPTIONS, + SET_SUBSCRIPTION_LATEST: SET_SUBSCRIPTION_LATEST, + SET_SUBSCRIPTION_NOTIFICATION: SET_SUBSCRIPTION_NOTIFICATION, + SET_SUBSCRIPTION_NOTIFICATIONS: SET_SUBSCRIPTION_NOTIFICATIONS, + CHECK_SUBSCRIPTION_STARTED: CHECK_SUBSCRIPTION_STARTED, + CHECK_SUBSCRIPTION_COMPLETED: CHECK_SUBSCRIPTION_COMPLETED, + CHECK_SUBSCRIPTIONS_SUBSCRIBE: CHECK_SUBSCRIPTIONS_SUBSCRIBE, + CLEAR_PUBLISH: CLEAR_PUBLISH, + UPDATE_PUBLISH_FORM: UPDATE_PUBLISH_FORM, + PUBLISH_START: PUBLISH_START, + PUBLISH_SUCCESS: PUBLISH_SUCCESS, + PUBLISH_FAIL: PUBLISH_FAIL, + CLEAR_PUBLISH_ERROR: CLEAR_PUBLISH_ERROR, + REMOVE_PENDING_PUBLISH: REMOVE_PENDING_PUBLISH, + DO_PREPARE_EDIT: DO_PREPARE_EDIT, + CREATE_NOTIFICATION: CREATE_NOTIFICATION, + EDIT_NOTIFICATION: EDIT_NOTIFICATION, + DELETE_NOTIFICATION: DELETE_NOTIFICATION, + DISMISS_NOTIFICATION: DISMISS_NOTIFICATION, + CREATE_TOAST: CREATE_TOAST, + DISMISS_TOAST: DISMISS_TOAST, + CREATE_ERROR: CREATE_ERROR, + DISMISS_ERROR: DISMISS_ERROR, + FETCH_DATE: FETCH_DATE, + FETCH_COST_INFO_STARTED: FETCH_COST_INFO_STARTED, + FETCH_COST_INFO_COMPLETED: FETCH_COST_INFO_COMPLETED, + FETCH_COST_INFO_FAILED: FETCH_COST_INFO_FAILED, + TOGGLE_TAG_FOLLOW: TOGGLE_TAG_FOLLOW, + TAG_ADD: TAG_ADD, + TAG_DELETE: TAG_DELETE }); -const API_DOWN = 'apiDown'; -const READY = 'ready'; -const IN_PROGRESS = 'inProgress'; -const COMPLETE = 'complete'; -const MANUAL = 'manual'; +const CC_LICENSES = [{ + value: 'Creative Commons Attribution 4.0 International', + url: 'https://creativecommons.org/licenses/by/4.0/legalcode' +}, { + value: 'Creative Commons Attribution-ShareAlike 4.0 International', + url: 'https://creativecommons.org/licenses/by-sa/4.0/legalcode' +}, { + value: 'Creative Commons Attribution-NoDerivatives 4.0 International', + url: 'https://creativecommons.org/licenses/by-nd/4.0/legalcode' +}, { + value: 'Creative Commons Attribution-NonCommercial 4.0 International', + url: 'https://creativecommons.org/licenses/by-nc/4.0/legalcode' +}, { + value: 'Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International', + url: 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode' +}, { + value: 'Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International', + url: 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode' +}]; -var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - API_DOWN: API_DOWN, - READY: READY, - IN_PROGRESS: IN_PROGRESS, - COMPLETE: COMPLETE, - MANUAL: MANUAL +const NONE = 'None'; +const PUBLIC_DOMAIN = 'Public Domain'; +const OTHER = 'other'; +const COPYRIGHT = 'copyright'; + +var licenses = /*#__PURE__*/Object.freeze({ + CC_LICENSES: CC_LICENSES, + NONE: NONE, + PUBLIC_DOMAIN: PUBLIC_DOMAIN, + OTHER: OTHER, + COPYRIGHT: COPYRIGHT +}); + +const AUTH = 'auth'; +const BACKUP = 'backup'; +const CHANNEL = 'channel'; +const DISCOVER = 'discover'; +const FILE = 'file'; +const DOWNLOADED = 'downloaded'; +const PUBLISHED = 'published'; +const GET_CREDITS = 'getcredits'; +const HELP = 'help'; +const INVITE = 'invite'; +const PUBLISH = 'publish'; +const REPORT = 'report'; +const REWARDS = 'rewards'; +const SEARCH = 'search'; +const SEND_CREDITS = 'send'; +const SETTINGS = 'settings'; +const SHOW = 'show'; +const SUBSCRIPTIONS = 'subscriptions'; +const TRANSACTION_HISTORY = 'history'; +const HISTORY = 'user_history'; +const WALLET = 'wallet'; + +var pages = /*#__PURE__*/Object.freeze({ + AUTH: AUTH, + BACKUP: BACKUP, + CHANNEL: CHANNEL, + DISCOVER: DISCOVER, + FILE: FILE, + DOWNLOADED: DOWNLOADED, + PUBLISHED: PUBLISHED, + GET_CREDITS: GET_CREDITS, + HELP: HELP, + INVITE: INVITE, + PUBLISH: PUBLISH, + REPORT: REPORT, + REWARDS: REWARDS, + SEARCH: SEARCH, + SEND_CREDITS: SEND_CREDITS, + SETTINGS: SETTINGS, + SHOW: SHOW, + SUBSCRIPTIONS: SUBSCRIPTIONS, + TRANSACTION_HISTORY: TRANSACTION_HISTORY, + HISTORY: HISTORY, + WALLET: WALLET }); /* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ @@ -477,43 +555,20 @@ const FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; const KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; var settings = /*#__PURE__*/Object.freeze({ - CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, - NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, - EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, - LANGUAGE: LANGUAGE, - SHOW_NSFW: SHOW_NSFW, - SHOW_UNAVAILABLE: SHOW_UNAVAILABLE, - INSTANT_PURCHASE_ENABLED: INSTANT_PURCHASE_ENABLED, - INSTANT_PURCHASE_MAX: INSTANT_PURCHASE_MAX, - THEME: THEME, - THEMES: THEMES, - AUTOMATIC_DARK_MODE_ENABLED: AUTOMATIC_DARK_MODE_ENABLED, - BACKGROUND_PLAY_ENABLED: BACKGROUND_PLAY_ENABLED, - FOREGROUND_NOTIFICATION_ENABLED: FOREGROUND_NOTIFICATION_ENABLED, - KEEP_DAEMON_RUNNING: KEEP_DAEMON_RUNNING -}); - -// eslint-disable-next-line import/prefer-default-export -const ALL = 'all'; -const SPEND = 'spend'; -const RECEIVE = 'receive'; -const PUBLISH = 'publish'; -const CHANNEL = 'channel'; -const TIP = 'tip'; -const SUPPORT = 'support'; -const UPDATE = 'update'; -const ABANDON = 'abandon'; - -var transaction_types = /*#__PURE__*/Object.freeze({ - ALL: ALL, - SPEND: SPEND, - RECEIVE: RECEIVE, - PUBLISH: PUBLISH, - CHANNEL: CHANNEL, - TIP: TIP, - SUPPORT: SUPPORT, - UPDATE: UPDATE, - ABANDON: ABANDON + CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, + NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, + EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, + LANGUAGE: LANGUAGE, + SHOW_NSFW: SHOW_NSFW, + SHOW_UNAVAILABLE: SHOW_UNAVAILABLE, + INSTANT_PURCHASE_ENABLED: INSTANT_PURCHASE_ENABLED, + INSTANT_PURCHASE_MAX: INSTANT_PURCHASE_MAX, + THEME: THEME, + THEMES: THEMES, + AUTOMATIC_DARK_MODE_ENABLED: AUTOMATIC_DARK_MODE_ENABLED, + BACKGROUND_PLAY_ENABLED: BACKGROUND_PLAY_ENABLED, + FOREGROUND_NOTIFICATION_ENABLED: FOREGROUND_NOTIFICATION_ENABLED, + KEEP_DAEMON_RUNNING: KEEP_DAEMON_RUNNING }); const DATE_NEW = 'dateNew'; @@ -522,56 +577,47 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - DATE_NEW: DATE_NEW, - DATE_OLD: DATE_OLD, - TITLE: TITLE, - FILENAME: FILENAME + DATE_NEW: DATE_NEW, + DATE_OLD: DATE_OLD, + TITLE: TITLE, + FILENAME: FILENAME }); -const AUTH = 'auth'; -const BACKUP = 'backup'; -const CHANNEL$1 = 'channel'; -const DISCOVER = 'discover'; -const FILE = 'file'; -const DOWNLOADED = 'downloaded'; -const PUBLISHED = 'published'; -const GET_CREDITS = 'getcredits'; -const HELP = 'help'; -const INVITE = 'invite'; -const PUBLISH$1 = 'publish'; -const REPORT = 'report'; -const REWARDS = 'rewards'; -const SEARCH = 'search'; -const SEND_CREDITS = 'send'; -const SETTINGS = 'settings'; -const SHOW = 'show'; -const SUBSCRIPTIONS = 'subscriptions'; -const TRANSACTION_HISTORY = 'history'; -const HISTORY = 'user_history'; -const WALLET = 'wallet'; +const API_DOWN = 'apiDown'; +const READY = 'ready'; +const IN_PROGRESS = 'inProgress'; +const COMPLETE = 'complete'; +const MANUAL = 'manual'; -var pages = /*#__PURE__*/Object.freeze({ - AUTH: AUTH, - BACKUP: BACKUP, - CHANNEL: CHANNEL$1, - DISCOVER: DISCOVER, - FILE: FILE, - DOWNLOADED: DOWNLOADED, - PUBLISHED: PUBLISHED, - GET_CREDITS: GET_CREDITS, - HELP: HELP, - INVITE: INVITE, - PUBLISH: PUBLISH$1, - REPORT: REPORT, - REWARDS: REWARDS, - SEARCH: SEARCH, - SEND_CREDITS: SEND_CREDITS, - SETTINGS: SETTINGS, - SHOW: SHOW, - SUBSCRIPTIONS: SUBSCRIPTIONS, - TRANSACTION_HISTORY: TRANSACTION_HISTORY, - HISTORY: HISTORY, - WALLET: WALLET +var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ + API_DOWN: API_DOWN, + READY: READY, + IN_PROGRESS: IN_PROGRESS, + COMPLETE: COMPLETE, + MANUAL: MANUAL +}); + +// eslint-disable-next-line import/prefer-default-export +const ALL = 'all'; +const SPEND = 'spend'; +const RECEIVE = 'receive'; +const PUBLISH$1 = 'publish'; +const CHANNEL$1 = 'channel'; +const TIP = 'tip'; +const SUPPORT = 'support'; +const UPDATE = 'update'; +const ABANDON = 'abandon'; + +var transaction_types = /*#__PURE__*/Object.freeze({ + ALL: ALL, + SPEND: SPEND, + RECEIVE: RECEIVE, + PUBLISH: PUBLISH$1, + CHANNEL: CHANNEL$1, + TIP: TIP, + SUPPORT: SUPPORT, + UPDATE: UPDATE, + ABANDON: ABANDON }); const SEARCH_TYPES = { @@ -1493,7 +1539,7 @@ const selectTransactionItems = reselect.createSelector(selectTransactionsById, b const append = []; append.push(...tx.claim_info.map(item => Object.assign({}, tx, item, { - type: item.claim_name[0] === '@' ? CHANNEL : PUBLISH + type: item.claim_name[0] === '@' ? CHANNEL$1 : PUBLISH$1 }))); append.push(...tx.support_info.map(item => Object.assign({}, tx, item, { type: !item.is_tip ? SUPPORT : TIP @@ -2578,6 +2624,372 @@ function doSetFileListSort(page, value) { }; } +// + +const formatLbryUriForWeb = uri => { + const { claimName, claimId } = parseURI(uri); + + let webUrl = `/${claimName}`; + if (claimId) { + webUrl += `/${claimId}`; + } + + return webUrl; +}; + +var _extends$4 = 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; }; + +const doResetThumbnailStatus = () => dispatch => { + dispatch({ + type: UPDATE_PUBLISH_FORM, + data: { + thumbnailPath: '' + } + }); + + return fetch('https://spee.ch/api/config/site/publishing').then(res => res.json()).then(status => { + if (status.disabled) { + throw Error(); + } + + return dispatch({ + type: UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: READY, + thumbnail: '' + } + }); + }).catch(() => dispatch({ + type: UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: API_DOWN, + thumbnail: '' + } + })); +}; + +const doClearPublish = () => dispatch => { + dispatch({ type: CLEAR_PUBLISH }); + return dispatch(doResetThumbnailStatus()); +}; + +const doUpdatePublishForm = publishFormValue => dispatch => dispatch({ + type: UPDATE_PUBLISH_FORM, + data: _extends$4({}, publishFormValue) +}); + +const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter) => dispatch => { + let thumbnail, fileExt, fileName, fileType; + + const makeid = () => { + let text = ''; + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 24; i += 1) text += possible.charAt(Math.floor(Math.random() * 62)); + return text; + }; + + const uploadError = (error = '') => { + dispatch(batchActions({ + type: UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: READY, + thumbnail: '', + nsfw: false + } + }, doError(error))); + }; + + dispatch({ + type: UPDATE_PUBLISH_FORM, + data: { uploadThumbnailStatus: IN_PROGRESS } + }); + + if (fsAdapter && fsAdapter.readFile && filePath) { + fsAdapter.readFile(filePath, 'base64').then(base64Image => { + fileExt = 'png'; + fileName = 'thumbnail.png'; + fileType = 'image/png'; + + const data = new FormData(); + const name = makeid(); + data.append('name', name); + data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); + + return fetch('https://spee.ch/api/claim/publish', { + method: 'POST', + body: data + }).then(response => response.json()).then(json => json.success ? dispatch({ + type: UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: COMPLETE, + thumbnail: `${json.data.url}${fileExt}` + } + }) : uploadError(json.message)).catch(err => uploadError(err.message)); + }); + } else { + if (filePath) { + thumbnail = fs.readFileSync(filePath); + fileExt = path.extname(filePath); + fileName = path.basename(filePath); + fileType = `image/${fileExt.slice(1)}`; + } else if (thumbnailBuffer) { + thumbnail = thumbnailBuffer; + fileExt = '.png'; + fileName = 'thumbnail.png'; + fileType = 'image/png'; + } else { + return null; + } + + const data = new FormData(); + const name = makeid(); + const file = new File([thumbnail], fileName, { type: fileType }); + data.append('name', name); + data.append('file', file); + + return fetch('https://spee.ch/api/claim/publish', { + method: 'POST', + body: data + }).then(response => response.json()).then(json => json.success ? dispatch({ + type: UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: COMPLETE, + thumbnail: `${json.data.url}${fileExt}` + } + }) : uploadError(json.message)).catch(err => uploadError(err.message)); + } +}; + +const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { + const { name, amount, channel_name: channelName, value } = claim; + + const { + author, + description, + // use same values as default state + // fee will be undefined for free content + fee = { + amount: 0, + currency: 'LBC' + }, + languages, + license, + license_url: licenseUrl, + thumbnail, + title + } = value; + + const publishData = { + name, + channel: channelName, + bid: amount, + contentIsFree: !fee.amount, + author, + description, + fee: { amount: fee.amount, currency: fee.currency }, + languages, + thumbnail: thumbnail ? thumbnail.url : null, + title, + uri, + uploadThumbnailStatus: thumbnail ? MANUAL : undefined, + licenseUrl, + nsfw: isClaimNsfw(claim) + }; + + // Make sure custom liscence's are mapped properly + // If the license isn't one of the standard licenses, map the custom license and description/url + if (!CC_LICENSES.some(({ value }) => value === license)) { + if (!license || license === NONE || license === PUBLIC_DOMAIN) { + publishData.licenseType = license; + } else if (license && !licenseUrl && license !== NONE) { + publishData.licenseType = COPYRIGHT; + } else { + publishData.licenseType = OTHER; + } + + publishData.otherLicenseDescription = license; + } else { + publishData.licenseType = license; + } + + if (fileInfo && fileInfo.download_path) { + try { + fs.accessSync(fileInfo.download_path, fs.constants.R_OK); + publishData.filePath = fileInfo.download_path; + } catch (e) { + console.error(e.name, e.message); + } + } + + dispatch({ type: DO_PREPARE_EDIT, data: publishData }); +}; + +const doPublish = params => (dispatch, getState) => { + dispatch({ type: PUBLISH_START }); + + const state = getState(); + const myChannels = selectMyChannelClaims(state); + const myClaims = selectMyClaimsWithoutChannels(state); + + const { + name, + bid, + filePath, + description, + language, + license, + licenseUrl, + thumbnail, + channel, + title, + contentIsFree, + fee, + uri, + nsfw, + claim + } = params; + + // get the claim id from the channel name, we will use that instead + const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); + const channelId = namedChannelClaim ? namedChannelClaim.claim_id : ''; + + const publishPayload = { + name, + bid: creditsToString(bid), + title, + license, + languages: [language], + description, + tags: claim && claim.value.tags || [], + locations: claim && claim.value.locations + }; + + // Temporary solution to keep the same publish flow with the new tags api + // Eventually we will allow users to enter their own tags on publish + // `nsfw` will probably be removed + + if (licenseUrl) { + publishPayload.license_url = licenseUrl; + } + + if (thumbnail) { + publishPayload.thumbnail_url = thumbnail; + } + + if (claim && claim.value.release_time) { + publishPayload.release_time = Number(claim.value.release_time); + } + + if (nsfw) { + if (!publishPayload.tags.includes('mature')) { + publishPayload.tags.push('mature'); + } + } else { + const indexToRemove = publishPayload.tags.indexOf('mature'); + if (indexToRemove > -1) { + publishPayload.tags.splice(indexToRemove, 1); + } + } + + if (channelId) { + publishPayload.channel_id = channelId; + } + + if (!contentIsFree && fee && fee.currency && Number(fee.amount) > 0) { + publishPayload.fee_currency = fee.currency; + publishPayload.fee_amount = creditsToString(fee.amount); + } + + // Only pass file on new uploads, not metadata only edits. + // The sdk will figure it out + if (filePath) publishPayload.file_path = filePath; + + const success = successResponse => { + //analytics.apiLogPublish(); + + const pendingClaim = successResponse.outputs[0]; + const actions = []; + + actions.push({ + type: PUBLISH_SUCCESS + }); + + //actions.push(doOpenModal(MODALS.PUBLISH, { uri })); + + // We have to fake a temp claim until the new pending one is returned by claim_list_mine + // We can't rely on claim_list_mine because there might be some delay before the new claims are returned + // Doing this allows us to show the pending claim immediately, it will get overwritten by the real one + const isMatch = claim => claim.claim_id === pendingClaim.claim_id; + const isEdit = myClaims.some(isMatch); + const myNewClaims = isEdit ? myClaims.map(claim => isMatch(claim) ? pendingClaim : claim) : myClaims.concat(pendingClaim); + + actions.push({ + type: FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + claims: myNewClaims + } + }); + + dispatch(batchActions(...actions)); + }; + + const failure = error => { + dispatch({ type: PUBLISH_FAIL }); + dispatch(doError(error.message)); + }; + + return lbryProxy.publish(publishPayload).then(success, failure); +}; + +// Calls claim_list_mine until any pending publishes are confirmed +const doCheckPendingPublishes = () => (dispatch, getState) => { + const state = getState(); + const pendingById = selectPendingById(state); + + if (!Object.keys(pendingById).length) { + return; + } + + let publishCheckInterval; + + const checkFileList = () => { + lbryProxy.claim_list().then(claims => { + claims.forEach(claim => { + // If it's confirmed, check if it was pending previously + if (claim.confirmations > 0 && pendingById[claim.claim_id]) { + delete pendingById[claim.claim_id]; + + // If it's confirmed, check if we should notify the user + if (selectosNotificationsEnabled(getState())) { + const notif = new window.Notification('LBRY Publish Complete', { + body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, + silent: false + }); + notif.onclick = () => { + dispatch(push(formatLbryUriForWeb(claim.permanent_url))); + }; + } + } + }); + + dispatch({ + type: FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + claims + } + }); + + if (!Object.keys(pendingById).length) { + clearInterval(publishCheckInterval); + } + }); + }; + + publishCheckInterval = setInterval(() => { + checkFileList(); + }, 30000); +}; + // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for // N milliseconds. If `immediate` is passed, trigger the function on the @@ -2844,7 +3256,7 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { }; } -var _extends$4 = 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; }; +var _extends$5 = 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; }; const reducers = {}; const defaultState = { @@ -2904,7 +3316,7 @@ function handleClaimAction(state, action) { } reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$4({}, handleClaimAction(state, action)); + return _extends$5({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -3085,7 +3497,7 @@ reducers[CLAIM_SEARCH_STARTED] = state => { }); }; reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { - return _extends$4({}, handleClaimAction(state, action), { + return _extends$5({}, handleClaimAction(state, action), { fetchingClaimSearch: false, lastClaimSearchUris: action.data.uris }); @@ -3102,89 +3514,106 @@ function claimsReducer(state = defaultState, action) { return state; } -var _extends$5 = 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; }; +// util for creating reducers +// based off of redux-actions +// https://redux-actions.js.org/docs/api/handleAction.html#handleactions + +// eslint-disable-next-line import/prefer-default-export +const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { + const handler = actionMap[action.type]; + + if (handler) { + const newState = handler(state, action); + return Object.assign({}, state, newState); + } + + // just return the original state if no handler + // returning a copy here breaks redux-persist + return state; +}; + +var _extends$6 = 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; }; + +const defaultState$1 = { + byId: {}, + commentsByUri: {}, + isLoading: false +}; + +const commentReducer = handleActions({ + [COMMENT_CREATE_STARTED]: (state, action) => _extends$6({}, state, { + isLoading: true + }), + + [COMMENT_CREATE_FAILED]: (state, action) => _extends$6({}, state, { + isLoading: false + }), + + [COMMENT_CREATE_COMPLETED]: (state, action) => { + const { comment, claimId } = action.data; + const byId = Object.assign({}, state.byId); + const comments = byId[claimId]; + const newComments = comments.slice(); + + newComments.unshift(comment); + byId[claimId] = newComments; + + return _extends$6({}, state, { + byId + }); + }, + + [COMMENT_LIST_STARTED]: state => _extends$6({}, state, { isLoading: true }), + + [COMMENT_LIST_COMPLETED]: (state, action) => { + const { comments, claimId, uri } = action.data; + const byId = Object.assign({}, state.byId); + const commentsByUri = Object.assign({}, state.commentsByUri); + + if (comments['items']) { + byId[claimId] = comments['items']; + commentsByUri[uri] = claimId; + } + return _extends$6({}, state, { + byId, + commentsByUri, + isLoading: false + }); + }, + + [COMMENT_LIST_FAILED]: (state, action) => _extends$6({}, state, { + isLoading: false + }) +}, defaultState$1); + +var _extends$7 = 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; }; const reducers$1 = {}; -const defaultState$1 = { - failedPurchaseUris: [], - purchasedUris: [], - purchasedStreamingUrls: {}, - purchaseUriErrorMessage: '' +const defaultState$2 = { + positions: {} }; -reducers$1[PURCHASE_URI_STARTED] = (state, action) => { - const { uri } = action.data; - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - if (newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); - } - - return _extends$5({}, state, { - failedPurchaseUris: newFailedPurchaseUris, - purchaseUriErrorMessage: '' +reducers$1[SET_CONTENT_POSITION] = (state, action) => { + const { claimId, outpoint, position } = action.data; + return _extends$7({}, state, { + positions: _extends$7({}, state.positions, { + [claimId]: _extends$7({}, state.positions[claimId], { + [outpoint]: position + }) + }) }); }; -reducers$1[PURCHASE_URI_COMPLETED] = (state, action) => { - const { uri, streamingUrl } = action.data; - const newPurchasedUris = state.purchasedUris.slice(); - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - const newPurchasedStreamingUrls = Object.assign({}, state.purchasedStreamingUrls); - - if (!newPurchasedUris.includes(uri)) { - newPurchasedUris.push(uri); - } - if (newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); - } - if (streamingUrl) { - newPurchasedStreamingUrls[uri] = streamingUrl; - } - - return _extends$5({}, state, { - failedPurchaseUris: newFailedPurchaseUris, - purchasedUris: newPurchasedUris, - purchasedStreamingUrls: newPurchasedStreamingUrls, - purchaseUriErrorMessage: '' - }); -}; - -reducers$1[PURCHASE_URI_FAILED] = (state, action) => { - const { uri, error } = action.data; - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - - if (!newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.push(uri); - } - - return _extends$5({}, state, { - failedPurchaseUris: newFailedPurchaseUris, - purchaseUriErrorMessage: error - }); -}; - -reducers$1[DELETE_PURCHASED_URI] = (state, action) => { - const { uri } = action.data; - const newPurchasedUris = state.purchasedUris.slice(); - if (newPurchasedUris.includes(uri)) { - newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); - } - - return _extends$5({}, state, { - purchasedUris: newPurchasedUris - }); -}; - -function fileReducer(state = defaultState$1, action) { +function contentReducer(state = defaultState$2, action) { const handler = reducers$1[action.type]; if (handler) return handler(state, action); return state; } -var _extends$6 = 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; }; +var _extends$8 = 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; }; const reducers$2 = {}; -const defaultState$2 = { +const defaultState$3 = { fileListPublishedSort: DATE_NEW, fileListDownloadedSort: DATE_NEW }; @@ -3317,12 +3746,12 @@ reducers$2[LOADING_VIDEO_STARTED] = (state, action) => { const newLoading = Object.assign({}, state.urisLoading); newLoading[uri] = true; - const newErrors = _extends$6({}, state.errors); + const newErrors = _extends$8({}, state.errors); if (uri in newErrors) delete newErrors[uri]; return Object.assign({}, state, { urisLoading: newLoading, - errors: _extends$6({}, newErrors) + errors: _extends$8({}, newErrors) }); }; @@ -3332,12 +3761,12 @@ reducers$2[LOADING_VIDEO_FAILED] = (state, action) => { const newLoading = Object.assign({}, state.urisLoading); delete newLoading[uri]; - const newErrors = _extends$6({}, state.errors); + const newErrors = _extends$8({}, state.errors); newErrors[uri] = true; return Object.assign({}, state, { urisLoading: newLoading, - errors: _extends$6({}, newErrors) + errors: _extends$8({}, newErrors) }); }; @@ -3354,33 +3783,94 @@ reducers$2[SET_FILE_LIST_SORT] = (state, action) => { }); }; -function fileInfoReducer(state = defaultState$2, action) { +function fileInfoReducer(state = defaultState$3, action) { const handler = reducers$2[action.type]; if (handler) return handler(state, action); return state; } -// util for creating reducers -// based off of redux-actions -// https://redux-actions.js.org/docs/api/handleAction.html#handleactions +var _extends$9 = 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; }; -// eslint-disable-next-line import/prefer-default-export -const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { - const handler = actionMap[action.type]; - - if (handler) { - const newState = handler(state, action); - return Object.assign({}, state, newState); - } - - // just return the original state if no handler - // returning a copy here breaks redux-persist - return state; +const reducers$3 = {}; +const defaultState$4 = { + failedPurchaseUris: [], + purchasedUris: [], + purchasedStreamingUrls: {}, + purchaseUriErrorMessage: '' }; -var _extends$7 = 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; }; +reducers$3[PURCHASE_URI_STARTED] = (state, action) => { + const { uri } = action.data; + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + if (newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); + } -const defaultState$3 = { + return _extends$9({}, state, { + failedPurchaseUris: newFailedPurchaseUris, + purchaseUriErrorMessage: '' + }); +}; + +reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { + const { uri, streamingUrl } = action.data; + const newPurchasedUris = state.purchasedUris.slice(); + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + const newPurchasedStreamingUrls = Object.assign({}, state.purchasedStreamingUrls); + + if (!newPurchasedUris.includes(uri)) { + newPurchasedUris.push(uri); + } + if (newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); + } + if (streamingUrl) { + newPurchasedStreamingUrls[uri] = streamingUrl; + } + + return _extends$9({}, state, { + failedPurchaseUris: newFailedPurchaseUris, + purchasedUris: newPurchasedUris, + purchasedStreamingUrls: newPurchasedStreamingUrls, + purchaseUriErrorMessage: '' + }); +}; + +reducers$3[PURCHASE_URI_FAILED] = (state, action) => { + const { uri, error } = action.data; + const newFailedPurchaseUris = state.failedPurchaseUris.slice(); + + if (!newFailedPurchaseUris.includes(uri)) { + newFailedPurchaseUris.push(uri); + } + + return _extends$9({}, state, { + failedPurchaseUris: newFailedPurchaseUris, + purchaseUriErrorMessage: error + }); +}; + +reducers$3[DELETE_PURCHASED_URI] = (state, action) => { + const { uri } = action.data; + const newPurchasedUris = state.purchasedUris.slice(); + if (newPurchasedUris.includes(uri)) { + newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); + } + + return _extends$9({}, state, { + purchasedUris: newPurchasedUris + }); +}; + +function fileReducer(state = defaultState$4, action) { + const handler = reducers$3[action.type]; + if (handler) return handler(state, action); + return state; +} + +var _extends$a = 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; }; + +const defaultState$5 = { notifications: [], toasts: [], errors: [] @@ -3393,7 +3883,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$7({}, state, { + return _extends$a({}, state, { toasts: newToasts }); }, @@ -3401,7 +3891,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$7({}, state, { + return _extends$a({}, state, { toasts: newToasts }); }, @@ -3412,7 +3902,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$7({}, state, { + return _extends$a({}, state, { notifications: newNotifications }); }, @@ -3423,7 +3913,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$7({}, state, { + return _extends$a({}, state, { notifications }); }, @@ -3432,7 +3922,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$7({}, state, { + return _extends$a({}, state, { notifications: newNotifications }); }, @@ -3443,7 +3933,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$7({}, state, { + return _extends$a({}, state, { errors: newErrors }); }, @@ -3451,15 +3941,83 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$7({}, state, { + return _extends$a({}, state, { errors: newErrors }); } -}, defaultState$3); +}, defaultState$5); -var _extends$8 = 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; }; +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; }; -const defaultState$4 = { +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 defaultState$6 = { + editingURI: undefined, + filePath: undefined, + contentIsFree: true, + fee: { + amount: 1, + currency: 'LBC' + }, + title: '', + thumbnail_url: '', + thumbnailPath: '', + uploadThumbnailStatus: API_DOWN, + description: '', + language: 'en', + nsfw: false, + channel: CHANNEL_ANONYMOUS, + channelId: '', + name: '', + nameError: undefined, + bid: 0.1, + bidError: undefined, + licenseType: 'None', + otherLicenseDescription: 'All rights reserved', + licenseUrl: '', + publishing: false, + publishSuccess: false, + publishError: undefined +}; + +const publishReducer = handleActions({ + [UPDATE_PUBLISH_FORM]: (state, action) => { + const { data } = action; + return _extends$b({}, state, data); + }, + [CLEAR_PUBLISH]: () => _extends$b({}, defaultState$6), + [PUBLISH_START]: state => _extends$b({}, state, { + publishing: true, + publishSuccess: false + }), + [PUBLISH_FAIL]: state => _extends$b({}, state, { + publishing: false + }), + [PUBLISH_SUCCESS]: state => _extends$b({}, state, { + publishing: false, + publishSuccess: true + }), + [DO_PREPARE_EDIT]: (state, action) => { + const publishData = _objectWithoutProperties(action.data, []); + const { channel, name, uri } = publishData; + + // The short uri is what is presented to the user + // The editingUri is the full uri with claim id + const shortUri = buildURI({ + channelName: channel, + contentName: name + }); + + return _extends$b({}, defaultState$6, publishData, { + editingURI: uri, + uri: shortUri + }); + } +}, defaultState$6); + +var _extends$c = 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; }; + +const defaultState$7 = { 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 @@ -3477,29 +4035,29 @@ const defaultState$4 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$8({}, state, { + [SEARCH_START]: state => _extends$c({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$8({}, state, { + return _extends$c({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$8({}, state, { + [SEARCH_FAIL]: state => _extends$c({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$8({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$c({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$8({}, state, { - suggestions: _extends$8({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$c({}, state, { + suggestions: _extends$c({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -3507,27 +4065,74 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$8({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$c({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$8({}, state, { + [SEARCH_FOCUS]: state => _extends$c({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$8({}, state, { + [SEARCH_BLUR]: state => _extends$c({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$8({}, oldOptions, newOptions); - return _extends$8({}, state, { + const options = _extends$c({}, oldOptions, newOptions); + return _extends$c({}, state, { options }); } -}, defaultState$4); +}, defaultState$7); -var _extends$9 = 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; }; +var _extends$d = 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; }; + +const tagsReducerBuilder = defaultState => handleActions({ + [TOGGLE_TAG_FOLLOW]: (state, action) => { + const { followedTags } = state; + const { name } = action.data; + + let newFollowedTags = followedTags.slice(); + + if (newFollowedTags.includes(name)) { + newFollowedTags = newFollowedTags.filter(tag => tag !== name); + } else { + newFollowedTags.push(name); + } + + return _extends$d({}, state, { + followedTags: newFollowedTags + }); + }, + + [TAG_ADD]: (state, action) => { + const { knownTags } = state; + const { name } = action.data; + + let newKnownTags = _extends$d({}, knownTags); + newKnownTags[name] = { name }; + + return _extends$d({}, state, { + knownTags: newKnownTags + }); + }, + + [TAG_DELETE]: (state, action) => { + const { knownTags, followedTags } = state; + const { name } = action.data; + + let newKnownTags = _extends$d({}, knownTags); + delete newKnownTags[name]; + const newFollowedTags = followedTags.filter(tag => tag !== name); + + return _extends$d({}, state, { + knownTags: newKnownTags, + followedTags: newFollowedTags + }); + } +}, defaultState); + +var _extends$e = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -3538,7 +4143,7 @@ const buildDraftTransaction = () => ({ // See details in https://github.com/lbryio/lbry/issues/1307 -const defaultState$5 = { +const defaultState$8 = { balance: undefined, totalBalance: undefined, latestBlock: undefined, @@ -3567,25 +4172,25 @@ const defaultState$5 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$9({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$e({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$9({}, state.transactions); + const byId = _extends$e({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$9({}, state, { + return _extends$e({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$9({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$e({}, state, { fetchingSupports: true }), @@ -3598,7 +4203,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$9({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$e({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -3607,7 +4212,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$9({}, state, { + return _extends$e({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -3620,56 +4225,56 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$9({}, state, { + return _extends$e({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$9({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$e({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$9({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$e({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$9({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$e({}, state, { balance: action.data.balance }), - [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$9({}, state, { + [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$e({}, state, { totalBalance: action.data.totalBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$9({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$e({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$9({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$e({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$9({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$e({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$9({}, state, { draftTransaction: newDraft }); + return _extends$e({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$9({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$e({}, oldDraft, { address: action.data.address }); - return _extends$9({}, state, { draftTransaction: newDraft }); + return _extends$e({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$9({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$e({}, state.draftTransaction, { sending: true }); - return _extends$9({}, state, { draftTransaction: newDraftTransaction }); + return _extends$e({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -3682,231 +4287,106 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$9({}, state, { draftTransaction: newDraftTransaction }); + return _extends$e({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$9({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$e({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$9({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$e({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$9({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$e({}, state, { error: action.data.error, sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$9({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$e({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$9({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$e({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$9({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$e({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$9({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$e({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$9({}, state, { + [WALLET_DECRYPT_START]: state => _extends$e({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$9({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$e({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$9({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$e({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$9({}, state, { + [WALLET_UNLOCK_START]: state => _extends$e({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$9({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$e({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$9({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$e({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$9({}, state, { + [WALLET_LOCK_START]: state => _extends$e({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$9({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$e({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$9({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$e({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$9({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$e({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$9({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$e({}, state, { latestBlock: action.data }) -}, defaultState$5); - -var _extends$a = 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; }; - -const reducers$3 = {}; -const defaultState$6 = { - positions: {} -}; - -reducers$3[SET_CONTENT_POSITION] = (state, action) => { - const { claimId, outpoint, position } = action.data; - return _extends$a({}, state, { - positions: _extends$a({}, state.positions, { - [claimId]: _extends$a({}, state.positions[claimId], { - [outpoint]: position - }) - }) - }); -}; - -function contentReducer(state = defaultState$6, action) { - const handler = reducers$3[action.type]; - if (handler) return handler(state, action); - return state; -} - -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; }; - -const defaultState$7 = { - byId: {}, - commentsByUri: {}, - isLoading: false -}; - -const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$b({}, state, { - isLoading: true - }), - - [COMMENT_CREATE_FAILED]: (state, action) => _extends$b({}, state, { - isLoading: false - }), - - [COMMENT_CREATE_COMPLETED]: (state, action) => { - const { comment, claimId } = action.data; - const byId = Object.assign({}, state.byId); - const comments = byId[claimId]; - const newComments = comments.slice(); - - newComments.unshift(comment); - byId[claimId] = newComments; - - return _extends$b({}, state, { - byId - }); - }, - - [COMMENT_LIST_STARTED]: state => _extends$b({}, state, { isLoading: true }), - - [COMMENT_LIST_COMPLETED]: (state, action) => { - const { comments, claimId, uri } = action.data; - const byId = Object.assign({}, state.byId); - const commentsByUri = Object.assign({}, state.commentsByUri); - - if (comments['items']) { - byId[claimId] = comments['items']; - commentsByUri[uri] = claimId; - } - return _extends$b({}, state, { - byId, - commentsByUri, - isLoading: false - }); - }, - - [COMMENT_LIST_FAILED]: (state, action) => _extends$b({}, state, { - isLoading: false - }) -}, defaultState$7); - -var _extends$c = 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; }; - -const tagsReducerBuilder = defaultState => handleActions({ - [TOGGLE_TAG_FOLLOW]: (state, action) => { - const { followedTags } = state; - const { name } = action.data; - - let newFollowedTags = followedTags.slice(); - - if (newFollowedTags.includes(name)) { - newFollowedTags = newFollowedTags.filter(tag => tag !== name); - } else { - newFollowedTags.push(name); - } - - return _extends$c({}, state, { - followedTags: newFollowedTags - }); - }, - - [TAG_ADD]: (state, action) => { - const { knownTags } = state; - const { name } = action.data; - - let newKnownTags = _extends$c({}, knownTags); - newKnownTags[name] = { name }; - - return _extends$c({}, state, { - knownTags: newKnownTags - }); - }, - - [TAG_DELETE]: (state, action) => { - const { knownTags, followedTags } = state; - const { name } = action.data; - - let newKnownTags = _extends$c({}, knownTags); - delete newKnownTags[name]; - const newFollowedTags = followedTags.filter(tag => tag !== name); - - return _extends$c({}, state, { - knownTags: newKnownTags, - followedTags: newFollowedTags - }); - } -}, defaultState); +}, defaultState$8); const selectState$5 = state => state.content || {}; @@ -3919,14 +4399,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$d = 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; }; +var _extends$f = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$d({ + return _extends$f({ id }, params); } @@ -3970,13 +4450,85 @@ const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsBy return byId && byId[claimId]; }); +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$8 = state => state.publish || {}; + +const selectPublishFormValues = reselect.createSelector(selectState$8, state => { + const formValues = _objectWithoutProperties$1(state, ['pendingPublish']); + return formValues; +}); +const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, publishState => { + const { editingURI, uri } = publishState; + + if (!editingURI || !uri) { + return false; + } + + const { isChannel: currentIsChannel, claimName: currentClaimName, contentName: currentContentName } = parseURI(uri); + const { isChannel: editIsChannel, claimName: editClaimName, contentName: editContentName } = parseURI(editingURI); + + // Depending on the previous/current use of a channel, we need to compare different things + // ex: going from a channel to anonymous, the new uri won't return contentName, so we need to use claimName + const currentName = currentIsChannel ? currentContentName : currentClaimName; + const editName = editIsChannel ? editContentName : editClaimName; + return currentName === editName; +}); + +const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, selectIsStillEditing, selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => { + const { contentName, claimName } = parseURI(uri); + const { claimId: editClaimId } = parseURI(editingURI); + + // If isStillEditing + // They clicked "edit" from the file page + // They haven't changed the channel/name after clicking edit + // Get the claim so they can edit without re-uploading a new file + return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName); +}); + +const selectIsResolvingPublishUris = reselect.createSelector(selectState$8, selectResolvingUris, ({ uri, name }, resolvingUris) => { + if (uri) { + const isResolvingUri = resolvingUris.includes(uri); + const { isChannel } = parseURI(uri); + + let isResolvingShortUri; + if (isChannel) { + const shortUri = buildURI({ contentName: name }); + isResolvingShortUri = resolvingUris.includes(shortUri); + } + + return isResolvingUri || isResolvingShortUri; + } + + return false; +}); + +const selectTakeOverAmount = reselect.createSelector(selectState$8, selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => { + // We only care about the winning claim for the short uri + const shortUri = buildURI({ contentName: name }); + const claimForShortUri = claimsByUri[shortUri]; + + if (!myClaimForUri && claimForShortUri) { + return claimForShortUri.effective_amount; + } else if (myClaimForUri && claimForShortUri) { + // https://github.com/lbryio/lbry/issues/1476 + // We should check the current effective_amount on my claim to see how much additional lbc + // is needed to win the claim. Currently this is not possible during a takeover. + // With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim" + // For now just ignore supports. We will just show the winning claim's bid amount + return claimForShortUri.effective_amount || claimForShortUri.amount; + } + + return null; +}); + // -const selectState$8 = state => state.tags || {}; +const selectState$9 = state => state.tags || {}; -const selectKnownTagsByName = reselect.createSelector(selectState$8, state => state.knownTags); +const selectKnownTagsByName = reselect.createSelector(selectState$9, state => state.knownTags); -const selectFollowedTagsList = reselect.createSelector(selectState$8, state => state.followedTags); +const selectFollowedTagsList = reselect.createSelector(selectState$9, state => state.followedTags); const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag })).sort((a, b) => a.name.localeCompare(b.name))); @@ -3995,6 +4547,8 @@ const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, sele }); exports.ACTIONS = action_types; +exports.CLAIM_VALUES = claim; +exports.LICENSES = licenses; exports.Lbry = lbryProxy; exports.PAGES = pages; exports.SEARCH_OPTIONS = SEARCH_OPTIONS; @@ -4015,7 +4569,9 @@ exports.doAddTag = doAddTag; exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; +exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doClaimSearch = doClaimSearch; +exports.doClearPublish = doClearPublish; exports.doCommentCreate = doCommentCreate; exports.doCommentList = doCommentList; exports.doCreateChannel = doCreateChannel; @@ -4034,7 +4590,10 @@ exports.doFileGet = doFileGet; exports.doFileList = doFileList; exports.doFocusSearchInput = doFocusSearchInput; exports.doGetNewAddress = doGetNewAddress; +exports.doPrepareEdit = doPrepareEdit; +exports.doPublish = doPublish; exports.doPurchaseUri = doPurchaseUri; +exports.doResetThumbnailStatus = doResetThumbnailStatus; exports.doResolveUri = doResolveUri; exports.doResolveUris = doResolveUris; exports.doSearch = doSearch; @@ -4049,9 +4608,11 @@ exports.doToggleTagFollow = doToggleTagFollow; exports.doTotalBalanceSubscribe = doTotalBalanceSubscribe; exports.doUpdateBalance = doUpdateBalance; exports.doUpdateBlockHeight = doUpdateBlockHeight; +exports.doUpdatePublishForm = doUpdatePublishForm; exports.doUpdateSearchOptions = doUpdateSearchOptions; exports.doUpdateSearchQuery = doUpdateSearchQuery; exports.doUpdateTotalBalance = doUpdateTotalBalance; +exports.doUploadThumbnail = doUploadThumbnail; exports.doWalletDecrypt = doWalletDecrypt; exports.doWalletEncrypt = doWalletEncrypt; exports.doWalletStatus = doWalletStatus; @@ -4100,6 +4661,7 @@ exports.normalizeURI = normalizeURI; exports.notificationsReducer = notificationsReducer; exports.parseQueryParams = parseQueryParams; exports.parseURI = parseURI; +exports.publishReducer = publishReducer; exports.regexAddress = regexAddress; exports.regexInvalidURI = regexInvalidURI; exports.savePosition = savePosition; @@ -4136,12 +4698,15 @@ exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; exports.selectIsFetchingFileList = selectIsFetchingFileList; exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileListDownloadedOrPublished; exports.selectIsFetchingTransactions = selectIsFetchingTransactions; +exports.selectIsResolvingPublishUris = selectIsResolvingPublishUris; exports.selectIsSearching = selectIsSearching; exports.selectIsSendingSupport = selectIsSendingSupport; +exports.selectIsStillEditing = selectIsStillEditing; exports.selectLastClaimSearchUris = selectLastClaimSearchUris; exports.selectLastPurchasedUri = selectLastPurchasedUri; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; +exports.selectMyClaimForUri = selectMyClaimForUri; exports.selectMyClaimUrisWithoutChannels = selectMyClaimUrisWithoutChannels; exports.selectMyClaims = selectMyClaims; exports.selectMyClaimsOutpoints = selectMyClaimsOutpoints; @@ -4150,6 +4715,7 @@ exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; exports.selectPendingById = selectPendingById; exports.selectPendingClaims = selectPendingClaims; exports.selectPlayingUri = selectPlayingUri; +exports.selectPublishFormValues = selectPublishFormValues; exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchasedStreamingUrls = selectPurchasedStreamingUrls; exports.selectPurchasedUris = selectPurchasedUris; @@ -4164,6 +4730,7 @@ exports.selectSearchSuggestions = selectSearchSuggestions; exports.selectSearchUrisByQuery = selectSearchUrisByQuery; exports.selectSearchValue = selectSearchValue; exports.selectSupportsByOutpoint = selectSupportsByOutpoint; +exports.selectTakeOverAmount = selectTakeOverAmount; exports.selectToast = selectToast; exports.selectTotalBalance = selectTotalBalance; exports.selectTotalDownloadProgress = selectTotalDownloadProgress; diff --git a/dist/flow-typed/Publish.js b/dist/flow-typed/Publish.js new file mode 100644 index 0000000..0d1cc0a --- /dev/null +++ b/dist/flow-typed/Publish.js @@ -0,0 +1,51 @@ +// @flow + +declare type UpdatePublishFormData = { + filePath?: string, + contentIsFree?: boolean, + fee?: { + amount: string, + currency: string, + }, + title?: string, + thumbnail_url?: string, + uploadThumbnailStatus?: string, + thumbnailPath?: string, + description?: string, + language?: string, + channel?: string, + channelId?: string, + name?: string, + nameError?: string, + bid?: number, + bidError?: string, + otherLicenseDescription?: string, + licenseUrl?: string, + licenseType?: string, + uri?: string, + nsfw: boolean, +}; + +declare type PublishParams = { + name: ?string, + bid: ?number, + filePath?: string, + description: ?string, + language: string, + publishingLicense?: string, + publishingLicenseUrl?: string, + thumbnail: ?string, + channel: string, + channelId?: string, + title: string, + contentIsFree: boolean, + uri?: string, + license: ?string, + licenseUrl: ?string, + fee?: { + amount: string, + currency: string, + }, + claim: StreamClaim, + nsfw: boolean, +}; diff --git a/flow-typed/Publish.js b/flow-typed/Publish.js new file mode 100644 index 0000000..0d1cc0a --- /dev/null +++ b/flow-typed/Publish.js @@ -0,0 +1,51 @@ +// @flow + +declare type UpdatePublishFormData = { + filePath?: string, + contentIsFree?: boolean, + fee?: { + amount: string, + currency: string, + }, + title?: string, + thumbnail_url?: string, + uploadThumbnailStatus?: string, + thumbnailPath?: string, + description?: string, + language?: string, + channel?: string, + channelId?: string, + name?: string, + nameError?: string, + bid?: number, + bidError?: string, + otherLicenseDescription?: string, + licenseUrl?: string, + licenseType?: string, + uri?: string, + nsfw: boolean, +}; + +declare type PublishParams = { + name: ?string, + bid: ?number, + filePath?: string, + description: ?string, + language: string, + publishingLicense?: string, + publishingLicenseUrl?: string, + thumbnail: ?string, + channel: string, + channelId?: string, + title: string, + contentIsFree: boolean, + uri?: string, + license: ?string, + licenseUrl: ?string, + fee?: { + amount: string, + currency: string, + }, + claim: StreamClaim, + nsfw: boolean, +}; diff --git a/src/constants/claim.js b/src/constants/claim.js new file mode 100644 index 0000000..4cf33ce --- /dev/null +++ b/src/constants/claim.js @@ -0,0 +1,5 @@ +export const MINIMUM_PUBLISH_BID = 0.00000001; + +export const CHANNEL_ANONYMOUS = 'anonymous'; +export const CHANNEL_NEW = 'new'; +export const PAGE_SIZE = 20; diff --git a/src/constants/licenses.js b/src/constants/licenses.js new file mode 100644 index 0000000..fbcc7e6 --- /dev/null +++ b/src/constants/licenses.js @@ -0,0 +1,31 @@ +export const CC_LICENSES = [ + { + value: 'Creative Commons Attribution 4.0 International', + url: 'https://creativecommons.org/licenses/by/4.0/legalcode', + }, + { + value: 'Creative Commons Attribution-ShareAlike 4.0 International', + url: 'https://creativecommons.org/licenses/by-sa/4.0/legalcode', + }, + { + value: 'Creative Commons Attribution-NoDerivatives 4.0 International', + url: 'https://creativecommons.org/licenses/by-nd/4.0/legalcode', + }, + { + value: 'Creative Commons Attribution-NonCommercial 4.0 International', + url: 'https://creativecommons.org/licenses/by-nc/4.0/legalcode', + }, + { + value: 'Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International', + url: 'https://creativecommons.org/licenses/by-nc-sa/4.0/legalcode', + }, + { + value: 'Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International', + url: 'https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode', + }, +]; + +export const NONE = 'None'; +export const PUBLIC_DOMAIN = 'Public Domain'; +export const OTHER = 'other'; +export const COPYRIGHT = 'copyright'; diff --git a/src/index.js b/src/index.js index 0e88ed3..5b861a1 100644 --- a/src/index.js +++ b/src/index.js @@ -1,9 +1,11 @@ +import * as CLAIM_VALUES from 'constants/claim'; import * as ACTIONS from 'constants/action_types'; -import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; -import * as SETTINGS from 'constants/settings'; -import * as TRANSACTIONS from 'constants/transaction_types'; -import * as SORT_OPTIONS from 'constants/sort_options'; +import * as LICENSES from 'constants/licenses'; import * as PAGES from 'constants/pages'; +import * as SETTINGS from 'constants/settings'; +import * as SORT_OPTIONS from 'constants/sort_options'; +import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; +import * as TRANSACTIONS from 'constants/transaction_types'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; import Lbry from 'lbry'; import { selectState as selectSearchState } from 'redux/selectors/search'; @@ -11,6 +13,8 @@ import { selectState as selectSearchState } from 'redux/selectors/search'; // constants export { ACTIONS, + CLAIM_VALUES, + LICENSES, THUMBNAIL_STATUSES, SEARCH_TYPES, SEARCH_OPTIONS, @@ -57,6 +61,16 @@ export { doSetFileListSort, } from 'redux/actions/file_info'; +export { + doResetThumbnailStatus, + doClearPublish, + doUpdatePublishForm, + doUploadThumbnail, + doPrepareEdit, + doPublish, + doCheckPendingPublishes +} from 'redux/actions/publish'; + export { doSearch, doUpdateSearchQuery, @@ -100,14 +114,15 @@ export { isClaimNsfw } from 'util/claim'; // reducers export { claimsReducer } from 'redux/reducers/claims'; -export { fileReducer } from 'redux/reducers/file'; -export { fileInfoReducer } from 'redux/reducers/file_info'; -export { notificationsReducer } from 'redux/reducers/notifications'; -export { searchReducer } from 'redux/reducers/search'; -export { walletReducer } from 'redux/reducers/wallet'; -export { contentReducer } from 'redux/reducers/content'; export { commentReducer } from 'redux/reducers/comments'; +export { contentReducer } from 'redux/reducers/content'; +export { fileInfoReducer } from 'redux/reducers/file_info'; +export { fileReducer } from 'redux/reducers/file'; +export { notificationsReducer } from 'redux/reducers/notifications'; +export { publishReducer } from 'redux/reducers/publish'; +export { searchReducer } from 'redux/reducers/search'; export { tagsReducerBuilder } from 'redux/reducers/tags'; +export { walletReducer } from 'redux/reducers/wallet'; // selectors export { makeSelectContentPositionForUri } from 'redux/selectors/content'; @@ -193,6 +208,14 @@ export { selectDownloadedUris, } from 'redux/selectors/file_info'; +export { + selectPublishFormValues, + selectIsStillEditing, + selectMyClaimForUri, + selectIsResolvingPublishUris, + selectTakeOverAmount, +} from 'redux/selectors/publish'; + export { selectSearchState }; export { makeSelectSearchUris, diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js new file mode 100644 index 0000000..ad98252 --- /dev/null +++ b/src/redux/actions/publish.js @@ -0,0 +1,404 @@ +// @flow +import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/licenses'; +import * as ACTIONS from 'constants/action_types'; +//import * as MODALS from 'constants/modal_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 { doError } from 'redux/actions/notifications'; +import { isClaimNsfw } from 'util/claim'; +import { + selectMyChannelClaims, + selectPendingById, + selectMyClaimsWithoutChannels, +} from 'redux/selectors/claims'; +import { formatLbryUriForWeb } from 'util/uri'; + +export const doResetThumbnailStatus = () => (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + thumbnailPath: '', + }, + }); + + return fetch('https://spee.ch/api/config/site/publishing') + .then(res => res.json()) + .then(status => { + if (status.disabled) { + throw Error(); + } + + return dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.READY, + thumbnail: '', + }, + }); + }) + .catch(() => + dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.API_DOWN, + thumbnail: '', + }, + }) + ); +}; + +export const doClearPublish = () => (dispatch: Dispatch) => { + dispatch({ type: ACTIONS.CLEAR_PUBLISH }); + return dispatch(doResetThumbnailStatus()); +}; + +export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => (dispatch: Dispatch) => + dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { ...publishFormValue }, + }); + +export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, fsAdapter: any) => (dispatch: Dispatch) => { + let thumbnail, fileExt, fileName, fileType; + + const makeid = () => { + let text = ''; + const possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + for (let i = 0; i < 24; i += 1) text += possible.charAt(Math.floor(Math.random() * 62)); + return text; + }; + + const uploadError = (error = '') => { + dispatch( + batchActions( + { + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.READY, + thumbnail: '', + nsfw: false, + }, + }, + doError(error) + ) + ); + } + + dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { uploadThumbnailStatus: THUMBNAIL_STATUSES.IN_PROGRESS }, + }); + + if (fsAdapter && fsAdapter.readFile && filePath) { + fsAdapter.readFile(filePath, 'base64').then(base64Image => { + fileExt = 'png'; + fileName = 'thumbnail.png'; + fileType = 'image/png'; + + const data = new FormData(); + const name = makeid(); + data.append('name', name); + data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); + + return fetch('https://spee.ch/api/claim/publish', { + method: 'POST', + body: data + }).then(response => response.json()) + .then(json => json.success + ? dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, + thumbnail: `${json.data.url}${fileExt}`, + }, + }) + : uploadError(json.message) + ) + .catch(err => uploadError(err.message)); + }); + } else { + if (filePath) { + thumbnail = fs.readFileSync(filePath); + fileExt = path.extname(filePath); + fileName = path.basename(filePath); + fileType = `image/${fileExt.slice(1)}`; + } else if (thumbnailBuffer) { + thumbnail = thumbnailBuffer; + fileExt = '.png'; + fileName = 'thumbnail.png'; + fileType = 'image/png'; + } else { + return null; + } + + const data = new FormData(); + const name = makeid(); + const file = new File([thumbnail], fileName, { type: fileType }); + data.append('name', name); + data.append('file', file); + + return fetch('https://spee.ch/api/claim/publish', { + method: 'POST', + body: data, + }) + .then(response => response.json()) + .then(json => + json.success + ? dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, + thumbnail: `${json.data.url}${fileExt}`, + }, + }) + : uploadError(json.message) + ) + .catch(err => uploadError(err.message)); + } +}; + +export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem) => (dispatch: Dispatch) => { + const { name, amount, channel_name: channelName, value } = claim; + + const { + author, + description, + // use same values as default state + // fee will be undefined for free content + fee = { + amount: 0, + currency: 'LBC', + }, + languages, + license, + license_url: licenseUrl, + thumbnail, + title, + } = value; + + const publishData: UpdatePublishFormData = { + name, + channel: channelName, + bid: amount, + contentIsFree: !fee.amount, + author, + description, + fee: { amount: fee.amount, currency: fee.currency }, + languages, + thumbnail: thumbnail ? thumbnail.url : null, + title, + uri, + uploadThumbnailStatus: thumbnail ? THUMBNAIL_STATUSES.MANUAL : undefined, + licenseUrl, + nsfw: isClaimNsfw(claim), + }; + + // Make sure custom liscence's are mapped properly + // If the license isn't one of the standard licenses, map the custom license and description/url + if (!CC_LICENSES.some(({ value }) => value === license)) { + if (!license || license === NONE || license === PUBLIC_DOMAIN) { + publishData.licenseType = license; + } else if (license && !licenseUrl && license !== NONE) { + publishData.licenseType = COPYRIGHT; + } else { + publishData.licenseType = OTHER; + } + + publishData.otherLicenseDescription = license; + } else { + publishData.licenseType = license; + } + + if (fileInfo && fileInfo.download_path) { + try { + fs.accessSync(fileInfo.download_path, fs.constants.R_OK); + publishData.filePath = fileInfo.download_path; + } catch (e) { + console.error(e.name, e.message); + } + } + + dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData }); +}; + +export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getState: () => {}) => { + dispatch({ type: ACTIONS.PUBLISH_START }); + + const state = getState(); + const myChannels = selectMyChannelClaims(state); + const myClaims = selectMyClaimsWithoutChannels(state); + + const { + name, + bid, + filePath, + description, + language, + license, + licenseUrl, + thumbnail, + channel, + title, + contentIsFree, + fee, + uri, + nsfw, + claim, + } = params; + + // get the claim id from the channel name, we will use that instead + const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); + const channelId = namedChannelClaim ? namedChannelClaim.claim_id : ''; + + const publishPayload: { + name: ?string, + channel_id?: string, + bid: number, + file_path?: string, + tags: Array, + locations?: Array, + license_url?: string, + thumbnail_url?: string, + release_time?: number, + fee_currency?: string, + fee_amount?: string, + } = { + name, + bid: creditsToString(bid), + title, + license, + languages: [language], + description, + tags: (claim && claim.value.tags) || [], + locations: claim && claim.value.locations, + }; + + // Temporary solution to keep the same publish flow with the new tags api + // Eventually we will allow users to enter their own tags on publish + // `nsfw` will probably be removed + + if (licenseUrl) { + publishPayload.license_url = licenseUrl; + } + + if (thumbnail) { + publishPayload.thumbnail_url = thumbnail; + } + + if (claim && claim.value.release_time) { + publishPayload.release_time = Number(claim.value.release_time); + } + + if (nsfw) { + if (!publishPayload.tags.includes('mature')) { + publishPayload.tags.push('mature'); + } + } else { + const indexToRemove = publishPayload.tags.indexOf('mature'); + if (indexToRemove > -1) { + publishPayload.tags.splice(indexToRemove, 1); + } + } + + if (channelId) { + publishPayload.channel_id = channelId; + } + + if (!contentIsFree && fee && (fee.currency && Number(fee.amount) > 0)) { + publishPayload.fee_currency = fee.currency; + publishPayload.fee_amount = creditsToString(fee.amount); + } + + // Only pass file on new uploads, not metadata only edits. + // The sdk will figure it out + if (filePath) publishPayload.file_path = filePath; + + const success = successResponse => { + //analytics.apiLogPublish(); + + const pendingClaim = successResponse.outputs[0]; + const actions = []; + + actions.push({ + type: ACTIONS.PUBLISH_SUCCESS, + }); + + //actions.push(doOpenModal(MODALS.PUBLISH, { uri })); + + // We have to fake a temp claim until the new pending one is returned by claim_list_mine + // We can't rely on claim_list_mine because there might be some delay before the new claims are returned + // Doing this allows us to show the pending claim immediately, it will get overwritten by the real one + const isMatch = claim => claim.claim_id === pendingClaim.claim_id; + const isEdit = myClaims.some(isMatch); + const myNewClaims = isEdit + ? myClaims.map(claim => (isMatch(claim) ? pendingClaim : claim)) + : myClaims.concat(pendingClaim); + + actions.push({ + type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + claims: myNewClaims, + }, + }); + + dispatch(batchActions(...actions)); + }; + + const failure = error => { + dispatch({ type: ACTIONS.PUBLISH_FAIL }); + dispatch(doError(error.message)); + }; + + return Lbry.publish(publishPayload).then(success, failure); +}; + +// Calls claim_list_mine until any pending publishes are confirmed +export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetState) => { + const state = getState(); + const pendingById = selectPendingById(state); + + if (!Object.keys(pendingById).length) { + return; + } + + let publishCheckInterval; + + const checkFileList = () => { + Lbry.claim_list().then(claims => { + claims.forEach(claim => { + // If it's confirmed, check if it was pending previously + if (claim.confirmations > 0 && pendingById[claim.claim_id]) { + delete pendingById[claim.claim_id]; + + // If it's confirmed, check if we should notify the user + if (selectosNotificationsEnabled(getState())) { + const notif = new window.Notification('LBRY Publish Complete', { + body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, + silent: false, + }); + notif.onclick = () => { + dispatch(push(formatLbryUriForWeb(claim.permanent_url))); + }; + } + } + }); + + dispatch({ + type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + claims, + }, + }); + + if (!Object.keys(pendingById).length) { + clearInterval(publishCheckInterval); + } + }); + }; + + publishCheckInterval = setInterval(() => { + checkFileList(); + }, 30000); +}; diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js new file mode 100644 index 0000000..310a2ff --- /dev/null +++ b/src/redux/reducers/publish.js @@ -0,0 +1,107 @@ +// @flow +import { handleActions } from 'util/redux-utils'; +import { buildURI } from 'lbryURI'; +import * as ACTIONS from 'constants/action_types'; +import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; +import { CHANNEL_ANONYMOUS } from 'constants/claim'; + +type PublishState = { + editingURI: ?string, + filePath: ?string, + contentIsFree: boolean, + fee: { + amount: number, + currency: string, + }, + title: string, + thumbnail_url: string, + thumbnailPath: string, + uploadThumbnailStatus: string, + description: string, + language: string, + channel: string, + channelId: ?string, + name: string, + nameError: ?string, + bid: number, + bidError: ?string, + otherLicenseDescription: string, + licenseUrl: string, +}; + +const defaultState: PublishState = { + editingURI: undefined, + filePath: undefined, + contentIsFree: true, + fee: { + amount: 1, + currency: 'LBC', + }, + title: '', + thumbnail_url: '', + thumbnailPath: '', + uploadThumbnailStatus: THUMBNAIL_STATUSES.API_DOWN, + description: '', + language: 'en', + nsfw: false, + channel: CHANNEL_ANONYMOUS, + channelId: '', + name: '', + nameError: undefined, + bid: 0.1, + bidError: undefined, + licenseType: 'None', + otherLicenseDescription: 'All rights reserved', + licenseUrl: '', + publishing: false, + publishSuccess: false, + publishError: undefined, +}; + +export const publishReducer = handleActions( + { + [ACTIONS.UPDATE_PUBLISH_FORM]: (state, action): PublishState => { + const { data } = action; + return { + ...state, + ...data, + }; + }, + [ACTIONS.CLEAR_PUBLISH]: (): PublishState => ({ + ...defaultState, + }), + [ACTIONS.PUBLISH_START]: (state: PublishState): PublishState => ({ + ...state, + publishing: true, + publishSuccess: false, + }), + [ACTIONS.PUBLISH_FAIL]: (state: PublishState): PublishState => ({ + ...state, + publishing: false, + }), + [ACTIONS.PUBLISH_SUCCESS]: (state: PublishState): PublishState => ({ + ...state, + publishing: false, + publishSuccess: true, + }), + [ACTIONS.DO_PREPARE_EDIT]: (state: PublishState, action) => { + const { ...publishData } = action.data; + const { channel, name, uri } = publishData; + + // The short uri is what is presented to the user + // The editingUri is the full uri with claim id + const shortUri = buildURI({ + channelName: channel, + contentName: name, + }); + + return { + ...defaultState, + ...publishData, + editingURI: uri, + uri: shortUri, + }; + }, + }, + defaultState +); diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js new file mode 100644 index 0000000..893a66f --- /dev/null +++ b/src/redux/selectors/publish.js @@ -0,0 +1,105 @@ +import { createSelector } from 'reselect'; +import { buildURI, parseURI } from 'lbryURI'; +import { + selectClaimsById, + selectMyClaimsWithoutChannels, + selectResolvingUris, + selectClaimsByUri, +} from 'redux/selectors/claims'; + +const selectState = state => state.publish || {}; + +export const selectPublishFormValues = createSelector( + selectState, + state => { + const { pendingPublish, ...formValues } = state; + return formValues; + } +); + +// Is the current uri the same as the uri they clicked "edit" on +export const selectIsStillEditing = createSelector( + selectPublishFormValues, + publishState => { + const { editingURI, uri } = publishState; + + if (!editingURI || !uri) { + return false; + } + + const { isChannel: currentIsChannel, claimName: currentClaimName, contentName: currentContentName } = parseURI(uri); + const { isChannel: editIsChannel, claimName: editClaimName, contentName: editContentName } = parseURI(editingURI); + + // Depending on the previous/current use of a channel, we need to compare different things + // ex: going from a channel to anonymous, the new uri won't return contentName, so we need to use claimName + const currentName = currentIsChannel ? currentContentName : currentClaimName; + const editName = editIsChannel ? editContentName : editClaimName; + return currentName === editName; + } +); + +export const selectMyClaimForUri = createSelector( + selectPublishFormValues, + selectIsStillEditing, + selectClaimsById, + selectMyClaimsWithoutChannels, + ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => { + const { contentName, claimName } = parseURI(uri); + const { claimId: editClaimId } = parseURI(editingURI); + + // If isStillEditing + // They clicked "edit" from the file page + // They haven't changed the channel/name after clicking edit + // Get the claim so they can edit without re-uploading a new file + return isStillEditing + ? claimsById[editClaimId] + : myClaims.find(claim => + !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName + ); + } +); + +export const selectIsResolvingPublishUris = createSelector( + selectState, + selectResolvingUris, + ({ uri, name }, resolvingUris) => { + if (uri) { + const isResolvingUri = resolvingUris.includes(uri); + const { isChannel } = parseURI(uri); + + let isResolvingShortUri; + if (isChannel) { + const shortUri = buildURI({ contentName: name }); + isResolvingShortUri = resolvingUris.includes(shortUri); + } + + return isResolvingUri || isResolvingShortUri; + } + + return false; + } +); + +export const selectTakeOverAmount = createSelector( + selectState, + selectMyClaimForUri, + selectClaimsByUri, + ({ name }, myClaimForUri, claimsByUri) => { + // We only care about the winning claim for the short uri + const shortUri = buildURI({ contentName: name }); + const claimForShortUri = claimsByUri[shortUri]; + + if (!myClaimForUri && claimForShortUri) { + return claimForShortUri.effective_amount; + } else if (myClaimForUri && claimForShortUri) { + // https://github.com/lbryio/lbry/issues/1476 + // We should check the current effective_amount on my claim to see how much additional lbc + // is needed to win the claim. Currently this is not possible during a takeover. + // With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim" + // For now just ignore supports. We will just show the winning claim's bid amount + return claimForShortUri.effective_amount || claimForShortUri.amount; + } + + return null; + } +); diff --git a/src/util/uri.js b/src/util/uri.js new file mode 100644 index 0000000..238126a --- /dev/null +++ b/src/util/uri.js @@ -0,0 +1,13 @@ +// @flow +import { parseURI } from 'lbryURI'; + +export const formatLbryUriForWeb = (uri: string) => { + const { claimName, claimId } = parseURI(uri); + + let webUrl = `/${claimName}`; + if (claimId) { + webUrl += `/${claimId}`; + } + + return webUrl; +}; -- 2.45.2 From d127725045c6d7b0dbfac8f31e0fc2d58a33ebe0 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 26 Jun 2019 18:01:49 -0400 Subject: [PATCH 043/371] default sort to newest content --- dist/bundle.es.js | 19 ++++++++++++++----- src/redux/actions/claims.js | 4 ++-- src/redux/reducers/claims.js | 12 +++++++++++- src/redux/selectors/claims.js | 8 ++++++-- src/redux/selectors/file_info.js | 6 +++++- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f29e5ca..d9ccfc2 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1363,9 +1363,9 @@ const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaim return [...claims, ...pendingClaims]; }); -const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/))); +const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp)); -const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => myClaims.map(claim => `lbry://${claim.name}#${claim.claim_id}`)); +const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => myClaims.sort((a, b) => a.confirmations - b.confirmations).map(claim => `lbry://${claim.name}#${claim.claim_id}`)); const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); @@ -2262,7 +2262,7 @@ function doClaimSearch(amount = 20, options = {}) { dispatch({ type: CLAIM_SEARCH_COMPLETED, - data: { resolveInfo, uris } + data: { resolveInfo, uris, append: options.page && options.page !== 1 } }); }; @@ -2444,7 +2444,7 @@ const selectFileListDownloadedSort = reselect.createSelector(selectState$3, stat const selectDownloadedUris = reselect.createSelector(selectFileInfosDownloaded, // We should use permament_url but it doesn't exist in file_list -info => info.map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)); +info => info.slice().reverse().map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)); // @@ -3497,9 +3497,18 @@ reducers[CLAIM_SEARCH_STARTED] = state => { }); }; reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { + const { lastClaimSearchUris } = state; + + let newClaimSearchUris = []; + if (action.data.append) { + newClaimSearchUris = lastClaimSearchUris.concat(action.data.uris); + } else { + newClaimSearchUris = action.data.uris; + } + return _extends$5({}, handleClaimAction(state, action), { fetchingClaimSearch: false, - lastClaimSearchUris: action.data.uris + lastClaimSearchUris: newClaimSearchUris }); }; reducers[CLAIM_SEARCH_FAILED] = state => { diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 518f02e..ea5e1a4 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -265,7 +265,7 @@ export function doFetchChannelListMine() { }; } -export function doClaimSearch(amount: number = 20, options: {} = {}) { +export function doClaimSearch(amount: number = 20, options: { page?: number } = {}) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CLAIM_SEARCH_STARTED, @@ -281,7 +281,7 @@ export function doClaimSearch(amount: number = 20, options: {} = {}) { dispatch({ type: ACTIONS.CLAIM_SEARCH_COMPLETED, - data: { resolveInfo, uris }, + data: { resolveInfo, uris, append: options.page && options.page !== 1 }, }); }; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index fd57b99..43ee173 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -21,6 +21,7 @@ type State = { abandoningById: { [string]: boolean }, fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, + lastClaimSearchUris: Array, claimsByChannel: { [string]: { all: Array, @@ -279,10 +280,19 @@ reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State): State => { }); }; 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); + } else { + newClaimSearchUris = action.data.uris; + } + return { ...handleClaimAction(state, action), fetchingClaimSearch: false, - lastClaimSearchUris: action.data.uris, + lastClaimSearchUris: newClaimSearchUris, }; }; reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State): State => { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 8fcfff6..f867409 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -256,12 +256,16 @@ export const selectMyClaims = createSelector( export const selectMyClaimsWithoutChannels = createSelector( selectMyClaims, - myClaims => myClaims.filter(claim => !claim.name.match(/^@/)) + myClaims => + myClaims.filter(claim => !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp) ); export const selectMyClaimUrisWithoutChannels = createSelector( selectMyClaimsWithoutChannels, - myClaims => myClaims.map(claim => `lbry://${claim.name}#${claim.claim_id}`) + myClaims => + myClaims + .sort((a, b) => a.confirmations - b.confirmations) + .map(claim => `lbry://${claim.name}#${claim.claim_id}`) ); export const selectAllMyClaimsByOutpoint = createSelector( diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index fbfc023..f323734 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -232,5 +232,9 @@ export const selectFileListDownloadedSort = createSelector( export const selectDownloadedUris = createSelector( selectFileInfosDownloaded, // We should use permament_url but it doesn't exist in file_list - info => info.map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) + info => + info + .slice() + .reverse() + .map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) ); -- 2.45.2 From a67f387498f387d3c37f89cad2c916d9a920beda Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 27 Jun 2019 02:13:54 -0400 Subject: [PATCH 044/371] fix search --- dist/bundle.es.js | 16 +++++++++------- src/redux/actions/search.js | 16 +++++++++------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d9ccfc2..c037ec6 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3112,12 +3112,14 @@ from, isBackgroundSearch = false) => (dispatch, getState) => { const actions = []; data.forEach(result => { - const uri = buildURI({ - claimName: result.name, - claimId: result.claimId - }); - actions.push(doResolveUri(uri)); - uris.push(uri); + if (result.name) { + const uri = buildURI({ + claimName: result.name, + claimId: result.claimId + }); + actions.push(doResolveUri(uri)); + uris.push(uri); + } }); actions.push({ @@ -3128,7 +3130,7 @@ from, isBackgroundSearch = false) => (dispatch, getState) => { } }); dispatch(batchActions(...actions)); - }).catch(() => { + }).catch(e => { dispatch({ type: SEARCH_FAIL }); diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 6844a80..6ce900e 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -117,12 +117,14 @@ export const doSearch = ( const actions = []; data.forEach(result => { - const uri = buildURI({ - claimName: result.name, - claimId: result.claimId, - }); - actions.push(doResolveUri(uri)); - uris.push(uri); + if (result.name) { + const uri = buildURI({ + claimName: result.name, + claimId: result.claimId, + }); + actions.push(doResolveUri(uri)); + uris.push(uri); + } }); actions.push({ @@ -134,7 +136,7 @@ export const doSearch = ( }); dispatch(batchActions(...actions)); }) - .catch(() => { + .catch(e => { dispatch({ type: ACTIONS.SEARCH_FAIL, }); -- 2.45.2 From 1b9d540c67a6b358cfbc4aa6b8842157f197f303 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 28 Jun 2019 12:07:32 -0400 Subject: [PATCH 045/371] don't throw error if bad url is passed --- dist/bundle.es.js | 36 ++++++++++++++++++++++++------------ src/lbryURI.js | 36 ++++++++++++++++++++++++------------ 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c037ec6..8a4ee2e 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -918,12 +918,14 @@ function parseURI(URI, requireProto = false) { // Validate protocol if (requireProto && !proto) { - throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); + console.error(__('LBRY URIs must include a protocol prefix (lbry://).')); + return {}; } // Validate and process name if (!claimName) { - throw new Error(__('URI does not include name.')); + console.error(__('URI does not include name.')); + return {}; } const isChannel = claimName.startsWith('@'); @@ -931,11 +933,13 @@ function parseURI(URI, requireProto = false) { if (isChannel) { if (!channelName) { - throw new Error(__('No channel name after @.')); + console.error(__('No channel name after @.')); + return {}; } if (channelName.length < channelNameMinLength) { - throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); + console.error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); + return {}; } contentName = path; @@ -943,7 +947,8 @@ function parseURI(URI, requireProto = false) { const nameBadChars = (channelName || claimName).match(regexInvalidURI); if (nameBadChars) { - throw new Error(__(`Invalid character %s in name: %s.`, nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); + console.error(__(`Invalid character %s in name: %s.`, nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); + return {}; } // Validate and process modifier (claim ID, bid position or claim sequence) @@ -952,7 +957,8 @@ function parseURI(URI, requireProto = false) { let bidPosition; if (modSep) { if (!modVal) { - throw new Error(__(`No modifier provided after separator %s.`, modSep)); + console.error(__(`No modifier provided after separator %s.`, modSep)); + return {}; } if (modSep === '#') { @@ -965,31 +971,37 @@ function parseURI(URI, requireProto = false) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__(`Invalid claim ID %s.`, claimId)); + console.error(__(`Invalid claim ID %s.`, claimId)); + return {}; } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Claim sequence must be a number.')); + console.error(__('Claim sequence must be a number.')); + return {}; } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Bid position must be a number.')); + console.error(__('Bid position must be a number.')); + return {}; } // Validate and process path if (path) { if (!isChannel) { - throw new Error(__('Only channel URIs may have a path.')); + console.error(__('Only channel URIs may have a path.')); + return {}; } const pathBadChars = path.match(regexInvalidURI); if (pathBadChars) { - throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); + console.error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); + return {}; } contentName = path; } else if (pathSep) { - throw new Error(__('No path provided after /')); + console.error(__('No path provided after /')); + return {}; } return _extends({ diff --git a/src/lbryURI.js b/src/lbryURI.js index 9b805f7..e3c4771 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -44,12 +44,14 @@ export function parseURI(URI, requireProto = false) { // Validate protocol if (requireProto && !proto) { - throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); + console.error(__('LBRY URIs must include a protocol prefix (lbry://).')); + return {}; } // Validate and process name if (!claimName) { - throw new Error(__('URI does not include name.')); + console.error(__('URI does not include name.')); + return {}; } const isChannel = claimName.startsWith('@'); @@ -57,11 +59,13 @@ export function parseURI(URI, requireProto = false) { if (isChannel) { if (!channelName) { - throw new Error(__('No channel name after @.')); + console.error(__('No channel name after @.')); + return {}; } if (channelName.length < channelNameMinLength) { - throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); + console.error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); + return {}; } contentName = path; @@ -69,13 +73,14 @@ export function parseURI(URI, requireProto = false) { const nameBadChars = (channelName || claimName).match(regexInvalidURI); if (nameBadChars) { - throw new Error( + console.error( __( `Invalid character %s in name: %s.`, nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', ') ) ); + return {}; } // Validate and process modifier (claim ID, bid position or claim sequence) @@ -84,7 +89,8 @@ export function parseURI(URI, requireProto = false) { let bidPosition; if (modSep) { if (!modVal) { - throw new Error(__(`No modifier provided after separator %s.`, modSep)); + console.error(__(`No modifier provided after separator %s.`, modSep)); + return {}; } if (modSep === '#') { @@ -97,31 +103,37 @@ export function parseURI(URI, requireProto = false) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__(`Invalid claim ID %s.`, claimId)); + console.error(__(`Invalid claim ID %s.`, claimId)); + return {}; } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Claim sequence must be a number.')); + console.error(__('Claim sequence must be a number.')); + return {}; } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Bid position must be a number.')); + console.error(__('Bid position must be a number.')); + return {}; } // Validate and process path if (path) { if (!isChannel) { - throw new Error(__('Only channel URIs may have a path.')); + console.error(__('Only channel URIs may have a path.')); + return {}; } const pathBadChars = path.match(regexInvalidURI); if (pathBadChars) { - throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); + console.error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); + return {}; } contentName = path; } else if (pathSep) { - throw new Error(__('No path provided after /')); + console.error(__('No path provided after /')); + return {}; } return { -- 2.45.2 From 63ba459574d7f8596b46b9e5f6c4bf09e08c71a5 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 1 Jul 2019 23:04:27 -0400 Subject: [PATCH 046/371] repond to pr feedback --- dist/bundle.es.js | 40 +++++++++++--------------------- src/lbryURI.js | 36 ++++++++++------------------ src/redux/selectors/claims.js | 2 +- src/redux/selectors/file_info.js | 2 +- 4 files changed, 28 insertions(+), 52 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8a4ee2e..9143564 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -918,14 +918,12 @@ function parseURI(URI, requireProto = false) { // Validate protocol if (requireProto && !proto) { - console.error(__('LBRY URIs must include a protocol prefix (lbry://).')); - return {}; + throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); } // Validate and process name if (!claimName) { - console.error(__('URI does not include name.')); - return {}; + throw new Error(__('URI does not include name.')); } const isChannel = claimName.startsWith('@'); @@ -933,13 +931,11 @@ function parseURI(URI, requireProto = false) { if (isChannel) { if (!channelName) { - console.error(__('No channel name after @.')); - return {}; + throw new Error(__('No channel name after @.')); } if (channelName.length < channelNameMinLength) { - console.error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); - return {}; + throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); } contentName = path; @@ -947,8 +943,7 @@ function parseURI(URI, requireProto = false) { const nameBadChars = (channelName || claimName).match(regexInvalidURI); if (nameBadChars) { - console.error(__(`Invalid character %s in name: %s.`, nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); - return {}; + throw new Error(__(`Invalid character %s in name: %s.`, nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); } // Validate and process modifier (claim ID, bid position or claim sequence) @@ -957,8 +952,7 @@ function parseURI(URI, requireProto = false) { let bidPosition; if (modSep) { if (!modVal) { - console.error(__(`No modifier provided after separator %s.`, modSep)); - return {}; + throw new Error(__(`No modifier provided after separator %s.`, modSep)); } if (modSep === '#') { @@ -971,37 +965,31 @@ function parseURI(URI, requireProto = false) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - console.error(__(`Invalid claim ID %s.`, claimId)); - return {}; + throw new Error(__(`Invalid claim ID %s.`, claimId)); } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - console.error(__('Claim sequence must be a number.')); - return {}; + throw new Error(__('Claim sequence must be a number.')); } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - console.error(__('Bid position must be a number.')); - return {}; + throw new Error(__('Bid position must be a number.')); } // Validate and process path if (path) { if (!isChannel) { - console.error(__('Only channel URIs may have a path.')); - return {}; + throw new Error(__('Only channel URIs may have a path.')); } const pathBadChars = path.match(regexInvalidURI); if (pathBadChars) { - console.error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); - return {}; + throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); } contentName = path; } else if (pathSep) { - console.error(__('No path provided after /')); - return {}; + throw new Error(__('No path provided after /')); } return _extends({ @@ -1377,7 +1365,7 @@ const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaim const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp)); -const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => myClaims.sort((a, b) => a.confirmations - b.confirmations).map(claim => `lbry://${claim.name}#${claim.claim_id}`)); +const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => myClaims.sort((a, b) => b.timestamp - a.timestamp).map(claim => `lbry://${claim.name}#${claim.claim_id}`)); const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); @@ -2456,7 +2444,7 @@ const selectFileListDownloadedSort = reselect.createSelector(selectState$3, stat const selectDownloadedUris = reselect.createSelector(selectFileInfosDownloaded, // We should use permament_url but it doesn't exist in file_list -info => info.slice().reverse().map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)); +info => info.slice().reverse().map(claim => console.log(claim) || `lbry://${claim.claim_name}#${claim.claim_id}`)); // diff --git a/src/lbryURI.js b/src/lbryURI.js index e3c4771..9b805f7 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -44,14 +44,12 @@ export function parseURI(URI, requireProto = false) { // Validate protocol if (requireProto && !proto) { - console.error(__('LBRY URIs must include a protocol prefix (lbry://).')); - return {}; + throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); } // Validate and process name if (!claimName) { - console.error(__('URI does not include name.')); - return {}; + throw new Error(__('URI does not include name.')); } const isChannel = claimName.startsWith('@'); @@ -59,13 +57,11 @@ export function parseURI(URI, requireProto = false) { if (isChannel) { if (!channelName) { - console.error(__('No channel name after @.')); - return {}; + throw new Error(__('No channel name after @.')); } if (channelName.length < channelNameMinLength) { - console.error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); - return {}; + throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); } contentName = path; @@ -73,14 +69,13 @@ export function parseURI(URI, requireProto = false) { const nameBadChars = (channelName || claimName).match(regexInvalidURI); if (nameBadChars) { - console.error( + throw new Error( __( `Invalid character %s in name: %s.`, nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', ') ) ); - return {}; } // Validate and process modifier (claim ID, bid position or claim sequence) @@ -89,8 +84,7 @@ export function parseURI(URI, requireProto = false) { let bidPosition; if (modSep) { if (!modVal) { - console.error(__(`No modifier provided after separator %s.`, modSep)); - return {}; + throw new Error(__(`No modifier provided after separator %s.`, modSep)); } if (modSep === '#') { @@ -103,37 +97,31 @@ export function parseURI(URI, requireProto = false) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - console.error(__(`Invalid claim ID %s.`, claimId)); - return {}; + throw new Error(__(`Invalid claim ID %s.`, claimId)); } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - console.error(__('Claim sequence must be a number.')); - return {}; + throw new Error(__('Claim sequence must be a number.')); } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - console.error(__('Bid position must be a number.')); - return {}; + throw new Error(__('Bid position must be a number.')); } // Validate and process path if (path) { if (!isChannel) { - console.error(__('Only channel URIs may have a path.')); - return {}; + throw new Error(__('Only channel URIs may have a path.')); } const pathBadChars = path.match(regexInvalidURI); if (pathBadChars) { - console.error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); - return {}; + throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); } contentName = path; } else if (pathSep) { - console.error(__('No path provided after /')); - return {}; + throw new Error(__('No path provided after /')); } return { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index f867409..7caa2d2 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -264,7 +264,7 @@ export const selectMyClaimUrisWithoutChannels = createSelector( selectMyClaimsWithoutChannels, myClaims => myClaims - .sort((a, b) => a.confirmations - b.confirmations) + .sort((a, b) => b.timestamp - a.timestamp) .map(claim => `lbry://${claim.name}#${claim.claim_id}`) ); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index f323734..637ea3c 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -236,5 +236,5 @@ export const selectDownloadedUris = createSelector( info .slice() .reverse() - .map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) + .map(claim => console.log(claim) || `lbry://${claim.claim_name}#${claim.claim_id}`) ); -- 2.45.2 From 8bfef313869ca48687cd8548075cdf3519f2c879 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Sun, 30 Jun 2019 21:16:44 -0400 Subject: [PATCH 047/371] jessop's commit - channel edit functionality --- dist/bundle.es.js | 56 +++++++++++++++++++++++++++++++++++ dist/flow-typed/Lbry.js | 2 ++ flow-typed/Lbry.js | 2 ++ src/constants/action_types.js | 3 ++ src/index.js | 2 ++ src/lbry.js | 1 + src/redux/actions/claims.js | 34 +++++++++++++++++++++ src/redux/reducers/claims.js | 11 +++++++ src/redux/selectors/claims.js | 8 +++++ 9 files changed, 119 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9143564..d81f802 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -103,6 +103,9 @@ const FETCH_CHANNEL_LIST_COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED'; const CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED'; const CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; const CREATE_CHANNEL_FAILED = 'CREATE_CHANNEL_FAILED'; +const UPDATE_CHANNEL_STARTED = 'UPDATE_CHANNEL_STARTED'; +const UPDATE_CHANNEL_COMPLETED = 'UPDATE_CHANNEL_COMPLETED'; +const UPDATE_CHANNEL_FAILED = 'UPDATE_CHANNEL_FAILED'; const PUBLISH_STARTED = 'PUBLISH_STARTED'; const PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; const PUBLISH_FAILED = 'PUBLISH_FAILED'; @@ -328,6 +331,9 @@ var action_types = /*#__PURE__*/Object.freeze({ CREATE_CHANNEL_STARTED: CREATE_CHANNEL_STARTED, CREATE_CHANNEL_COMPLETED: CREATE_CHANNEL_COMPLETED, CREATE_CHANNEL_FAILED: CREATE_CHANNEL_FAILED, + UPDATE_CHANNEL_STARTED: UPDATE_CHANNEL_STARTED, + UPDATE_CHANNEL_COMPLETED: UPDATE_CHANNEL_COMPLETED, + UPDATE_CHANNEL_FAILED: UPDATE_CHANNEL_FAILED, PUBLISH_STARTED: PUBLISH_STARTED, PUBLISH_COMPLETED: PUBLISH_COMPLETED, PUBLISH_FAILED: PUBLISH_FAILED, @@ -707,6 +713,7 @@ const Lbry = { claim_search: params => daemonCallWithResult('claim_search', params), claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), + channel_update: params => daemonCallWithResult('channel_update', params), channel_list: params => daemonCallWithResult('channel_list', params), stream_abandon: params => daemonCallWithResult('stream_abandon', params), channel_abandon: params => daemonCallWithResult('channel_abandon', params), @@ -1334,6 +1341,10 @@ const makeSelectDateForUri = uri => reselect.createSelector(makeSelectClaimForUr return dateObj; }); +const makeSelectAmountForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { + return claim && claim.amount; +}); + const makeSelectContentTypeForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { const source = claim && claim.value && claim.value.source; return source ? source.media_type : undefined; @@ -2229,6 +2240,38 @@ function doCreateChannel(name, amount) { }; } +function doUpdateChannel(params) { + return dispatch => { + dispatch({ + type: UPDATE_CHANNEL_STARTED + }); + const updateParams = { + claim_id: params.claim_id, + bid: creditsToString(params.amount), + title: params.title, + cover_url: params.cover, + thumbnail_url: params.thumbnail, + description: params.description, + website_url: params.website, + email: params.email, + replace: true + }; + + return lbryProxy.channel_update(updateParams).then(result => { + const channelClaim = result.outputs[0]; + dispatch({ + type: UPDATE_CHANNEL_COMPLETED, + data: { channelClaim } + }); + }).catch(error => { + dispatch({ + type: UPDATE_CHANNEL_FAILED, + data: error + }); + }); + }; +} + function doFetchChannelListMine() { return dispatch => { dispatch({ @@ -3476,6 +3519,17 @@ reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { }); }; +reducers[UPDATE_CHANNEL_COMPLETED] = (state, action) => { + const channelClaim = action.data.channelClaim; + const byId = Object.assign({}, state.byId); + + byId[channelClaim.claim_id] = channelClaim; + + return Object.assign({}, state, { + byId + }); +}; + reducers[RESOLVE_URIS_STARTED] = (state, action) => { const { uris } = action.data; @@ -4619,6 +4673,7 @@ exports.doToggleTagFollow = doToggleTagFollow; exports.doTotalBalanceSubscribe = doTotalBalanceSubscribe; exports.doUpdateBalance = doUpdateBalance; exports.doUpdateBlockHeight = doUpdateBlockHeight; +exports.doUpdateChannel = doUpdateChannel; exports.doUpdatePublishForm = doUpdatePublishForm; exports.doUpdateSearchOptions = doUpdateSearchOptions; exports.doUpdateSearchQuery = doUpdateSearchQuery; @@ -4636,6 +4691,7 @@ exports.isClaimNsfw = isClaimNsfw; exports.isNameValid = isNameValid; exports.isURIClaimable = isURIClaimable; exports.isURIValid = isURIValid; +exports.makeSelectAmountForUri = makeSelectAmountForUri; exports.makeSelectChannelForClaimUri = makeSelectChannelForClaimUri; exports.makeSelectClaimForUri = makeSelectClaimForUri; exports.makeSelectClaimIsMine = makeSelectClaimIsMine; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 9931f68..6438792 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -176,6 +176,8 @@ declare type LbryTypes = { claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, channel_create: (params: {}) => Promise, + // TODO fix this type: + channel_update: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 9931f68..6438792 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -176,6 +176,8 @@ declare type LbryTypes = { claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, channel_create: (params: {}) => Promise, + // TODO fix this type: + channel_update: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 3fa9547..bdbad5d 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -80,6 +80,9 @@ export const FETCH_CHANNEL_LIST_COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED'; export const CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED'; export const CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; export const CREATE_CHANNEL_FAILED = 'CREATE_CHANNEL_FAILED'; +export const UPDATE_CHANNEL_STARTED = 'UPDATE_CHANNEL_STARTED'; +export const UPDATE_CHANNEL_COMPLETED = 'UPDATE_CHANNEL_COMPLETED'; +export const UPDATE_CHANNEL_FAILED = 'UPDATE_CHANNEL_FAILED'; export const PUBLISH_STARTED = 'PUBLISH_STARTED'; export const PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; export const PUBLISH_FAILED = 'PUBLISH_FAILED'; diff --git a/src/index.js b/src/index.js index 5b861a1..9754c25 100644 --- a/src/index.js +++ b/src/index.js @@ -49,6 +49,7 @@ export { doResolveUri, doFetchChannelListMine, doCreateChannel, + doUpdateChannel, doClaimSearch, } from 'redux/actions/claims'; @@ -149,6 +150,7 @@ export { makeSelectCoverForUri, makeSelectTitleForUri, makeSelectDateForUri, + makeSelectAmountForUri, makeSelectTagsForUri, makeSelectContentTypeForUri, makeSelectIsUriResolving, diff --git a/src/lbry.js b/src/lbry.js index 617b24b..07fe1f0 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -71,6 +71,7 @@ const Lbry: LbryTypes = { claim_search: params => daemonCallWithResult('claim_search', params), claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), + channel_update: params => daemonCallWithResult('channel_update', params), channel_list: params => daemonCallWithResult('channel_list', params), stream_abandon: params => daemonCallWithResult('stream_abandon', params), channel_abandon: params => daemonCallWithResult('channel_abandon', params), diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index ea5e1a4..f973890 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -248,6 +248,40 @@ export function doCreateChannel(name: string, amount: number) { }; } +export function doUpdateChannel(params: any) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.UPDATE_CHANNEL_STARTED, + }); + const updateParams = { + claim_id: params.claim_id, + bid: creditsToString(params.amount), + title: params.title, + cover_url: params.cover, + thumbnail_url: params.thumbnail, + description: params.description, + website_url: params.website, + email: params.email, + replace: true, + }; + + return Lbry.channel_update(updateParams) + .then((result: ChannelCreateResponse) => { + const channelClaim = result.outputs[0]; + dispatch({ + type: ACTIONS.UPDATE_CHANNEL_COMPLETED, + data: { channelClaim }, + }); + }) + .catch(error => { + dispatch({ + type: ACTIONS.UPDATE_CHANNEL_FAILED, + data: error, + }); + }); + }; +} + export function doFetchChannelListMine() { return (dispatch: Dispatch) => { dispatch({ diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 43ee173..99a8f7f 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -257,6 +257,17 @@ reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State }); }; +reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { + const channelClaim: ChannelClaim = action.data.channelClaim; + const byId = Object.assign({}, state.byId); + + byId[channelClaim.claim_id] = channelClaim; + + return Object.assign({}, state, { + byId, + }); +}; + reducers[ACTIONS.RESOLVE_URIS_STARTED] = (state: State, action: any): State => { const { uris }: { uris: Array } = action.data; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 7caa2d2..69fddb5 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -204,6 +204,14 @@ export const makeSelectDateForUri = (uri: string) => } ); +export const makeSelectAmountForUri = (uri: string) => + createSelector( + makeSelectClaimForUri(uri), + claim => { + return claim && claim.amount; + } + ); + export const makeSelectContentTypeForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), -- 2.45.2 From 4c6147efcc3823c4008b99cf4815952cb02aacc4 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 2 Jul 2019 13:47:42 -0400 Subject: [PATCH 048/371] add ChannelUpdateResponse type --- dist/flow-typed/Lbry.js | 15 ++++++++------- flow-typed/Lbry.js | 15 ++++++++------- src/redux/actions/claims.js | 2 +- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 6438792..bc02e1f 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -65,9 +65,7 @@ declare type VersionResponse = { declare type ResolveResponse = { // Keys are the url(s) passed to resolve - [string]: - | Claim - | { error?: {} }, + [string]: Claim | { error?: {} }, }; declare type GetResponse = FileListItem; @@ -105,6 +103,10 @@ declare type ChannelCreateResponse = GenericTxResponse & { outputs: Array, }; +declare type UpdateChannelResponse = GenericTxResponse & { + outputs: Array, +}; + declare type CommentCreateResponse = Comment; declare type CommentListResponse = Array; @@ -157,10 +159,10 @@ declare type LbryTypes = { connectPromise: ?Promise, connect: () => void, daemonConnectionString: string, - apiRequestHeaders: {[key: string]: string}, + apiRequestHeaders: { [key: string]: string }, setDaemonConnectionString: string => void, setApiHeader: (string, string) => void, - unsetApiHeader: (string) => void, + unsetApiHeader: string => void, overrides: { [string]: ?Function }, setOverride: (string, Function) => void, getMediaType: (string, ?string) => string, @@ -176,8 +178,7 @@ declare type LbryTypes = { claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, channel_create: (params: {}) => Promise, - // TODO fix this type: - channel_update: (params: {}) => Promise, + channel_update: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 6438792..335eda1 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -65,9 +65,7 @@ declare type VersionResponse = { declare type ResolveResponse = { // Keys are the url(s) passed to resolve - [string]: - | Claim - | { error?: {} }, + [string]: Claim | { error?: {} }, }; declare type GetResponse = FileListItem; @@ -105,6 +103,10 @@ declare type ChannelCreateResponse = GenericTxResponse & { outputs: Array, }; +declare type ChannelUpdateResponse = GenericTxResponse & { + outputs: Array, +}; + declare type CommentCreateResponse = Comment; declare type CommentListResponse = Array; @@ -157,10 +159,10 @@ declare type LbryTypes = { connectPromise: ?Promise, connect: () => void, daemonConnectionString: string, - apiRequestHeaders: {[key: string]: string}, + apiRequestHeaders: { [key: string]: string }, setDaemonConnectionString: string => void, setApiHeader: (string, string) => void, - unsetApiHeader: (string) => void, + unsetApiHeader: string => void, overrides: { [string]: ?Function }, setOverride: (string, Function) => void, getMediaType: (string, ?string) => string, @@ -176,8 +178,7 @@ declare type LbryTypes = { claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, channel_create: (params: {}) => Promise, - // TODO fix this type: - channel_update: (params: {}) => Promise, + channel_update: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index f973890..51fd397 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -266,7 +266,7 @@ export function doUpdateChannel(params: any) { }; return Lbry.channel_update(updateParams) - .then((result: ChannelCreateResponse) => { + .then((result: ChannelUpdateResponse) => { const channelClaim = result.outputs[0]; dispatch({ type: ACTIONS.UPDATE_CHANNEL_COMPLETED, -- 2.45.2 From 009ae8b8fac991c306179b66ac76066e92e16322 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 2 Jul 2019 16:33:57 -0400 Subject: [PATCH 049/371] add tags back to redux --- dist/bundle.es.js | 36 +++++++++--- dist/flow-typed/Lbry.js | 4 +- src/constants/tags.js | 24 ++++++++ src/index.js | 8 ++- src/redux/reducers/tags.js | 115 +++++++++++++++++++++---------------- src/util/claim.js | 8 +-- 6 files changed, 127 insertions(+), 68 deletions(-) create mode 100644 src/constants/tags.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d81f802..2bde5b9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -645,6 +645,12 @@ const SEARCH_OPTIONS = { MEDIA_APPLICATION: 'application' }; +const DEFAULT_FOLLOWED_TAGS = ['blockchain', 'news', 'learning', 'technology', 'automotive', 'economics', 'food', 'science', 'art', 'nature']; + +const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; + +const DEFAULT_KNOWN_TAGS = ['beliefs', 'funny', 'gaming', 'pop culture', 'music', 'sports', 'weapons']; + // const CHECK_DAEMON_STARTED_TRY_NUMBER = 200; @@ -1208,9 +1214,7 @@ 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; }; -// - -const naughtyTags = ['porn', 'nsfw', 'mature', 'xxx'].reduce((acc, tag) => _extends$2({}, acc, { [tag]: true }), {}); +const matureTagMap = MATURE_TAGS.reduce((acc, tag) => _extends$2({}, acc, { [tag]: true }), {}); const isClaimNsfw = claim => { if (!claim) { @@ -1224,7 +1228,7 @@ const isClaimNsfw = claim => { const tags = claim.value.tags || []; for (let i = 0; i < tags.length; i += 1) { const tag = tags[i].toLowerCase(); - if (naughtyTags[tag]) { + if (matureTagMap[tag]) { return true; } } @@ -4152,7 +4156,18 @@ const searchReducer = handleActions({ var _extends$d = 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; }; -const tagsReducerBuilder = defaultState => handleActions({ +function getDefaultKnownTags() { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$d({}, tagsMap, { + [tag]: { name: tag } + }), {}); +} + +const defaultState$8 = { + followedTags: DEFAULT_FOLLOWED_TAGS, + knownTags: getDefaultKnownTags() +}; + +const tagsReducer = handleActions({ [TOGGLE_TAG_FOLLOW]: (state, action) => { const { followedTags } = state; const { name } = action.data; @@ -4195,7 +4210,7 @@ const tagsReducerBuilder = defaultState => handleActions({ followedTags: newFollowedTags }); } -}, defaultState); +}, defaultState$8); var _extends$e = 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; }; @@ -4208,7 +4223,7 @@ const buildDraftTransaction = () => ({ // See details in https://github.com/lbryio/lbry/issues/1307 -const defaultState$8 = { +const defaultState$9 = { balance: undefined, totalBalance: undefined, latestBlock: undefined, @@ -4451,7 +4466,7 @@ const walletReducer = handleActions({ [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$e({}, state, { latestBlock: action.data }) -}, defaultState$8); +}, defaultState$9); const selectState$5 = state => state.content || {}; @@ -4613,8 +4628,11 @@ const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, sele exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; +exports.DEFAULT_FOLLOWED_TAGS = DEFAULT_FOLLOWED_TAGS; +exports.DEFAULT_KNOWN_TAGS = DEFAULT_KNOWN_TAGS; exports.LICENSES = licenses; exports.Lbry = lbryProxy; +exports.MATURE_TAGS = MATURE_TAGS; exports.PAGES = pages; exports.SEARCH_OPTIONS = SEARCH_OPTIONS; exports.SEARCH_TYPES = SEARCH_TYPES; @@ -4818,6 +4836,6 @@ exports.selectWalletUnlockPending = selectWalletUnlockPending; exports.selectWalletUnlockResult = selectWalletUnlockResult; exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded; exports.setSearchApi = setSearchApi; -exports.tagsReducerBuilder = tagsReducerBuilder; +exports.tagsReducer = tagsReducer; exports.toQueryString = toQueryString; exports.walletReducer = walletReducer; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index bc02e1f..335eda1 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -103,7 +103,7 @@ declare type ChannelCreateResponse = GenericTxResponse & { outputs: Array, }; -declare type UpdateChannelResponse = GenericTxResponse & { +declare type ChannelUpdateResponse = GenericTxResponse & { outputs: Array, }; @@ -178,7 +178,7 @@ declare type LbryTypes = { claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, channel_create: (params: {}) => Promise, - channel_update: (params: {}) => Promise, + channel_update: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/src/constants/tags.js b/src/constants/tags.js new file mode 100644 index 0000000..09630bb --- /dev/null +++ b/src/constants/tags.js @@ -0,0 +1,24 @@ +export const DEFAULT_FOLLOWED_TAGS = [ + 'blockchain', + 'news', + 'learning', + 'technology', + 'automotive', + 'economics', + 'food', + 'science', + 'art', + 'nature', +]; + +export const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; + +export const DEFAULT_KNOWN_TAGS = [ + 'beliefs', + 'funny', + 'gaming', + 'pop culture', + 'music', + 'sports', + 'weapons', +]; diff --git a/src/index.js b/src/index.js index 9754c25..3202149 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import * as SORT_OPTIONS from 'constants/sort_options'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as TRANSACTIONS from 'constants/transaction_types'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; +import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS } from 'constants/tags'; import Lbry from 'lbry'; import { selectState as selectSearchState } from 'redux/selectors/search'; @@ -22,6 +23,9 @@ export { TRANSACTIONS, SORT_OPTIONS, PAGES, + DEFAULT_KNOWN_TAGS, + DEFAULT_FOLLOWED_TAGS, + MATURE_TAGS, }; // common @@ -69,7 +73,7 @@ export { doUploadThumbnail, doPrepareEdit, doPublish, - doCheckPendingPublishes + doCheckPendingPublishes, } from 'redux/actions/publish'; export { @@ -122,7 +126,7 @@ export { fileReducer } from 'redux/reducers/file'; export { notificationsReducer } from 'redux/reducers/notifications'; export { publishReducer } from 'redux/reducers/publish'; export { searchReducer } from 'redux/reducers/search'; -export { tagsReducerBuilder } from 'redux/reducers/tags'; +export { tagsReducer } from 'redux/reducers/tags'; export { walletReducer } from 'redux/reducers/wallet'; // selectors diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index aca5976..79692ba 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -1,55 +1,70 @@ // @flow import * as ACTIONS from 'constants/action_types'; import { handleActions } from 'util/redux-utils'; +import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS } from 'constants/tags'; -export const tagsReducerBuilder = (defaultState: TagState) => - handleActions( - { - [ACTIONS.TOGGLE_TAG_FOLLOW]: (state: TagState, action: TagAction): TagState => { - const { followedTags } = state; - const { name } = action.data; - - let newFollowedTags = followedTags.slice(); - - if (newFollowedTags.includes(name)) { - newFollowedTags = newFollowedTags.filter(tag => tag !== name); - } else { - newFollowedTags.push(name); - } - - return { - ...state, - followedTags: newFollowedTags, - }; - }, - - [ACTIONS.TAG_ADD]: (state: TagState, action: TagAction) => { - const { knownTags } = state; - const { name } = action.data; - - let newKnownTags = { ...knownTags }; - newKnownTags[name] = { name }; - - return { - ...state, - knownTags: newKnownTags, - }; - }, - - [ACTIONS.TAG_DELETE]: (state: TagState, action: TagAction) => { - const { knownTags, followedTags } = state; - const { name } = action.data; - - let newKnownTags = { ...knownTags }; - delete newKnownTags[name]; - const newFollowedTags = followedTags.filter(tag => tag !== name); - - return { - ...state, - knownTags: newKnownTags, - followedTags: newFollowedTags, - }; - }, - }, - defaultState +function getDefaultKnownTags() { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce( + (tagsMap, tag) => ({ + ...tagsMap, + [tag]: { name: tag }, + }), + {} ); +} + +const defaultState: TagState = { + followedTags: DEFAULT_FOLLOWED_TAGS, + knownTags: getDefaultKnownTags(), +}; + +export const tagsReducer = handleActions( + { + [ACTIONS.TOGGLE_TAG_FOLLOW]: (state: TagState, action: TagAction): TagState => { + const { followedTags } = state; + const { name } = action.data; + + let newFollowedTags = followedTags.slice(); + + if (newFollowedTags.includes(name)) { + newFollowedTags = newFollowedTags.filter(tag => tag !== name); + } else { + newFollowedTags.push(name); + } + + return { + ...state, + followedTags: newFollowedTags, + }; + }, + + [ACTIONS.TAG_ADD]: (state: TagState, action: TagAction) => { + const { knownTags } = state; + const { name } = action.data; + + let newKnownTags = { ...knownTags }; + newKnownTags[name] = { name }; + + return { + ...state, + knownTags: newKnownTags, + }; + }, + + [ACTIONS.TAG_DELETE]: (state: TagState, action: TagAction) => { + const { knownTags, followedTags } = state; + const { name } = action.data; + + let newKnownTags = { ...knownTags }; + delete newKnownTags[name]; + const newFollowedTags = followedTags.filter(tag => tag !== name); + + return { + ...state, + knownTags: newKnownTags, + followedTags: newFollowedTags, + }; + }, + }, + defaultState +); diff --git a/src/util/claim.js b/src/util/claim.js index 73adb7a..b5d6a96 100644 --- a/src/util/claim.js +++ b/src/util/claim.js @@ -1,9 +1,7 @@ // @flow +import { MATURE_TAGS } from 'constants/tags'; -const naughtyTags = ['porn', 'nsfw', 'mature', 'xxx'].reduce( - (acc, tag) => ({ ...acc, [tag]: true }), - {} -); +const matureTagMap = MATURE_TAGS.reduce((acc, tag) => ({ ...acc, [tag]: true }), {}); export const isClaimNsfw = (claim: Claim): boolean => { if (!claim) { @@ -17,7 +15,7 @@ export const isClaimNsfw = (claim: Claim): boolean => { const tags = claim.value.tags || []; for (let i = 0; i < tags.length; i += 1) { const tag = tags[i].toLowerCase(); - if (naughtyTags[tag]) { + if (matureTagMap[tag]) { return true; } } -- 2.45.2 From 321b4e9d936fa1fa5a829c4685aabe71b5121735 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 3 Jul 2019 10:53:12 +0100 Subject: [PATCH 050/371] fix makeSelectDateForUri error on mobile --- 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 2bde5b9..242adef 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1337,7 +1337,7 @@ const makeSelectMetadataItemForUri = (uri, key) => reselect.createSelector(makeS const makeSelectTitleForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); const makeSelectDateForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { - const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta.creation_timestamp * 1000); + const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta.creation_timestamp ? claim.meta.creation_timestamp * 1000 : null); if (!timestamp) { return undefined; } diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 69fddb5..afd084d 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -195,7 +195,7 @@ export const makeSelectDateForUri = (uri: string) => claim.value && (claim.value.release_time ? claim.value.release_time * 1000 - : claim.meta.creation_timestamp * 1000); + : (claim.meta.creation_timestamp ? claim.meta.creation_timestamp * 1000 : null)); if (!timestamp) { return undefined; } -- 2.45.2 From c83489e78ed368d368ad25552fce25e7de2d64b5 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 5 Jul 2019 13:35:17 -0400 Subject: [PATCH 051/371] remove console.log --- dist/bundle.es.js | 2 +- src/redux/selectors/file_info.js | 40 ++++++++++++++++---------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 242adef..5055500 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2491,7 +2491,7 @@ const selectFileListDownloadedSort = reselect.createSelector(selectState$3, stat const selectDownloadedUris = reselect.createSelector(selectFileInfosDownloaded, // We should use permament_url but it doesn't exist in file_list -info => info.slice().reverse().map(claim => console.log(claim) || `lbry://${claim.claim_name}#${claim.claim_id}`)); +info => info.slice().reverse().map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)); // diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 637ea3c..8133733 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -190,31 +190,31 @@ export const selectSearchDownloadUris = query => return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(fileInfo => { - const { - channel_name: channelName, - claim_id: claimId, - claim_name: claimName, - } = fileInfo; + const { + channel_name: channelName, + claim_id: claimId, + claim_name: claimName, + } = fileInfo; - const uriParams = {}; + const uriParams = {}; - if (channelName) { - const claim = claimsById[claimId]; - if (claim && claim.signing_channel) { - uriParams.claimId = claim.signing_channel.claim_id; + if (channelName) { + const claim = claimsById[claimId]; + if (claim && claim.signing_channel) { + uriParams.claimId = claim.signing_channel.claim_id; + } else { + uriParams.claimId = claimId; + } + uriParams.channelName = channelName; + uriParams.contentName = claimName; } else { uriParams.claimId = claimId; + uriParams.claimName = claimName; } - uriParams.channelName = channelName; - uriParams.contentName = claimName; - } else { - uriParams.claimId = claimId; - uriParams.claimName = claimName; - } - const uri = buildURI(uriParams); - return uri; - }) + const uri = buildURI(uriParams); + return uri; + }) : null; } ); @@ -236,5 +236,5 @@ export const selectDownloadedUris = createSelector( info .slice() .reverse() - .map(claim => console.log(claim) || `lbry://${claim.claim_name}#${claim.claim_id}`) + .map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) ); -- 2.45.2 From 66225f02c86cc38c37e2d17206c3ba4fa5631420 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 8 Jul 2019 14:28:14 -0400 Subject: [PATCH 052/371] add selector for short_url --- dist/bundle.es.js | 3 +++ src/index.js | 1 + src/redux/selectors/claims.js | 10 +++++++++- 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 5055500..be9be87 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1501,6 +1501,8 @@ const selectFetchingClaimSearch = reselect.createSelector(selectState$1, state = const selectLastClaimSearchUris = reselect.createSelector(selectState$1, state => state.lastClaimSearchUris); +const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => console.log(claim) || claim && claim.short_url); + const selectState$2 = state => state.wallet || {}; const selectWalletState = selectState$2; @@ -4736,6 +4738,7 @@ exports.makeSelectPendingByUri = makeSelectPendingByUri; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; exports.makeSelectSearchUris = makeSelectSearchUris; +exports.makeSelectShortUrlForUri = makeSelectShortUrlForUri; exports.makeSelectStreamingUrlForUri = makeSelectStreamingUrlForUri; exports.makeSelectTagsForUri = makeSelectTagsForUri; exports.makeSelectThumbnailForUri = makeSelectThumbnailForUri; diff --git a/src/index.js b/src/index.js index 3202149..3c7c82f 100644 --- a/src/index.js +++ b/src/index.js @@ -169,6 +169,7 @@ export { makeSelectClaimIsPending, makeSelectPendingByUri, makeSelectClaimsInChannelForCurrentPageState, + makeSelectShortUrlForUri, selectPendingById, selectClaimsById, selectClaimsByUri, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index afd084d..af42470 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -195,7 +195,9 @@ export const makeSelectDateForUri = (uri: string) => claim.value && (claim.value.release_time ? claim.value.release_time * 1000 - : (claim.meta.creation_timestamp ? claim.meta.creation_timestamp * 1000 : null)); + : claim.meta.creation_timestamp + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -468,3 +470,9 @@ export const selectLastClaimSearchUris = createSelector( selectState, state => state.lastClaimSearchUris ); + +export const makeSelectShortUrlForUri = (uri: string) => + createSelector( + makeSelectClaimForUri(uri), + claim => console.log(claim) || (claim && claim.short_url) + ); -- 2.45.2 From bb82aed61a5569e565daa784eb25fc1d639c0c22 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 8 Jul 2019 14:29:07 -0400 Subject: [PATCH 053/371] fix typo --- 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 be9be87..0fcf003 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1501,7 +1501,7 @@ const selectFetchingClaimSearch = reselect.createSelector(selectState$1, state = const selectLastClaimSearchUris = reselect.createSelector(selectState$1, state => state.lastClaimSearchUris); -const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => console.log(claim) || claim && claim.short_url); +const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); const selectState$2 = state => state.wallet || {}; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index af42470..50777c3 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -474,5 +474,5 @@ export const selectLastClaimSearchUris = createSelector( export const makeSelectShortUrlForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), - claim => console.log(claim) || (claim && claim.short_url) + claim => claim && claim.short_url ); -- 2.45.2 From 310e0f5bd6ae875dcb8492dba9622a923a012a08 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 9 Jul 2019 01:17:51 -0400 Subject: [PATCH 054/371] update default suggested tags --- dist/bundle.es.js | 2 +- src/constants/tags.js | 489 +++++++++++++++++++++++++++++++++++++++++- 2 files changed, 489 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 0fcf003..2a53b10 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -649,7 +649,7 @@ const DEFAULT_FOLLOWED_TAGS = ['blockchain', 'news', 'learning', 'technology', ' const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['beliefs', 'funny', 'gaming', 'pop culture', 'music', 'sports', 'weapons']; +const DEFAULT_KNOWN_TAGS = ['activism', 'adventure', 'adventures', 'agnostic', 'aliens', 'altcoin', 'altcoins', 'amazon', 'anarchism', 'anarchist', 'anarchy', 'android', 'animal', 'animals', 'animation', 'anime', 'apex', 'apple', 'ark', 'ark survival evolved', 'art', 'artist', 'aspire', 'atheism', 'atheist', 'australia', 'auto', 'automotive', 'autos & vehicles', 'bass', 'batman', 'battle royale', 'beach', 'beat', 'beats', 'beliefs', 'ben shapiro', 'bible', 'bitcoin', 'bitcoin gratis', 'bitcoin news', 'bitcoin price', 'black ops', 'blockchain', 'blogger', 'bo1', 'bo2', 'bo3', 'bo4', 'bodybuilding', 'boom', 'boss', 'btc', 'building', 'business', 'california', 'call of duty', 'camping', 'canon', 'car', 'cars', 'cbs', 'chill', 'chris', 'christian', 'christianity', 'christmas', 'church', 'clips', 'cnn', 'cod', 'colorful hair', 'comedy', 'comics', 'commentary', 'community', 'computer', 'conservative', 'console', 'conspiracy', 'cool long hair', 'cover', 'crafting', 'crash', 'creative hairstyles', 'crypto', 'crypto news', 'cryptocurrency', 'cryptocurrency news', 'culture', 'cute', 'daily', 'daily vlog', 'dance', 'day', 'death', 'democrat', 'design', 'destiny', 'destiny 2', 'diet', 'digital', 'discord', 'disney', 'diy', 'dj', 'dlc', 'dog', 'donald trump', 'dope', 'dota 2', 'dragon', 'drama', 'drawing', 'drone', 'duty', 'earth', 'ecig', 'economics', 'economy', 'edm', 'Education', 'eggs', 'electronic', 'eliquid', 'england', 'Entertainment', 'eos', 'epic', 'eth', 'ethereum', 'ethereum news', 'exploration', 'extreme', 'facebook', 'fail', 'fake news', 'fallout 4', 'family', 'family friendly', 'fantasy', 'far cry 5', 'fashion', 'fiction', 'film', 'film & animation', 'final', 'fire', 'fitness', 'flat', 'flat earth', 'floral', 'food', 'food holidays', 'football', 'fortnite', 'fortnite battle royale', 'fox', 'fox news', 'fps', 'fpv', 'france', 'freedom', 'full time rving', 'fullhd', 'fun', 'funny', 'funny moments', 'future', 'future bass', 'game', 'game reviews', 'gameplay', 'gamer', 'gamers', 'games', 'gaming', 'garden', 'germany', 'ghost', 'god', 'gold', 'government', 'grand theft auto', 'grand theft auto v', 'gta', 'gta 5', 'gta v', 'guitar', 'guns', 'gym', 'hack', 'halloween', 'halo', 'hangoutsonair', 'happy', 'health', 'healthy', 'help', 'hilarious', 'hillary clinton', 'hip hop', 'history', 'hoa', 'holiday', 'horror', 'house', 'how', 'how to', 'how to make money', 'how to make money online', 'how - to', 'howto', 'Howto & Style', 'humor', 'ico', 'illuminati', 'indie', 'industry', 'insane', 'instrumental', 'investing', 'ios', 'ipad', 'iphone', 'israel', 'jesus', 'joyetech', 'Juvenile fiction', 'knife', 'latest news', 'league', 'league of legends', 'learning', 'lee', 'lessons', "let's play", 'lets play', 'level', 'liberal', 'libertarian', 'liberty', 'light', 'lightning', 'linux', 'litecoin', 'lol', 'lord', 'love', 'magic', 'maps', 'mario', 'mark dice', 'marvel', 'mass effect', 'massively multiplayer online role - playing game', 'master', 'mature', 'media', 'meme', 'memes', 'metal', 'microsoft', 'military', 'minecraft', 'mining', 'mix', 'mmo', 'mmorpg', 'mobile', 'mod', 'modded', 'mods', 'mojang', 'money', 'motivation', 'movie', 'msnbc', 'multiplayer', 'music', 'music video', 'muslim', 'mw2', 'mw3', 'nasa', 'nature', 'nbc', 'network', 'new music', 'news', 'News & Politics', 'news radio', 'nibiru', 'ninja', 'nintendo', 'nintendo switch', 'Nonprofits & Activism', 'obama', 'online', 'online learning', 'open world', 'opinion', 'outdoor', 'overwatch', 'pacman', 'paladins', 'paranormal', 'parody', 'patreon', 'paypal', 'pc', 'pc game', 'pc gaming', 'peace', 'People & Blogs', 'pets & animals', 'photography', 'planet', 'planet x', 'planets', 'play', "playerunknown's battlegrounds", 'playing', 'plays', 'playstation', 'playstation 4', 'playthrough', 'podcast', 'pokemon', 'political', 'politics', 'pop culture', 'post', 'prank', 'press', 'pro', 'progressive', 'progressive talk', 'ps2', 'ps3', 'ps4', 'ps4live', 'ps4share', 'psychology', 'pubg', 'pubg mobile', 'puzzle', 'pvp', 'quad', 'race', 'racing', 'rainbow', 'ram', 'random', 'rap', 'raw', 'rda', 'react', 'reaction', 'reading', 'reaper', 'religion', 'remix', 'republican', 'resident evil', 'retro', 'reviews', 'ripple', 'roblox', 'rock', 'role-playing game', 'rpg', 'rta', 'rv', 'rv park', 'samsung', 'sandbox', 'satire', 'school', 'sci-fi', 'science', 'science & technology', 'science fiction', 'secret', 'secular', 'secular talk', 'senate', 'sharefactory', 'shooter game', 'shooting', 'Short stories', 'sick', 'silly', 'sims', 'sims 3', 'sims 4', 'simulation', 'singing', 'skyrim', 'smok', 'sniper', 'sniping', 'Social life and customs', 'song', 'sony', 'sony computer entertainment', 'sony interactive entertainment', 'soul', 'sound', 'soundtrack', 'space', 'special', 'sports', 'squad gameplay', 'srpski', 'star', 'star wars', 'steam', 'strategy', 'stream', 'studio', 'style', 'subscribe', 'sun', 'suomi', 'super smash bros', 'supercell', 'survival', 'survival horror', 'switch', 'tactical', 'teaser', 'tech', 'technology', 'the best', 'timelapse', 'top 10', 'tourism', 'track', 'trading', 'trailer', 'training', 'trap', 'travel', 'Travel & Events', 'travel trailer', 'travel vlog', 'trending', 'trump', 'truth', 'tutorial', 'twitch', 'twitter', 'ubisoft', 'ufo', 'unboxing', 'united states', 'universe', 'vacation', 'vape', 'vape review', 'vaper', 'vaping', 'vapor', 'Various', 'vegan', 'Verschillende', 'video blog', 'video game', 'video games', 'videogame', 'viral', 'vlogging', 'voluntaryist', 'walkthrough', 'war', 'warrior', 'water', 'weapons', 'weird', 'wii', 'wii u', 'windows', 'workout', 'world', 'world of warcraft', 'wrestling', 'ww2', 'wwe', 'xbox', 'xbox 360', 'xbox one', 'zombie', 'zombies']; // diff --git a/src/constants/tags.js b/src/constants/tags.js index 09630bb..36cf48e 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -14,11 +14,498 @@ export const DEFAULT_FOLLOWED_TAGS = [ export const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; export const DEFAULT_KNOWN_TAGS = [ + 'activism', + 'adventure', + 'adventures', + 'agnostic', + 'aliens', + 'altcoin', + 'altcoins', + 'amazon', + 'anarchism', + 'anarchist', + 'anarchy', + 'android', + 'animal', + 'animals', + 'animation', + 'anime', + 'apex', + 'apple', + 'ark', + 'ark survival evolved', + 'art', + 'artist', + 'aspire', + 'atheism', + 'atheist', + 'australia', + 'auto', + 'automotive', + 'autos & vehicles', + 'bass', + 'batman', + 'battle royale', + 'beach', + 'beat', + 'beats', 'beliefs', + 'ben shapiro', + 'bible', + 'bitcoin', + 'bitcoin gratis', + 'bitcoin news', + 'bitcoin price', + 'black ops', + 'blockchain', + 'blogger', + 'bo1', + 'bo2', + 'bo3', + 'bo4', + 'bodybuilding', + 'boom', + 'boss', + 'btc', + 'building', + 'business', + 'california', + 'call of duty', + 'camping', + 'canon', + 'car', + 'cars', + 'cbs', + 'chill', + 'chris', + 'christian', + 'christianity', + 'christmas', + 'church', + 'clips', + 'cnn', + 'cod', + 'colorful hair', + 'comedy', + 'comics', + 'commentary', + 'community', + 'computer', + 'conservative', + 'console', + 'conspiracy', + 'cool long hair', + 'cover', + 'crafting', + 'crash', + 'creative hairstyles', + 'crypto', + 'crypto news', + 'cryptocurrency', + 'cryptocurrency news', + 'culture', + 'cute', + 'daily', + 'daily vlog', + 'dance', + 'day', + 'death', + 'democrat', + 'design', + 'destiny', + 'destiny 2', + 'diet', + 'digital', + 'discord', + 'disney', + 'diy', + 'dj', + 'dlc', + 'dog', + 'donald trump', + 'dope', + 'dota 2', + 'dragon', + 'drama', + 'drawing', + 'drone', + 'duty', + 'earth', + 'ecig', + 'economics', + 'economy', + 'edm', + 'Education', + 'eggs', + 'electronic', + 'eliquid', + 'england', + 'Entertainment', + 'eos', + 'epic', + 'eth', + 'ethereum', + 'ethereum news', + 'exploration', + 'extreme', + 'facebook', + 'fail', + 'fake news', + 'fallout 4', + 'family', + 'family friendly', + 'fantasy', + 'far cry 5', + 'fashion', + 'fiction', + 'film', + 'film & animation', + 'final', + 'fire', + 'fitness', + 'flat', + 'flat earth', + 'floral', + 'food', + 'food holidays', + 'football', + 'fortnite', + 'fortnite battle royale', + 'fox', + 'fox news', + 'fps', + 'fpv', + 'france', + 'freedom', + 'full time rving', + 'fullhd', + 'fun', 'funny', + 'funny moments', + 'future', + 'future bass', + 'game', + 'game reviews', + 'gameplay', + 'gamer', + 'gamers', + 'games', 'gaming', - 'pop culture', + 'garden', + 'germany', + 'ghost', + 'god', + 'gold', + 'government', + 'grand theft auto', + 'grand theft auto v', + 'gta', + 'gta 5', + 'gta v', + 'guitar', + 'guns', + 'gym', + 'hack', + 'halloween', + 'halo', + 'hangoutsonair', + 'happy', + 'health', + 'healthy', + 'help', + 'hilarious', + 'hillary clinton', + 'hip hop', + 'history', + 'hoa', + 'holiday', + 'horror', + 'house', + 'how', + 'how to', + 'how to make money', + 'how to make money online', + 'how - to', + 'howto', + 'Howto & Style', + 'humor', + 'ico', + 'illuminati', + 'indie', + 'industry', + 'insane', + 'instrumental', + 'investing', + 'ios', + 'ipad', + 'iphone', + 'israel', + 'jesus', + 'joyetech', + 'Juvenile fiction', + 'knife', + 'latest news', + 'league', + 'league of legends', + 'learning', + 'lee', + 'lessons', + "let's play", + 'lets play', + 'level', + 'liberal', + 'libertarian', + 'liberty', + 'light', + 'lightning', + 'linux', + 'litecoin', + 'lol', + 'lord', + 'love', + 'magic', + 'maps', + 'mario', + 'mark dice', + 'marvel', + 'mass effect', + 'massively multiplayer online role - playing game', + 'master', + 'mature', + 'media', + 'meme', + 'memes', + 'metal', + 'microsoft', + 'military', + 'minecraft', + 'mining', + 'mix', + 'mmo', + 'mmorpg', + 'mobile', + 'mod', + 'modded', + 'mods', + 'mojang', + 'money', + 'motivation', + 'movie', + 'msnbc', + 'multiplayer', 'music', + 'music video', + 'muslim', + 'mw2', + 'mw3', + 'nasa', + 'nature', + 'nbc', + 'network', + 'new music', + 'news', + 'News & Politics', + 'news radio', + 'nibiru', + 'ninja', + 'nintendo', + 'nintendo switch', + 'Nonprofits & Activism', + 'obama', + 'online', + 'online learning', + 'open world', + 'opinion', + 'outdoor', + 'overwatch', + 'pacman', + 'paladins', + 'paranormal', + 'parody', + 'patreon', + 'paypal', + 'pc', + 'pc game', + 'pc gaming', + 'peace', + 'People & Blogs', + 'pets & animals', + 'photography', + 'planet', + 'planet x', + 'planets', + 'play', + "playerunknown's battlegrounds", + 'playing', + 'plays', + 'playstation', + 'playstation 4', + 'playthrough', + 'podcast', + 'pokemon', + 'political', + 'politics', + 'pop culture', + 'post', + 'prank', + 'press', + 'pro', + 'progressive', + 'progressive talk', + 'ps2', + 'ps3', + 'ps4', + 'ps4live', + 'ps4share', + 'psychology', + 'pubg', + 'pubg mobile', + 'puzzle', + 'pvp', + 'quad', + 'race', + 'racing', + 'rainbow', + 'ram', + 'random', + 'rap', + 'raw', + 'rda', + 'react', + 'reaction', + 'reading', + 'reaper', + 'religion', + 'remix', + 'republican', + 'resident evil', + 'retro', + 'reviews', + 'ripple', + 'roblox', + 'rock', + 'role-playing game', + 'rpg', + 'rta', + 'rv', + 'rv park', + 'samsung', + 'sandbox', + 'satire', + 'school', + 'sci-fi', + 'science', + 'science & technology', + 'science fiction', + 'secret', + 'secular', + 'secular talk', + 'senate', + 'sharefactory', + 'shooter game', + 'shooting', + 'Short stories', + 'sick', + 'silly', + 'sims', + 'sims 3', + 'sims 4', + 'simulation', + 'singing', + 'skyrim', + 'smok', + 'sniper', + 'sniping', + 'Social life and customs', + 'song', + 'sony', + 'sony computer entertainment', + 'sony interactive entertainment', + 'soul', + 'sound', + 'soundtrack', + 'space', + 'special', 'sports', + 'squad gameplay', + 'srpski', + 'star', + 'star wars', + 'steam', + 'strategy', + 'stream', + 'studio', + 'style', + 'subscribe', + 'sun', + 'suomi', + 'super smash bros', + 'supercell', + 'survival', + 'survival horror', + 'switch', + 'tactical', + 'teaser', + 'tech', + 'technology', + 'the best', + 'timelapse', + 'top 10', + 'tourism', + 'track', + 'trading', + 'trailer', + 'training', + 'trap', + 'travel', + 'Travel & Events', + 'travel trailer', + 'travel vlog', + 'trending', + 'trump', + 'truth', + 'tutorial', + 'twitch', + 'twitter', + 'ubisoft', + 'ufo', + 'unboxing', + 'united states', + 'universe', + 'vacation', + 'vape', + 'vape review', + 'vaper', + 'vaping', + 'vapor', + 'Various', + 'vegan', + 'Verschillende', + 'video blog', + 'video game', + 'video games', + 'videogame', + 'viral', + 'vlogging', + 'voluntaryist', + 'walkthrough', + 'war', + 'warrior', + 'water', 'weapons', + 'weird', + 'wii', + 'wii u', + 'windows', + 'workout', + 'world', + 'world of warcraft', + 'wrestling', + 'ww2', + 'wwe', + 'xbox', + 'xbox 360', + 'xbox one', + 'zombie', + 'zombies', ]; -- 2.45.2 From 0ff6364a40253387fbe1c4a5b5cd444f616d84e6 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 9 Jul 2019 01:58:31 -0400 Subject: [PATCH 055/371] fix sort for pending publishes --- dist/bundle.es.js | 10 +++++++++- src/redux/selectors/claims.js | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2a53b10..9d26ff4 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1380,7 +1380,15 @@ const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaim const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp)); -const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => myClaims.sort((a, b) => b.timestamp - a.timestamp).map(claim => `lbry://${claim.name}#${claim.claim_id}`)); +const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => myClaims.sort((a, b) => { + if (!a.timestamp) { + return -1; + } else if (!b.timestamp) { + return 1; + } else { + return b.timestamp - a.timestamp; + } +}).map(claim => `lbry://${claim.name}#${claim.claim_id}`)); const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 50777c3..ee59028 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -274,7 +274,15 @@ export const selectMyClaimUrisWithoutChannels = createSelector( selectMyClaimsWithoutChannels, myClaims => myClaims - .sort((a, b) => b.timestamp - a.timestamp) + .sort((a, b) => { + if (!a.timestamp) { + return -1; + } else if (!b.timestamp) { + return 1; + } else { + return b.timestamp - a.timestamp; + } + }) .map(claim => `lbry://${claim.name}#${claim.claim_id}`) ); -- 2.45.2 From 6ba6ba26f3aa5a82bd7d870ac1c94cec63807e41 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 10 Jul 2019 12:48:50 -0400 Subject: [PATCH 056/371] add 'tag' as search suggestion --- dist/bundle.es.js | 8 +++++++- src/constants/search.js | 1 + src/redux/selectors/search.js | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9d26ff4..72eb982 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -629,7 +629,8 @@ var transaction_types = /*#__PURE__*/Object.freeze({ const SEARCH_TYPES = { FILE: 'file', CHANNEL: 'channel', - SEARCH: 'search' + SEARCH: 'search', + TAG: 'tag' }; const SEARCH_OPTIONS = { @@ -1138,6 +1139,11 @@ const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selec }); } + searchSuggestions.push({ + value: query, + type: SEARCH_TYPES.TAG + }); + const apiSuggestions = suggestions[query] || []; if (apiSuggestions.length) { searchSuggestions = searchSuggestions.concat(apiSuggestions.filter(suggestion => suggestion !== query).map(suggestion => { diff --git a/src/constants/search.js b/src/constants/search.js index 80d291f..16b3620 100644 --- a/src/constants/search.js +++ b/src/constants/search.js @@ -2,6 +2,7 @@ export const SEARCH_TYPES = { FILE: 'file', CHANNEL: 'channel', SEARCH: 'search', + TAG: 'tag', }; export const SEARCH_OPTIONS = { diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index e2f1c1a..152a99e 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -96,6 +96,11 @@ export const selectSearchSuggestions: Array = createSelector( }); } + searchSuggestions.push({ + value: query, + type: SEARCH_TYPES.TAG, + }); + const apiSuggestions = suggestions[query] || []; if (apiSuggestions.length) { searchSuggestions = searchSuggestions.concat( -- 2.45.2 From 87fdb8084edca1f966e603280739bde979aa0f65 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 10 Jul 2019 23:13:34 -0400 Subject: [PATCH 057/371] remove 'amount' from doClaimSearch arguments --- dist/bundle.es.js | 6 ++---- src/redux/actions/claims.js | 3 +-- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 72eb982..bb0f029 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2309,7 +2309,7 @@ function doFetchChannelListMine() { }; } -function doClaimSearch(amount = 20, options = {}) { +function doClaimSearch(options = {}) { return dispatch => { dispatch({ type: CLAIM_SEARCH_STARTED @@ -2336,9 +2336,7 @@ function doClaimSearch(amount = 20, options = {}) { }); }; - lbryProxy.claim_search(_extends$3({ - page_size: amount - }, options)).then(success, failure); + lbryProxy.claim_search(_extends$3({}, options)).then(success, failure); }; } diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 51fd397..6145566 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -299,7 +299,7 @@ export function doFetchChannelListMine() { }; } -export function doClaimSearch(amount: number = 20, options: { page?: number } = {}) { +export function doClaimSearch(options: { page_size?: number, page?: number } = {}) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CLAIM_SEARCH_STARTED, @@ -327,7 +327,6 @@ export function doClaimSearch(amount: number = 20, options: { page?: number } = }; Lbry.claim_search({ - page_size: amount, ...options, }).then(success, failure); }; -- 2.45.2 From 15e36688fb762b0b424a837de0f5a405b05463a2 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 11 Jul 2019 14:21:22 -0400 Subject: [PATCH 058/371] fix invalid uri to reject spaces --- 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 bb0f029..bf663d3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -894,7 +894,7 @@ const channelNameMinLength = 1; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls -const regexInvalidURI = exports.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}$/; /** diff --git a/src/lbryURI.js b/src/lbryURI.js index 9b805f7..42045d0 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 = (exports.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}$/; /** -- 2.45.2 From 87e01209f56cb3326c12ffc114072c48f72c1a3e Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 11 Jul 2019 15:00:45 -0400 Subject: [PATCH 059/371] don't crash on bad uris --- dist/bundle.es.js | 46 ++++++++++++++++++++++++++-------- src/redux/selectors/claims.js | 47 +++++++++++++++++++++++++++-------- 2 files changed, 72 insertions(+), 21 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index bf663d3..b0934b0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1277,8 +1277,14 @@ const selectPendingById = reselect.createSelector(selectState$1, state => state. const selectPendingClaims = reselect.createSelector(selectState$1, state => Object.values(state.pendingById || [])); const makeSelectClaimIsPending = uri => reselect.createSelector(selectPendingById, pendingById => { - const { claimId } = parseURI(uri); - return Boolean(pendingById[claimId]); + let claimId; + try { + ({ claimId } = parseURI(uri)); + } catch (e) {} + + if (claimId) { + return Boolean(pendingById[claimId]); + } }); const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, pendingById => { @@ -1289,13 +1295,21 @@ const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => { // Check if a claim is pending first // It won't be in claimsByUri because resolving it will return nothing - const { claimId } = parseURI(uri); - const pendingClaim = pendingById[claimId]; - if (pendingClaim) { - return pendingClaim; - } - return byUri && byUri[normalizeURI(uri)]; + let claimId; + try { + ({ claimId } = parseURI(uri)); + } catch (e) {} + + if (claimId) { + const pendingClaim = pendingById[claimId]; + + if (pendingClaim) { + return pendingClaim; + } + + return byUri && byUri[normalizeURI(uri)]; + } }); const selectMyClaimsRaw = reselect.createSelector(selectState$1, state => state.myClaims); @@ -1305,8 +1319,20 @@ const selectAbandoningIds = reselect.createSelector(selectState$1, state => Obje const selectMyActiveClaims = reselect.createSelector(selectMyClaimsRaw, selectAbandoningIds, (claims, abandoningIds) => new Set(claims && claims.map(claim => claim.claim_id).filter(claimId => Object.keys(abandoningIds).indexOf(claimId) === -1))); const makeSelectClaimIsMine = rawUri => { - const uri = normalizeURI(rawUri); - return reselect.createSelector(selectClaimsByUri, selectMyActiveClaims, (claims, myClaims) => claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id)); + let uri; + try { + uri = normalizeURI(rawUri); + } catch (e) {} + + return reselect.createSelector(selectClaimsByUri, selectMyActiveClaims, (claims, myClaims) => { + try { + parseURI(uri); + } catch (e) { + return false; + } + + claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); + }); }; const selectAllFetchingChannelClaims = reselect.createSelector(selectState$1, state => state.fetchingChannelClaims || {}); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index ee59028..9212755 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -60,8 +60,14 @@ export const makeSelectClaimIsPending = (uri: string) => createSelector( selectPendingById, pendingById => { - const { claimId } = parseURI(uri); - return Boolean(pendingById[claimId]); + let claimId; + try { + ({ claimId } = parseURI(uri)); + } catch (e) {} + + if (claimId) { + return Boolean(pendingById[claimId]); + } } ); @@ -81,13 +87,21 @@ export const makeSelectClaimForUri = (uri: string) => (byUri, pendingById) => { // Check if a claim is pending first // It won't be in claimsByUri because resolving it will return nothing - const { claimId } = parseURI(uri); - const pendingClaim = pendingById[claimId]; - if (pendingClaim) { - return pendingClaim; - } - return byUri && byUri[normalizeURI(uri)]; + let claimId; + try { + ({ claimId } = parseURI(uri)); + } catch (e) {} + + if (claimId) { + const pendingClaim = pendingById[claimId]; + + if (pendingClaim) { + return pendingClaim; + } + + return byUri && byUri[normalizeURI(uri)]; + } } ); @@ -114,12 +128,23 @@ export const selectMyActiveClaims = createSelector( ); export const makeSelectClaimIsMine = (rawUri: string) => { - const uri = normalizeURI(rawUri); + let uri; + try { + uri = normalizeURI(rawUri); + } catch (e) {} + return createSelector( selectClaimsByUri, selectMyActiveClaims, - (claims, myClaims) => - claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id) + (claims, myClaims) => { + try { + parseURI(uri); + } catch (e) { + return false; + } + + claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); + } ); }; -- 2.45.2 From eb3a7afc46ef69678149ad5caff3829473d75b43 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 11 Jul 2019 16:33:22 -0400 Subject: [PATCH 060/371] fix typo --- 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 b0934b0..5c81678 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1331,7 +1331,7 @@ const makeSelectClaimIsMine = rawUri => { return false; } - claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); + return claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); }); }; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 9212755..9b3d841 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -143,7 +143,7 @@ export const makeSelectClaimIsMine = (rawUri: string) => { return false; } - claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); + return claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); } ); }; -- 2.45.2 From b59fdfa1d8191b0930ec97b2c70e2918e790c843 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 15 Jul 2019 03:44:02 +0100 Subject: [PATCH 061/371] support multiple simultaneous claim_search requests --- dist/bundle.es.js | 89 +++++++++++++++++++++++++++++++++++ src/constants/action_types.js | 3 ++ src/index.js | 5 ++ src/redux/actions/claims.js | 38 +++++++++++++++ src/redux/reducers/claims.js | 35 ++++++++++++++ src/redux/selectors/claims.js | 22 +++++++++ 6 files changed, 192 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9d26ff4..eefdaaa 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -117,6 +117,9 @@ const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL'; const CLAIM_SEARCH_STARTED = 'CLAIM_SEARCH_STARTED'; const CLAIM_SEARCH_COMPLETED = 'CLAIM_SEARCH_COMPLETED'; const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; +const CLAIM_SEARCH_BY_TAGS_STARTED = 'CLAIM_SEARCH_BY_TAGS_STARTED'; +const CLAIM_SEARCH_BY_TAGS_COMPLETED = 'CLAIM_SEARCH_BY_TAGS_COMPLETED'; +const CLAIM_SEARCH_BY_TAGS_FAILED = 'CLAIM_SEARCH_BY_TAGS_FAILED'; // Comments const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; @@ -345,6 +348,9 @@ var action_types = /*#__PURE__*/Object.freeze({ CLAIM_SEARCH_STARTED: CLAIM_SEARCH_STARTED, CLAIM_SEARCH_COMPLETED: CLAIM_SEARCH_COMPLETED, CLAIM_SEARCH_FAILED: CLAIM_SEARCH_FAILED, + CLAIM_SEARCH_BY_TAGS_STARTED: CLAIM_SEARCH_BY_TAGS_STARTED, + CLAIM_SEARCH_BY_TAGS_COMPLETED: CLAIM_SEARCH_BY_TAGS_COMPLETED, + CLAIM_SEARCH_BY_TAGS_FAILED: CLAIM_SEARCH_BY_TAGS_FAILED, COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, @@ -1511,6 +1517,14 @@ const selectLastClaimSearchUris = reselect.createSelector(selectState$1, state = const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); +const selectFetchingClaimSearchByTags = reselect.createSelector(selectState$1, state => state.fetchingClaimSearchByTags); + +const selectClaimSearchUrisByTags = reselect.createSelector(selectState$1, state => state.claimSearchUrisByTags); + +const makeSelectFetchingClaimSearchForTags = tags => reselect.createSelector(selectFetchingClaimSearchByTags, byTags => byTags[tags]); + +const makeSelectClaimSearchUrisForTags = tags => reselect.createSelector(selectClaimSearchUrisByTags, byTags => byTags[tags]); + const selectState$2 = state => state.wallet || {}; const selectWalletState = selectState$2; @@ -2336,6 +2350,43 @@ function doClaimSearch(amount = 20, options = {}) { }; } +// tags can be one or many (comma separated) +function doClaimSearchByTags(tags, amount = 10, options = {}) { + return dispatch => { + const tagList = tags.join(','); + 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 + }, options)).then(success, failure); + }; +} + const selectState$3 = state => state.fileInfo || {}; const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); @@ -3332,6 +3383,8 @@ const defaultState = { abandoningById: {}, pendingById: {}, fetchingClaimSearch: false, + claimSearchUrisByTags: [], + fetchingClaimSearchByTags: [], lastClaimSearchUris: [] }; @@ -3587,6 +3640,37 @@ reducers[CLAIM_SEARCH_FAILED] = state => { }); }; +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 { tags, uris } = action.data; + + // TODO: append? + claimSearchUrisByTags[tags] = uris; + fetchingClaimSearchByTags[tags] = false; // or delete the key instead? + + return Object.assign({}, state, { + claimSearchUrisByTags, + fetchingClaimSearchByTags + }); +}; +reducers[CLAIM_SEARCH_BY_TAGS_FAILED] = (state, action) => { + const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); + fetchingClaimSearchByTags[action.data.tags] = false; + + return Object.assign({}, state, { + fetchingClaimSearchByTags + }); +}; + function claimsReducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); @@ -4664,6 +4748,7 @@ exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doClaimSearch = doClaimSearch; +exports.doClaimSearchByTags = doClaimSearchByTags; exports.doClearPublish = doClearPublish; exports.doCommentCreate = doCommentCreate; exports.doCommentList = doCommentList; @@ -4725,6 +4810,7 @@ exports.makeSelectClaimForUri = makeSelectClaimForUri; exports.makeSelectClaimIsMine = makeSelectClaimIsMine; exports.makeSelectClaimIsNsfw = makeSelectClaimIsNsfw; exports.makeSelectClaimIsPending = makeSelectClaimIsPending; +exports.makeSelectClaimSearchUrisForTags = makeSelectClaimSearchUrisForTags; exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannelForCurrentPageState; exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; exports.makeSelectCommentsForUri = makeSelectCommentsForUri; @@ -4734,6 +4820,7 @@ exports.makeSelectCoverForUri = makeSelectCoverForUri; exports.makeSelectDateForUri = makeSelectDateForUri; exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; +exports.makeSelectFetchingClaimSearchForTags = makeSelectFetchingClaimSearchForTags; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileForUri; exports.makeSelectIsUriResolving = makeSelectIsUriResolving; @@ -4769,6 +4856,7 @@ exports.selectAllMyClaimsByOutpoint = selectAllMyClaimsByOutpoint; exports.selectBalance = selectBalance; exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; +exports.selectClaimSearchUrisByTags = selectClaimSearchUrisByTags; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; exports.selectCurrentChannelPage = selectCurrentChannelPage; @@ -4782,6 +4870,7 @@ exports.selectDraftTransactionError = selectDraftTransactionError; exports.selectError = selectError; exports.selectFailedPurchaseUris = selectFailedPurchaseUris; exports.selectFetchingClaimSearch = selectFetchingClaimSearch; +exports.selectFetchingClaimSearchByTags = selectFetchingClaimSearchByTags; exports.selectFetchingMyChannels = selectFetchingMyChannels; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index bdbad5d..d4e3a3e 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -94,6 +94,9 @@ export const CLEAR_CONTENT_HISTORY_ALL = 'CLEAR_CONTENT_HISTORY_ALL'; export const CLAIM_SEARCH_STARTED = 'CLAIM_SEARCH_STARTED'; export const CLAIM_SEARCH_COMPLETED = 'CLAIM_SEARCH_COMPLETED'; export const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; +export const CLAIM_SEARCH_BY_TAGS_STARTED = 'CLAIM_SEARCH_BY_TAGS_STARTED'; +export const CLAIM_SEARCH_BY_TAGS_COMPLETED = 'CLAIM_SEARCH_BY_TAGS_COMPLETED'; +export const CLAIM_SEARCH_BY_TAGS_FAILED = 'CLAIM_SEARCH_BY_TAGS_FAILED'; // Comments export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; diff --git a/src/index.js b/src/index.js index 3c7c82f..5cbdb71 100644 --- a/src/index.js +++ b/src/index.js @@ -55,6 +55,7 @@ export { doCreateChannel, doUpdateChannel, doClaimSearch, + doClaimSearchByTags, } from 'redux/actions/claims'; export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -193,6 +194,10 @@ export { selectCurrentChannelPage, selectFetchingClaimSearch, selectLastClaimSearchUris, + selectFetchingClaimSearchByTags, + selectClaimSearchUrisByTags, + makeSelectFetchingClaimSearchForTags, + makeSelectClaimSearchUrisForTags, } 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 51fd397..b52faed 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -332,3 +332,41 @@ export function doClaimSearch(amount: number = 20, options: { page?: number } = }).then(success, failure); }; } + +// tags can be one or many (comma separated) +export function doClaimSearchByTags(tags: Array, amount: number = 10, options: { page?: number } = {}) { + return (dispatch: Dispatch) => { + const tagList = tags.join(','); + 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, + ...options, + }).then(success, failure); + }; +} diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 99a8f7f..e6e7794 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -22,6 +22,8 @@ type State = { fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, lastClaimSearchUris: Array, + fetchingClaimSearchByTags: { [string]: boolean }, + claimSearchUrisByTags: { [string]: { all: Array } }, claimsByChannel: { [string]: { all: Array, @@ -45,6 +47,8 @@ const defaultState = { abandoningById: {}, pendingById: {}, fetchingClaimSearch: false, + claimSearchUrisByTags: [], + fetchingClaimSearchByTags: [], lastClaimSearchUris: [], }; @@ -312,6 +316,37 @@ reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State): State => { }); }; +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 { tags, uris } = action.data; + + // TODO: append? + claimSearchUrisByTags[tags] = uris; + fetchingClaimSearchByTags[tags] = false; // or delete the key instead? + + return Object.assign({}, state, { + claimSearchUrisByTags, + fetchingClaimSearchByTags, + }); +}; +reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_FAILED] = (state: State, action: any): State => { + const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); + fetchingClaimSearchByTags[action.data.tags] = false; + + return Object.assign({}, state, { + fetchingClaimSearchByTags, + }); +}; + export function claimsReducer(state: State = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index ee59028..a451615 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -484,3 +484,25 @@ export const makeSelectShortUrlForUri = (uri: string) => 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: string) => + createSelector( + selectFetchingClaimSearchByTags, + byTags => byTags[tags] + ); + +export const makeSelectClaimSearchUrisForTags = (tags: string) => + createSelector( + selectClaimSearchUrisByTags, + byTags => byTags[tags] + ); -- 2.45.2 From dddb10687c4f93e73d15ce7978f3e9ff719b0941 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 15 Jul 2019 04:22:52 +0100 Subject: [PATCH 062/371] add any_tags parameter to claim_search --- dist/bundle.es.js | 3 ++- src/redux/actions/claims.js | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index eefdaaa..6604bcb 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2382,7 +2382,8 @@ function doClaimSearchByTags(tags, amount = 10, options = {}) { }; lbryProxy.claim_search(_extends$3({ - page_size: amount + page_size: amount, + any_tags: tags }, options)).then(success, failure); }; } diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index b52faed..b563dde 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -366,6 +366,7 @@ export function doClaimSearchByTags(tags: Array, amount: number = 10, op Lbry.claim_search({ page_size: amount, + any_tags: tags, ...options, }).then(success, failure); }; -- 2.45.2 From b2044499c5f43e519384433538c1225d56d3a1f2 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 16 Jul 2019 10:15:51 +0100 Subject: [PATCH 063/371] implement append for multi claim_search calls --- dist/bundle.es.js | 13 +++++++++---- src/redux/reducers/claims.js | 13 +++++++++---- 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 6604bcb..793c5de 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3652,14 +3652,19 @@ reducers[CLAIM_SEARCH_BY_TAGS_STARTED] = (state, action) => { reducers[CLAIM_SEARCH_BY_TAGS_COMPLETED] = (state, action) => { const fetchingClaimSearchByTags = Object.assign({}, state.fetchingClaimSearchByTags); const claimSearchUrisByTags = Object.assign({}, state.claimSearchUrisByTags); - const { tags, uris } = action.data; + const { append, tags, uris } = action.data; - // TODO: append? - claimSearchUrisByTags[tags] = uris; + let newClaimSearchUrisByTags = []; + if (action.data.append) { + // todo: check for duplicate uris when concatenating? + newClaimSearchUrisByTags = claimSearchUrisByTags.concat(uris); + } else { + newClaimSearchUrisByTags = uris; + } fetchingClaimSearchByTags[tags] = false; // or delete the key instead? return Object.assign({}, state, { - claimSearchUrisByTags, + claimSearchUrisByTags: newClaimSearchUrisByTags, fetchingClaimSearchByTags }); }; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index e6e7794..538e028 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -327,14 +327,19 @@ reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_STARTED] = (state: State, action: any): St 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 { tags, uris } = action.data; + const { append, tags, uris } = action.data; - // TODO: append? - claimSearchUrisByTags[tags] = uris; + let newClaimSearchUrisByTags = []; + if (action.data.append) { + // todo: check for duplicate uris when concatenating? + newClaimSearchUrisByTags = claimSearchUrisByTags.concat(uris); + } else { + newClaimSearchUrisByTags = uris; + } fetchingClaimSearchByTags[tags] = false; // or delete the key instead? return Object.assign({}, state, { - claimSearchUrisByTags, + claimSearchUrisByTags: newClaimSearchUrisByTags, fetchingClaimSearchByTags, }); }; -- 2.45.2 From d76b170c82b230c00e101d1559d84f63b9c180f7 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 17 Jul 2019 16:46:22 -0400 Subject: [PATCH 064/371] adds authorUri to comment type --- dist/flow-typed/Comment.js | 3 ++- flow-typed/Comment.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/dist/flow-typed/Comment.js b/dist/flow-typed/Comment.js index 808dda8..f2f35b7 100644 --- a/dist/flow-typed/Comment.js +++ b/dist/flow-typed/Comment.js @@ -1,5 +1,6 @@ declare type Comment = { - author: string, + author?: string, + author_url?: string, claim_index?: number, comment_id?: number, downvotes?: number, diff --git a/flow-typed/Comment.js b/flow-typed/Comment.js index 808dda8..f2f35b7 100644 --- a/flow-typed/Comment.js +++ b/flow-typed/Comment.js @@ -1,5 +1,6 @@ declare type Comment = { - author: string, + author?: string, + author_url?: string, claim_index?: number, comment_id?: number, downvotes?: number, -- 2.45.2 From d4e66b7613075c47692e8f663cc38a0666ff1b9f Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Thu, 18 Jul 2019 14:25:40 +0100 Subject: [PATCH 065/371] fix append --- dist/bundle.es.js | 7 +++---- src/redux/reducers/claims.js | 8 ++++---- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 793c5de..b971f6b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3654,17 +3654,16 @@ reducers[CLAIM_SEARCH_BY_TAGS_COMPLETED] = (state, action) => { const claimSearchUrisByTags = Object.assign({}, state.claimSearchUrisByTags); const { append, tags, uris } = action.data; - let newClaimSearchUrisByTags = []; if (action.data.append) { // todo: check for duplicate uris when concatenating? - newClaimSearchUrisByTags = claimSearchUrisByTags.concat(uris); + claimSearchUrisByTags[tags] = claimSearchUrisByTags[tags] && claimSearchUrisByTags[tags].length ? claimSearchUrisByTags[tags].concat(uris) : uris; } else { - newClaimSearchUrisByTags = uris; + claimSearchUrisByTags[tags] = uris; } fetchingClaimSearchByTags[tags] = false; // or delete the key instead? return Object.assign({}, state, { - claimSearchUrisByTags: newClaimSearchUrisByTags, + claimSearchUrisByTags, fetchingClaimSearchByTags }); }; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 538e028..5d1a147 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -329,17 +329,17 @@ reducers[ACTIONS.CLAIM_SEARCH_BY_TAGS_COMPLETED] = (state: State, action: any): const claimSearchUrisByTags = Object.assign({}, state.claimSearchUrisByTags); const { append, tags, uris } = action.data; - let newClaimSearchUrisByTags = []; if (action.data.append) { // todo: check for duplicate uris when concatenating? - newClaimSearchUrisByTags = claimSearchUrisByTags.concat(uris); + claimSearchUrisByTags[tags] = claimSearchUrisByTags[tags] && claimSearchUrisByTags[tags].length ? + claimSearchUrisByTags[tags].concat(uris) : uris; } else { - newClaimSearchUrisByTags = uris; + claimSearchUrisByTags[tags] = uris; } fetchingClaimSearchByTags[tags] = false; // or delete the key instead? return Object.assign({}, state, { - claimSearchUrisByTags: newClaimSearchUrisByTags, + claimSearchUrisByTags, fetchingClaimSearchByTags, }); }; -- 2.45.2 From b07dfa172a526aa5e09af57bb6cf33790c8d0c91 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 18 Jul 2019 10:27:35 -0400 Subject: [PATCH 066/371] add tags to doUpdateChannel --- dist/bundle.es.js | 9 ++++++++- src/redux/actions/claims.js | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 5c81678..93d521e 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2300,9 +2300,16 @@ function doUpdateChannel(params) { description: params.description, website_url: params.website, email: params.email, - replace: true + replace: true, + tags: [] }; + if (params.tags) { + updateParams.tags = params.tags.map(tag => tag.name); + } + + // TODO add languages and locations as above + return lbryProxy.channel_update(updateParams).then(result => { const channelClaim = result.outputs[0]; dispatch({ diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 6145566..a97dea0 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -263,8 +263,15 @@ export function doUpdateChannel(params: any) { website_url: params.website, email: params.email, replace: true, + tags: [], }; + if (params.tags) { + updateParams.tags = params.tags.map(tag => tag.name); + } + + // TODO add languages and locations as above + return Lbry.channel_update(updateParams) .then((result: ChannelUpdateResponse) => { const channelClaim = result.outputs[0]; -- 2.45.2 From ee93a47f893052d6a94b6439eb09eb3fb976f90c Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Fri, 19 Jul 2019 15:20:24 -0400 Subject: [PATCH 067/371] feat: supports vs tips Adds additional boolean to tell if something is a support or not. Also, fixes snackbar. Removes uri which is not used. --- dist/bundle.es.js | 24 ++++++++++++++++++------ src/redux/actions/claims.js | 17 ++++++++++++----- src/redux/actions/wallet.js | 10 +++++++--- 3 files changed, 37 insertions(+), 14 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 5c81678..bbea132 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1901,10 +1901,13 @@ function doSetDraftTransactionAddress(address) { }; } -function doSendTip(amount, claimId, uri, successCallback, errorCallback) { +function doSendTip(amount, claimId, successCallback, errorCallback) { return (dispatch, getState) => { const state = getState(); const balance = selectBalance(state); + const myClaims = selectMyClaimsRaw(state); + + const isSupport = myClaims.find(claim => claim.claim_id === claimId); if (balance - amount <= 0) { dispatch(doToast({ @@ -1916,7 +1919,7 @@ function doSendTip(amount, claimId, uri, successCallback, errorCallback) { const success = () => { dispatch(doToast({ - message: __(`You sent ${amount} LBC as a tip, Mahalo!`), + message: isSupport ? __(`You sent ${amount} LBC as a support!`) : __(`You sent ${amount} LBC as a tip, Mahalo!`), linkText: __('History'), linkTarget: __('/wallet') })); @@ -1955,7 +1958,7 @@ function doSendTip(amount, claimId, uri, successCallback, errorCallback) { lbryProxy.support_create({ claim_id: claimId, amount: creditsToString(amount), - tip: true + tip: isSupport ? false : true }).then(success, error); }; } @@ -2188,7 +2191,7 @@ function doAbandonClaim(txid, nout) { const errorCallback = () => { dispatch(doToast({ - message: isClaim ? 'Error abandoning your claim' : 'Error unlocking your tip', + message: isClaim ? 'Error abandoning your claim/support' : 'Error unlocking your tip', isError: true })); }; @@ -2199,13 +2202,22 @@ function doAbandonClaim(txid, nout) { data }); + let abandonMessage; + if (isClaim) { + abandonMessage = 'Successfully abandoned your claim.'; + } else if (supportToAbandon) { + abandonMessage = 'Successfully abandoned your support.'; + } else { + abandonMessage = 'Successfully unlocked your tip!'; + } + dispatch(doToast({ - message: isClaim ? 'Successfully abandoned your claim' : 'Successfully unlocked your tip!' + message: abandonMessage })); // After abandoning, call claim_list to show the claim as abandoned // Also fetch transactions to show the new abandon transaction - dispatch(doFetchClaimListMine()); + if (isClaim) dispatch(doFetchClaimListMine()); dispatch(doFetchTransactions()); }; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 6145566..b6f224f 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -142,7 +142,7 @@ export function doAbandonClaim(txid: string, nout: number) { const errorCallback = () => { dispatch( doToast({ - message: isClaim ? 'Error abandoning your claim' : 'Error unlocking your tip', + message: isClaim ? 'Error abandoning your claim/support' : 'Error unlocking your tip', isError: true, }) ); @@ -154,17 +154,24 @@ export function doAbandonClaim(txid: string, nout: number) { data, }); + let abandonMessage; + if (isClaim) { + abandonMessage = 'Successfully abandoned your claim.'; + } else if (supportToAbandon) { + abandonMessage = 'Successfully abandoned your support.'; + } else { + abandonMessage = 'Successfully unlocked your tip!'; + } + dispatch( doToast({ - message: isClaim - ? 'Successfully abandoned your claim' - : 'Successfully unlocked your tip!', + message: abandonMessage, }) ); // After abandoning, call claim_list to show the claim as abandoned // Also fetch transactions to show the new abandon transaction - dispatch(doFetchClaimListMine()); + if (isClaim) dispatch(doFetchClaimListMine()); dispatch(doFetchTransactions()); }; diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 74c9126..7f0f0b5 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -3,6 +3,7 @@ import Lbry from 'lbry'; import { doToast } from 'redux/actions/notifications'; import { selectBalance } from 'redux/selectors/wallet'; import { creditsToString } from 'util/formatCredits'; +import { selectMyClaimsRaw } from 'redux/selectors/claims'; export function doUpdateBalance() { return (dispatch, getState) => { @@ -208,10 +209,13 @@ export function doSetDraftTransactionAddress(address) { }; } -export function doSendTip(amount, claimId, uri, successCallback, errorCallback) { +export function doSendTip(amount, claimId, successCallback, errorCallback) { return (dispatch, getState) => { const state = getState(); const balance = selectBalance(state); + const myClaims: Array = selectMyClaimsRaw(state); + + const isSupport = myClaims.find(claim => claim.claim_id === claimId); if (balance - amount <= 0) { dispatch( @@ -226,7 +230,7 @@ export function doSendTip(amount, claimId, uri, successCallback, errorCallback) const success = () => { dispatch( doToast({ - message: __(`You sent ${amount} LBC as a tip, Mahalo!`), + message: isSupport ? __(`You sent ${amount} LBC as a support!`) : __(`You sent ${amount} LBC as a tip, Mahalo!`), linkText: __('History'), linkTarget: __('/wallet'), }) @@ -268,7 +272,7 @@ export function doSendTip(amount, claimId, uri, successCallback, errorCallback) Lbry.support_create({ claim_id: claimId, amount: creditsToString(amount), - tip: true, + tip: isSupport ? false : true, }).then(success, error); }; } -- 2.45.2 From 6e8c643f45ba5324f0c634a065c01dfe5d3d1b57 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 23 Jul 2019 12:57:49 -0400 Subject: [PATCH 068/371] fix: wording --- dist/bundle.es.js | 2 +- src/redux/actions/wallet.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index bbea132..7171d8b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1919,7 +1919,7 @@ function doSendTip(amount, claimId, successCallback, errorCallback) { const success = () => { dispatch(doToast({ - message: isSupport ? __(`You sent ${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/actions/wallet.js b/src/redux/actions/wallet.js index 7f0f0b5..6e5dce6 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -230,7 +230,7 @@ export function doSendTip(amount, claimId, successCallback, errorCallback) { const success = () => { dispatch( doToast({ - message: isSupport ? __(`You sent ${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'), }) -- 2.45.2 From 8b5b9bca1eec058ddbe28029f127917414902d65 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 23 Jul 2019 15:39:45 -0400 Subject: [PATCH 069/371] update default tags --- dist/bundle.es.js | 4 +- src/constants/tags.js | 993 +++++++++++++++++++++--------------------- tags.js | 1 + 3 files changed, 501 insertions(+), 497 deletions(-) create mode 100644 tags.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 539d032..6d7e134 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -646,11 +646,11 @@ const SEARCH_OPTIONS = { MEDIA_APPLICATION: 'application' }; -const DEFAULT_FOLLOWED_TAGS = ['blockchain', 'news', 'learning', 'technology', 'automotive', 'economics', 'food', 'science', 'art', 'nature']; +const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'economics', 'education', 'gaming', 'music', 'news', 'science', 'sports', 'technology']; const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['activism', 'adventure', 'adventures', 'agnostic', 'aliens', 'altcoin', 'altcoins', 'amazon', 'anarchism', 'anarchist', 'anarchy', 'android', 'animal', 'animals', 'animation', 'anime', 'apex', 'apple', 'ark', 'ark survival evolved', 'art', 'artist', 'aspire', 'atheism', 'atheist', 'australia', 'auto', 'automotive', 'autos & vehicles', 'bass', 'batman', 'battle royale', 'beach', 'beat', 'beats', 'beliefs', 'ben shapiro', 'bible', 'bitcoin', 'bitcoin gratis', 'bitcoin news', 'bitcoin price', 'black ops', 'blockchain', 'blogger', 'bo1', 'bo2', 'bo3', 'bo4', 'bodybuilding', 'boom', 'boss', 'btc', 'building', 'business', 'california', 'call of duty', 'camping', 'canon', 'car', 'cars', 'cbs', 'chill', 'chris', 'christian', 'christianity', 'christmas', 'church', 'clips', 'cnn', 'cod', 'colorful hair', 'comedy', 'comics', 'commentary', 'community', 'computer', 'conservative', 'console', 'conspiracy', 'cool long hair', 'cover', 'crafting', 'crash', 'creative hairstyles', 'crypto', 'crypto news', 'cryptocurrency', 'cryptocurrency news', 'culture', 'cute', 'daily', 'daily vlog', 'dance', 'day', 'death', 'democrat', 'design', 'destiny', 'destiny 2', 'diet', 'digital', 'discord', 'disney', 'diy', 'dj', 'dlc', 'dog', 'donald trump', 'dope', 'dota 2', 'dragon', 'drama', 'drawing', 'drone', 'duty', 'earth', 'ecig', 'economics', 'economy', 'edm', 'Education', 'eggs', 'electronic', 'eliquid', 'england', 'Entertainment', 'eos', 'epic', 'eth', 'ethereum', 'ethereum news', 'exploration', 'extreme', 'facebook', 'fail', 'fake news', 'fallout 4', 'family', 'family friendly', 'fantasy', 'far cry 5', 'fashion', 'fiction', 'film', 'film & animation', 'final', 'fire', 'fitness', 'flat', 'flat earth', 'floral', 'food', 'food holidays', 'football', 'fortnite', 'fortnite battle royale', 'fox', 'fox news', 'fps', 'fpv', 'france', 'freedom', 'full time rving', 'fullhd', 'fun', 'funny', 'funny moments', 'future', 'future bass', 'game', 'game reviews', 'gameplay', 'gamer', 'gamers', 'games', 'gaming', 'garden', 'germany', 'ghost', 'god', 'gold', 'government', 'grand theft auto', 'grand theft auto v', 'gta', 'gta 5', 'gta v', 'guitar', 'guns', 'gym', 'hack', 'halloween', 'halo', 'hangoutsonair', 'happy', 'health', 'healthy', 'help', 'hilarious', 'hillary clinton', 'hip hop', 'history', 'hoa', 'holiday', 'horror', 'house', 'how', 'how to', 'how to make money', 'how to make money online', 'how - to', 'howto', 'Howto & Style', 'humor', 'ico', 'illuminati', 'indie', 'industry', 'insane', 'instrumental', 'investing', 'ios', 'ipad', 'iphone', 'israel', 'jesus', 'joyetech', 'Juvenile fiction', 'knife', 'latest news', 'league', 'league of legends', 'learning', 'lee', 'lessons', "let's play", 'lets play', 'level', 'liberal', 'libertarian', 'liberty', 'light', 'lightning', 'linux', 'litecoin', 'lol', 'lord', 'love', 'magic', 'maps', 'mario', 'mark dice', 'marvel', 'mass effect', 'massively multiplayer online role - playing game', 'master', 'mature', 'media', 'meme', 'memes', 'metal', 'microsoft', 'military', 'minecraft', 'mining', 'mix', 'mmo', 'mmorpg', 'mobile', 'mod', 'modded', 'mods', 'mojang', 'money', 'motivation', 'movie', 'msnbc', 'multiplayer', 'music', 'music video', 'muslim', 'mw2', 'mw3', 'nasa', 'nature', 'nbc', 'network', 'new music', 'news', 'News & Politics', 'news radio', 'nibiru', 'ninja', 'nintendo', 'nintendo switch', 'Nonprofits & Activism', 'obama', 'online', 'online learning', 'open world', 'opinion', 'outdoor', 'overwatch', 'pacman', 'paladins', 'paranormal', 'parody', 'patreon', 'paypal', 'pc', 'pc game', 'pc gaming', 'peace', 'People & Blogs', 'pets & animals', 'photography', 'planet', 'planet x', 'planets', 'play', "playerunknown's battlegrounds", 'playing', 'plays', 'playstation', 'playstation 4', 'playthrough', 'podcast', 'pokemon', 'political', 'politics', 'pop culture', 'post', 'prank', 'press', 'pro', 'progressive', 'progressive talk', 'ps2', 'ps3', 'ps4', 'ps4live', 'ps4share', 'psychology', 'pubg', 'pubg mobile', 'puzzle', 'pvp', 'quad', 'race', 'racing', 'rainbow', 'ram', 'random', 'rap', 'raw', 'rda', 'react', 'reaction', 'reading', 'reaper', 'religion', 'remix', 'republican', 'resident evil', 'retro', 'reviews', 'ripple', 'roblox', 'rock', 'role-playing game', 'rpg', 'rta', 'rv', 'rv park', 'samsung', 'sandbox', 'satire', 'school', 'sci-fi', 'science', 'science & technology', 'science fiction', 'secret', 'secular', 'secular talk', 'senate', 'sharefactory', 'shooter game', 'shooting', 'Short stories', 'sick', 'silly', 'sims', 'sims 3', 'sims 4', 'simulation', 'singing', 'skyrim', 'smok', 'sniper', 'sniping', 'Social life and customs', 'song', 'sony', 'sony computer entertainment', 'sony interactive entertainment', 'soul', 'sound', 'soundtrack', 'space', 'special', 'sports', 'squad gameplay', 'srpski', 'star', 'star wars', 'steam', 'strategy', 'stream', 'studio', 'style', 'subscribe', 'sun', 'suomi', 'super smash bros', 'supercell', 'survival', 'survival horror', 'switch', 'tactical', 'teaser', 'tech', 'technology', 'the best', 'timelapse', 'top 10', 'tourism', 'track', 'trading', 'trailer', 'training', 'trap', 'travel', 'Travel & Events', 'travel trailer', 'travel vlog', 'trending', 'trump', 'truth', 'tutorial', 'twitch', 'twitter', 'ubisoft', 'ufo', 'unboxing', 'united states', 'universe', 'vacation', 'vape', 'vape review', 'vaper', 'vaping', 'vapor', 'Various', 'vegan', 'Verschillende', 'video blog', 'video game', 'video games', 'videogame', 'viral', 'vlogging', 'voluntaryist', 'walkthrough', 'war', 'warrior', 'water', 'weapons', 'weird', 'wii', 'wii u', 'windows', 'workout', 'world', 'world of warcraft', 'wrestling', 'ww2', 'wwe', 'xbox', 'xbox 360', 'xbox one', 'zombie', 'zombies']; +const DEFAULT_KNOWN_TAGS = ['gaming', 'pop culture', 'Entertainment', 'technology', 'music', 'funny', 'Education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'sony interactive entertainment', 'film & animation', 'game', 'weapons', "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', 'ps4live', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'ps4share', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'xbox', 'autos & vehicles', 'Travel & Events', 'food', 'science', 'xbox one', 'liberal', 'democrat', 'progressive', 'survival', 'Nonprofits & Activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', "let's", 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox 360', 'animation', 'unboxing', 'money', 'how', 'travel', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'sony computer entertainment', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets & animals', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'grand theft auto v', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'gta 5', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'crypto news', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'fortnite battle royale', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'xbox360', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'Juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 100, 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'action role-playing game', 'playthrough part', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing video game', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'Humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser']; // diff --git a/src/constants/tags.js b/src/constants/tags.js index 36cf48e..807a048 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -1,511 +1,514 @@ export const DEFAULT_FOLLOWED_TAGS = [ - 'blockchain', - 'news', - 'learning', - 'technology', - 'automotive', - 'economics', - 'food', - 'science', 'art', - 'nature', + 'automotive', + 'blockchain', + 'comedy', + 'economics', + 'education', + 'gaming', + 'music', + 'news', + 'science', + 'sports', + 'technology', ]; export const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; export const DEFAULT_KNOWN_TAGS = [ - 'activism', - 'adventure', - 'adventures', - 'agnostic', - 'aliens', - 'altcoin', - 'altcoins', - 'amazon', - 'anarchism', - 'anarchist', - 'anarchy', - 'android', - 'animal', - 'animals', - 'animation', - 'anime', - 'apex', - 'apple', - 'ark', - 'ark survival evolved', - 'art', - 'artist', - 'aspire', - 'atheism', - 'atheist', - 'australia', - 'auto', - 'automotive', - 'autos & vehicles', - 'bass', - 'batman', - 'battle royale', - 'beach', - 'beat', - 'beats', - 'beliefs', - 'ben shapiro', - 'bible', - 'bitcoin', - 'bitcoin gratis', - 'bitcoin news', - 'bitcoin price', - 'black ops', - 'blockchain', - 'blogger', - 'bo1', - 'bo2', - 'bo3', - 'bo4', - 'bodybuilding', - 'boom', - 'boss', - 'btc', - 'building', - 'business', - 'california', - 'call of duty', - 'camping', - 'canon', - 'car', - 'cars', - 'cbs', - 'chill', - 'chris', - 'christian', - 'christianity', - 'christmas', - 'church', - 'clips', - 'cnn', - 'cod', - 'colorful hair', - 'comedy', - 'comics', - 'commentary', - 'community', - 'computer', - 'conservative', - 'console', - 'conspiracy', - 'cool long hair', - 'cover', - 'crafting', - 'crash', - 'creative hairstyles', - 'crypto', - 'crypto news', - 'cryptocurrency', - 'cryptocurrency news', - 'culture', - 'cute', - 'daily', - 'daily vlog', - 'dance', - 'day', - 'death', - 'democrat', - 'design', - 'destiny', - 'destiny 2', - 'diet', - 'digital', - 'discord', - 'disney', - 'diy', - 'dj', - 'dlc', - 'dog', - 'donald trump', - 'dope', - 'dota 2', - 'dragon', - 'drama', - 'drawing', - 'drone', - 'duty', - 'earth', - 'ecig', - 'economics', - 'economy', - 'edm', - 'Education', - 'eggs', - 'electronic', - 'eliquid', - 'england', - 'Entertainment', - 'eos', - 'epic', - 'eth', - 'ethereum', - 'ethereum news', - 'exploration', - 'extreme', - 'facebook', - 'fail', - 'fake news', - 'fallout 4', - 'family', - 'family friendly', - 'fantasy', - 'far cry 5', - 'fashion', - 'fiction', - 'film', - 'film & animation', - 'final', - 'fire', - 'fitness', - 'flat', - 'flat earth', - 'floral', - 'food', - 'food holidays', - 'football', - 'fortnite', - 'fortnite battle royale', - 'fox', - 'fox news', - 'fps', - 'fpv', - 'france', - 'freedom', - 'full time rving', - 'fullhd', - 'fun', - 'funny', - 'funny moments', - 'future', - 'future bass', - 'game', - 'game reviews', - 'gameplay', - 'gamer', - 'gamers', - 'games', 'gaming', - 'garden', - 'germany', - 'ghost', - 'god', - 'gold', - 'government', - 'grand theft auto', - 'grand theft auto v', - 'gta', - 'gta 5', - 'gta v', - 'guitar', - 'guns', - 'gym', - 'hack', - 'halloween', - 'halo', - 'hangoutsonair', - 'happy', - 'health', - 'healthy', - 'help', - 'hilarious', - 'hillary clinton', - 'hip hop', - 'history', - 'hoa', - 'holiday', - 'horror', - 'house', - 'how', - 'how to', - 'how to make money', - 'how to make money online', - 'how - to', - 'howto', - 'Howto & Style', - 'humor', - 'ico', - 'illuminati', - 'indie', - 'industry', - 'insane', - 'instrumental', - 'investing', - 'ios', - 'ipad', - 'iphone', - 'israel', - 'jesus', - 'joyetech', - 'Juvenile fiction', - 'knife', - 'latest news', - 'league', - 'league of legends', - 'learning', - 'lee', - 'lessons', - "let's play", - 'lets play', - 'level', - 'liberal', - 'libertarian', - 'liberty', - 'light', - 'lightning', - 'linux', - 'litecoin', - 'lol', - 'lord', - 'love', - 'magic', - 'maps', - 'mario', - 'mark dice', - 'marvel', - 'mass effect', - 'massively multiplayer online role - playing game', - 'master', - 'mature', - 'media', - 'meme', - 'memes', - 'metal', - 'microsoft', - 'military', - 'minecraft', - 'mining', - 'mix', - 'mmo', - 'mmorpg', - 'mobile', - 'mod', - 'modded', - 'mods', - 'mojang', - 'money', - 'motivation', - 'movie', - 'msnbc', - 'multiplayer', - 'music', - 'music video', - 'muslim', - 'mw2', - 'mw3', - 'nasa', - 'nature', - 'nbc', - 'network', - 'new music', - 'news', - 'News & Politics', - 'news radio', - 'nibiru', - 'ninja', - 'nintendo', - 'nintendo switch', - 'Nonprofits & Activism', - 'obama', - 'online', - 'online learning', - 'open world', - 'opinion', - 'outdoor', - 'overwatch', - 'pacman', - 'paladins', - 'paranormal', - 'parody', - 'patreon', - 'paypal', - 'pc', - 'pc game', - 'pc gaming', - 'peace', - 'People & Blogs', - 'pets & animals', - 'photography', - 'planet', - 'planet x', - 'planets', - 'play', - "playerunknown's battlegrounds", - 'playing', - 'plays', - 'playstation', - 'playstation 4', - 'playthrough', - 'podcast', - 'pokemon', - 'political', - 'politics', 'pop culture', - 'post', - 'prank', - 'press', - 'pro', - 'progressive', - 'progressive talk', - 'ps2', - 'ps3', - 'ps4', - 'ps4live', - 'ps4share', - 'psychology', - 'pubg', - 'pubg mobile', - 'puzzle', - 'pvp', - 'quad', - 'race', - 'racing', - 'rainbow', - 'ram', - 'random', - 'rap', - 'raw', - 'rda', - 'react', - 'reaction', - 'reading', - 'reaper', - 'religion', - 'remix', - 'republican', - 'resident evil', - 'retro', - 'reviews', - 'ripple', - 'roblox', - 'rock', - 'role-playing game', - 'rpg', - 'rta', - 'rv', - 'rv park', - 'samsung', - 'sandbox', - 'satire', - 'school', - 'sci-fi', - 'science', - 'science & technology', - 'science fiction', - 'secret', - 'secular', - 'secular talk', - 'senate', - 'sharefactory', - 'shooter game', - 'shooting', - 'Short stories', - 'sick', - 'silly', - 'sims', - 'sims 3', - 'sims 4', - 'simulation', - 'singing', - 'skyrim', - 'smok', - 'sniper', - 'sniping', - 'Social life and customs', - 'song', - 'sony', - 'sony computer entertainment', - 'sony interactive entertainment', - 'soul', - 'sound', - 'soundtrack', - 'space', - 'special', - 'sports', - 'squad gameplay', - 'srpski', - 'star', - 'star wars', - 'steam', - 'strategy', - 'stream', - 'studio', - 'style', - 'subscribe', - 'sun', - 'suomi', - 'super smash bros', - 'supercell', - 'survival', - 'survival horror', - 'switch', - 'tactical', - 'teaser', - 'tech', + 'Entertainment', 'technology', - 'the best', - 'timelapse', - 'top 10', - 'tourism', - 'track', - 'trading', - 'trailer', - 'training', - 'trap', - 'travel', - 'Travel & Events', - 'travel trailer', - 'travel vlog', - 'trending', - 'trump', - 'truth', + 'music', + 'funny', + 'Education', + 'learning', + 'news', + 'gameplay', + 'nature', + 'beliefs', + 'comedy', + 'games', + 'sony interactive entertainment', + 'film & animation', + 'game', + 'weapons', + "let's play", + 'blockchain', + 'video game', + 'sports', + 'walkthrough', + 'ps4live', + 'art', + 'pc', + 'minecraft', + 'playthrough', + 'economics', + 'automotive', + 'play', + 'ps4share', 'tutorial', 'twitch', - 'twitter', - 'ubisoft', - 'ufo', - 'unboxing', - 'united states', - 'universe', - 'vacation', - 'vape', - 'vape review', - 'vaper', - 'vaping', - 'vapor', - 'Various', - 'vegan', - 'Verschillende', - 'video blog', - 'video game', - 'video games', - 'videogame', - 'viral', - 'vlogging', - 'voluntaryist', - 'walkthrough', - 'war', - 'warrior', - 'water', - 'weapons', - 'weird', - 'wii', - 'wii u', - 'windows', - 'workout', - 'world', - 'world of warcraft', - 'wrestling', - 'ww2', - 'wwe', + 'how to', + 'ps4', + 'bitcoin', + 'fortnite', + 'commentary', + 'lets play', + 'fun', + 'politics', 'xbox', - 'xbox 360', + 'autos & vehicles', + 'Travel & Events', + 'food', + 'science', 'xbox one', - 'zombie', + 'liberal', + 'democrat', + 'progressive', + 'survival', + 'Nonprofits & Activism', + 'cryptocurrency', + 'playstation', + 'nintendo', + 'government', + 'steam', + 'podcast', + 'gamer', + 'horror', + 'conservative', + 'reaction', + 'trailer', + 'love', + 'cnn', + 'republican', + 'political', + 'hangoutsonair', + 'hoa', + 'msnbc', + 'cbs', + 'anime', + 'donald trump', + 'fiction', + 'fox news', + 'crypto', + 'ethereum', + 'call of duty', + 'android', + 'multiplayer', + 'epic', + 'rpg', + 'adventure', + 'secular talk', + 'btc', + 'atheist', + 'atheism', + 'video games', + 'ps3', + 'cod', + 'online', + 'agnostic', + 'movie', + 'fps', + 'lets', + 'mod', + 'world', + 'reviews', + 'sharefactory', + 'space', + 'pokemon', + 'stream', + 'hilarious', + 'lol', + 'sony', + 'god', + "let's", + 'dance', + 'pvp', + 'tech', + 'strategy', 'zombies', + 'fail', + 'film', + 'xbox 360', + 'animation', + 'unboxing', + 'money', + 'how', + 'travel', + 'wwe', + 'mods', + 'indie', + 'pubg', + 'ios', + 'history', + 'rap', + 'sony computer entertainment', + 'mobile', + 'trump', + 'hack', + 'flat earth', + 'trap', + 'humor', + 'vlogging', + 'fox', + 'news radio', + 'facebook', + 'edm', + 'fitness', + 'vaping', + 'hip hop', + 'secular', + 'jesus', + 'song', + 'vape', + 'guitar', + 'remix', + 'mining', + 'daily', + 'diy', + 'pets & animals', + 'videogame', + 'death', + 'funny moments', + 'religion', + 'media', + 'viral', + 'war', + 'nbc', + 'freedom', + 'gold', + 'family', + 'meme', + 'zombie', + 'photography', + 'chill', + 'sniper', + 'computer', + 'iphone', + 'dragon', + 'bible', + 'pro', + 'overwatch', + 'litecoin', + 'gta', + 'house', + 'fire', + 'bass', + 'bitcoin news', + 'truth', + 'crash', + 'mario', + 'league of legends', + 'wii', + 'mmorpg', + 'grand theft auto v', + 'health', + 'marvel', + 'racing', + 'apple', + 'instrumental', + 'earth', + 'destiny', + 'satire', + 'race', + 'training', + 'electronic', + 'boss', + 'roblox', + 'family friendly', + 'california', + 'react', + 'christian', + 'mmo', + 'twitter', + 'help', + 'star', + 'cars', + 'random', + 'top 10', + 'ninja', + 'guns', + 'linux', + 'lessons', + 'vegan', + 'future', + 'dota 2', + 'studio', + 'star wars', + 'gta 5', + 'shooting', + 'nasa', + 'rock', + 'league', + 'subscribe', + 'water', + 'gta v', + 'car', + 'samsung', + 'music video', + 'skyrim', + 'dog', + 'comics', + 'shooter game', + 'bo3', + 'halloween', + 'liberty', + 'eth', + 'conspiracy', + 'knife', + 'fashion', + 'stories', + 'vapor', + 'nvidia', + 'cute', + 'beat', + 'nintendo switch', + 'fantasy', + 'christmas', + 'world of warcraft', + 'industry', + 'cartoon', + 'crypto news', + 'garden', + 'animals', + 'windows', + 'happy', + 'magic', + 'memes', + 'design', + 'tactical', + 'fallout 4', + 'puzzle', + 'parody', + 'rv', + 'beats', + 'fortnite battle royale', + 'building', + 'disney', + 'drone', + 'ps2', + 'beach', + 'metal', + 'christianity', + 'business', + 'mix', + 'bo2', + 'cover', + 'senate', + '4k', + 'united states', + 'final', + 'hero', + 'playing', + 'dlc', + 'ubisoft', + 'halo', + 'pc gaming', + 'raw', + 'investing', + 'online learning', + 'software', + 'ark', + 'mojang', + 'console', + 'battle royale', + 'canon', + 'microsoft', + 'camping', + 'cryptocurrency news', + 'ufo', + 'progressive talk', + 'switch', + 'fpv', + 'arcade', + 'school', + 'driving', + 'bodybuilding', + 'drama', + 'retro', + 'science fiction', + 'eggs', + 'australia', + 'modded', + 'rainbow', + 'gamers', + 'resident evil', + 'drawing', + 'brasil', + 'england', + 'hillary clinton', + 'singing', + 'final fantasy', + 'hiphop', + 'video blog', + 'mature', + 'quad', + 'noob', + 'simulation', + 'illuminati', + 'poetry', + 'dayz', + 'manga', + 'howto', + 'insane', + 'xbox360', + 'press', + 'special', + 'church', + 'ico', + 'weird', + 'libertarian', + 'crafting', + 'level', + 'comic', + 'sandbox', + 'daily vlog', + 'outdoor', + 'black ops', + 'sound', + 'christ', + 'duty', + 'Juvenile fiction', + 'pc game', + 'how-to', + 'ww2', + 'creepy', + 'artist', + 'galaxy', + 'destiny 2', + 'new music', + 'quest', + 'lee', + 'pacman', + 'super smash bros', + 'day', + 'survival horror', + 'patreon', + 'bitcoin price', + 'trending', + 'open world', + 'wii u', + 'dope', + 'reaper', + 'sniping', + 'dubstep', + 'truck', + 'planet', + 'dc', + 'amazon', + 'spirituality', + 'universe', + 'video game culture', + 'community', + 'cat', + 'aliens', + 'tourism', + 'altcoins', + 'style', + 'travel trailer', + 'rda', + '5859dfec-026f-46ba-bea0-02bf43aa1a6f', + 'gun', + 100, + 'secret', + 'far cry 5', + 'auto', + 'culture', + 'dj', + 'mw2', + 'lord', + 'full time rving', + 'role-playing game', + 'prank', + 'grand theft auto', + 'master', + 'wrestling', + 'sci-fi', + 'workout', + 'ghost', + 'fake news', + 'silly', + 'season', + 'bo4', + 'trading', + 'extreme', + 'economy', + 'combat', + 'plays', + 'muslim', + 'pubg mobile', + 'clips', + 'bo1', + 'paypal', + 'sims', + 'exploration', + 'light', + 'ripple', + 'paranormal', + 'football', + 'capcom', + 'rta', + 'discord', + 'action role-playing game', + 'playthrough part', + 'batman', + 'player', + 'server', + 'anarchy', + 'military', + 'playlist', + 'cosplay', + 'rv park', + 'rant', + 'edit', + 'germany', + 'reading', + 'chris', + 'flash', + 'loot', + 'bitcoin gratis', + 'game reviews', + 'movies', + 'stupid', + 'latest news', + 'squad gameplay', + 'guru', + 'timelapse', + 'black ops 3', + 'holiday', + 'soul', + 'motivation', + 'mw3', + 'vacation', + 'sega', + '19th century', + 'pop', + 'sims 4', + 'post', + 'smok', + 'island', + 'scotland', + 'paladins', + 'warrior', + 'creepypasta', + 'role-playing video game', + 'solar', + 'vr', + 'animal', + 'peace', + 'consciousness', + 'dota', + 'audio', + 'mass effect', + 'Humour', + 'first look', + 'videogames', + 'future bass', + 'freestyle', + 'hardcore', + 'portugal', + 'dantdm', + 'teaser', ]; diff --git a/tags.js b/tags.js new file mode 100644 index 0000000..65d8fcc --- /dev/null +++ b/tags.js @@ -0,0 +1 @@ +gaming,People & Blogs,pop culture,Entertainment,technology,music,funny,Education,learning,news,gameplay,science & technology,playstation 4,nature,beliefs,News & Politics,comedy,games,sony interactive entertainment,film & animation,game,Howto & Style,weapons,let's play,blockchain,video game,sports,walkthrough,ps4live,art,pc,minecraft,playthrough,economics,automotive,play,ps4share,tutorial,twitch,how to,ps4,bitcoin,fortnite,commentary,lets play,fun,politics,xbox,autos & vehicles,Travel & Events,food,science,xbox one,liberal,democrat,progressive,survival,Nonprofits & Activism,cryptocurrency,playstation,nintendo,government,steam,podcast,gamer,horror,conservative,reaction,trailer,love,cnn,republican,political,hangoutsonair,hoa,msnbc,cbs,anime,donald trump,fiction,fox news,crypto,ethereum,call of duty,android,multiplayer,epic,rpg,adventure,secular talk,btc,atheist,atheism,video games,ps3,cod,online,agnostic,movie,fps,lets,mod,world,reviews,sharefactory,space,pokemon,stream,hilarious,lol,sony,god,let's,dance,pvp,tech,strategy,zombies,fail,film,xbox 360,animation,unboxing,money,how,travel,wwe,mods,indie,pubg,ios,history,rap,sony computer entertainment,mobile,trump,hack,flat earth,trap,humor,vlogging,fox,news radio,facebook,edm,fitness,vaping,hip hop,secular,jesus,song,vape,guitar,remix,mining,daily,diy,pets & animals,videogame,death,funny moments,religion,media,viral,war,nbc,freedom,gold,family,meme,zombie,photography,chill,sniper,computer,iphone,dragon,bible,pro,overwatch,litecoin,gta,house,fire,bass,bitcoin news,truth,crash,mario,league of legends,wii,mmorpg,grand theft auto v,health,marvel,racing,apple,instrumental,earth,destiny,satire,race,training,electronic,boss,roblox,family friendly,california,react,christian,mmo,twitter,help,star,cars,random,top 10,ninja,guns,linux,lessons,vegan,future,dota 2,studio,star wars,gta 5,shooting,nasa,rock,league,subscribe,water,gta v,car,samsung,music video,skyrim,dog,comics,shooter game,bo3,halloween,liberty,eth,conspiracy,knife,fashion,stories,vapor,nvidia,cute,beat,nintendo switch,fantasy,christmas,world of warcraft,industry,cartoon,crypto news,garden,animals,windows,happy,magic,memes,design,tactical,fallout 4,puzzle,parody,rv,beats,fortnite battle royale,building,disney,drone,ps2,beach,metal,christianity,business,mix,bo2,cover,senate,4k,united states,final,hero,playing,dlc,ubisoft,halo,pc gaming,raw,investing,online learning,software,ark,mojang,console,battle royale,canon,microsoft,camping,cryptocurrency news,ufo,progressive talk,switch,fpv,arcade,school,driving,bodybuilding,drama,retro,science fiction,eggs,australia,modded,rainbow,gamers,resident evil,drawing,brasil,england,hillary clinton,singing,final fantasy,hiphop,video blog,mature,quad,noob,simulation,illuminati,poetry,dayz,manga,howto,insane,xbox360,press,special,church,ico,weird,libertarian,crafting,level,comic,sandbox,daily vlog,outdoor,black ops,sound,christ,duty,Juvenile fiction,pc game,how-to,ww2,creepy,artist,galaxy,destiny 2,new music,quest,lee,pacman,super smash bros,day,survival horror,patreon,bitcoin price,trending,open world,wii u,dope,reaper,sniping,dubstep,truck,planet,dc,amazon,spirituality,universe,video game culture,community,cat,aliens,tourism,altcoins,style,travel trailer,rda,5859dfec-026f-46ba-bea0-02bf43aa1a6f,gun,100,secret,far cry 5,auto,culture,dj,mw2,lord,full time rving,role-playing game,prank,grand theft auto,master,wrestling,sci-fi,workout,ghost,fake news,silly,season,bo4,trading,extreme,economy,combat,plays,muslim,pubg mobile,clips,bo1,paypal,sims,exploration,light,ripple,paranormal,football,capcom,rta,discord,action role-playing game,playthrough part,batman,player,server,anarchy,military,playlist,cosplay,rv park,rant,edit,germany,reading,chris,flash,loot,bitcoin gratis,game reviews,movies,stupid,latest news,squad gameplay,guru,timelapse,black ops 3,holiday,soul,motivation,mw3,vacation,sega,19th century,pop,sims 4,post,smok,island,scotland,paladins,warrior,creepypasta,role-playing video game,solar,vr,animal,peace,consciousness,dota,audio,mass effect,Humour,first look,videogames,future bass,freestyle,hardcore,portugal,dantdm,teaser \ No newline at end of file -- 2.45.2 From baf54ea00d29c12b481cad25eb6796ee6d11486b Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 23 Jul 2019 15:42:48 -0400 Subject: [PATCH 070/371] remove '100' tag --- dist/bundle.es.js | 2 +- src/constants/tags.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 6d7e134..6db3b82 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -650,7 +650,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['gaming', 'pop culture', 'Entertainment', 'technology', 'music', 'funny', 'Education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'sony interactive entertainment', 'film & animation', 'game', 'weapons', "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', 'ps4live', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'ps4share', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'xbox', 'autos & vehicles', 'Travel & Events', 'food', 'science', 'xbox one', 'liberal', 'democrat', 'progressive', 'survival', 'Nonprofits & Activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', "let's", 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox 360', 'animation', 'unboxing', 'money', 'how', 'travel', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'sony computer entertainment', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets & animals', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'grand theft auto v', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'gta 5', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'crypto news', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'fortnite battle royale', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'xbox360', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'Juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 100, 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'action role-playing game', 'playthrough part', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing video game', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'Humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser']; +const DEFAULT_KNOWN_TAGS = ['gaming', 'pop culture', 'Entertainment', 'technology', 'music', 'funny', 'Education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'sony interactive entertainment', 'film & animation', 'game', 'weapons', "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', 'ps4live', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'ps4share', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'xbox', 'autos & vehicles', 'Travel & Events', 'food', 'science', 'xbox one', 'liberal', 'democrat', 'progressive', 'survival', 'Nonprofits & Activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', "let's", 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox 360', 'animation', 'unboxing', 'money', 'how', 'travel', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'sony computer entertainment', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets & animals', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'grand theft auto v', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'gta 5', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'crypto news', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'fortnite battle royale', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'xbox360', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'Juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'action role-playing game', 'playthrough part', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing video game', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'Humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser']; // diff --git a/src/constants/tags.js b/src/constants/tags.js index 807a048..ef3fd9e 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -411,7 +411,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', - 100, 'secret', 'far cry 5', 'auto', -- 2.45.2 From dfbb8d128a76dd9cca9d39903f652a027bbea9e7 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 24 Jul 2019 03:14:46 -0400 Subject: [PATCH 071/371] Delete tags.js --- tags.js | 1 - 1 file changed, 1 deletion(-) delete mode 100644 tags.js diff --git a/tags.js b/tags.js deleted file mode 100644 index 65d8fcc..0000000 --- a/tags.js +++ /dev/null @@ -1 +0,0 @@ -gaming,People & Blogs,pop culture,Entertainment,technology,music,funny,Education,learning,news,gameplay,science & technology,playstation 4,nature,beliefs,News & Politics,comedy,games,sony interactive entertainment,film & animation,game,Howto & Style,weapons,let's play,blockchain,video game,sports,walkthrough,ps4live,art,pc,minecraft,playthrough,economics,automotive,play,ps4share,tutorial,twitch,how to,ps4,bitcoin,fortnite,commentary,lets play,fun,politics,xbox,autos & vehicles,Travel & Events,food,science,xbox one,liberal,democrat,progressive,survival,Nonprofits & Activism,cryptocurrency,playstation,nintendo,government,steam,podcast,gamer,horror,conservative,reaction,trailer,love,cnn,republican,political,hangoutsonair,hoa,msnbc,cbs,anime,donald trump,fiction,fox news,crypto,ethereum,call of duty,android,multiplayer,epic,rpg,adventure,secular talk,btc,atheist,atheism,video games,ps3,cod,online,agnostic,movie,fps,lets,mod,world,reviews,sharefactory,space,pokemon,stream,hilarious,lol,sony,god,let's,dance,pvp,tech,strategy,zombies,fail,film,xbox 360,animation,unboxing,money,how,travel,wwe,mods,indie,pubg,ios,history,rap,sony computer entertainment,mobile,trump,hack,flat earth,trap,humor,vlogging,fox,news radio,facebook,edm,fitness,vaping,hip hop,secular,jesus,song,vape,guitar,remix,mining,daily,diy,pets & animals,videogame,death,funny moments,religion,media,viral,war,nbc,freedom,gold,family,meme,zombie,photography,chill,sniper,computer,iphone,dragon,bible,pro,overwatch,litecoin,gta,house,fire,bass,bitcoin news,truth,crash,mario,league of legends,wii,mmorpg,grand theft auto v,health,marvel,racing,apple,instrumental,earth,destiny,satire,race,training,electronic,boss,roblox,family friendly,california,react,christian,mmo,twitter,help,star,cars,random,top 10,ninja,guns,linux,lessons,vegan,future,dota 2,studio,star wars,gta 5,shooting,nasa,rock,league,subscribe,water,gta v,car,samsung,music video,skyrim,dog,comics,shooter game,bo3,halloween,liberty,eth,conspiracy,knife,fashion,stories,vapor,nvidia,cute,beat,nintendo switch,fantasy,christmas,world of warcraft,industry,cartoon,crypto news,garden,animals,windows,happy,magic,memes,design,tactical,fallout 4,puzzle,parody,rv,beats,fortnite battle royale,building,disney,drone,ps2,beach,metal,christianity,business,mix,bo2,cover,senate,4k,united states,final,hero,playing,dlc,ubisoft,halo,pc gaming,raw,investing,online learning,software,ark,mojang,console,battle royale,canon,microsoft,camping,cryptocurrency news,ufo,progressive talk,switch,fpv,arcade,school,driving,bodybuilding,drama,retro,science fiction,eggs,australia,modded,rainbow,gamers,resident evil,drawing,brasil,england,hillary clinton,singing,final fantasy,hiphop,video blog,mature,quad,noob,simulation,illuminati,poetry,dayz,manga,howto,insane,xbox360,press,special,church,ico,weird,libertarian,crafting,level,comic,sandbox,daily vlog,outdoor,black ops,sound,christ,duty,Juvenile fiction,pc game,how-to,ww2,creepy,artist,galaxy,destiny 2,new music,quest,lee,pacman,super smash bros,day,survival horror,patreon,bitcoin price,trending,open world,wii u,dope,reaper,sniping,dubstep,truck,planet,dc,amazon,spirituality,universe,video game culture,community,cat,aliens,tourism,altcoins,style,travel trailer,rda,5859dfec-026f-46ba-bea0-02bf43aa1a6f,gun,100,secret,far cry 5,auto,culture,dj,mw2,lord,full time rving,role-playing game,prank,grand theft auto,master,wrestling,sci-fi,workout,ghost,fake news,silly,season,bo4,trading,extreme,economy,combat,plays,muslim,pubg mobile,clips,bo1,paypal,sims,exploration,light,ripple,paranormal,football,capcom,rta,discord,action role-playing game,playthrough part,batman,player,server,anarchy,military,playlist,cosplay,rv park,rant,edit,germany,reading,chris,flash,loot,bitcoin gratis,game reviews,movies,stupid,latest news,squad gameplay,guru,timelapse,black ops 3,holiday,soul,motivation,mw3,vacation,sega,19th century,pop,sims 4,post,smok,island,scotland,paladins,warrior,creepypasta,role-playing video game,solar,vr,animal,peace,consciousness,dota,audio,mass effect,Humour,first look,videogames,future bass,freestyle,hardcore,portugal,dantdm,teaser \ No newline at end of file -- 2.45.2 From 89a2db061319d3a469c60b72c07bad6c7a6ff62b Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 26 Jul 2019 07:27:09 +0100 Subject: [PATCH 072/371] fix tags key --- dist/bundle.es.js | 14 +++++++++----- src/redux/actions/claims.js | 3 ++- src/redux/reducers/claims.js | 4 ++-- src/redux/selectors/claims.js | 10 +++++----- src/util/claim.js | 4 ++++ 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b971f6b..a1f0e26 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1242,6 +1242,10 @@ const isClaimNsfw = claim => { return false; }; +const createNormalizedTagKey = tags => { + return tags.sort().join(','); +}; + // const selectState$1 = state => state.claims || {}; @@ -1521,9 +1525,9 @@ const selectFetchingClaimSearchByTags = reselect.createSelector(selectState$1, s const selectClaimSearchUrisByTags = reselect.createSelector(selectState$1, state => state.claimSearchUrisByTags); -const makeSelectFetchingClaimSearchForTags = tags => reselect.createSelector(selectFetchingClaimSearchByTags, byTags => byTags[tags]); +const makeSelectFetchingClaimSearchForTags = tags => reselect.createSelector(selectFetchingClaimSearchByTags, byTags => byTags[createNormalizedTagKey(tags)]); -const makeSelectClaimSearchUrisForTags = tags => reselect.createSelector(selectClaimSearchUrisByTags, byTags => byTags[tags]); +const makeSelectClaimSearchUrisForTags = tags => reselect.createSelector(selectClaimSearchUrisByTags, byTags => byTags[createNormalizedTagKey(tags)]); const selectState$2 = state => state.wallet || {}; @@ -2353,7 +2357,7 @@ function doClaimSearch(amount = 20, options = {}) { // tags can be one or many (comma separated) function doClaimSearchByTags(tags, amount = 10, options = {}) { return dispatch => { - const tagList = tags.join(','); + const tagList = createNormalizedTagKey(tags); dispatch({ type: CLAIM_SEARCH_BY_TAGS_STARTED, data: { tags: tagList } @@ -3384,8 +3388,8 @@ const defaultState = { abandoningById: {}, pendingById: {}, fetchingClaimSearch: false, - claimSearchUrisByTags: [], - fetchingClaimSearchByTags: [], + claimSearchUrisByTags: {}, + fetchingClaimSearchByTags: {}, lastClaimSearchUris: [] }; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index b563dde..c60e2a6 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -8,6 +8,7 @@ import { doFetchTransactions } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { creditsToString } from 'util/formatCredits'; import { batchActions } from 'util/batchActions'; +import { createNormalizedTagKey } from 'util/claim'; export function doResolveUris(uris: Array, returnCachedClaims: boolean = false) { return (dispatch: Dispatch, getState: GetState) => { @@ -336,7 +337,7 @@ export function doClaimSearch(amount: number = 20, options: { page?: number } = // tags can be one or many (comma separated) export function doClaimSearchByTags(tags: Array, amount: number = 10, options: { page?: number } = {}) { return (dispatch: Dispatch) => { - const tagList = tags.join(','); + const tagList = createNormalizedTagKey(tags); dispatch({ type: ACTIONS.CLAIM_SEARCH_BY_TAGS_STARTED, data: { tags: tagList }, diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 5d1a147..1681f76 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -47,8 +47,8 @@ const defaultState = { abandoningById: {}, pendingById: {}, fetchingClaimSearch: false, - claimSearchUrisByTags: [], - fetchingClaimSearchByTags: [], + claimSearchUrisByTags: {}, + fetchingClaimSearchByTags: {}, lastClaimSearchUris: [], }; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index a451615..e1e4d4d 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 } from 'util/claim'; +import { isClaimNsfw, createNormalizedTagKey } from 'util/claim'; import { getSearchQueryString } from 'util/query_params'; const selectState = state => state.claims || {}; @@ -495,14 +495,14 @@ export const selectClaimSearchUrisByTags = createSelector( state => state.claimSearchUrisByTags ); -export const makeSelectFetchingClaimSearchForTags = (tags: string) => +export const makeSelectFetchingClaimSearchForTags = (tags: Array) => createSelector( selectFetchingClaimSearchByTags, - byTags => byTags[tags] + byTags => byTags[createNormalizedTagKey(tags)] ); -export const makeSelectClaimSearchUrisForTags = (tags: string) => +export const makeSelectClaimSearchUrisForTags = (tags: Array) => createSelector( selectClaimSearchUrisByTags, - byTags => byTags[tags] + byTags => byTags[createNormalizedTagKey(tags)] ); diff --git a/src/util/claim.js b/src/util/claim.js index b5d6a96..84243cb 100644 --- a/src/util/claim.js +++ b/src/util/claim.js @@ -22,3 +22,7 @@ export const isClaimNsfw = (claim: Claim): boolean => { return false; }; + +export const createNormalizedTagKey = (tags: Array): string => { + return tags.sort().join(','); +}; -- 2.45.2 From 4b1438af93b1bb2478f2b52ae1a1bcc74c11997a Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 26 Jul 2019 07:34:16 +0100 Subject: [PATCH 073/371] update makeSelectThumbnailForUrl --- 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 a1f0e26..b1a0a7f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1366,7 +1366,7 @@ 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 : undefined; + return thumbnail && thumbnail.url && thumbnail.url.trim().length() > 0 ? thumbnail.url : undefined; }); const makeSelectCoverForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index e1e4d4d..ba50ac5 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -228,7 +228,7 @@ export const makeSelectThumbnailForUri = (uri: string) => makeSelectClaimForUri(uri), claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; - return thumbnail ? thumbnail.url : undefined; + return thumbnail && thumbnail.url && thumbnail.url.trim().length() > 0 ? thumbnail.url : undefined; } ); -- 2.45.2 From f56321a93f2b4ed2b92e3003b28dfec2ccda5257 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 26 Jul 2019 07:45:02 +0100 Subject: [PATCH 074/371] ensure that tag names in followedTags are always lowercase --- dist/bundle.es.js | 2 +- src/redux/selectors/tags.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b1a0a7f..659d58f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4713,7 +4713,7 @@ const selectKnownTagsByName = reselect.createSelector(selectState$9, state => st const selectFollowedTagsList = reselect.createSelector(selectState$9, state => state.followedTags); -const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag })).sort((a, b) => a.name.localeCompare(b.name))); +const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag.toLowerCase() })).sort((a, b) => a.name.localeCompare(b.name))); const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, selectFollowedTagsList, (tagsByName, followedTags) => { const followedTagsSet = new Set(followedTags); diff --git a/src/redux/selectors/tags.js b/src/redux/selectors/tags.js index e3bbe4c..d38d375 100644 --- a/src/redux/selectors/tags.js +++ b/src/redux/selectors/tags.js @@ -16,7 +16,7 @@ export const selectFollowedTagsList = createSelector( export const selectFollowedTags = createSelector( selectFollowedTagsList, (followedTags: Array): Array => - followedTags.map(tag => ({ name: tag })).sort((a, b) => a.name.localeCompare(b.name)) + followedTags.map(tag => ({ name: tag.toLowerCase() })).sort((a, b) => a.name.localeCompare(b.name)) ); export const selectUnfollowedTags = createSelector( -- 2.45.2 From e3d12fb896b44ee68685d63566bf223ea82b917a Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 26 Jul 2019 08:17:52 +0100 Subject: [PATCH 075/371] fix thumbnail url trim --- 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 659d58f..f0e52b7 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1366,7 +1366,7 @@ 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; + return thumbnail && thumbnail.url && thumbnail.url.trim().length > 0 ? thumbnail.url : undefined; }); const makeSelectCoverForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index ba50ac5..3037402 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -228,7 +228,7 @@ 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; } ); -- 2.45.2 From 67a654f60630710cae72419448a73a18d076d18a Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 26 Jul 2019 08:20:37 +0100 Subject: [PATCH 076/371] handle null parameter for createNormalizedTagKey --- dist/bundle.es.js | 2 +- src/util/claim.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f0e52b7..c592cfd 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1243,7 +1243,7 @@ const isClaimNsfw = claim => { }; const createNormalizedTagKey = tags => { - return tags.sort().join(','); + return tags ? tags.sort().join(',') : ''; }; // diff --git a/src/util/claim.js b/src/util/claim.js index 84243cb..1e24a10 100644 --- a/src/util/claim.js +++ b/src/util/claim.js @@ -24,5 +24,5 @@ export const isClaimNsfw = (claim: Claim): boolean => { }; export const createNormalizedTagKey = (tags: Array): string => { - return tags.sort().join(','); + return tags ? tags.sort().join(',') : ''; }; -- 2.45.2 From 046bc18eef26af69227c792711f9762fa3aafdb6 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 4 Jul 2019 22:20:56 -0400 Subject: [PATCH 077/371] enables publish for desktop adds reduxCallbacks for post publish actions publish callback modal works better callbacks publish callbacks passed as params cleanup --- dist/bundle.es.js | 304 ++++++++++++++++----------------- dist/flow-typed/Publish.js | 4 +- flow-typed/Publish.js | 4 +- src/index.js | 1 + src/redux/actions/claims.js | 8 +- src/redux/actions/publish.js | 166 +++++++++--------- src/redux/reducers/publish.js | 2 + src/redux/selectors/publish.js | 10 +- 8 files changed, 251 insertions(+), 248 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 87259bf..3bdbd0e 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 fs = _interopDefault(require('fs')); +var path = _interopDefault(require('path')); const MINIMUM_PUBLISH_BID = 0.00000001; @@ -2082,14 +2084,6 @@ function doUpdateBlockHeight() { }); } -// https://github.com/reactjs/redux/issues/911 -function batchActions(...actions) { - return { - type: 'BATCH_ACTIONS', - actions - }; -} - 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) { @@ -2786,18 +2780,90 @@ function doSetFileListSort(page, value) { }; } -// +// https://github.com/reactjs/redux/issues/911 +function batchActions(...actions) { + return { + type: 'BATCH_ACTIONS', + actions + }; +} -const formatLbryUriForWeb = uri => { - const { claimName, claimId } = parseURI(uri); +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; } - let webUrl = `/${claimName}`; - if (claimId) { - webUrl += `/${claimId}`; +const selectState$5 = state => state.publish || {}; + +const selectPublishFormValues = reselect.createSelector(selectState$5, state => { + const formValues = _objectWithoutProperties(state, ['pendingPublish']); + return formValues; +}); +const makeSelectPublishFormValue = item => reselect.createSelector(selectState$5, state => state[item]); + +// Is the current uri the same as the uri they clicked "edit" on +const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, publishState => { + const { editingURI, uri } = publishState; + + if (!editingURI || !uri) { + return false; } - return webUrl; -}; + const { isChannel: currentIsChannel, claimName: currentClaimName, contentName: currentContentName } = parseURI(uri); + const { isChannel: editIsChannel, claimName: editClaimName, contentName: editContentName } = parseURI(editingURI); + + // Depending on the previous/current use of a channel, we need to compare different things + // ex: going from a channel to anonymous, the new uri won't return contentName, so we need to use claimName + const currentName = currentIsChannel ? currentContentName : currentClaimName; + const editName = editIsChannel ? editContentName : editClaimName; + return currentName === editName; +}); + +const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, selectIsStillEditing, selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => { + const { contentName, claimName } = parseURI(uri); + const { claimId: editClaimId } = parseURI(editingURI); + + // If isStillEditing + // They clicked "edit" from the file page + // They haven't changed the channel/name after clicking edit + // Get the claim so they can edit without re-uploading a new file + return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName); +}); + +const selectIsResolvingPublishUris = reselect.createSelector(selectState$5, selectResolvingUris, ({ uri, name }, resolvingUris) => { + if (uri) { + const isResolvingUri = resolvingUris.includes(uri); + const { isChannel } = parseURI(uri); + + let isResolvingShortUri; + if (isChannel) { + const shortUri = buildURI({ contentName: name }); + isResolvingShortUri = resolvingUris.includes(shortUri); + } + + return isResolvingUri || isResolvingShortUri; + } + + return false; +}); + +const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => { + // We only care about the winning claim for the short uri + const shortUri = buildURI({ contentName: name }); + const claimForShortUri = claimsByUri[shortUri]; + + if (!myClaimForUri && claimForShortUri) { + return claimForShortUri.effective_amount; + } else if (myClaimForUri && claimForShortUri) { + // https://github.com/lbryio/lbry/issues/1476 + // We should check the current effective_amount on my claim to see how much additional lbc + // is needed to win the claim. Currently this is not possible during a takeover. + // With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim" + // For now just ignore supports. We will just show the winning claim's bid amount + return claimForShortUri.effective_amount || claimForShortUri.amount; + } + + return null; +}); + +// var _extends$4 = 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; }; @@ -2875,6 +2941,7 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter) => dispatch => const data = new FormData(); const name = makeid(); data.append('name', name); + // $FlowFixMe data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); return fetch('https://spee.ch/api/claim/publish', { @@ -2923,15 +2990,15 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter) => dispatch => }; const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { - const { name, amount, channel_name: channelName, value } = claim; - + const { name, amount, value } = claim; + const channelName = claim && claim.signing_channel && claim.signing_channel.normalized_name || null; const { author, description, // use same values as default state // fee will be undefined for free content fee = { - amount: 0, + amount: '0', currency: 'LBC' }, languages, @@ -2943,7 +3010,6 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { const publishData = { name, - channel: channelName, bid: amount, contentIsFree: !fee.amount, author, @@ -2973,6 +3039,9 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { } else { publishData.licenseType = license; } + if (channelName) { + publishData['channel'] = channelName; + } if (fileInfo && fileInfo.download_path) { try { @@ -2986,13 +3055,17 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { dispatch({ type: DO_PREPARE_EDIT, data: publishData }); }; -const doPublish = params => (dispatch, getState) => { +const doPublish = (success, fail) => (dispatch, getState) => { dispatch({ type: PUBLISH_START }); const state = getState(); + const myClaimForUri = selectMyClaimForUri(state); const myChannels = selectMyChannelClaims(state); const myClaims = selectMyClaimsWithoutChannels(state); + // get redux publish form + const publishData = selectPublishFormValues(state); + // destructure the data values const { name, bid, @@ -3001,6 +3074,8 @@ const doPublish = params => (dispatch, getState) => { language, license, licenseUrl, + licenseType, + otherLicenseDescription, thumbnail, channel, title, @@ -3008,8 +3083,20 @@ const doPublish = params => (dispatch, getState) => { fee, uri, nsfw, - claim - } = params; + // claim, + tags, + locations + } = publishData; + + let publishingLicense; + switch (licenseType) { + case COPYRIGHT: + case OTHER: + publishingLicense = otherLicenseDescription; + break; + default: + publishingLicense = licenseType; + } // get the claim id from the channel name, we will use that instead const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); @@ -3017,19 +3104,23 @@ const doPublish = params => (dispatch, getState) => { const publishPayload = { name, - bid: creditsToString(bid), title, - license, - languages: [language], description, - tags: claim && claim.value.tags || [], - locations: claim && claim.value.locations - }; + locations: locations, + bid: creditsToString(bid), + languages: [language], + tags: tags && tags.map(tag => tag.name), + thumbnail_url: thumbnail + }; // Temporary solution to keep the same publish flow with the new tags api // Eventually we will allow users to enter their own tags on publish // `nsfw` will probably be removed + if (publishingLicense) { + publishPayload.license = publishingLicense; + } + if (licenseUrl) { publishPayload.license_url = licenseUrl; } @@ -3038,8 +3129,8 @@ const doPublish = params => (dispatch, getState) => { publishPayload.thumbnail_url = thumbnail; } - if (claim && claim.value.release_time) { - publishPayload.release_time = Number(claim.value.release_time); + if (myClaimForUri && myClaimForUri.value.release_time) { + publishPayload.release_time = Number(myClaimForUri.value.release_time); } if (nsfw) { @@ -3066,41 +3157,7 @@ const doPublish = params => (dispatch, getState) => { // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; - const success = successResponse => { - //analytics.apiLogPublish(); - - const pendingClaim = successResponse.outputs[0]; - const actions = []; - - actions.push({ - type: PUBLISH_SUCCESS - }); - - //actions.push(doOpenModal(MODALS.PUBLISH, { uri })); - - // We have to fake a temp claim until the new pending one is returned by claim_list_mine - // We can't rely on claim_list_mine because there might be some delay before the new claims are returned - // Doing this allows us to show the pending claim immediately, it will get overwritten by the real one - const isMatch = claim => claim.claim_id === pendingClaim.claim_id; - const isEdit = myClaims.some(isMatch); - const myNewClaims = isEdit ? myClaims.map(claim => isMatch(claim) ? pendingClaim : claim) : myClaims.concat(pendingClaim); - - actions.push({ - type: FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims: myNewClaims - } - }); - - dispatch(batchActions(...actions)); - }; - - const failure = error => { - dispatch({ type: PUBLISH_FAIL }); - dispatch(doError(error.message)); - }; - - return lbryProxy.publish(publishPayload).then(success, failure); + return lbryProxy.publish(publishPayload).then(success, fail); }; // Calls claim_list_mine until any pending publishes are confirmed @@ -3116,21 +3173,22 @@ const doCheckPendingPublishes = () => (dispatch, getState) => { const checkFileList = () => { lbryProxy.claim_list().then(claims => { + // $FlowFixMe claims.forEach(claim => { // If it's confirmed, check if it was pending previously if (claim.confirmations > 0 && pendingById[claim.claim_id]) { delete pendingById[claim.claim_id]; - + // TODO fix notifications - pass as param as well? // If it's confirmed, check if we should notify the user - if (selectosNotificationsEnabled(getState())) { - const notif = new window.Notification('LBRY Publish Complete', { - body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, - silent: false - }); - notif.onclick = () => { - dispatch(push(formatLbryUriForWeb(claim.permanent_url))); - }; - } + // if (selectosNotificationsEnabled(getState())) { + // const notif = new window.Notification('LBRY Publish Complete', { + // body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, + // silent: false, + // }); + // notif.onclick = () => { + // dispatch(push(formatLbryUriForWeb(claim.permanent_url))); + // }; + // } } }); @@ -4170,7 +4228,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(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$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 defaultState$6 = { editingURI: undefined, @@ -4196,6 +4254,7 @@ const defaultState$6 = { licenseType: 'None', otherLicenseDescription: 'All rights reserved', licenseUrl: '', + tags: [], publishing: false, publishSuccess: false, publishError: undefined @@ -4219,7 +4278,7 @@ const publishReducer = handleActions({ publishSuccess: true }), [DO_PREPARE_EDIT]: (state, action) => { - const publishData = _objectWithoutProperties(action.data, []); + const publishData = _objectWithoutProperties$1(action.data, []); const { channel, name, uri } = publishData; // The short uri is what is presented to the user @@ -4620,9 +4679,9 @@ const walletReducer = handleActions({ }) }, defaultState$9); -const selectState$5 = state => state.content || {}; +const selectState$6 = state => state.content || {}; -const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$5, makeSelectClaimForUri(uri), (state, claim) => { +const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$6, makeSelectClaimForUri(uri), (state, claim) => { if (!claim) { return null; } @@ -4633,9 +4692,9 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta var _extends$f = 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; }; -const selectState$6 = state => state.notifications || {}; +const selectState$7 = state => state.notifications || {}; -const selectToast = reselect.createSelector(selectState$6, state => { +const selectToast = reselect.createSelector(selectState$7, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; return _extends$f({ @@ -4646,7 +4705,7 @@ const selectToast = reselect.createSelector(selectState$6, state => { return null; }); -const selectError = reselect.createSelector(selectState$6, state => { +const selectError = reselect.createSelector(selectState$7, state => { if (state.errors.length) { const { error } = state.errors[0]; return { @@ -4659,11 +4718,11 @@ const selectError = reselect.createSelector(selectState$6, state => { // -const selectState$7 = state => state.comments || {}; +const selectState$8 = state => state.comments || {}; -const selectCommentsById = reselect.createSelector(selectState$7, state => state.byId || {}); +const selectCommentsById = reselect.createSelector(selectState$8, state => state.byId || {}); -const selectCommentsByUri = reselect.createSelector(selectState$7, state => { +const selectCommentsByUri = reselect.createSelector(selectState$8, state => { const byUri = state.commentsByUri || {}; const comments = {}; Object.keys(byUri).forEach(uri => { @@ -4682,78 +4741,6 @@ const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsBy return byId && byId[claimId]; }); -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$8 = state => state.publish || {}; - -const selectPublishFormValues = reselect.createSelector(selectState$8, state => { - const formValues = _objectWithoutProperties$1(state, ['pendingPublish']); - return formValues; -}); -const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, publishState => { - const { editingURI, uri } = publishState; - - if (!editingURI || !uri) { - return false; - } - - const { isChannel: currentIsChannel, claimName: currentClaimName, contentName: currentContentName } = parseURI(uri); - const { isChannel: editIsChannel, claimName: editClaimName, contentName: editContentName } = parseURI(editingURI); - - // Depending on the previous/current use of a channel, we need to compare different things - // ex: going from a channel to anonymous, the new uri won't return contentName, so we need to use claimName - const currentName = currentIsChannel ? currentContentName : currentClaimName; - const editName = editIsChannel ? editContentName : editClaimName; - return currentName === editName; -}); - -const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, selectIsStillEditing, selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => { - const { contentName, claimName } = parseURI(uri); - const { claimId: editClaimId } = parseURI(editingURI); - - // If isStillEditing - // They clicked "edit" from the file page - // They haven't changed the channel/name after clicking edit - // Get the claim so they can edit without re-uploading a new file - return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName); -}); - -const selectIsResolvingPublishUris = reselect.createSelector(selectState$8, selectResolvingUris, ({ uri, name }, resolvingUris) => { - if (uri) { - const isResolvingUri = resolvingUris.includes(uri); - const { isChannel } = parseURI(uri); - - let isResolvingShortUri; - if (isChannel) { - const shortUri = buildURI({ contentName: name }); - isResolvingShortUri = resolvingUris.includes(shortUri); - } - - return isResolvingUri || isResolvingShortUri; - } - - return false; -}); - -const selectTakeOverAmount = reselect.createSelector(selectState$8, selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => { - // We only care about the winning claim for the short uri - const shortUri = buildURI({ contentName: name }); - const claimForShortUri = claimsByUri[shortUri]; - - if (!myClaimForUri && claimForShortUri) { - return claimForShortUri.effective_amount; - } else if (myClaimForUri && claimForShortUri) { - // https://github.com/lbryio/lbry/issues/1476 - // We should check the current effective_amount on my claim to see how much additional lbc - // is needed to win the claim. Currently this is not possible during a takeover. - // With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim" - // For now just ignore supports. We will just show the winning claim's bid amount - return claimForShortUri.effective_amount || claimForShortUri.amount; - } - - return null; -}); - // const selectState$9 = state => state.tags || {}; @@ -4888,6 +4875,7 @@ exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectPendingByUri = makeSelectPendingByUri; +exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; exports.makeSelectSearchUris = makeSelectSearchUris; diff --git a/dist/flow-typed/Publish.js b/dist/flow-typed/Publish.js index 0d1cc0a..4c48692 100644 --- a/dist/flow-typed/Publish.js +++ b/dist/flow-typed/Publish.js @@ -17,7 +17,7 @@ declare type UpdatePublishFormData = { channelId?: string, name?: string, nameError?: string, - bid?: number, + bid?: string, bidError?: string, otherLicenseDescription?: string, licenseUrl?: string, @@ -25,7 +25,7 @@ declare type UpdatePublishFormData = { uri?: string, nsfw: boolean, }; - +// This was only used when we were passing params instead of selecting them declare type PublishParams = { name: ?string, bid: ?number, diff --git a/flow-typed/Publish.js b/flow-typed/Publish.js index 0d1cc0a..4c48692 100644 --- a/flow-typed/Publish.js +++ b/flow-typed/Publish.js @@ -17,7 +17,7 @@ declare type UpdatePublishFormData = { channelId?: string, name?: string, nameError?: string, - bid?: number, + bid?: string, bidError?: string, otherLicenseDescription?: string, licenseUrl?: string, @@ -25,7 +25,7 @@ declare type UpdatePublishFormData = { uri?: string, nsfw: boolean, }; - +// This was only used when we were passing params instead of selecting them declare type PublishParams = { name: ?string, bid: ?number, diff --git a/src/index.js b/src/index.js index 5cbdb71..07a30dd 100644 --- a/src/index.js +++ b/src/index.js @@ -221,6 +221,7 @@ export { } from 'redux/selectors/file_info'; export { + makeSelectPublishFormValue, selectPublishFormValues, selectIsStillEditing, selectMyClaimForUri, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index f6fbd95..34e1be3 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -1,7 +1,7 @@ // @flow import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; -import { normalizeURI, parseURI } from 'lbryURI'; +import { normalizeURI } from 'lbryURI'; import { doToast } from 'redux/actions/notifications'; import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux/selectors/claims'; import { doFetchTransactions } from 'redux/actions/wallet'; @@ -348,7 +348,11 @@ export function doClaimSearch(options: { page_size?: number, page?: number } = { } // tags can be one or many (comma separated) -export function doClaimSearchByTags(tags: Array, amount: number = 10, options: { page?: number } = {}) { +export function doClaimSearchByTags( + tags: Array, + amount: number = 10, + options: { page?: number } = {} +) { return (dispatch: Dispatch) => { const tagList = createNormalizedTagKey(tags); dispatch({ diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index ad98252..a8f6bb9 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -1,7 +1,6 @@ // @flow import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/licenses'; import * as ACTIONS from 'constants/action_types'; -//import * as MODALS from 'constants/modal_types'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import Lbry from 'lbry'; import { batchActions } from 'util/batchActions'; @@ -13,6 +12,15 @@ import { selectPendingById, selectMyClaimsWithoutChannels, } from 'redux/selectors/claims'; +import { + selectPublishFormValues, + selectMyClaimForUri, +} from 'redux/selectors/publish'; +// @if TARGET='app' +import fs from 'fs'; +import path from 'path'; +// @endif + import { formatLbryUriForWeb } from 'util/uri'; export const doResetThumbnailStatus = () => (dispatch: Dispatch) => { @@ -84,7 +92,7 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, doError(error) ) ); - } + }; dispatch({ type: ACTIONS.UPDATE_PUBLISH_FORM, @@ -100,21 +108,22 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, const data = new FormData(); const name = makeid(); data.append('name', name); + // $FlowFixMe data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); return fetch('https://spee.ch/api/claim/publish', { method: 'POST', - body: data + body: data, }).then(response => response.json()) .then(json => json.success - ? dispatch({ - type: ACTIONS.UPDATE_PUBLISH_FORM, - data: { - uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, - thumbnail: `${json.data.url}${fileExt}`, - }, - }) - : uploadError(json.message) + ? dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, + thumbnail: `${json.data.url}${fileExt}`, + }, + }) + : uploadError(json.message) ) .catch(err => uploadError(err.message)); }); @@ -147,12 +156,12 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, .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)); @@ -160,15 +169,15 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, }; export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem) => (dispatch: Dispatch) => { - const { name, amount, channel_name: channelName, value } = claim; - + const { name, amount, value } = claim; + const channelName = (claim && claim.signing_channel && claim.signing_channel.normalized_name) || null; const { author, description, // use same values as default state // fee will be undefined for free content fee = { - amount: 0, + amount: '0', currency: 'LBC', }, languages, @@ -180,7 +189,6 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis const publishData: UpdatePublishFormData = { name, - channel: channelName, bid: amount, contentIsFree: !fee.amount, author, @@ -210,6 +218,9 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis } else { publishData.licenseType = license; } + if (channelName) { + publishData['channel'] = channelName; + } if (fileInfo && fileInfo.download_path) { try { @@ -223,13 +234,17 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData }); }; -export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getState: () => {}) => { +export const doPublish = (success: Function, fail: Function) => (dispatch: Dispatch, getState: () => {}) => { dispatch({ type: ACTIONS.PUBLISH_START }); const state = getState(); + const myClaimForUri = selectMyClaimForUri(state); const myChannels = selectMyChannelClaims(state); const myClaims = selectMyClaimsWithoutChannels(state); + // get redux publish form + const publishData = selectPublishFormValues(state); + // destructure the data values const { name, bid, @@ -238,6 +253,8 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat language, license, licenseUrl, + licenseType, + otherLicenseDescription, thumbnail, channel, title, @@ -245,8 +262,20 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat fee, uri, nsfw, - claim, - } = params; + // claim, + tags, + locations, + } = publishData; + + let publishingLicense; + switch (licenseType) { + case COPYRIGHT: + case OTHER: + publishingLicense = otherLicenseDescription; + break; + default: + publishingLicense = licenseType; + } // get the claim id from the channel name, we will use that instead const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); @@ -254,31 +283,39 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat const publishPayload: { name: ?string, + bid: string, + description?: string, channel_id?: string, - bid: number, file_path?: string, - tags: Array, - locations?: Array, + license_url?: string, + license?: string, thumbnail_url?: string, release_time?: number, fee_currency?: string, fee_amount?: string, + languages?: Array, + tags: Array, + locations?: Array, } = { name, - bid: creditsToString(bid), title, - license, - languages: [language], description, - tags: (claim && claim.value.tags) || [], - locations: claim && claim.value.locations, - }; + locations: locations, + bid: creditsToString(bid), + languages: [language], + tags: tags && tags.map(tag => tag.name), + thumbnail_url: thumbnail, + }; // Temporary solution to keep the same publish flow with the new tags api // Eventually we will allow users to enter their own tags on publish // `nsfw` will probably be removed + if (publishingLicense) { + publishPayload.license = publishingLicense; + } + if (licenseUrl) { publishPayload.license_url = licenseUrl; } @@ -287,8 +324,8 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat publishPayload.thumbnail_url = thumbnail; } - if (claim && claim.value.release_time) { - publishPayload.release_time = Number(claim.value.release_time); + if (myClaimForUri && myClaimForUri.value.release_time) { + publishPayload.release_time = Number(myClaimForUri.value.release_time); } if (nsfw) { @@ -315,43 +352,7 @@ export const doPublish = (params: PublishParams) => (dispatch: Dispatch, getStat // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; - const success = successResponse => { - //analytics.apiLogPublish(); - - const pendingClaim = successResponse.outputs[0]; - const actions = []; - - actions.push({ - type: ACTIONS.PUBLISH_SUCCESS, - }); - - //actions.push(doOpenModal(MODALS.PUBLISH, { uri })); - - // We have to fake a temp claim until the new pending one is returned by claim_list_mine - // We can't rely on claim_list_mine because there might be some delay before the new claims are returned - // Doing this allows us to show the pending claim immediately, it will get overwritten by the real one - const isMatch = claim => claim.claim_id === pendingClaim.claim_id; - const isEdit = myClaims.some(isMatch); - const myNewClaims = isEdit - ? myClaims.map(claim => (isMatch(claim) ? pendingClaim : claim)) - : myClaims.concat(pendingClaim); - - actions.push({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims: myNewClaims, - }, - }); - - dispatch(batchActions(...actions)); - }; - - const failure = error => { - dispatch({ type: ACTIONS.PUBLISH_FAIL }); - dispatch(doError(error.message)); - }; - - return Lbry.publish(publishPayload).then(success, failure); + return Lbry.publish(publishPayload).then(success, fail); }; // Calls claim_list_mine until any pending publishes are confirmed @@ -367,21 +368,22 @@ export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetS const checkFileList = () => { Lbry.claim_list().then(claims => { + // $FlowFixMe claims.forEach(claim => { // If it's confirmed, check if it was pending previously if (claim.confirmations > 0 && pendingById[claim.claim_id]) { delete pendingById[claim.claim_id]; - + // TODO fix notifications - pass as param as well? // If it's confirmed, check if we should notify the user - if (selectosNotificationsEnabled(getState())) { - const notif = new window.Notification('LBRY Publish Complete', { - body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, - silent: false, - }); - notif.onclick = () => { - dispatch(push(formatLbryUriForWeb(claim.permanent_url))); - }; - } + // if (selectosNotificationsEnabled(getState())) { + // const notif = new window.Notification('LBRY Publish Complete', { + // body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, + // silent: false, + // }); + // notif.onclick = () => { + // dispatch(push(formatLbryUriForWeb(claim.permanent_url))); + // }; + // } } }); diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js index 310a2ff..9cf1aae 100644 --- a/src/redux/reducers/publish.js +++ b/src/redux/reducers/publish.js @@ -27,6 +27,7 @@ type PublishState = { bidError: ?string, otherLicenseDescription: string, licenseUrl: string, + tags: Array }; const defaultState: PublishState = { @@ -53,6 +54,7 @@ const defaultState: PublishState = { licenseType: 'None', otherLicenseDescription: 'All rights reserved', licenseUrl: '', + tags: [], publishing: false, publishSuccess: false, publishError: undefined, diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index 893a66f..37f0dab 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -17,6 +17,12 @@ export const selectPublishFormValues = createSelector( } ); +export const makeSelectPublishFormValue = item => + createSelector( + selectState, + state => state[item] + ); + // Is the current uri the same as the uri they clicked "edit" on export const selectIsStillEditing = createSelector( selectPublishFormValues, @@ -54,8 +60,8 @@ export const selectMyClaimForUri = createSelector( return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => - !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName - ); + !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName + ); } ); -- 2.45.2 From d1048ff8350de88145e9c532db424cef4703e139 Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 12 Jul 2019 21:33:28 -0400 Subject: [PATCH 078/371] adds notification callback to doCheckPendingPublishes --- dist/bundle.es.js | 15 ++----- src/redux/actions/publish.js | 80 +++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 48 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3bdbd0e..4dee9f3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3161,7 +3161,7 @@ const doPublish = (success, fail) => (dispatch, getState) => { }; // Calls claim_list_mine until any pending publishes are confirmed -const doCheckPendingPublishes = () => (dispatch, getState) => { +const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { const state = getState(); const pendingById = selectPendingById(state); @@ -3179,16 +3179,9 @@ const doCheckPendingPublishes = () => (dispatch, getState) => { if (claim.confirmations > 0 && pendingById[claim.claim_id]) { delete pendingById[claim.claim_id]; // TODO fix notifications - pass as param as well? - // If it's confirmed, check if we should notify the user - // if (selectosNotificationsEnabled(getState())) { - // const notif = new window.Notification('LBRY Publish Complete', { - // body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, - // silent: false, - // }); - // notif.onclick = () => { - // dispatch(push(formatLbryUriForWeb(claim.permanent_url))); - // }; - // } + if (onConfirmed) { + onConfirmed(claim); + } } }); diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index a8f6bb9..4539dcb 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -12,10 +12,7 @@ import { selectPendingById, selectMyClaimsWithoutChannels, } from 'redux/selectors/claims'; -import { - selectPublishFormValues, - selectMyClaimForUri, -} from 'redux/selectors/publish'; +import { selectPublishFormValues, selectMyClaimForUri } from 'redux/selectors/publish'; // @if TARGET='app' import fs from 'fs'; import path from 'path'; @@ -62,13 +59,19 @@ export const doClearPublish = () => (dispatch: Dispatch) => { return dispatch(doResetThumbnailStatus()); }; -export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => (dispatch: Dispatch) => +export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => ( + dispatch: Dispatch +) => dispatch({ type: ACTIONS.UPDATE_PUBLISH_FORM, data: { ...publishFormValue }, }); -export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, fsAdapter: any) => (dispatch: Dispatch) => { +export const doUploadThumbnail = ( + filePath: string, + thumbnailBuffer: Uint8Array, + fsAdapter: any +) => (dispatch: Dispatch) => { let thumbnail, fileExt, fileName, fileType; const makeid = () => { @@ -114,16 +117,18 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, return fetch('https://spee.ch/api/claim/publish', { method: 'POST', body: data, - }).then(response => response.json()) - .then(json => json.success - ? dispatch({ - type: ACTIONS.UPDATE_PUBLISH_FORM, - data: { - uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, - thumbnail: `${json.data.url}${fileExt}`, - }, - }) - : uploadError(json.message) + }) + .then(response => response.json()) + .then(json => + json.success + ? dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, + thumbnail: `${json.data.url}${fileExt}`, + }, + }) + : uploadError(json.message) ) .catch(err => uploadError(err.message)); }); @@ -156,21 +161,24 @@ export const doUploadThumbnail = (filePath: string, thumbnailBuffer: Uint8Array, .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)); } }; -export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem) => (dispatch: Dispatch) => { +export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem) => ( + dispatch: Dispatch +) => { const { name, amount, value } = claim; - const channelName = (claim && claim.signing_channel && claim.signing_channel.normalized_name) || null; + const channelName = + (claim && claim.signing_channel && claim.signing_channel.normalized_name) || null; const { author, description, @@ -234,7 +242,10 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData }); }; -export const doPublish = (success: Function, fail: Function) => (dispatch: Dispatch, getState: () => {}) => { +export const doPublish = (success: Function, fail: Function) => ( + dispatch: Dispatch, + getState: () => {} +) => { dispatch({ type: ACTIONS.PUBLISH_START }); const state = getState(); @@ -306,7 +317,6 @@ export const doPublish = (success: Function, fail: Function) => (dispatch: Dispa languages: [language], tags: tags && tags.map(tag => tag.name), thumbnail_url: thumbnail, - }; // Temporary solution to keep the same publish flow with the new tags api // Eventually we will allow users to enter their own tags on publish @@ -356,7 +366,10 @@ export const doPublish = (success: Function, fail: Function) => (dispatch: Dispa }; // Calls claim_list_mine until any pending publishes are confirmed -export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetState) => { +export const doCheckPendingPublishes = (onConfirmed: Function) => ( + dispatch: Dispatch, + getState: GetState +) => { const state = getState(); const pendingById = selectPendingById(state); @@ -374,16 +387,9 @@ export const doCheckPendingPublishes = () => (dispatch: Dispatch, getState: GetS if (claim.confirmations > 0 && pendingById[claim.claim_id]) { delete pendingById[claim.claim_id]; // TODO fix notifications - pass as param as well? - // If it's confirmed, check if we should notify the user - // if (selectosNotificationsEnabled(getState())) { - // const notif = new window.Notification('LBRY Publish Complete', { - // body: `${claim.value.title} has been published to lbry://${claim.name}. Click here to view it`, - // silent: false, - // }); - // notif.onclick = () => { - // dispatch(push(formatLbryUriForWeb(claim.permanent_url))); - // }; - // } + if (onConfirmed) { + onConfirmed(claim); + } } }); -- 2.45.2 From 99f2e8e92f7742abd1ba4789fdbe744274dced97 Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 12 Jul 2019 23:01:16 -0400 Subject: [PATCH 079/371] cleanup --- dist/bundle.es.js | 7 +------ src/redux/actions/publish.js | 8 +------- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4dee9f3..d047cd5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2863,8 +2863,6 @@ const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClai return null; }); -// - var _extends$4 = 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; }; const doResetThumbnailStatus = () => dispatch => { @@ -3024,7 +3022,7 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { nsfw: isClaimNsfw(claim) }; - // Make sure custom liscence's are mapped properly + // Make sure custom licenses are mapped properly // If the license isn't one of the standard licenses, map the custom license and description/url if (!CC_LICENSES.some(({ value }) => value === license)) { if (!license || license === NONE || license === PUBLIC_DOMAIN) { @@ -3083,7 +3081,6 @@ const doPublish = (success, fail) => (dispatch, getState) => { fee, uri, nsfw, - // claim, tags, locations } = publishData; @@ -3111,7 +3108,6 @@ const doPublish = (success, fail) => (dispatch, getState) => { languages: [language], tags: tags && tags.map(tag => tag.name), thumbnail_url: thumbnail - }; // Temporary solution to keep the same publish flow with the new tags api // Eventually we will allow users to enter their own tags on publish @@ -3178,7 +3174,6 @@ const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { // If it's confirmed, check if it was pending previously if (claim.confirmations > 0 && pendingById[claim.claim_id]) { delete pendingById[claim.claim_id]; - // TODO fix notifications - pass as param as well? if (onConfirmed) { onConfirmed(claim); } diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 4539dcb..311531c 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -13,12 +13,8 @@ import { selectMyClaimsWithoutChannels, } from 'redux/selectors/claims'; import { selectPublishFormValues, selectMyClaimForUri } from 'redux/selectors/publish'; -// @if TARGET='app' import fs from 'fs'; import path from 'path'; -// @endif - -import { formatLbryUriForWeb } from 'util/uri'; export const doResetThumbnailStatus = () => (dispatch: Dispatch) => { dispatch({ @@ -211,7 +207,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis nsfw: isClaimNsfw(claim), }; - // Make sure custom liscence's are mapped properly + // Make sure custom licenses are mapped properly // If the license isn't one of the standard licenses, map the custom license and description/url if (!CC_LICENSES.some(({ value }) => value === license)) { if (!license || license === NONE || license === PUBLIC_DOMAIN) { @@ -273,7 +269,6 @@ export const doPublish = (success: Function, fail: Function) => ( fee, uri, nsfw, - // claim, tags, locations, } = publishData; @@ -386,7 +381,6 @@ export const doCheckPendingPublishes = (onConfirmed: Function) => ( // If it's confirmed, check if it was pending previously if (claim.confirmations > 0 && pendingById[claim.claim_id]) { delete pendingById[claim.claim_id]; - // TODO fix notifications - pass as param as well? if (onConfirmed) { onConfirmed(claim); } -- 2.45.2 From 09ed2b5d18d19796c36ff25e68034c50188cd2e0 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 29 Jul 2019 14:42:28 -0400 Subject: [PATCH 080/371] bring in desktop publish changes --- dist/bundle.es.js | 19 +++++----------- dist/flow-typed/Publish.js | 24 -------------------- flow-typed/Publish.js | 24 -------------------- src/redux/actions/publish.js | 43 +++++++++++++++--------------------- 4 files changed, 24 insertions(+), 86 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d047cd5..f7b480f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3009,10 +3009,10 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { const publishData = { name, bid: amount, - contentIsFree: !fee.amount, + contentIsFree: fee.amount === '0', author, description, - fee: { amount: fee.amount, currency: fee.currency }, + fee, languages, thumbnail: thumbnail ? thumbnail.url : null, title, @@ -3080,7 +3080,6 @@ const doPublish = (success, fail) => (dispatch, getState) => { contentIsFree, fee, uri, - nsfw, tags, locations } = publishData; @@ -3125,19 +3124,13 @@ const doPublish = (success, fail) => (dispatch, getState) => { publishPayload.thumbnail_url = thumbnail; } + // Set release time to curret date. On edits, keep original release/transaction time as release_time if (myClaimForUri && myClaimForUri.value.release_time) { publishPayload.release_time = Number(myClaimForUri.value.release_time); - } - - if (nsfw) { - if (!publishPayload.tags.includes('mature')) { - publishPayload.tags.push('mature'); - } + } else if (myClaimForUri && myClaimForUri.timestamp) { + publishPayload.release_time = Number(myClaimForUri.timestamp); } else { - const indexToRemove = publishPayload.tags.indexOf('mature'); - if (indexToRemove > -1) { - publishPayload.tags.splice(indexToRemove, 1); - } + publishPayload.release_time = Number(Math.round(Date.now() / 1000)); } if (channelId) { diff --git a/dist/flow-typed/Publish.js b/dist/flow-typed/Publish.js index 4c48692..87955ae 100644 --- a/dist/flow-typed/Publish.js +++ b/dist/flow-typed/Publish.js @@ -25,27 +25,3 @@ declare type UpdatePublishFormData = { uri?: string, nsfw: boolean, }; -// This was only used when we were passing params instead of selecting them -declare type PublishParams = { - name: ?string, - bid: ?number, - filePath?: string, - description: ?string, - language: string, - publishingLicense?: string, - publishingLicenseUrl?: string, - thumbnail: ?string, - channel: string, - channelId?: string, - title: string, - contentIsFree: boolean, - uri?: string, - license: ?string, - licenseUrl: ?string, - fee?: { - amount: string, - currency: string, - }, - claim: StreamClaim, - nsfw: boolean, -}; diff --git a/flow-typed/Publish.js b/flow-typed/Publish.js index 4c48692..87955ae 100644 --- a/flow-typed/Publish.js +++ b/flow-typed/Publish.js @@ -25,27 +25,3 @@ declare type UpdatePublishFormData = { uri?: string, nsfw: boolean, }; -// This was only used when we were passing params instead of selecting them -declare type PublishParams = { - name: ?string, - bid: ?number, - filePath?: string, - description: ?string, - language: string, - publishingLicense?: string, - publishingLicenseUrl?: string, - thumbnail: ?string, - channel: string, - channelId?: string, - title: string, - contentIsFree: boolean, - uri?: string, - license: ?string, - licenseUrl: ?string, - fee?: { - amount: string, - currency: string, - }, - claim: StreamClaim, - nsfw: boolean, -}; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 311531c..95b2229 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -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)); @@ -194,10 +194,10 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis const publishData: UpdatePublishFormData = { name, bid: amount, - contentIsFree: !fee.amount, + contentIsFree: fee.amount === '0', author, description, - fee: { amount: fee.amount, currency: fee.currency }, + fee, languages, thumbnail: thumbnail ? thumbnail.url : null, title, @@ -268,7 +268,6 @@ export const doPublish = (success: Function, fail: Function) => ( contentIsFree, fee, uri, - nsfw, tags, locations, } = publishData; @@ -329,19 +328,13 @@ export const doPublish = (success: Function, fail: Function) => ( publishPayload.thumbnail_url = thumbnail; } + // Set release time to curret date. On edits, keep original release/transaction time as release_time if (myClaimForUri && myClaimForUri.value.release_time) { publishPayload.release_time = Number(myClaimForUri.value.release_time); - } - - if (nsfw) { - if (!publishPayload.tags.includes('mature')) { - publishPayload.tags.push('mature'); - } + } else if (myClaimForUri && myClaimForUri.timestamp) { + publishPayload.release_time = Number(myClaimForUri.timestamp); } else { - const indexToRemove = publishPayload.tags.indexOf('mature'); - if (indexToRemove > -1) { - publishPayload.tags.splice(indexToRemove, 1); - } + publishPayload.release_time = Number(Math.round(Date.now() / 1000)); } if (channelId) { -- 2.45.2 From b87e2f92f30b11942a40ddc09b5c0424360c8393 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 17 Jul 2019 16:50:58 -0400 Subject: [PATCH 081/371] 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, 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 -- 2.45.2 From 3e7b5d05c056dd831c04d848c0b71c983c36b8c3 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 17 Jul 2019 17:34:00 -0400 Subject: [PATCH 082/371] 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: {}, -- 2.45.2 From 8910693fe1fc4166fdc748d128344012c3d61874 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 29 Jul 2019 14:48:44 -0400 Subject: [PATCH 083/371] 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() { -- 2.45.2 From a1ae63d0b6c048248aa5615f814601616df15031 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 30 Jul 2019 11:48:45 -0400 Subject: [PATCH 084/371] 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, 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, 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, - 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, - fetchingClaimSearchByTags: { [string]: boolean }, - claimSearchUrisByTags: { [string]: { all: Array } }, + fetchingClaimSearchByQuery: { [string]: boolean }, + claimSearchByQuery: { [string]: Array }, claimsByChannel: { [string]: { all: Array, @@ -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) => - createSelector( - selectFetchingClaimSearchByTags, - byTags => byTags[createNormalizedTagKey(tags)] - ); - -export const makeSelectClaimSearchUrisForTags = (tags: Array) => - 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 => { - 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; +} -- 2.45.2 From c04f6806f7fb3eb77a19ede8651d1498eccfe16c Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 30 Jul 2019 12:00:36 -0400 Subject: [PATCH 085/371] 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(); } ); -- 2.45.2 From 3266ebd933bc4af5e24c62c3ca956b5ee967db32 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 30 Jul 2019 12:04:04 -0400 Subject: [PATCH 086/371] 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 ''; - } - } -); -- 2.45.2 From b257431eae9ff2e3bdb1db7fd7cee389cd8b7fd9 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 30 Jul 2019 12:15:29 -0400 Subject: [PATCH 087/371] 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}$/; /** -- 2.45.2 From 2c70556bdfcc4abfffc1a4df9fa410d34638915d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 31 Jul 2019 15:03:56 -0400 Subject: [PATCH 088/371] 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(); -- 2.45.2 From 250f5003d9e3cce1c150f3fa7dfac11ec43bc306 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 31 Jul 2019 15:14:51 -0400 Subject: [PATCH 089/371] fix typo --- dist/bundle.es.js | 6 +++--- src/index.js | 2 +- src/redux/selectors/claims.js | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e80bf8e..ba4e814 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1561,9 +1561,9 @@ const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataFo return metadata && metadata.tags || []; }); -const selectfetchingClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.fetchingClaimSearchByQuery || {}); +const selectFetchingClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.fetchingClaimSearchByQuery || {}); -const selectFetchingClaimSearch = reselect.createSelector(selectfetchingClaimSearchByQuery, fetchingClaimSearchByQuery => Boolean(Object.keys(fetchingClaimSearchByQuery).length)); +const selectFetchingClaimSearch = reselect.createSelector(selectFetchingClaimSearchByQuery, fetchingClaimSearchByQuery => Boolean(Object.keys(fetchingClaimSearchByQuery).length)); const selectClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.claimSearchByQuery || {}); @@ -4844,6 +4844,7 @@ exports.selectDraftTransactionError = selectDraftTransactionError; exports.selectError = selectError; exports.selectFailedPurchaseUris = selectFailedPurchaseUris; exports.selectFetchingClaimSearch = selectFetchingClaimSearch; +exports.selectFetchingClaimSearchByQuery = selectFetchingClaimSearchByQuery; exports.selectFetchingMyChannels = selectFetchingMyChannels; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; @@ -4907,7 +4908,6 @@ 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 05690a8..c2016be 100644 --- a/src/index.js +++ b/src/index.js @@ -192,7 +192,7 @@ export { selectChannelClaimCounts, selectCurrentChannelPage, selectFetchingClaimSearch, - selectfetchingClaimSearchByQuery, + selectFetchingClaimSearchByQuery, selectClaimSearchByQuery, } from 'redux/selectors/claims'; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index c9dc1ac..7c477dc 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -500,13 +500,13 @@ export const makeSelectTagsForUri = (uri: string) => } ); -export const selectfetchingClaimSearchByQuery = createSelector( +export const selectFetchingClaimSearchByQuery = createSelector( selectState, state => state.fetchingClaimSearchByQuery || {} ); export const selectFetchingClaimSearch = createSelector( - selectfetchingClaimSearchByQuery, + selectFetchingClaimSearchByQuery, fetchingClaimSearchByQuery => Boolean(Object.keys(fetchingClaimSearchByQuery).length) ); -- 2.45.2 From 8406e8c25e88c67d725f791eedf400995ff388b2 Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 26 Jul 2019 10:45:14 -0400 Subject: [PATCH 090/371] supports user channel block uri list --- dist/flow-typed/Blocklist.js | 10 +++++++++ flow-typed/Blocklist.js | 10 +++++++++ src/constants/action_types.js | 2 ++ src/index.js | 5 +++++ src/redux/actions/blocked.js | 9 ++++++++ src/redux/reducers/blocked.js | 29 ++++++++++++++++++++++++ src/redux/selectors/blocked.js | 14 ++++++++++++ src/redux/selectors/file_info.js | 38 ++++++++++++++++---------------- 8 files changed, 98 insertions(+), 19 deletions(-) create mode 100644 dist/flow-typed/Blocklist.js create mode 100644 flow-typed/Blocklist.js create mode 100644 src/redux/actions/blocked.js create mode 100644 src/redux/reducers/blocked.js create mode 100644 src/redux/selectors/blocked.js diff --git a/dist/flow-typed/Blocklist.js b/dist/flow-typed/Blocklist.js new file mode 100644 index 0000000..454a714 --- /dev/null +++ b/dist/flow-typed/Blocklist.js @@ -0,0 +1,10 @@ +declare type BlocklistState = { + blockedChannels: Array +}; + +declare type BlocklistAction = { + type: string, + data: { + uri: string, + }, +}; diff --git a/flow-typed/Blocklist.js b/flow-typed/Blocklist.js new file mode 100644 index 0000000..454a714 --- /dev/null +++ b/flow-typed/Blocklist.js @@ -0,0 +1,10 @@ +declare type BlocklistState = { + blockedChannels: Array +}; + +declare type BlocklistAction = { + type: string, + data: { + uri: string, + }, +}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index d4e3a3e..b75997b 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -235,3 +235,5 @@ export const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; export const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; export const TAG_ADD = 'TAG_ADD'; export const TAG_DELETE = 'TAG_DELETE'; +// Blocked Channels +export const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; diff --git a/src/index.js b/src/index.js index c2016be..8f03f36 100644 --- a/src/index.js +++ b/src/index.js @@ -111,6 +111,8 @@ export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; export { doCommentList, doCommentCreate } from 'redux/actions/comments'; +export { doToggleBlockChannel } from 'redux/actions/blocked'; + // utils export { batchActions } from 'util/batch-actions'; export { parseQueryParams, toQueryString } from 'util/query-params'; @@ -127,6 +129,7 @@ export { notificationsReducer } from 'redux/reducers/notifications'; export { publishReducer } from 'redux/reducers/publish'; export { searchReducer } from 'redux/reducers/search'; export { tagsReducer } from 'redux/reducers/tags'; +export { blockChannelReducer } from 'redux/reducers/blocked'; export { walletReducer } from 'redux/reducers/wallet'; // selectors @@ -269,3 +272,5 @@ export { } from 'redux/selectors/wallet'; export { selectFollowedTags, selectUnfollowedTags } from 'redux/selectors/tags'; + +export { selectBlockedChannels, selectChannelIsBlocked } from 'redux/selectors/blocked'; diff --git a/src/redux/actions/blocked.js b/src/redux/actions/blocked.js new file mode 100644 index 0000000..1e96563 --- /dev/null +++ b/src/redux/actions/blocked.js @@ -0,0 +1,9 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; + +export const doToggleBlockChannel = (uri: string) => ({ + type: ACTIONS.TOGGLE_BLOCK_CHANNEL, + data: { + uri, + }, +}); diff --git a/src/redux/reducers/blocked.js b/src/redux/reducers/blocked.js new file mode 100644 index 0000000..92f9200 --- /dev/null +++ b/src/redux/reducers/blocked.js @@ -0,0 +1,29 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; +import { handleActions } from 'util/redux-utils'; + +const defaultState: BlocklistState = { + blockedChannels: [], +} + +export const blockChannelReducer = handleActions( + { + [ACTIONS.TOGGLE_BLOCK_CHANNEL]: (state: BlocklistState, action: BlocklistAction): BlocklistState => { + const { blockedChannels } = state; + const { uri } = action.data; + console.log('test', uri) + let newBlockedChannels = blockedChannels.slice(); + + if (newBlockedChannels.includes(uri)) { + newBlockedChannels = newBlockedChannels.filter(id => id !== uri); + } else { + newBlockedChannels.push(uri); + } + + return { + blockedChannels: newBlockedChannels, + }; + }, + }, + defaultState +); diff --git a/src/redux/selectors/blocked.js b/src/redux/selectors/blocked.js new file mode 100644 index 0000000..7ab7af5 --- /dev/null +++ b/src/redux/selectors/blocked.js @@ -0,0 +1,14 @@ +// @flow +import { createSelector } from 'reselect'; + +const selectState = (state: { blockedChannels: BlocklistState }) => state.blockedChannels || {}; + +export const selectBlockedChannels = createSelector( + selectState, + (state: BlocklistState) => state +); + +export const selectChannelIsBlocked = (uri: string) => createSelector( + selectState, + (state: BlocklistState) => { return state.blockedChannels.includes(uri) } +); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 8133733..f323734 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -190,31 +190,31 @@ export const selectSearchDownloadUris = query => return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(fileInfo => { - const { - channel_name: channelName, - claim_id: claimId, - claim_name: claimName, - } = fileInfo; + const { + channel_name: channelName, + claim_id: claimId, + claim_name: claimName, + } = fileInfo; - const uriParams = {}; + const uriParams = {}; - if (channelName) { - const claim = claimsById[claimId]; - if (claim && claim.signing_channel) { - uriParams.claimId = claim.signing_channel.claim_id; - } else { - uriParams.claimId = claimId; - } - uriParams.channelName = channelName; - uriParams.contentName = claimName; + if (channelName) { + const claim = claimsById[claimId]; + if (claim && claim.signing_channel) { + uriParams.claimId = claim.signing_channel.claim_id; } else { uriParams.claimId = claimId; - uriParams.claimName = claimName; } + uriParams.channelName = channelName; + uriParams.contentName = claimName; + } else { + uriParams.claimId = claimId; + uriParams.claimName = claimName; + } - const uri = buildURI(uriParams); - return uri; - }) + const uri = buildURI(uriParams); + return uri; + }) : null; } ); -- 2.45.2 From d41a2a8a30428360af6cbe123c9500f4d75814c7 Mon Sep 17 00:00:00 2001 From: jessop Date: Sun, 28 Jul 2019 23:24:31 -0400 Subject: [PATCH 091/371] adds blocked channel count --- src/index.js | 2 +- src/redux/reducers/blocked.js | 1 - src/redux/selectors/blocked.js | 7 ++++++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/index.js b/src/index.js index 8f03f36..1d28615 100644 --- a/src/index.js +++ b/src/index.js @@ -273,4 +273,4 @@ export { export { selectFollowedTags, selectUnfollowedTags } from 'redux/selectors/tags'; -export { selectBlockedChannels, selectChannelIsBlocked } from 'redux/selectors/blocked'; +export { selectBlockedChannels, selectChannelIsBlocked, selectBlockedChannelsCount } from 'redux/selectors/blocked'; diff --git a/src/redux/reducers/blocked.js b/src/redux/reducers/blocked.js index 92f9200..dc90d01 100644 --- a/src/redux/reducers/blocked.js +++ b/src/redux/reducers/blocked.js @@ -11,7 +11,6 @@ export const blockChannelReducer = handleActions( [ACTIONS.TOGGLE_BLOCK_CHANNEL]: (state: BlocklistState, action: BlocklistAction): BlocklistState => { const { blockedChannels } = state; const { uri } = action.data; - console.log('test', uri) let newBlockedChannels = blockedChannels.slice(); if (newBlockedChannels.includes(uri)) { diff --git a/src/redux/selectors/blocked.js b/src/redux/selectors/blocked.js index 7ab7af5..a5946a8 100644 --- a/src/redux/selectors/blocked.js +++ b/src/redux/selectors/blocked.js @@ -5,7 +5,12 @@ const selectState = (state: { blockedChannels: BlocklistState }) => state.blocke export const selectBlockedChannels = createSelector( selectState, - (state: BlocklistState) => state + (state: BlocklistState) => state.blockedChannels +); + +export const selectBlockedChannelsCount = createSelector( + selectState, + (state: BlocklistState) => state.blockedChannels.length ); export const selectChannelIsBlocked = (uri: string) => createSelector( -- 2.45.2 From e25af99fb8f635ce3bae278ad574f75f6ce49c23 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 1 Aug 2019 20:57:27 -0400 Subject: [PATCH 092/371] bundle --- dist/bundle.es.js | 59 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ba4e814..e744b19 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -260,6 +260,8 @@ const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; const TAG_ADD = 'TAG_ADD'; const TAG_DELETE = 'TAG_DELETE'; +// Blocked Channels +const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; var action_types = /*#__PURE__*/Object.freeze({ WINDOW_FOCUSED: WINDOW_FOCUSED, @@ -466,7 +468,8 @@ var action_types = /*#__PURE__*/Object.freeze({ FETCH_COST_INFO_FAILED: FETCH_COST_INFO_FAILED, TOGGLE_TAG_FOLLOW: TOGGLE_TAG_FOLLOW, TAG_ADD: TAG_ADD, - TAG_DELETE: TAG_DELETE + TAG_DELETE: TAG_DELETE, + TOGGLE_BLOCK_CHANNEL: TOGGLE_BLOCK_CHANNEL }); const CC_LICENSES = [{ @@ -3432,6 +3435,15 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { }; } +// + +const doToggleBlockChannel = uri => ({ + type: TOGGLE_BLOCK_CHANNEL, + data: { + uri + } +}); + var _extends$5 = 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; }; const reducers = {}; @@ -4353,6 +4365,30 @@ const tagsReducer = handleActions({ } }, defaultState$8); +// + +const defaultState$9 = { + blockedChannels: [] +}; + +const blockChannelReducer = handleActions({ + [TOGGLE_BLOCK_CHANNEL]: (state, action) => { + const { blockedChannels } = state; + const { uri } = action.data; + let newBlockedChannels = blockedChannels.slice(); + + if (newBlockedChannels.includes(uri)) { + newBlockedChannels = newBlockedChannels.filter(id => id !== uri); + } else { + newBlockedChannels.push(uri); + } + + return { + blockedChannels: newBlockedChannels + }; + } +}, defaultState$9); + var _extends$e = 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; }; const buildDraftTransaction = () => ({ @@ -4364,7 +4400,7 @@ const buildDraftTransaction = () => ({ // See details in https://github.com/lbryio/lbry/issues/1307 -const defaultState$9 = { +const defaultState$a = { balance: undefined, totalBalance: undefined, latestBlock: undefined, @@ -4607,7 +4643,7 @@ const walletReducer = handleActions({ [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$e({}, state, { latestBlock: action.data }) -}, defaultState$9); +}, defaultState$a); const selectState$6 = state => state.content || {}; @@ -4695,6 +4731,18 @@ const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, sele return tagsToReturn; }); +// + +const selectState$a = state => state.blockedChannels || {}; + +const selectBlockedChannels = reselect.createSelector(selectState$a, state => state.blockedChannels); + +const selectBlockedChannelsCount = reselect.createSelector(selectState$a, state => state.blockedChannels.length); + +const selectChannelIsBlocked = uri => reselect.createSelector(selectState$a, state => { + return state.blockedChannels.includes(uri); +}); + exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; exports.DEFAULT_FOLLOWED_TAGS = DEFAULT_FOLLOWED_TAGS; @@ -4710,6 +4758,7 @@ exports.SORT_OPTIONS = sort_options; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; exports.batchActions = batchActions; +exports.blockChannelReducer = blockChannelReducer; exports.buildURI = buildURI; exports.claimsReducer = claimsReducer; exports.commentReducer = commentReducer; @@ -4757,6 +4806,7 @@ exports.doSetDraftTransactionAmount = doSetDraftTransactionAmount; exports.doSetFileListSort = doSetFileListSort; exports.doSetTransactionListFilter = doSetTransactionListFilter; exports.doToast = doToast; +exports.doToggleBlockChannel = doToggleBlockChannel; exports.doToggleTagFollow = doToggleTagFollow; exports.doTotalBalanceSubscribe = doTotalBalanceSubscribe; exports.doUpdateBalance = doUpdateBalance; @@ -4828,8 +4878,11 @@ exports.selectAllClaimsByChannel = selectAllClaimsByChannel; exports.selectAllFetchingChannelClaims = selectAllFetchingChannelClaims; exports.selectAllMyClaimsByOutpoint = selectAllMyClaimsByOutpoint; exports.selectBalance = selectBalance; +exports.selectBlockedChannels = selectBlockedChannels; +exports.selectBlockedChannelsCount = selectBlockedChannelsCount; exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; +exports.selectChannelIsBlocked = selectChannelIsBlocked; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; -- 2.45.2 From 8f12baa88f6f057eb3b7d0cf04d6e4bb0eb11763 Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 2 Aug 2019 10:56:32 -0400 Subject: [PATCH 093/371] changes after review --- dist/bundle.es.js | 12 ++++++------ src/index.js | 8 ++++++-- src/redux/reducers/blocked.js | 9 ++++++--- src/redux/selectors/blocked.js | 17 ++++++++++------- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e744b19..c138c15 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4371,7 +4371,7 @@ const defaultState$9 = { blockedChannels: [] }; -const blockChannelReducer = handleActions({ +const blockedReducer = handleActions({ [TOGGLE_BLOCK_CHANNEL]: (state, action) => { const { blockedChannels } = state; const { uri } = action.data; @@ -4733,14 +4733,14 @@ const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, sele // -const selectState$a = state => state.blockedChannels || {}; +const selectState$a = state => state.blocked || {}; const selectBlockedChannels = reselect.createSelector(selectState$a, state => state.blockedChannels); -const selectBlockedChannelsCount = reselect.createSelector(selectState$a, state => state.blockedChannels.length); +const selectBlockedChannelsCount = reselect.createSelector(selectBlockedChannels, state => state.length); -const selectChannelIsBlocked = uri => reselect.createSelector(selectState$a, state => { - return state.blockedChannels.includes(uri); +const selectChannelIsBlocked = uri => reselect.createSelector(selectBlockedChannels, state => { + return state.includes(uri); }); exports.ACTIONS = action_types; @@ -4758,7 +4758,7 @@ exports.SORT_OPTIONS = sort_options; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; exports.batchActions = batchActions; -exports.blockChannelReducer = blockChannelReducer; +exports.blockedReducer = blockedReducer; exports.buildURI = buildURI; exports.claimsReducer = claimsReducer; exports.commentReducer = commentReducer; diff --git a/src/index.js b/src/index.js index 1d28615..2f93891 100644 --- a/src/index.js +++ b/src/index.js @@ -129,7 +129,7 @@ export { notificationsReducer } from 'redux/reducers/notifications'; export { publishReducer } from 'redux/reducers/publish'; export { searchReducer } from 'redux/reducers/search'; export { tagsReducer } from 'redux/reducers/tags'; -export { blockChannelReducer } from 'redux/reducers/blocked'; +export { blockedReducer } from 'redux/reducers/blocked'; export { walletReducer } from 'redux/reducers/wallet'; // selectors @@ -273,4 +273,8 @@ export { export { selectFollowedTags, selectUnfollowedTags } from 'redux/selectors/tags'; -export { selectBlockedChannels, selectChannelIsBlocked, selectBlockedChannelsCount } from 'redux/selectors/blocked'; +export { + selectBlockedChannels, + selectChannelIsBlocked, + selectBlockedChannelsCount, +} from 'redux/selectors/blocked'; diff --git a/src/redux/reducers/blocked.js b/src/redux/reducers/blocked.js index dc90d01..4855fe0 100644 --- a/src/redux/reducers/blocked.js +++ b/src/redux/reducers/blocked.js @@ -4,11 +4,14 @@ import { handleActions } from 'util/redux-utils'; const defaultState: BlocklistState = { blockedChannels: [], -} +}; -export const blockChannelReducer = handleActions( +export const blockedReducer = handleActions( { - [ACTIONS.TOGGLE_BLOCK_CHANNEL]: (state: BlocklistState, action: BlocklistAction): BlocklistState => { + [ACTIONS.TOGGLE_BLOCK_CHANNEL]: ( + state: BlocklistState, + action: BlocklistAction + ): BlocklistState => { const { blockedChannels } = state; const { uri } = action.data; let newBlockedChannels = blockedChannels.slice(); diff --git a/src/redux/selectors/blocked.js b/src/redux/selectors/blocked.js index a5946a8..424ea89 100644 --- a/src/redux/selectors/blocked.js +++ b/src/redux/selectors/blocked.js @@ -1,7 +1,7 @@ // @flow import { createSelector } from 'reselect'; -const selectState = (state: { blockedChannels: BlocklistState }) => state.blockedChannels || {}; +const selectState = (state: { blocked: BlocklistState }) => state.blocked || {}; export const selectBlockedChannels = createSelector( selectState, @@ -9,11 +9,14 @@ export const selectBlockedChannels = createSelector( ); export const selectBlockedChannelsCount = createSelector( - selectState, - (state: BlocklistState) => state.blockedChannels.length + selectBlockedChannels, + (state: Array) => state.length ); -export const selectChannelIsBlocked = (uri: string) => createSelector( - selectState, - (state: BlocklistState) => { return state.blockedChannels.includes(uri) } -); +export const selectChannelIsBlocked = (uri: string) => + createSelector( + selectBlockedChannels, + (state: Array) => { + return state.includes(uri); + } + ); -- 2.45.2 From 9d71be9b1b21b1bd6e23ea092cd5cdef3796e83d Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 23 Jul 2019 12:22:26 -0400 Subject: [PATCH 094/371] [wip] range requests --- src/redux/actions/file.js | 2 +- src/redux/reducers/file_info.js | 4 +++- src/redux/selectors/file_info.js | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 337f85f..0afe464 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -55,7 +55,7 @@ export function doFileGet(uri: string, saveFile: boolean = true) { dispatch( doToast({ - message: `Failed to download ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`, + message: `Failed to view ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`, isError: true, }) ); diff --git a/src/redux/reducers/file_info.js b/src/redux/reducers/file_info.js index dbc5e86..5f20148 100644 --- a/src/redux/reducers/file_info.js +++ b/src/redux/reducers/file_info.js @@ -91,13 +91,15 @@ reducers[ACTIONS.DOWNLOADING_PROGRESSED] = (state, action) => { }; reducers[ACTIONS.DOWNLOADING_CANCELED] = (state, action) => { - const { outpoint } = action.data; + const { uri, outpoint } = action.data; const newDownloading = Object.assign({}, state.downloadingByOutpoint); delete newDownloading[outpoint]; + delete newLoading[uri]; return Object.assign({}, state, { downloadingByOutpoint: newDownloading, + urisLoading: newLoading, }); }; diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index f323734..7c045fe 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -72,7 +72,7 @@ export const selectFileInfosDownloaded = createSelector( return ( fileInfo && myClaimIds.indexOf(fileInfo.claim_id) === -1 && - (fileInfo.completed || fileInfo.written_bytes) + (fileInfo.completed || fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0 ) ); }) ); -- 2.45.2 From faf44023091c7a4d38c03076360ed348ea5b3522 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 2 Aug 2019 02:21:28 -0400 Subject: [PATCH 095/371] working? --- dist/bundle.es.js | 94 ++++++++++++++++++++++++-------- dist/flow-typed/Lbry.js | 2 +- flow-typed/Lbry.js | 2 +- package.json | 1 + src/index.js | 4 ++ src/lbry.js | 47 ++++++++++------ src/redux/actions/file.js | 27 +++++++-- src/redux/selectors/file.js | 9 ++- src/redux/selectors/file_info.js | 42 +++++++++++++- yarn.lock | 5 ++ 10 files changed, 181 insertions(+), 52 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c138c15..2177543 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5,6 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } require('proxy-polyfill'); +var mime = _interopDefault(require('mime')); var reselect = require('reselect'); var uuid = _interopDefault(require('uuid/v4')); var fs = _interopDefault(require('fs')); @@ -696,23 +697,30 @@ const Lbry = { }, // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk - getMediaType: (contentType, extname) => { - if (extname) { - const formats = [[/^(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/^(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/^(html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org)$/i, 'document'], [/^(stl|obj|fbx|gcode)$/i, '3D-file']]; + getMediaType: (contentType, fileName) => { + const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book']]; + + const extName = mime.getExtension(contentType); + const fileExt = extName ? `.${extName}` : null; + const testString = fileName || fileExt; + + // Get mediaType from file extension + if (testString) { const res = formats.reduce((ret, testpair) => { - switch (testpair[0].test(ret)) { - case true: - return testpair[1]; - default: - return ret; - } - }, extname); - return res === extname ? 'unknown' : res; - } else if (contentType) { - // $FlowFixMe + const [regex, mediaType] = testpair; + + return regex.test(ret) ? mediaType : ret; + }, testString); + + if (res !== testString) return res; + } + + // Get mediaType from contentType + if (contentType) { return (/^[^/]+/.exec(contentType)[0] ); } + return 'unknown'; }, @@ -2447,7 +2455,7 @@ const makeSelectLoadingForUri = uri => reselect.createSelector(selectUrisLoading const selectFileInfosDownloaded = reselect.createSelector(selectFileInfosByOutpoint, selectMyClaims, (byOutpoint, myClaims) => Object.values(byOutpoint).filter(fileInfo => { const myClaimIds = myClaims.map(claim => claim.claim_id); - return fileInfo && myClaimIds.indexOf(fileInfo.claim_id) === -1 && (fileInfo.completed || fileInfo.written_bytes); + return fileInfo && myClaimIds.indexOf(fileInfo.claim_id) === -1 && (fileInfo.completed || fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0); })); // export const selectFileInfoForUri = (state, props) => { @@ -2586,6 +2594,27 @@ const selectDownloadedUris = reselect.createSelector(selectFileInfosDownloaded, // We should use permament_url but it doesn't exist in file_list info => info.slice().reverse().map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)); +const makeSelectMediaTypeForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), makeSelectContentTypeForUri(uri), (fileInfo, contentType) => { + if (!fileInfo && !contentType) { + return undefined; + } + + const fileName = fileInfo && fileInfo.file_name; + return lbryProxy.getMediaType(contentType, fileName); +}); + +const makeSelectUriIsStreamable = uri => reselect.createSelector(makeSelectMediaTypeForUri(uri), mediaType => { + const isStreamable = ['audio', 'video', 'image'].indexOf(mediaType) !== -1; + return isStreamable; +}); + +const makeSelectDownloadPathForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { + return fileInfo && fileInfo.download_path; +}); +const makeSelectFileNameForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { + return fileInfo && fileInfo.file_name; +}); + // const selectState$4 = state => state.file || {}; @@ -2600,11 +2629,13 @@ const selectPurchasedStreamingUrls = reselect.createSelector(selectState$4, stat const selectLastPurchasedUri = reselect.createSelector(selectState$4, state => state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null); -const makeSelectStreamingUrlForUri = uri => reselect.createSelector(selectPurchasedStreamingUrls, streamingUrls => streamingUrls && streamingUrls[uri]); +const makeSelectStreamingUrlForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { + return fileInfo && fileInfo.streaming_url; +}); // -function doFileGet(uri, saveFile = true) { +function doFileGet(uri, saveFile = true, onSuccess) { return dispatch => { dispatch({ type: LOADING_FILE_STARTED, @@ -2615,7 +2646,7 @@ function doFileGet(uri, saveFile = true) { // set save_file argument to True to save the file (old behaviour) lbryProxy.get({ uri, save_file: saveFile }).then(streamInfo => { - const timeout = streamInfo === null || typeof streamInfo !== 'object'; + const timeout = streamInfo === null || typeof streamInfo !== 'object' || streamInfo.error === 'Timeout'; if (timeout) { dispatch({ @@ -2633,8 +2664,19 @@ function doFileGet(uri, saveFile = true) { const { streaming_url: streamingUrl } = streamInfo; dispatch({ type: PURCHASE_URI_COMPLETED, - data: { uri, streamingUrl: !saveFile && streamingUrl ? streamingUrl : null } + data: { uri, streamingUrl } }); + dispatch({ + type: FETCH_FILE_INFO_COMPLETED, + data: { + fileInfo: streamInfo, + outpoint: streamInfo.outpoint + } + }); + + if (onSuccess) { + onSuccess(streamInfo); + } } }).catch(() => { dispatch({ @@ -2647,14 +2689,14 @@ function doFileGet(uri, saveFile = true) { }); dispatch(doToast({ - message: `Failed to download ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`, + message: `Failed to view ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`, isError: true })); }); }; } -function doPurchaseUri(uri, costInfo, saveFile = true) { +function doPurchaseUri(uri, costInfo, saveFile = true, onSuccess) { return (dispatch, getState) => { dispatch({ type: PURCHASE_URI_STARTED, @@ -2685,7 +2727,7 @@ function doPurchaseUri(uri, costInfo, saveFile = true) { return; } - dispatch(doFileGet(uri, saveFile)); + dispatch(doFileGet(uri, saveFile, onSuccess)); }; } @@ -3921,13 +3963,15 @@ reducers$2[DOWNLOADING_PROGRESSED] = (state, action) => { }; reducers$2[DOWNLOADING_CANCELED] = (state, action) => { - const { outpoint } = action.data; + const { uri, outpoint } = action.data; const newDownloading = Object.assign({}, state.downloadingByOutpoint); delete newDownloading[outpoint]; + delete newLoading[uri]; return Object.assign({}, state, { - downloadingByOutpoint: newDownloading + downloadingByOutpoint: newDownloading, + urisLoading: newLoading }); }; @@ -4842,12 +4886,15 @@ exports.makeSelectContentPositionForUri = makeSelectContentPositionForUri; exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; exports.makeSelectCoverForUri = makeSelectCoverForUri; exports.makeSelectDateForUri = makeSelectDateForUri; +exports.makeSelectDownloadPathForUri = makeSelectDownloadPathForUri; exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; +exports.makeSelectFileNameForUri = makeSelectFileNameForUri; exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileForUri; exports.makeSelectIsUriResolving = makeSelectIsUriResolving; exports.makeSelectLoadingForUri = makeSelectLoadingForUri; +exports.makeSelectMediaTypeForUri = makeSelectMediaTypeForUri; exports.makeSelectMetadataForUri = makeSelectMetadataForUri; exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; @@ -4864,6 +4911,7 @@ exports.makeSelectThumbnailForUri = makeSelectThumbnailForUri; exports.makeSelectTitleForUri = makeSelectTitleForUri; exports.makeSelectTotalItemsForChannel = makeSelectTotalItemsForChannel; exports.makeSelectTotalPagesForChannel = makeSelectTotalPagesForChannel; +exports.makeSelectUriIsStreamable = makeSelectUriIsStreamable; exports.normalizeURI = normalizeURI; exports.notificationsReducer = notificationsReducer; exports.parseQueryParams = parseQueryParams; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 335eda1..a403ffb 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -68,7 +68,7 @@ declare type ResolveResponse = { [string]: Claim | { error?: {} }, }; -declare type GetResponse = FileListItem; +declare type GetResponse = FileListItem & { error?: string }; declare type GenericTxResponse = { height: number, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 335eda1..a403ffb 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -68,7 +68,7 @@ declare type ResolveResponse = { [string]: Claim | { error?: {} }, }; -declare type GetResponse = FileListItem; +declare type GetResponse = FileListItem & { error?: string }; declare type GenericTxResponse = { height: number, diff --git a/package.json b/package.json index 21b595f..8cba56d 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "format": "prettier 'src/**/*.{js,json}' --write" }, "dependencies": { + "mime": "^2.4.4", "proxy-polyfill": "0.1.6", "reselect": "^3.0.0", "uuid": "^3.3.2" diff --git a/src/index.js b/src/index.js index 2f93891..9a5574e 100644 --- a/src/index.js +++ b/src/index.js @@ -217,6 +217,10 @@ export { selectFileListDownloadedSort, selectFileListPublishedSort, selectDownloadedUris, + makeSelectMediaTypeForUri, + makeSelectUriIsStreamable, + makeSelectDownloadPathForUri, + makeSelectFileNameForUri, } from 'redux/selectors/file_info'; export { diff --git a/src/lbry.js b/src/lbry.js index 07fe1f0..5ceb6dd 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -1,5 +1,6 @@ // @flow import 'proxy-polyfill'; +import mime from 'mime'; const CHECK_DAEMON_STARTED_TRY_NUMBER = 200; // @@ -32,27 +33,37 @@ const Lbry: LbryTypes = { }, // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk - getMediaType: (contentType: string, extname: ?string) => { - if (extname) { - const formats = [ - [/^(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], - [/^(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], - [/^(html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org)$/i, 'document'], - [/^(stl|obj|fbx|gcode)$/i, '3D-file'], - ]; + getMediaType: (contentType?: string, fileName: ?string) => { + const formats = [ + [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], + [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], + [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], + [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], + [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], + [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], + [/\.(cbr|cbt|cbz)$/i, 'comic-book'], + ]; + + const extName = mime.getExtension(contentType); + const fileExt = extName ? `.${extName}` : null; + const testString = fileName || fileExt; + + // Get mediaType from file extension + if (testString) { const res = formats.reduce((ret, testpair) => { - switch (testpair[0].test(ret)) { - case true: - return testpair[1]; - default: - return ret; - } - }, extname); - return res === extname ? 'unknown' : res; - } else if (contentType) { - // $FlowFixMe + const [regex, mediaType] = testpair; + + return regex.test(ret) ? mediaType : ret; + }, testString); + + if (res !== testString) return res; + } + + // Get mediaType from contentType + if (contentType) { return /^[^/]+/.exec(contentType)[0]; } + return 'unknown'; }, diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 0afe464..305ff4f 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -9,7 +9,7 @@ import { makeSelectStreamingUrlForUri } from 'redux/selectors/file'; type Dispatch = (action: any) => any; type GetState = () => { file: FileState }; -export function doFileGet(uri: string, saveFile: boolean = true) { +export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: GetResponse => any) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.LOADING_FILE_STARTED, @@ -21,7 +21,8 @@ export function doFileGet(uri: string, saveFile: boolean = true) { // set save_file argument to True to save the file (old behaviour) Lbry.get({ uri, save_file: saveFile }) .then((streamInfo: GetResponse) => { - const timeout = streamInfo === null || typeof streamInfo !== 'object'; + const timeout = + streamInfo === null || typeof streamInfo !== 'object' || streamInfo.error === 'Timeout'; if (timeout) { dispatch({ @@ -39,8 +40,19 @@ export function doFileGet(uri: string, saveFile: boolean = true) { const { streaming_url: streamingUrl } = streamInfo; dispatch({ type: ACTIONS.PURCHASE_URI_COMPLETED, - data: { uri, streamingUrl: !saveFile && streamingUrl ? streamingUrl : null }, + data: { uri, streamingUrl }, }); + dispatch({ + type: ACTIONS.FETCH_FILE_INFO_COMPLETED, + data: { + fileInfo: streamInfo, + outpoint: streamInfo.outpoint, + }, + }); + + if (onSuccess) { + onSuccess(streamInfo); + } } }) .catch(() => { @@ -63,7 +75,12 @@ export function doFileGet(uri: string, saveFile: boolean = true) { }; } -export function doPurchaseUri(uri: string, costInfo: { cost: number }, saveFile: boolean = true) { +export function doPurchaseUri( + uri: string, + costInfo: { cost: number }, + saveFile: boolean = true, + onSuccess?: GetResponse => any +) { return (dispatch: Dispatch, getState: GetState) => { dispatch({ type: ACTIONS.PURCHASE_URI_STARTED, @@ -98,7 +115,7 @@ export function doPurchaseUri(uri: string, costInfo: { cost: number }, saveFile: return; } - dispatch(doFileGet(uri, saveFile)); + dispatch(doFileGet(uri, saveFile, onSuccess)); }; } diff --git a/src/redux/selectors/file.js b/src/redux/selectors/file.js index 7e0a1a1..3e5b4b8 100644 --- a/src/redux/selectors/file.js +++ b/src/redux/selectors/file.js @@ -1,5 +1,6 @@ // @flow import { createSelector } from 'reselect'; +import { makeSelectFileInfoForUri } from 'redux/selectors/file_info'; type State = { file: FileState }; @@ -31,8 +32,10 @@ export const selectLastPurchasedUri: (state: State) => string = createSelector( state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null ); -export const makeSelectStreamingUrlForUri = (uri: string): ((state: State) => {}) => +export const makeSelectStreamingUrlForUri = (uri: string) => createSelector( - selectPurchasedStreamingUrls, - streamingUrls => streamingUrls && streamingUrls[uri] + makeSelectFileInfoForUri(uri), + fileInfo => { + return fileInfo && fileInfo.streaming_url; + } ); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 7c045fe..7454209 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -3,9 +3,11 @@ import { selectIsFetchingClaimListMine, selectMyClaims, selectClaimsById, + makeSelectContentTypeForUri, } from 'redux/selectors/claims'; import { createSelector } from 'reselect'; import { buildURI } from 'lbryURI'; +import Lbry from 'lbry'; export const selectState = state => state.fileInfo || {}; @@ -72,7 +74,7 @@ export const selectFileInfosDownloaded = createSelector( return ( fileInfo && myClaimIds.indexOf(fileInfo.claim_id) === -1 && - (fileInfo.completed || fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0 ) + (fileInfo.completed || fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0) ); }) ); @@ -238,3 +240,41 @@ export const selectDownloadedUris = createSelector( .reverse() .map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) ); + +export const makeSelectMediaTypeForUri = (uri: string) => + createSelector( + makeSelectFileInfoForUri(uri), + makeSelectContentTypeForUri(uri), + (fileInfo, contentType) => { + if (!fileInfo && !contentType) { + return undefined; + } + + const fileName = fileInfo && fileInfo.file_name; + return Lbry.getMediaType(contentType, fileName); + } + ); + +export const makeSelectUriIsStreamable = (uri: string) => + createSelector( + makeSelectMediaTypeForUri(uri), + mediaType => { + const isStreamable = ['audio', 'video', 'image'].indexOf(mediaType) !== -1; + return isStreamable; + } + ); + +export const makeSelectDownloadPathForUri = (uri: string) => + createSelector( + makeSelectFileInfoForUri(uri), + fileInfo => { + return fileInfo && fileInfo.download_path; + } + ); +export const makeSelectFileNameForUri = (uri: string) => + createSelector( + makeSelectFileInfoForUri(uri), + fileInfo => { + return fileInfo && fileInfo.file_name; + } + ); diff --git a/yarn.lock b/yarn.lock index 49dc513..182afdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3523,6 +3523,11 @@ mime-types@^2.1.12, mime-types@~2.1.17: dependencies: mime-db "~1.33.0" +mime@^2.4.4: + version "2.4.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" + integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== + mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" -- 2.45.2 From c27c6ba6150a1fa30d874a678af94b116041f557 Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 5 Aug 2019 17:27:14 -0400 Subject: [PATCH 096/371] dont crash --- dist/bundle.es.js | 2 +- src/redux/selectors/claims.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c138c15..14e4c16 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1533,7 +1533,7 @@ const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSe const { title } = claim.value; - const searchQuery = getSearchQueryString(title.replace(/\//, ' ')); + const searchQuery = getSearchQueryString(title ? title.replace(/\//, ' ') : ''); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 7c477dc..eac3390 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -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; } @@ -456,7 +456,7 @@ export const makeSelectRecommendedContentForUri = (uri: string) => const { title } = claim.value; - const searchQuery = getSearchQueryString(title.replace(/\//, ' ')); + const searchQuery = getSearchQueryString(title ? title.replace(/\//, ' ') : ''); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { -- 2.45.2 From fe66fae040e6e5f07b726af946d46540f4babc8e Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 5 Aug 2019 22:52:46 -0400 Subject: [PATCH 097/371] remove purchasedStreamingUrls --- dist/bundle.es.js | 36 +++++++---------------------------- dist/flow-typed/File.js | 5 ++--- dist/flow-typed/mime.js | 4 ++++ flow-typed/File.js | 5 ++--- flow-typed/mime.js | 4 ++++ src/constants/action_types.js | 3 --- src/index.js | 1 - src/lbry.js | 5 ++++- src/redux/actions/file.js | 13 ++----------- src/redux/reducers/file.js | 8 +------- src/redux/selectors/file.js | 5 ----- 11 files changed, 26 insertions(+), 63 deletions(-) create mode 100644 dist/flow-typed/mime.js create mode 100644 flow-typed/mime.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2177543..568ff79 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -153,9 +153,6 @@ const PURCHASE_URI_STARTED = 'PURCHASE_URI_STARTED'; const PURCHASE_URI_COMPLETED = 'PURCHASE_URI_COMPLETED'; const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; -const LOADING_FILE_STARTED = 'LOADING_FILE_STARTED'; -const LOADING_FILE_COMPLETED = 'LOADING_FILE_COMPLETED'; -const LOADING_FILE_FAILED = 'LOADING_FILE_FAILED'; // Search const SEARCH_START = 'SEARCH_START'; @@ -382,9 +379,6 @@ var action_types = /*#__PURE__*/Object.freeze({ PURCHASE_URI_COMPLETED: PURCHASE_URI_COMPLETED, PURCHASE_URI_FAILED: PURCHASE_URI_FAILED, DELETE_PURCHASED_URI: DELETE_PURCHASED_URI, - LOADING_FILE_STARTED: LOADING_FILE_STARTED, - LOADING_FILE_COMPLETED: LOADING_FILE_COMPLETED, - LOADING_FILE_FAILED: LOADING_FILE_FAILED, SEARCH_START: SEARCH_START, SEARCH_SUCCESS: SEARCH_SUCCESS, SEARCH_FAIL: SEARCH_FAIL, @@ -717,8 +711,10 @@ const Lbry = { // Get mediaType from contentType if (contentType) { - return (/^[^/]+/.exec(contentType)[0] - ); + const matches = /^[^/]+/.exec(contentType); + if (matches) { + return matches[0]; + } } return 'unknown'; @@ -2625,8 +2621,6 @@ const selectFailedPurchaseUris = reselect.createSelector(selectState$4, state => const selectPurchasedUris = reselect.createSelector(selectState$4, state => state.purchasedUris); -const selectPurchasedStreamingUrls = reselect.createSelector(selectState$4, state => state.purchasedStreamingUrls); - const selectLastPurchasedUri = reselect.createSelector(selectState$4, state => state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null); const makeSelectStreamingUrlForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { @@ -2638,7 +2632,7 @@ const makeSelectStreamingUrlForUri = uri => reselect.createSelector(makeSelectFi function doFileGet(uri, saveFile = true, onSuccess) { return dispatch => { dispatch({ - type: LOADING_FILE_STARTED, + type: PURCHASE_URI_STARTED, data: { uri } @@ -2649,10 +2643,6 @@ function doFileGet(uri, saveFile = true, onSuccess) { const timeout = streamInfo === null || typeof streamInfo !== 'object' || streamInfo.error === 'Timeout'; if (timeout) { - dispatch({ - type: LOADING_FILE_FAILED, - data: { uri } - }); dispatch({ type: PURCHASE_URI_FAILED, data: { uri } @@ -2661,10 +2651,9 @@ function doFileGet(uri, saveFile = true, onSuccess) { dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); } else { // purchase was completed successfully - const { streaming_url: streamingUrl } = streamInfo; dispatch({ type: PURCHASE_URI_COMPLETED, - data: { uri, streamingUrl } + data: { uri } }); dispatch({ type: FETCH_FILE_INFO_COMPLETED, @@ -2679,10 +2668,6 @@ function doFileGet(uri, saveFile = true, onSuccess) { } } }).catch(() => { - dispatch({ - type: LOADING_FILE_FAILED, - data: { uri } - }); dispatch({ type: PURCHASE_URI_FAILED, data: { uri } @@ -4060,7 +4045,6 @@ const reducers$3 = {}; const defaultState$4 = { failedPurchaseUris: [], purchasedUris: [], - purchasedStreamingUrls: {}, purchaseUriErrorMessage: '' }; @@ -4078,10 +4062,9 @@ reducers$3[PURCHASE_URI_STARTED] = (state, action) => { }; reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { - const { uri, streamingUrl } = action.data; + const { uri } = action.data; const newPurchasedUris = state.purchasedUris.slice(); const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - const newPurchasedStreamingUrls = Object.assign({}, state.purchasedStreamingUrls); if (!newPurchasedUris.includes(uri)) { newPurchasedUris.push(uri); @@ -4089,14 +4072,10 @@ reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { if (newFailedPurchaseUris.includes(uri)) { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - if (streamingUrl) { - newPurchasedStreamingUrls[uri] = streamingUrl; - } return _extends$9({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, - purchasedStreamingUrls: newPurchasedStreamingUrls, purchaseUriErrorMessage: '' }); }; @@ -4976,7 +4955,6 @@ exports.selectPendingClaims = selectPendingClaims; exports.selectPlayingUri = selectPlayingUri; exports.selectPublishFormValues = selectPublishFormValues; exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; -exports.selectPurchasedStreamingUrls = selectPurchasedStreamingUrls; exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index 42c9b16..c4c151c 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -38,7 +38,6 @@ declare type FileListItem = { declare type FileState = { failedPurchaseUris: Array, purchasedUris: Array, - purchasedStreamingUrls: {}, }; declare type PurchaseUriCompleted = { @@ -53,7 +52,7 @@ declare type PurchaseUriFailed = { type: ACTIONS.PURCHASE_URI_FAILED, data: { uri: string, - error: any + error: any, }, }; @@ -68,6 +67,6 @@ declare type PurchaseUriStarted = { declare type DeletePurchasedUri = { type: ACTIONS.DELETE_PURCHASED_URI, data: { - uri: string + uri: string, }, }; diff --git a/dist/flow-typed/mime.js b/dist/flow-typed/mime.js new file mode 100644 index 0000000..476b179 --- /dev/null +++ b/dist/flow-typed/mime.js @@ -0,0 +1,4 @@ +// @flow +declare module 'mime' { + declare module.exports: any; +} diff --git a/flow-typed/File.js b/flow-typed/File.js index 42c9b16..c4c151c 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -38,7 +38,6 @@ declare type FileListItem = { declare type FileState = { failedPurchaseUris: Array, purchasedUris: Array, - purchasedStreamingUrls: {}, }; declare type PurchaseUriCompleted = { @@ -53,7 +52,7 @@ declare type PurchaseUriFailed = { type: ACTIONS.PURCHASE_URI_FAILED, data: { uri: string, - error: any + error: any, }, }; @@ -68,6 +67,6 @@ declare type PurchaseUriStarted = { declare type DeletePurchasedUri = { type: ACTIONS.DELETE_PURCHASED_URI, data: { - uri: string + uri: string, }, }; diff --git a/flow-typed/mime.js b/flow-typed/mime.js new file mode 100644 index 0000000..476b179 --- /dev/null +++ b/flow-typed/mime.js @@ -0,0 +1,4 @@ +// @flow +declare module 'mime' { + declare module.exports: any; +} diff --git a/src/constants/action_types.js b/src/constants/action_types.js index b75997b..4b07603 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -127,9 +127,6 @@ export const PURCHASE_URI_STARTED = 'PURCHASE_URI_STARTED'; export const PURCHASE_URI_COMPLETED = 'PURCHASE_URI_COMPLETED'; export const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; export const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; -export const LOADING_FILE_STARTED = 'LOADING_FILE_STARTED'; -export const LOADING_FILE_COMPLETED = 'LOADING_FILE_COMPLETED'; -export const LOADING_FILE_FAILED = 'LOADING_FILE_FAILED'; // Search export const SEARCH_START = 'SEARCH_START'; diff --git a/src/index.js b/src/index.js index 9a5574e..2161100 100644 --- a/src/index.js +++ b/src/index.js @@ -140,7 +140,6 @@ export { selectToast, selectError } from 'redux/selectors/notifications'; export { selectFailedPurchaseUris, selectPurchasedUris, - selectPurchasedStreamingUrls, selectPurchaseUriErrorMessage, selectLastPurchasedUri, makeSelectStreamingUrlForUri, diff --git a/src/lbry.js b/src/lbry.js index 5ceb6dd..b87a8a2 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -61,7 +61,10 @@ const Lbry: LbryTypes = { // Get mediaType from contentType if (contentType) { - return /^[^/]+/.exec(contentType)[0]; + const matches = /^[^/]+/.exec(contentType); + if (matches) { + return matches[0]; + } } return 'unknown'; diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 305ff4f..1697687 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -12,7 +12,7 @@ type GetState = () => { file: FileState }; export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: GetResponse => any) { return (dispatch: Dispatch) => { dispatch({ - type: ACTIONS.LOADING_FILE_STARTED, + type: ACTIONS.PURCHASE_URI_STARTED, data: { uri, }, @@ -25,10 +25,6 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get streamInfo === null || typeof streamInfo !== 'object' || streamInfo.error === 'Timeout'; if (timeout) { - dispatch({ - type: ACTIONS.LOADING_FILE_FAILED, - data: { uri }, - }); dispatch({ type: ACTIONS.PURCHASE_URI_FAILED, data: { uri }, @@ -37,10 +33,9 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); } else { // purchase was completed successfully - const { streaming_url: streamingUrl } = streamInfo; dispatch({ type: ACTIONS.PURCHASE_URI_COMPLETED, - data: { uri, streamingUrl }, + data: { uri }, }); dispatch({ type: ACTIONS.FETCH_FILE_INFO_COMPLETED, @@ -56,10 +51,6 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get } }) .catch(() => { - dispatch({ - type: ACTIONS.LOADING_FILE_FAILED, - data: { uri }, - }); dispatch({ type: ACTIONS.PURCHASE_URI_FAILED, data: { uri }, diff --git a/src/redux/reducers/file.js b/src/redux/reducers/file.js index 95a3b7e..0e9a40e 100644 --- a/src/redux/reducers/file.js +++ b/src/redux/reducers/file.js @@ -5,7 +5,6 @@ const reducers = {}; const defaultState = { failedPurchaseUris: [], purchasedUris: [], - purchasedStreamingUrls: {}, purchaseUriErrorMessage: '', }; @@ -30,10 +29,9 @@ reducers[ACTIONS.PURCHASE_URI_COMPLETED] = ( state: FileState, action: PurchaseUriCompleted ): FileState => { - const { uri, streamingUrl } = action.data; + const { uri } = action.data; const newPurchasedUris = state.purchasedUris.slice(); const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - const newPurchasedStreamingUrls = Object.assign({}, state.purchasedStreamingUrls); if (!newPurchasedUris.includes(uri)) { newPurchasedUris.push(uri); @@ -41,15 +39,11 @@ reducers[ACTIONS.PURCHASE_URI_COMPLETED] = ( if (newFailedPurchaseUris.includes(uri)) { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - if (streamingUrl) { - newPurchasedStreamingUrls[uri] = streamingUrl; - } return { ...state, failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, - purchasedStreamingUrls: newPurchasedStreamingUrls, purchaseUriErrorMessage: '', }; }; diff --git a/src/redux/selectors/file.js b/src/redux/selectors/file.js index 3e5b4b8..dbdb0be 100644 --- a/src/redux/selectors/file.js +++ b/src/redux/selectors/file.js @@ -21,11 +21,6 @@ export const selectPurchasedUris: (state: State) => Array = createSelect state => state.purchasedUris ); -export const selectPurchasedStreamingUrls: (state: State) => {} = createSelector( - selectState, - state => state.purchasedStreamingUrls -); - export const selectLastPurchasedUri: (state: State) => string = createSelector( selectState, state => -- 2.45.2 From d6ca449bd97499f93de39445837802e39ca9524c Mon Sep 17 00:00:00 2001 From: zxawry Date: Sun, 11 Aug 2019 17:29:21 +0100 Subject: [PATCH 098/371] add selector for total supports --- src/redux/selectors/wallet.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 654836d..274287d 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -90,6 +90,21 @@ export const selectSupportsByOutpoint = createSelector( state => state.supports || {} ); +export const selectTotalSupports = createSelector( + selectSupportsByOutpoint, + byOutpoint => { + let total = parseFloat("0.0"); + //let total = 0.0; + + Object.values(byOutpoint).forEach(support => { + const { amount } = support; + total = amount ? total + parseFloat(amount) : total; + }); + + return total; + } +); + export const selectTransactionItems = createSelector( selectTransactionsById, byId => { -- 2.45.2 From 79e41150b95efc4a19d4ef05a0a8d8ecefdd5bd1 Mon Sep 17 00:00:00 2001 From: zxawry Date: Sun, 11 Aug 2019 17:29:56 +0100 Subject: [PATCH 099/371] add selector for claim supports --- src/redux/selectors/claims.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index eac3390..082aa31 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -1,6 +1,7 @@ // @flow import { normalizeURI, buildURI, parseURI } from 'lbryURI'; import { selectSearchUrisByQuery } from 'redux/selectors/search'; +import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { createSelector } from 'reselect'; import { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; import { getSearchQueryString } from 'util/query-params'; @@ -531,3 +532,24 @@ export const makeSelectShortUrlForUri = (uri: string) => makeSelectClaimForUri(uri), claim => claim && claim.short_url ); + +export const makeSelectSupportsForUri = (uri: string) => + createSelector( + selectSupportsByOutpoint, + makeSelectClaimForUri(uri), + (byOutpoint, claim: ?StreamClaim) => { + if (!claim || !claim.is_mine) { + return null; + } + + const { claim_id: claimId } = claim; + let total = parseFloat("0.0"); + + Object.values(byOutpoint).forEach(support => { + const { claim_id, amount } = support + total = (claim_id === claimId && amount) ? total + parseFloat(amount) : total; + }); + + return total; + } + ); -- 2.45.2 From f0edb11ac1ba164d3f3f301fd2746df9fe900959 Mon Sep 17 00:00:00 2001 From: zxawry Date: Sun, 11 Aug 2019 17:30:29 +0100 Subject: [PATCH 100/371] export added selectors --- src/index.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/index.js b/src/index.js index 2f93891..a138016 100644 --- a/src/index.js +++ b/src/index.js @@ -173,6 +173,7 @@ export { makeSelectPendingByUri, makeSelectClaimsInChannelForCurrentPageState, makeSelectShortUrlForUri, + makeSelectSupportsForUri, selectPendingById, selectClaimsById, selectClaimsByUri, @@ -245,6 +246,7 @@ export { selectTotalBalance, selectTransactionsById, selectSupportsByOutpoint, + selectTotalSupports, selectTransactionItems, selectRecentTransactions, selectHasTransactions, -- 2.45.2 From 836531d8a24ded1cd6149bfdc2dc40ba8d7f4145 Mon Sep 17 00:00:00 2001 From: zxawry Date: Sun, 11 Aug 2019 17:33:49 +0100 Subject: [PATCH 101/371] cleanup --- src/redux/selectors/wallet.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 274287d..6ca8b77 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -94,7 +94,6 @@ export const selectTotalSupports = createSelector( selectSupportsByOutpoint, byOutpoint => { let total = parseFloat("0.0"); - //let total = 0.0; Object.values(byOutpoint).forEach(support => { const { amount } = support; -- 2.45.2 From e10986e8e54d25480ac2b5dd2a31fec8b254471a Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 13 Aug 2019 16:27:32 +0100 Subject: [PATCH 102/371] Mobile updates (#179) * return lowercase tag names for unfollowed tags * fix: thumbnail url * fix claim.meta.creation_timestamp check * track if the last page reached was reached for claim_search queries * fix CLAIM_SEARCH_FAILED reducer --- dist/bundle.es.js | 35 ++++++++++++++++++++++++----------- src/index.js | 1 + src/redux/actions/claims.js | 8 +++++++- src/redux/actions/publish.js | 34 +++++++++++++++++----------------- src/redux/reducers/claims.js | 14 ++++++++++++-- src/redux/selectors/claims.js | 11 ++++++++--- src/redux/selectors/tags.js | 2 +- 7 files changed, 70 insertions(+), 35 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 14e4c16..4626cbb 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 fs = _interopDefault(require('fs')); -var path = _interopDefault(require('path')); const MINIMUM_PUBLISH_BID = 0.00000001; @@ -1392,7 +1390,7 @@ const makeSelectMetadataItemForUri = (uri, key) => reselect.createSelector(makeS const makeSelectTitleForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => metadata && metadata.title); const makeSelectDateForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { - const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta.creation_timestamp ? claim.meta.creation_timestamp * 1000 : null); + const timestamp = claim && claim.value && (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp ? claim.meta.creation_timestamp * 1000 : null); if (!timestamp) { return undefined; } @@ -1570,6 +1568,8 @@ const selectFetchingClaimSearch = reselect.createSelector(selectFetchingClaimSea const selectClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.claimSearchByQuery || {}); +const selectClaimSearchByQueryLastPageReached = reselect.createSelector(selectState$1, state => state.claimSearchByQueryLastPageReached || {}); + const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); const selectState$2 = state => state.wallet || {}; @@ -2403,7 +2403,13 @@ function doClaimSearch(options = { dispatch({ type: CLAIM_SEARCH_COMPLETED, - data: { query, resolveInfo, uris, append: options.page && options.page !== 1 } + data: { + query, + resolveInfo, + uris, + append: options.page && options.page !== 1, + pageSize: options.page_size + } }); }; @@ -2880,7 +2886,7 @@ const doUpdatePublishForm = publishFormValue => dispatch => dispatch({ data: _extends$4({}, publishFormValue) }); -const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter) => dispatch => { +const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter, fs, path) => dispatch => { let thumbnail, fileExt, fileName, fileType; const makeid = () => { @@ -2925,7 +2931,7 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter) => dispatch => type: UPDATE_PUBLISH_FORM, data: { uploadThumbnailStatus: COMPLETE, - thumbnail: `${json.data.url}${fileExt}` + thumbnail: `${json.data.url}.${fileExt}` } }) : uploadError(json.message)).catch(err => uploadError(err.message)); }); @@ -2963,7 +2969,7 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter) => dispatch => } }; -const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { +const doPrepareEdit = (claim, uri, fileInfo, fs) => dispatch => { const { name, amount, value } = claim; const channelName = claim && claim.signing_channel && claim.signing_channel.normalized_name || null; const { @@ -3017,7 +3023,7 @@ const doPrepareEdit = (claim, uri, fileInfo) => dispatch => { publishData['channel'] = channelName; } - if (fileInfo && fileInfo.download_path) { + if (fs && fileInfo && fileInfo.download_path) { try { fs.accessSync(fileInfo.download_path, fs.constants.R_OK); publishData.filePath = fileInfo.download_path; @@ -3462,6 +3468,7 @@ const defaultState = { pendingById: {}, claimSearchError: false, claimSearchByQuery: {}, + claimSearchByQueryLastPageReached: {}, fetchingClaimSearchByQuery: {} }; @@ -3703,7 +3710,8 @@ reducers[CLAIM_SEARCH_STARTED] = (state, action) => { reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); const claimSearchByQuery = Object.assign({}, state.claimSearchByQuery); - const { append, query, uris } = action.data; + const claimSearchByQueryLastPageReached = Object.assign({}, state.claimSearchByQueryLastPageReached); + const { append, query, uris, pageSize } = action.data; if (append) { // todo: check for duplicate uris when concatenating? @@ -3712,17 +3720,21 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { claimSearchByQuery[query] = uris; } + // the returned number of uris is less than the page size, so we're on the last page + claimSearchByQueryLastPageReached[query] = uris.length < pageSize; + delete fetchingClaimSearchByQuery[query]; return Object.assign({}, state, _extends$5({}, handleClaimAction(state, action), { claimSearchByQuery, + claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery })); }; reducers[CLAIM_SEARCH_FAILED] = (state, action) => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); - fetchingClaimSearchByQuery[action.data.tags] = false; + delete fetchingClaimSearchByQuery[action.data.query]; return Object.assign({}, state, { fetchingClaimSearchByQuery @@ -4724,7 +4736,7 @@ const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, sele Object.keys(tagsByName).forEach(key => { if (!followedTagsSet.has(key)) { const { name } = tagsByName[key]; - tagsToReturn.push({ name }); + tagsToReturn.push({ name: name.toLowerCase() }); } }); @@ -4884,6 +4896,7 @@ exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; exports.selectChannelIsBlocked = selectChannelIsBlocked; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; +exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; exports.selectCurrentChannelPage = selectCurrentChannelPage; diff --git a/src/index.js b/src/index.js index 2f93891..6a3bdc1 100644 --- a/src/index.js +++ b/src/index.js @@ -197,6 +197,7 @@ export { selectFetchingClaimSearch, selectFetchingClaimSearchByQuery, selectClaimSearchByQuery, + selectClaimSearchByQueryLastPageReached, } 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 902c87b..0f6e44e 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -336,7 +336,13 @@ export function doClaimSearch( dispatch({ type: ACTIONS.CLAIM_SEARCH_COMPLETED, - data: { query, resolveInfo, uris, append: options.page && options.page !== 1 }, + data: { + query, + resolveInfo, + uris, + append: options.page && options.page !== 1, + pageSize: options.page_size, + }, }); }; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 38cb9bd..69844c0 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -13,8 +13,6 @@ import { selectMyClaimsWithoutChannels, } from 'redux/selectors/claims'; import { selectPublishFormValues, selectMyClaimForUri } from 'redux/selectors/publish'; -import fs from 'fs'; -import path from 'path'; export const doResetThumbnailStatus = () => (dispatch: Dispatch) => { dispatch({ @@ -66,7 +64,9 @@ export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => export const doUploadThumbnail = ( filePath: string, thumbnailBuffer: Uint8Array, - fsAdapter: any + fsAdapter: any, + fs: any, + path: any ) => (dispatch: Dispatch) => { let thumbnail, fileExt, fileName, fileType; @@ -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,19 +157,19 @@ 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)); } }; -export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem) => ( +export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem, fs: any) => ( dispatch: Dispatch ) => { const { name, amount, value } = claim; @@ -226,7 +226,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis publishData['channel'] = channelName; } - if (fileInfo && fileInfo.download_path) { + if (fs && fileInfo && fileInfo.download_path) { try { fs.accessSync(fileInfo.download_path, fs.constants.R_OK); publishData.filePath = fileInfo.download_path; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index a001d3a..ba94348 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -23,6 +23,7 @@ type State = { fetchingMyChannels: boolean, fetchingClaimSearchByQuery: { [string]: boolean }, claimSearchByQuery: { [string]: Array }, + claimSearchByQueryLastPageReached: { [string]: Array }, claimsByChannel: { [string]: { all: Array, @@ -47,6 +48,7 @@ const defaultState = { pendingById: {}, claimSearchError: false, claimSearchByQuery: {}, + claimSearchByQueryLastPageReached: {}, fetchingClaimSearchByQuery: {}, }; @@ -299,7 +301,11 @@ reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State, action: any): State => { reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); const claimSearchByQuery = Object.assign({}, state.claimSearchByQuery); - const { append, query, uris } = action.data; + const claimSearchByQueryLastPageReached = Object.assign( + {}, + state.claimSearchByQueryLastPageReached + ); + const { append, query, uris, pageSize } = action.data; if (append) { // todo: check for duplicate uris when concatenating? @@ -311,18 +317,22 @@ reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => claimSearchByQuery[query] = uris; } + // the returned number of uris is less than the page size, so we're on the last page + claimSearchByQueryLastPageReached[query] = uris.length < pageSize; + delete fetchingClaimSearchByQuery[query]; return Object.assign({}, state, { ...handleClaimAction(state, action), claimSearchByQuery, + claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery, }); }; reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State, action: any): State => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); - fetchingClaimSearchByQuery[action.data.tags] = false; + delete fetchingClaimSearchByQuery[action.data.query]; return Object.assign({}, state, { fetchingClaimSearchByQuery, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index eac3390..896fb76 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -222,9 +222,9 @@ export const makeSelectDateForUri = (uri: string) => claim.value && (claim.value.release_time ? claim.value.release_time * 1000 - : claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + : claim.meta && claim.meta.creation_timestamp + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -515,6 +515,11 @@ export const selectClaimSearchByQuery = createSelector( state => state.claimSearchByQuery || {} ); +export const selectClaimSearchByQueryLastPageReached = createSelector( + selectState, + state => state.claimSearchByQueryLastPageReached || {} +); + export const makeSelectClaimSearchUrisByOptions = (options: {}) => createSelector( selectClaimSearchByQuery, diff --git a/src/redux/selectors/tags.js b/src/redux/selectors/tags.js index d38d375..ec805a0 100644 --- a/src/redux/selectors/tags.js +++ b/src/redux/selectors/tags.js @@ -29,7 +29,7 @@ export const selectUnfollowedTags = createSelector( Object.keys(tagsByName).forEach(key => { if (!followedTagsSet.has(key)) { const { name } = tagsByName[key]; - tagsToReturn.push({ name }); + tagsToReturn.push({ name: name.toLowerCase() }); } }); -- 2.45.2 From 291b06864261c97d1c8be228ee86191ead537612 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 13 Aug 2019 13:33:32 -0400 Subject: [PATCH 103/371] use FETCH_FILE_INFO_XXX in favor of LOADING_URI_XXX --- dist/bundle.es.js | 230 +++++++++++++++----------------- src/constants/action_types.js | 1 + src/redux/actions/file.js | 20 ++- src/redux/reducers/file_info.js | 45 ++----- 4 files changed, 133 insertions(+), 163 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 568ff79..35d2b55 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -137,6 +137,7 @@ const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'; const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'; +const FETCH_FILE_INFO_FAILED = 'FETCH_FILE_INFO_FAILED'; const LOADING_VIDEO_STARTED = 'LOADING_VIDEO_STARTED'; const LOADING_VIDEO_COMPLETED = 'LOADING_VIDEO_COMPLETED'; const LOADING_VIDEO_FAILED = 'LOADING_VIDEO_FAILED'; @@ -363,6 +364,7 @@ var action_types = /*#__PURE__*/Object.freeze({ FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, FETCH_FILE_INFO_COMPLETED: FETCH_FILE_INFO_COMPLETED, + FETCH_FILE_INFO_FAILED: FETCH_FILE_INFO_FAILED, LOADING_VIDEO_STARTED: LOADING_VIDEO_STARTED, LOADING_VIDEO_COMPLETED: LOADING_VIDEO_COMPLETED, LOADING_VIDEO_FAILED: LOADING_VIDEO_FAILED, @@ -2630,11 +2632,15 @@ const makeSelectStreamingUrlForUri = uri => reselect.createSelector(makeSelectFi // function doFileGet(uri, saveFile = true, onSuccess) { - return dispatch => { + return (dispatch, getState) => { + const state = getState(); + const { nout, txid } = makeSelectClaimForUri(uri)(state); + const outpoint = `${txid}:${nout}`; + dispatch({ - type: PURCHASE_URI_STARTED, + type: FETCH_FILE_INFO_STARTED, data: { - uri + outpoint } }); @@ -2644,8 +2650,8 @@ function doFileGet(uri, saveFile = true, onSuccess) { if (timeout) { dispatch({ - type: PURCHASE_URI_FAILED, - data: { uri } + type: FETCH_FILE_INFO_FAILED, + data: { outpoint } }); dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); @@ -2673,6 +2679,11 @@ function doFileGet(uri, saveFile = true, onSuccess) { data: { uri } }); + dispatch({ + type: FETCH_FILE_INFO_FAILED, + data: { outpoint } + }); + dispatch(doToast({ message: `Failed to view ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`, isError: true @@ -3858,8 +3869,6 @@ function contentReducer(state = defaultState$2, action) { return state; } -var _extends$8 = 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; }; - const reducers$2 = {}; const defaultState$3 = { fileListPublishedSort: DATE_NEW, @@ -3914,20 +3923,27 @@ reducers$2[FETCH_FILE_INFO_COMPLETED] = (state, action) => { }); }; +reducers$2[FETCH_FILE_INFO_FAILED] = (state, action) => { + const { outpoint } = action.data; + const newFetching = Object.assign({}, state.fetching); + delete newFetching[outpoint]; + + return Object.assign({}, state, { + fetching: newFetching + }); +}; + reducers$2[DOWNLOADING_STARTED] = (state, action) => { const { uri, outpoint, fileInfo } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); const newDownloading = Object.assign({}, state.downloadingByOutpoint); - const newLoading = Object.assign({}, state.urisLoading); newDownloading[outpoint] = true; newByOutpoint[outpoint] = fileInfo; - delete newLoading[uri]; return Object.assign({}, state, { downloadingByOutpoint: newDownloading, - urisLoading: newLoading, byOutpoint: newByOutpoint }); }; @@ -3952,11 +3968,9 @@ reducers$2[DOWNLOADING_CANCELED] = (state, action) => { const newDownloading = Object.assign({}, state.downloadingByOutpoint); delete newDownloading[outpoint]; - delete newLoading[uri]; return Object.assign({}, state, { - downloadingByOutpoint: newDownloading, - urisLoading: newLoading + downloadingByOutpoint: newDownloading }); }; @@ -3990,36 +4004,6 @@ reducers$2[FILE_DELETE] = (state, action) => { }); }; -reducers$2[LOADING_VIDEO_STARTED] = (state, action) => { - const { uri } = action.data; - - const newLoading = Object.assign({}, state.urisLoading); - newLoading[uri] = true; - - const newErrors = _extends$8({}, state.errors); - if (uri in newErrors) delete newErrors[uri]; - - return Object.assign({}, state, { - urisLoading: newLoading, - errors: _extends$8({}, newErrors) - }); -}; - -reducers$2[LOADING_VIDEO_FAILED] = (state, action) => { - const { uri } = action.data; - - const newLoading = Object.assign({}, state.urisLoading); - delete newLoading[uri]; - - const newErrors = _extends$8({}, state.errors); - newErrors[uri] = true; - - return Object.assign({}, state, { - urisLoading: newLoading, - errors: _extends$8({}, newErrors) - }); -}; - reducers$2[SET_FILE_LIST_SORT] = (state, action) => { const pageSortStates = { [PUBLISHED]: 'fileListPublishedSort', @@ -4039,7 +4023,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -var _extends$9 = 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; }; +var _extends$8 = 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; }; const reducers$3 = {}; const defaultState$4 = { @@ -4055,7 +4039,7 @@ reducers$3[PURCHASE_URI_STARTED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$9({}, state, { + return _extends$8({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: '' }); @@ -4073,7 +4057,7 @@ reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$9({}, state, { + return _extends$8({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, purchaseUriErrorMessage: '' @@ -4088,7 +4072,7 @@ reducers$3[PURCHASE_URI_FAILED] = (state, action) => { newFailedPurchaseUris.push(uri); } - return _extends$9({}, state, { + return _extends$8({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: error }); @@ -4101,7 +4085,7 @@ reducers$3[DELETE_PURCHASED_URI] = (state, action) => { newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); } - return _extends$9({}, state, { + return _extends$8({}, state, { purchasedUris: newPurchasedUris }); }; @@ -4112,7 +4096,7 @@ function fileReducer(state = defaultState$4, action) { return state; } -var _extends$a = 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; }; +var _extends$9 = 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; }; const defaultState$5 = { notifications: [], @@ -4127,7 +4111,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$a({}, state, { + return _extends$9({}, state, { toasts: newToasts }); }, @@ -4135,7 +4119,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$a({}, state, { + return _extends$9({}, state, { toasts: newToasts }); }, @@ -4146,7 +4130,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$a({}, state, { + return _extends$9({}, state, { notifications: newNotifications }); }, @@ -4157,7 +4141,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$a({}, state, { + return _extends$9({}, state, { notifications }); }, @@ -4166,7 +4150,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$a({}, state, { + return _extends$9({}, state, { notifications: newNotifications }); }, @@ -4177,7 +4161,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$a({}, state, { + return _extends$9({}, state, { errors: newErrors }); }, @@ -4185,13 +4169,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$a({}, state, { + return _extends$9({}, state, { errors: newErrors }); } }, defaultState$5); -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; }; +var _extends$a = 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$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; } @@ -4228,17 +4212,17 @@ const defaultState$6 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$b({}, state, data); + return _extends$a({}, state, data); }, - [CLEAR_PUBLISH]: () => _extends$b({}, defaultState$6), - [PUBLISH_START]: state => _extends$b({}, state, { + [CLEAR_PUBLISH]: () => _extends$a({}, defaultState$6), + [PUBLISH_START]: state => _extends$a({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$b({}, state, { + [PUBLISH_FAIL]: state => _extends$a({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$b({}, state, { + [PUBLISH_SUCCESS]: state => _extends$a({}, state, { publishing: false, publishSuccess: true }), @@ -4253,14 +4237,14 @@ const publishReducer = handleActions({ contentName: name }); - return _extends$b({}, defaultState$6, publishData, { + return _extends$a({}, defaultState$6, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$6); -var _extends$c = 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; }; +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; }; const defaultState$7 = { isActive: false, // does the user have any typed text in the search input @@ -4280,29 +4264,29 @@ const defaultState$7 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$c({}, state, { + [SEARCH_START]: state => _extends$b({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$c({}, state, { + return _extends$b({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$c({}, state, { + [SEARCH_FAIL]: state => _extends$b({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$c({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$b({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$c({}, state, { - suggestions: _extends$c({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$b({}, state, { + suggestions: _extends$b({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -4310,30 +4294,30 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$c({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$b({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$c({}, state, { + [SEARCH_FOCUS]: state => _extends$b({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$c({}, state, { + [SEARCH_BLUR]: state => _extends$b({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$c({}, oldOptions, newOptions); - return _extends$c({}, state, { + const options = _extends$b({}, oldOptions, newOptions); + return _extends$b({}, state, { options }); } }, defaultState$7); -var _extends$d = 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; }; +var _extends$c = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$d({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$c({}, tagsMap, { [tag]: { name: tag } }), {}); } @@ -4356,7 +4340,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$d({}, state, { + return _extends$c({}, state, { followedTags: newFollowedTags }); }, @@ -4365,10 +4349,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$d({}, knownTags); + let newKnownTags = _extends$c({}, knownTags); newKnownTags[name] = { name }; - return _extends$d({}, state, { + return _extends$c({}, state, { knownTags: newKnownTags }); }, @@ -4377,11 +4361,11 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$d({}, knownTags); + let newKnownTags = _extends$c({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$d({}, state, { + return _extends$c({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -4412,7 +4396,7 @@ const blockedReducer = handleActions({ } }, defaultState$9); -var _extends$e = 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; }; +var _extends$d = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -4452,25 +4436,25 @@ const defaultState$a = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$e({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$d({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$e({}, state.transactions); + const byId = _extends$d({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$e({}, state, { + return _extends$d({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$e({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$d({}, state, { fetchingSupports: true }), @@ -4483,7 +4467,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$e({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$d({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -4492,7 +4476,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$e({}, state, { + return _extends$d({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -4505,56 +4489,56 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$e({}, state, { + return _extends$d({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$e({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$d({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$e({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$d({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$e({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$d({}, state, { balance: action.data.balance }), - [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$e({}, state, { + [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$d({}, state, { totalBalance: action.data.totalBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$e({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$d({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$e({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$d({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$e({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$d({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$e({}, state, { draftTransaction: newDraft }); + return _extends$d({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$e({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$d({}, oldDraft, { address: action.data.address }); - return _extends$e({}, state, { draftTransaction: newDraft }); + return _extends$d({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$e({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$d({}, state.draftTransaction, { sending: true }); - return _extends$e({}, state, { draftTransaction: newDraftTransaction }); + return _extends$d({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -4567,103 +4551,103 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$e({}, state, { draftTransaction: newDraftTransaction }); + return _extends$d({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$e({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$d({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$e({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$d({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$e({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$d({}, state, { error: action.data.error, sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$d({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$e({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$d({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$d({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$e({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$d({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$e({}, state, { + [WALLET_DECRYPT_START]: state => _extends$d({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$d({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$e({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$d({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$e({}, state, { + [WALLET_UNLOCK_START]: state => _extends$d({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$d({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$e({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$d({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$e({}, state, { + [WALLET_LOCK_START]: state => _extends$d({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$d({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$e({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$d({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$e({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$d({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$e({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$d({}, state, { latestBlock: action.data }) }, defaultState$a); @@ -4679,14 +4663,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$f = 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; }; +var _extends$e = 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; }; const selectState$7 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$7, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$f({ + return _extends$e({ id }, params); } diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 4b07603..be13241 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -111,6 +111,7 @@ export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; export const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'; export const FETCH_FILE_INFO_COMPLETED = 'FETCH_FILE_INFO_COMPLETED'; +export const FETCH_FILE_INFO_FAILED = 'FETCH_FILE_INFO_FAILED'; export const LOADING_VIDEO_STARTED = 'LOADING_VIDEO_STARTED'; export const LOADING_VIDEO_COMPLETED = 'LOADING_VIDEO_COMPLETED'; export const LOADING_VIDEO_FAILED = 'LOADING_VIDEO_FAILED'; diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 1697687..79d9b99 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -5,16 +5,21 @@ import { doToast } from 'redux/actions/notifications'; import { selectBalance } from 'redux/selectors/wallet'; import { makeSelectFileInfoForUri, selectDownloadingByOutpoint } from 'redux/selectors/file_info'; import { makeSelectStreamingUrlForUri } from 'redux/selectors/file'; +import { makeSelectClaimForUri } from 'redux/selectors/claims'; type Dispatch = (action: any) => any; type GetState = () => { file: FileState }; export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: GetResponse => any) { - return (dispatch: Dispatch) => { + return (dispatch: Dispatch, getState: () => any) => { + const state = getState(); + const { nout, txid } = makeSelectClaimForUri(uri)(state); + const outpoint = `${txid}:${nout}`; + dispatch({ - type: ACTIONS.PURCHASE_URI_STARTED, + type: ACTIONS.FETCH_FILE_INFO_STARTED, data: { - uri, + outpoint, }, }); @@ -26,8 +31,8 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get if (timeout) { dispatch({ - type: ACTIONS.PURCHASE_URI_FAILED, - data: { uri }, + type: ACTIONS.FETCH_FILE_INFO_FAILED, + data: { outpoint }, }); dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); @@ -56,6 +61,11 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get data: { uri }, }); + dispatch({ + type: ACTIONS.FETCH_FILE_INFO_FAILED, + data: { outpoint }, + }); + dispatch( doToast({ message: `Failed to view ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`, diff --git a/src/redux/reducers/file_info.js b/src/redux/reducers/file_info.js index 5f20148..cb86718 100644 --- a/src/redux/reducers/file_info.js +++ b/src/redux/reducers/file_info.js @@ -57,20 +57,27 @@ reducers[ACTIONS.FETCH_FILE_INFO_COMPLETED] = (state, action) => { }); }; +reducers[ACTIONS.FETCH_FILE_INFO_FAILED] = (state, action) => { + const { outpoint } = action.data; + const newFetching = Object.assign({}, state.fetching); + delete newFetching[outpoint]; + + return Object.assign({}, state, { + fetching: newFetching, + }); +}; + reducers[ACTIONS.DOWNLOADING_STARTED] = (state, action) => { const { uri, outpoint, fileInfo } = action.data; const newByOutpoint = Object.assign({}, state.byOutpoint); const newDownloading = Object.assign({}, state.downloadingByOutpoint); - const newLoading = Object.assign({}, state.urisLoading); newDownloading[outpoint] = true; newByOutpoint[outpoint] = fileInfo; - delete newLoading[uri]; return Object.assign({}, state, { downloadingByOutpoint: newDownloading, - urisLoading: newLoading, byOutpoint: newByOutpoint, }); }; @@ -95,11 +102,9 @@ reducers[ACTIONS.DOWNLOADING_CANCELED] = (state, action) => { const newDownloading = Object.assign({}, state.downloadingByOutpoint); delete newDownloading[outpoint]; - delete newLoading[uri]; return Object.assign({}, state, { downloadingByOutpoint: newDownloading, - urisLoading: newLoading, }); }; @@ -133,36 +138,6 @@ reducers[ACTIONS.FILE_DELETE] = (state, action) => { }); }; -reducers[ACTIONS.LOADING_VIDEO_STARTED] = (state, action) => { - const { uri } = action.data; - - const newLoading = Object.assign({}, state.urisLoading); - newLoading[uri] = true; - - const newErrors = { ...state.errors }; - if (uri in newErrors) delete newErrors[uri]; - - return Object.assign({}, state, { - urisLoading: newLoading, - errors: { ...newErrors }, - }); -}; - -reducers[ACTIONS.LOADING_VIDEO_FAILED] = (state, action) => { - const { uri } = action.data; - - const newLoading = Object.assign({}, state.urisLoading); - delete newLoading[uri]; - - const newErrors = { ...state.errors }; - newErrors[uri] = true; - - return Object.assign({}, state, { - urisLoading: newLoading, - errors: { ...newErrors }, - }); -}; - reducers[ACTIONS.SET_FILE_LIST_SORT] = (state, action) => { const pageSortStates = { [PAGES.PUBLISHED]: 'fileListPublishedSort', -- 2.45.2 From 58bbdb9a2e537b3994d545ede120d070a7b41ee5 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 13 Aug 2019 21:05:30 -0400 Subject: [PATCH 104/371] default 'value' to object for edits so we don't need to pass in an empty object if we just want to populate the name --- dist/bundle.es.js | 2 +- src/redux/actions/publish.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 568f1c6..d7554c7 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3008,7 +3008,7 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter, fs, path) => di }; const doPrepareEdit = (claim, uri, fileInfo, fs) => dispatch => { - const { name, amount, value } = claim; + const { name, amount, value = {} } = claim; const channelName = claim && claim.signing_channel && claim.signing_channel.normalized_name || null; const { author, diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 69844c0..6c23373 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -172,7 +172,7 @@ export const doUploadThumbnail = ( export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem, fs: any) => ( dispatch: Dispatch ) => { - const { name, amount, value } = claim; + const { name, amount, value = {} } = claim; const channelName = (claim && claim.signing_channel && claim.signing_channel.normalized_name) || null; const { -- 2.45.2 From 4e093983eaf3d9e7513119657d731b808ead74a6 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 13 Aug 2019 23:52:17 -0400 Subject: [PATCH 105/371] fix: add back lost code from bad rebase --- dist/bundle.es.js | 8 ++++---- src/redux/actions/wallet.js | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d7554c7..4ef40cc 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1936,13 +1936,13 @@ function doSetDraftTransactionAddress(address) { }; } -function doSendTip(amount, claimId, successCallback, errorCallback) { +function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { return (dispatch, getState) => { const state = getState(); const balance = selectBalance(state); const myClaims = selectMyClaimsRaw(state); - const isSupport = myClaims.find(claim => claim.claim_id === claimId); + const shouldSupport = isSupport || myClaims.find(claim => claim.claim_id === claimId); if (balance - amount <= 0) { dispatch(doToast({ @@ -1954,7 +1954,7 @@ 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: shouldSupport ? __(`You deposited ${amount} LBC as a support!`) : __(`You sent ${amount} LBC as a tip, Mahalo!`), linkText: __('History'), linkTarget: __('/wallet') })); @@ -1993,7 +1993,7 @@ function doSendTip(amount, claimId, successCallback, errorCallback) { lbryProxy.support_create({ claim_id: claimId, amount: creditsToString(amount), - tip: isSupport ? false : true + tip: !shouldSupport }).then(success, error); }; } diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 00865bd..475436f 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -209,13 +209,13 @@ export function doSetDraftTransactionAddress(address) { }; } -export function doSendTip(amount, claimId, successCallback, errorCallback) { +export function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { return (dispatch, getState) => { const state = getState(); const balance = selectBalance(state); - const myClaims: Array = selectMyClaimsRaw(state); + const myClaims = selectMyClaimsRaw(state); - const isSupport = myClaims.find(claim => claim.claim_id === claimId); + const shouldSupport = isSupport || myClaims.find(claim => claim.claim_id === claimId); if (balance - amount <= 0) { dispatch( @@ -230,7 +230,7 @@ export function doSendTip(amount, claimId, successCallback, errorCallback) { const success = () => { dispatch( doToast({ - message: isSupport + message: shouldSupport ? __(`You deposited ${amount} LBC as a support!`) : __(`You sent ${amount} LBC as a tip, Mahalo!`), linkText: __('History'), @@ -274,7 +274,7 @@ export function doSendTip(amount, claimId, successCallback, errorCallback) { Lbry.support_create({ claim_id: claimId, amount: creditsToString(amount), - tip: isSupport ? false : true, + tip: !shouldSupport, }).then(success, error); }; } -- 2.45.2 From b3692b532f781f1501ea5b73f58745adfd800e4c Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 14 Aug 2019 12:52:24 -0400 Subject: [PATCH 106/371] add makeSelectFilePartlyDownloaded selector --- dist/bundle.es.js | 13 +++++++++++++ src/index.js | 1 + src/redux/selectors/file_info.js | 26 ++++++++++++++++++++++---- 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4ef40cc..4aa187a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2615,6 +2615,18 @@ const makeSelectUriIsStreamable = uri => reselect.createSelector(makeSelectMedia const makeSelectDownloadPathForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { return fileInfo && fileInfo.download_path; }); + +const makeSelectFilePartlyDownloaded = uri => reselect.createSelector(selectFileInfosByOutpoint, makeSelectClaimForUri(uri), (downloadsByOutpoint, claim) => { + if (!claim) { + return false; + } + + const { txid, nout } = claim; + const outpoint = `${txid}:${nout}`; + const isDownloaded = downloadsByOutpoint[outpoint]; + return isDownloaded; +}); + const makeSelectFileNameForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { return fileInfo && fileInfo.file_name; }); @@ -4866,6 +4878,7 @@ exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; exports.makeSelectFileNameForUri = makeSelectFileNameForUri; +exports.makeSelectFilePartlyDownloaded = makeSelectFilePartlyDownloaded; exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileForUri; exports.makeSelectIsUriResolving = makeSelectIsUriResolving; exports.makeSelectLoadingForUri = makeSelectLoadingForUri; diff --git a/src/index.js b/src/index.js index 1cb6cee..d47feb8 100644 --- a/src/index.js +++ b/src/index.js @@ -221,6 +221,7 @@ export { makeSelectUriIsStreamable, makeSelectDownloadPathForUri, makeSelectFileNameForUri, + makeSelectFilePartlyDownloaded, } from 'redux/selectors/file_info'; export { diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 7454209..8c014c5 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -4,6 +4,7 @@ import { selectMyClaims, selectClaimsById, makeSelectContentTypeForUri, + makeSelectClaimForUri, } from 'redux/selectors/claims'; import { createSelector } from 'reselect'; import { buildURI } from 'lbryURI'; @@ -241,7 +242,7 @@ export const selectDownloadedUris = createSelector( .map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) ); -export const makeSelectMediaTypeForUri = (uri: string) => +export const makeSelectMediaTypeForUri = uri => createSelector( makeSelectFileInfoForUri(uri), makeSelectContentTypeForUri(uri), @@ -255,7 +256,7 @@ export const makeSelectMediaTypeForUri = (uri: string) => } ); -export const makeSelectUriIsStreamable = (uri: string) => +export const makeSelectUriIsStreamable = uri => createSelector( makeSelectMediaTypeForUri(uri), mediaType => { @@ -264,14 +265,31 @@ export const makeSelectUriIsStreamable = (uri: string) => } ); -export const makeSelectDownloadPathForUri = (uri: string) => +export const makeSelectDownloadPathForUri = uri => createSelector( makeSelectFileInfoForUri(uri), fileInfo => { return fileInfo && fileInfo.download_path; } ); -export const makeSelectFileNameForUri = (uri: string) => + +export const makeSelectFilePartlyDownloaded = uri => + createSelector( + selectFileInfosByOutpoint, + makeSelectClaimForUri(uri), + (downloadsByOutpoint, claim) => { + if (!claim) { + return false; + } + + const { txid, nout } = claim; + const outpoint = `${txid}:${nout}`; + const isDownloaded = downloadsByOutpoint[outpoint]; + return isDownloaded; + } + ); + +export const makeSelectFileNameForUri = uri => createSelector( makeSelectFileInfoForUri(uri), fileInfo => { -- 2.45.2 From adbbd7e66019239409cd51ce3b8b1a42071bea83 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 14 Aug 2019 13:08:38 -0400 Subject: [PATCH 107/371] fix: loading selector after getting rid of urisLoading - missed this --- dist/bundle.es.js | 13 +++++++++++-- src/redux/selectors/file_info.js | 14 ++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4aa187a..aeb5956 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2452,9 +2452,18 @@ const makeSelectDownloadingForUri = uri => reselect.createSelector(selectDownloa return byOutpoint[fileInfo.outpoint]; }); -const selectUrisLoading = reselect.createSelector(selectState$3, state => state.urisLoading || {}); +const selectUrisLoading = reselect.createSelector(selectState$3, state => state.fetching || {}); -const makeSelectLoadingForUri = uri => reselect.createSelector(selectUrisLoading, byUri => byUri && byUri[uri]); +const makeSelectLoadingForUri = uri => reselect.createSelector(selectUrisLoading, makeSelectClaimForUri(uri), (fetchingByOutpoint, claim) => { + if (!claim) { + return false; + } + + const { txid, nout } = claim; + const outpoint = `${txid}:${nout}`; + const isFetching = fetchingByOutpoint[outpoint]; + return isFetching; +}); const selectFileInfosDownloaded = reselect.createSelector(selectFileInfosByOutpoint, selectMyClaims, (byOutpoint, myClaims) => Object.values(byOutpoint).filter(fileInfo => { const myClaimIds = myClaims.map(claim => claim.claim_id); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 8c014c5..25af571 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -56,13 +56,23 @@ export const makeSelectDownloadingForUri = uri => export const selectUrisLoading = createSelector( selectState, - state => state.urisLoading || {} + state => state.fetching || {} ); export const makeSelectLoadingForUri = uri => createSelector( selectUrisLoading, - byUri => byUri && byUri[uri] + makeSelectClaimForUri(uri), + (fetchingByOutpoint, claim) => { + if (!claim) { + return false; + } + + const { txid, nout } = claim; + const outpoint = `${txid}:${nout}`; + const isFetching = fetchingByOutpoint[outpoint]; + return isFetching; + } ); export const selectFileInfosDownloaded = createSelector( -- 2.45.2 From 1bd625f0c6e9e36d14eb0c520a3eb99f9600705d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 14 Aug 2019 13:51:30 -0400 Subject: [PATCH 108/371] actually check if something's been downloaded --- dist/bundle.es.js | 9 +++------ src/redux/selectors/file_info.js | 12 ++++-------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index aeb5956..baa40ce 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2625,15 +2625,12 @@ const makeSelectDownloadPathForUri = uri => reselect.createSelector(makeSelectFi return fileInfo && fileInfo.download_path; }); -const makeSelectFilePartlyDownloaded = uri => reselect.createSelector(selectFileInfosByOutpoint, makeSelectClaimForUri(uri), (downloadsByOutpoint, claim) => { - if (!claim) { +const makeSelectFilePartlyDownloaded = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { + if (!fileInfo) { return false; } - const { txid, nout } = claim; - const outpoint = `${txid}:${nout}`; - const isDownloaded = downloadsByOutpoint[outpoint]; - return isDownloaded; + return fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0; }); const makeSelectFileNameForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 25af571..c36bd76 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -285,17 +285,13 @@ export const makeSelectDownloadPathForUri = uri => export const makeSelectFilePartlyDownloaded = uri => createSelector( - selectFileInfosByOutpoint, - makeSelectClaimForUri(uri), - (downloadsByOutpoint, claim) => { - if (!claim) { + makeSelectFileInfoForUri(uri), + fileInfo => { + if (!fileInfo) { return false; } - const { txid, nout } = claim; - const outpoint = `${txid}:${nout}`; - const isDownloaded = downloadsByOutpoint[outpoint]; - return isDownloaded; + return fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0; } ); -- 2.45.2 From 1a3615cddba989703da1fae3925fdac30f1a801c Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Wed, 14 Aug 2019 14:47:57 -0400 Subject: [PATCH 109/371] fix: publish bugs Fixes files being passed on edit + tags not repopulating. --- dist/bundle.es.js | 15 ++++----------- src/redux/actions/publish.js | 11 ++--------- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index aeb5956..8cd3dd8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3044,7 +3044,8 @@ const doPrepareEdit = (claim, uri, fileInfo, fs) => dispatch => { license, license_url: licenseUrl, thumbnail, - title + title, + tags } = value; const publishData = { @@ -3060,7 +3061,8 @@ const doPrepareEdit = (claim, uri, fileInfo, fs) => dispatch => { uri, uploadThumbnailStatus: thumbnail ? MANUAL : undefined, licenseUrl, - nsfw: isClaimNsfw(claim) + nsfw: isClaimNsfw(claim), + tags: tags ? tags.map(tag => ({ name: tag })) : [] }; // Make sure custom licenses are mapped properly @@ -3082,15 +3084,6 @@ const doPrepareEdit = (claim, uri, fileInfo, fs) => dispatch => { publishData['channel'] = channelName; } - if (fs && fileInfo && fileInfo.download_path) { - try { - fs.accessSync(fileInfo.download_path, fs.constants.R_OK); - publishData.filePath = fileInfo.download_path; - } catch (e) { - console.error(e.name, e.message); - } - } - dispatch({ type: DO_PREPARE_EDIT, data: publishData }); }; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 6c23373..5db20c9 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -189,6 +189,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis license_url: licenseUrl, thumbnail, title, + tags, } = value; const publishData: UpdatePublishFormData = { @@ -205,6 +206,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis uploadThumbnailStatus: thumbnail ? THUMBNAIL_STATUSES.MANUAL : undefined, licenseUrl, nsfw: isClaimNsfw(claim), + tags: tags ? tags.map(tag => ({ name: tag })) : [], }; // Make sure custom licenses are mapped properly @@ -226,15 +228,6 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis publishData['channel'] = channelName; } - if (fs && fileInfo && fileInfo.download_path) { - try { - fs.accessSync(fileInfo.download_path, fs.constants.R_OK); - publishData.filePath = fileInfo.download_path; - } catch (e) { - console.error(e.name, e.message); - } - } - dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData }); }; -- 2.45.2 From 6005fa245a888e2de045d7e42411847de7943f52 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Wed, 14 Aug 2019 18:22:50 -0400 Subject: [PATCH 110/371] fix: streaming + downloads Allows you to download while streaming + re-download already streamed content if it was deleted or settings changed. --- dist/bundle.es.js | 2 +- src/redux/actions/file.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index baa40ce..79ea5d8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2730,7 +2730,7 @@ function doPurchaseUri(uri, costInfo, saveFile = true, onSuccess) { const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint]; const alreadyStreaming = makeSelectStreamingUrlForUri(uri)(state); - if (alreadyDownloading || alreadyStreaming) { + if (!saveFile && (alreadyDownloading || alreadyStreaming)) { dispatch({ type: PURCHASE_URI_FAILED, data: { uri, error: `Already fetching uri: ${uri}` } diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 79d9b99..f6befff 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -95,7 +95,7 @@ export function doPurchaseUri( const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint]; const alreadyStreaming = makeSelectStreamingUrlForUri(uri)(state); - if (alreadyDownloading || alreadyStreaming) { + if (!saveFile && (alreadyDownloading || alreadyStreaming)) { dispatch({ type: ACTIONS.PURCHASE_URI_FAILED, data: { uri, error: `Already fetching uri: ${uri}` }, -- 2.45.2 From 027c517ec653f328eeed2cf509b1062b0f787f22 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 14 Aug 2019 23:47:04 -0400 Subject: [PATCH 111/371] update for 0.38.7 account_balance api changes --- dist/bundle.es.js | 4 ++-- src/redux/actions/wallet.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index baa40ce..049f588 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1750,8 +1750,8 @@ function doUpdateBalance() { const { wallet: { balance: balanceInStore } } = getState(); - lbryProxy.account_balance().then(balanceAsString => { - const balance = parseFloat(balanceAsString); + lbryProxy.account_balance().then(({ available }) => { + const balance = parseFloat(available); if (balanceInStore !== balance) { dispatch({ type: UPDATE_BALANCE, diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 475436f..8757422 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -10,8 +10,8 @@ export function doUpdateBalance() { const { wallet: { balance: balanceInStore }, } = getState(); - Lbry.account_balance().then(balanceAsString => { - const balance = parseFloat(balanceAsString); + Lbry.account_balance().then(({ available }) => { + const balance = parseFloat(available); if (balanceInStore !== balance) { dispatch({ type: ACTIONS.UPDATE_BALANCE, -- 2.45.2 From 197e55b6390025ad779ea219afe457a902bd6073 Mon Sep 17 00:00:00 2001 From: zxawry Date: Thu, 15 Aug 2019 07:13:50 +0100 Subject: [PATCH 112/371] yarn build --- dist/bundle.es.js | 331 +++++++++++++++++++++++++--------------------- 1 file changed, 180 insertions(+), 151 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 14e4c16..eb98dbd 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1229,6 +1229,156 @@ function doDismissError() { }; } +const selectState$1 = state => state.wallet || {}; + +const selectWalletState = selectState$1; + +const selectWalletIsEncrypted = reselect.createSelector(selectState$1, state => state.walletIsEncrypted); + +const selectWalletEncryptPending = reselect.createSelector(selectState$1, state => state.walletEncryptPending); + +const selectWalletEncryptSucceeded = reselect.createSelector(selectState$1, state => state.walletEncryptSucceded); + +const selectWalletEncryptResult = reselect.createSelector(selectState$1, state => state.walletEncryptResult); + +const selectWalletDecryptPending = reselect.createSelector(selectState$1, state => state.walletDecryptPending); + +const selectWalletDecryptSucceeded = reselect.createSelector(selectState$1, state => state.walletDecryptSucceded); + +const selectWalletDecryptResult = reselect.createSelector(selectState$1, state => state.walletDecryptResult); + +const selectWalletUnlockPending = reselect.createSelector(selectState$1, state => state.walletUnlockPending); + +const selectWalletUnlockSucceeded = reselect.createSelector(selectState$1, state => state.walletUnlockSucceded); + +const selectWalletUnlockResult = reselect.createSelector(selectState$1, state => state.walletUnlockResult); + +const selectWalletLockPending = reselect.createSelector(selectState$1, state => state.walletLockPending); + +const selectWalletLockSucceeded = reselect.createSelector(selectState$1, state => state.walletLockSucceded); + +const selectWalletLockResult = reselect.createSelector(selectState$1, state => state.walletLockResult); + +const selectBalance = reselect.createSelector(selectState$1, state => state.balance); + +const selectTotalBalance = reselect.createSelector(selectState$1, state => state.totalBalance); + +const selectTransactionsById = reselect.createSelector(selectState$1, state => state.transactions || {}); + +const selectSupportsByOutpoint = reselect.createSelector(selectState$1, state => state.supports || {}); + +const selectTotalSupports = reselect.createSelector(selectSupportsByOutpoint, byOutpoint => { + let total = parseFloat("0.0"); + + Object.values(byOutpoint).forEach(support => { + const { amount } = support; + total = amount ? total + parseFloat(amount) : total; + }); + + return total; +}); + +const selectTransactionItems = reselect.createSelector(selectTransactionsById, byId => { + const items = []; + + Object.keys(byId).forEach(txid => { + const tx = byId[txid]; + + // ignore dust/fees + // it is fee only txn if all infos are also empty + if (Math.abs(tx.value) === Math.abs(tx.fee) && tx.claim_info.length === 0 && tx.support_info.length === 0 && tx.update_info.length === 0 && tx.abandon_info.length === 0) { + return; + } + + const append = []; + + append.push(...tx.claim_info.map(item => Object.assign({}, tx, item, { + type: item.claim_name[0] === '@' ? CHANNEL$1 : PUBLISH$1 + }))); + append.push(...tx.support_info.map(item => Object.assign({}, tx, item, { + type: !item.is_tip ? SUPPORT : TIP + }))); + append.push(...tx.update_info.map(item => Object.assign({}, tx, item, { type: UPDATE }))); + append.push(...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: ABANDON }))); + + if (!append.length) { + append.push(Object.assign({}, tx, { + type: tx.value < 0 ? SPEND : RECEIVE + })); + } + + items.push(...append.map(item => { + // value on transaction, amount on outpoint + // amount is always positive, but should match sign of value + const balanceDelta = parseFloat(item.balance_delta); + const value = parseFloat(item.value); + const amount = balanceDelta || value; + const fee = parseFloat(tx.fee); + + return { + txid, + timestamp: tx.timestamp, + date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, + amount, + fee, + claim_id: item.claim_id, + claim_name: item.claim_name, + type: item.type || SPEND, + nout: item.nout, + confirmations: tx.confirmations + }; + })); + }); + + return items.sort((tx1, tx2) => { + if (!tx1.timestamp && !tx2.timestamp) { + return 0; + } else if (!tx1.timestamp && tx2.timestamp) { + return -1; + } else if (tx1.timestamp && !tx2.timestamp) { + return 1; + } + + return tx2.timestamp - tx1.timestamp; + }); +}); + +const selectRecentTransactions = reselect.createSelector(selectTransactionItems, transactions => { + const threshold = new Date(); + threshold.setDate(threshold.getDate() - 7); + return transactions.filter(transaction => { + if (!transaction.date) { + return true; // pending transaction + } + + return transaction.date > threshold; + }); +}); + +const selectHasTransactions = reselect.createSelector(selectTransactionItems, transactions => transactions && transactions.length > 0); + +const selectIsFetchingTransactions = reselect.createSelector(selectState$1, state => state.fetchingTransactions); + +const selectIsSendingSupport = reselect.createSelector(selectState$1, state => state.sendingSupport); + +const selectReceiveAddress = reselect.createSelector(selectState$1, state => state.receiveAddress); + +const selectGettingNewAddress = reselect.createSelector(selectState$1, state => state.gettingNewAddress); + +const selectDraftTransaction = reselect.createSelector(selectState$1, state => state.draftTransaction || {}); + +const selectDraftTransactionAmount = reselect.createSelector(selectDraftTransaction, draft => draft.amount); + +const selectDraftTransactionAddress = reselect.createSelector(selectDraftTransaction, draft => draft.address); + +const selectDraftTransactionError = reselect.createSelector(selectDraftTransaction, draft => draft.error); + +const selectBlocks = reselect.createSelector(selectState$1, state => state.blocks); + +const selectCurrentHeight = reselect.createSelector(selectState$1, state => state.latestBlock); + +const selectTransactionListFilter = reselect.createSelector(selectState$1, state => state.transactionListFilter || ''); + 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; } @@ -1265,13 +1415,13 @@ function createNormalizedClaimSearchKey(options) { // -const selectState$1 = state => state.claims || {}; +const selectState$2 = state => state.claims || {}; -const selectClaimsById = reselect.createSelector(selectState$1, state => state.byId || {}); +const selectClaimsById = reselect.createSelector(selectState$2, state => state.byId || {}); -const selectCurrentChannelPage = reselect.createSelector(selectState$1, state => state.currentChannelPage || 1); +const selectCurrentChannelPage = reselect.createSelector(selectState$2, state => state.currentChannelPage || 1); -const selectClaimsByUri = reselect.createSelector(selectState$1, selectClaimsById, (state, byId) => { +const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { const byUri = state.claimsByUri || {}; const claims = {}; @@ -1291,11 +1441,11 @@ const selectClaimsByUri = reselect.createSelector(selectState$1, selectClaimsByI return claims; }); -const selectAllClaimsByChannel = reselect.createSelector(selectState$1, state => state.claimsByChannel || {}); +const selectAllClaimsByChannel = reselect.createSelector(selectState$2, state => state.claimsByChannel || {}); -const selectPendingById = reselect.createSelector(selectState$1, state => state.pendingById || {}); +const selectPendingById = reselect.createSelector(selectState$2, state => state.pendingById || {}); -const selectPendingClaims = reselect.createSelector(selectState$1, state => Object.values(state.pendingById || [])); +const selectPendingClaims = reselect.createSelector(selectState$2, state => Object.values(state.pendingById || [])); const makeSelectClaimIsPending = uri => reselect.createSelector(selectPendingById, pendingById => { let claimId; @@ -1335,9 +1485,9 @@ const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, } }); -const selectMyClaimsRaw = reselect.createSelector(selectState$1, state => state.myClaims); +const selectMyClaimsRaw = reselect.createSelector(selectState$2, state => state.myClaims); -const selectAbandoningIds = reselect.createSelector(selectState$1, state => Object.keys(state.abandoningById || {})); +const selectAbandoningIds = reselect.createSelector(selectState$2, state => Object.keys(state.abandoningById || {})); const selectMyActiveClaims = reselect.createSelector(selectMyClaimsRaw, selectAbandoningIds, (claims, abandoningIds) => new Set(claims && claims.map(claim => claim.claim_id).filter(claimId => Object.keys(abandoningIds).indexOf(claimId) === -1))); @@ -1358,7 +1508,7 @@ const makeSelectClaimIsMine = rawUri => { }); }; -const selectAllFetchingChannelClaims = reselect.createSelector(selectState$1, state => state.fetchingChannelClaims || {}); +const selectAllFetchingChannelClaims = reselect.createSelector(selectState$2, state => state.fetchingChannelClaims || {}); const makeSelectFetchingChannelClaims = uri => reselect.createSelector(selectAllFetchingChannelClaims, fetching => fetching && fetching[uri]); @@ -1423,7 +1573,7 @@ const makeSelectCoverForUri = uri => reselect.createSelector(makeSelectClaimForU return cover ? cover.url : undefined; }); -const selectIsFetchingClaimListMine = reselect.createSelector(selectState$1, state => state.isFetchingClaimListMine); +const selectIsFetchingClaimListMine = reselect.createSelector(selectState$2, state => state.isFetchingClaimListMine); const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, (myClaimIds, byId, abandoningIds, pendingClaims) => { const claims = []; @@ -1459,9 +1609,9 @@ const selectMyClaimsOutpoints = reselect.createSelector(selectMyClaims, myClaims return outpoints; }); -const selectFetchingMyChannels = reselect.createSelector(selectState$1, state => state.fetchingMyChannels); +const selectFetchingMyChannels = reselect.createSelector(selectState$2, state => state.fetchingMyChannels); -const selectMyChannelClaims = reselect.createSelector(selectState$1, selectClaimsById, (state, byId) => { +const selectMyChannelClaims = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { const ids = state.myChannelClaims || []; const claims = []; @@ -1475,13 +1625,13 @@ const selectMyChannelClaims = reselect.createSelector(selectState$1, selectClaim return claims; }); -const selectResolvingUris = reselect.createSelector(selectState$1, state => state.resolvingUris || []); +const selectResolvingUris = reselect.createSelector(selectState$2, state => state.resolvingUris || []); const makeSelectIsUriResolving = uri => reselect.createSelector(selectResolvingUris, resolvingUris => resolvingUris && resolvingUris.indexOf(uri) !== -1); -const selectPlayingUri = reselect.createSelector(selectState$1, state => state.playingUri); +const selectPlayingUri = reselect.createSelector(selectState$2, state => state.playingUri); -const selectChannelClaimCounts = reselect.createSelector(selectState$1, state => state.channelClaimCounts || {}); +const selectChannelClaimCounts = reselect.createSelector(selectState$2, state => state.channelClaimCounts || {}); const makeSelectTotalItemsForChannel = uri => reselect.createSelector(selectChannelClaimCounts, byUri => byUri && byUri[uri]); @@ -1564,153 +1714,30 @@ const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataFo return metadata && metadata.tags || []; }); -const selectFetchingClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.fetchingClaimSearchByQuery || {}); +const selectFetchingClaimSearchByQuery = reselect.createSelector(selectState$2, state => state.fetchingClaimSearchByQuery || {}); const selectFetchingClaimSearch = reselect.createSelector(selectFetchingClaimSearchByQuery, fetchingClaimSearchByQuery => Boolean(Object.keys(fetchingClaimSearchByQuery).length)); -const selectClaimSearchByQuery = reselect.createSelector(selectState$1, state => state.claimSearchByQuery || {}); +const selectClaimSearchByQuery = reselect.createSelector(selectState$2, state => state.claimSearchByQuery || {}); const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); -const selectState$2 = state => state.wallet || {}; +const makeSelectSupportsForUri = uri => reselect.createSelector(selectSupportsByOutpoint, makeSelectClaimForUri(uri), (byOutpoint, claim) => { + if (!claim || !claim.is_mine) { + return null; + } -const selectWalletState = selectState$2; + const { claim_id: claimId } = claim; + let total = parseFloat("0.0"); -const selectWalletIsEncrypted = reselect.createSelector(selectState$2, state => state.walletIsEncrypted); - -const selectWalletEncryptPending = reselect.createSelector(selectState$2, state => state.walletEncryptPending); - -const selectWalletEncryptSucceeded = reselect.createSelector(selectState$2, state => state.walletEncryptSucceded); - -const selectWalletEncryptResult = reselect.createSelector(selectState$2, state => state.walletEncryptResult); - -const selectWalletDecryptPending = reselect.createSelector(selectState$2, state => state.walletDecryptPending); - -const selectWalletDecryptSucceeded = reselect.createSelector(selectState$2, state => state.walletDecryptSucceded); - -const selectWalletDecryptResult = reselect.createSelector(selectState$2, state => state.walletDecryptResult); - -const selectWalletUnlockPending = reselect.createSelector(selectState$2, state => state.walletUnlockPending); - -const selectWalletUnlockSucceeded = reselect.createSelector(selectState$2, state => state.walletUnlockSucceded); - -const selectWalletUnlockResult = reselect.createSelector(selectState$2, state => state.walletUnlockResult); - -const selectWalletLockPending = reselect.createSelector(selectState$2, state => state.walletLockPending); - -const selectWalletLockSucceeded = reselect.createSelector(selectState$2, state => state.walletLockSucceded); - -const selectWalletLockResult = reselect.createSelector(selectState$2, state => state.walletLockResult); - -const selectBalance = reselect.createSelector(selectState$2, state => state.balance); - -const selectTotalBalance = reselect.createSelector(selectState$2, state => state.totalBalance); - -const selectTransactionsById = reselect.createSelector(selectState$2, state => state.transactions || {}); - -const selectSupportsByOutpoint = reselect.createSelector(selectState$2, state => state.supports || {}); - -const selectTransactionItems = reselect.createSelector(selectTransactionsById, byId => { - const items = []; - - Object.keys(byId).forEach(txid => { - const tx = byId[txid]; - - // ignore dust/fees - // it is fee only txn if all infos are also empty - if (Math.abs(tx.value) === Math.abs(tx.fee) && tx.claim_info.length === 0 && tx.support_info.length === 0 && tx.update_info.length === 0 && tx.abandon_info.length === 0) { - return; - } - - const append = []; - - append.push(...tx.claim_info.map(item => Object.assign({}, tx, item, { - type: item.claim_name[0] === '@' ? CHANNEL$1 : PUBLISH$1 - }))); - append.push(...tx.support_info.map(item => Object.assign({}, tx, item, { - type: !item.is_tip ? SUPPORT : TIP - }))); - append.push(...tx.update_info.map(item => Object.assign({}, tx, item, { type: UPDATE }))); - append.push(...tx.abandon_info.map(item => Object.assign({}, tx, item, { type: ABANDON }))); - - if (!append.length) { - append.push(Object.assign({}, tx, { - type: tx.value < 0 ? SPEND : RECEIVE - })); - } - - items.push(...append.map(item => { - // value on transaction, amount on outpoint - // amount is always positive, but should match sign of value - const balanceDelta = parseFloat(item.balance_delta); - const value = parseFloat(item.value); - const amount = balanceDelta || value; - const fee = parseFloat(tx.fee); - - return { - txid, - timestamp: tx.timestamp, - date: tx.timestamp ? new Date(Number(tx.timestamp) * 1000) : null, - amount, - fee, - claim_id: item.claim_id, - claim_name: item.claim_name, - type: item.type || SPEND, - nout: item.nout, - confirmations: tx.confirmations - }; - })); + Object.values(byOutpoint).forEach(support => { + const { claim_id, amount } = support; + total = claim_id === claimId && amount ? total + parseFloat(amount) : total; }); - return items.sort((tx1, tx2) => { - if (!tx1.timestamp && !tx2.timestamp) { - return 0; - } else if (!tx1.timestamp && tx2.timestamp) { - return -1; - } else if (tx1.timestamp && !tx2.timestamp) { - return 1; - } - - return tx2.timestamp - tx1.timestamp; - }); + return total; }); -const selectRecentTransactions = reselect.createSelector(selectTransactionItems, transactions => { - const threshold = new Date(); - threshold.setDate(threshold.getDate() - 7); - return transactions.filter(transaction => { - if (!transaction.date) { - return true; // pending transaction - } - - return transaction.date > threshold; - }); -}); - -const selectHasTransactions = reselect.createSelector(selectTransactionItems, transactions => transactions && transactions.length > 0); - -const selectIsFetchingTransactions = reselect.createSelector(selectState$2, state => state.fetchingTransactions); - -const selectIsSendingSupport = reselect.createSelector(selectState$2, state => state.sendingSupport); - -const selectReceiveAddress = reselect.createSelector(selectState$2, state => state.receiveAddress); - -const selectGettingNewAddress = reselect.createSelector(selectState$2, state => state.gettingNewAddress); - -const selectDraftTransaction = reselect.createSelector(selectState$2, state => state.draftTransaction || {}); - -const selectDraftTransactionAmount = reselect.createSelector(selectDraftTransaction, draft => draft.amount); - -const selectDraftTransactionAddress = reselect.createSelector(selectDraftTransaction, draft => draft.address); - -const selectDraftTransactionError = reselect.createSelector(selectDraftTransaction, draft => draft.error); - -const selectBlocks = reselect.createSelector(selectState$2, state => state.blocks); - -const selectCurrentHeight = reselect.createSelector(selectState$2, state => state.latestBlock); - -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+$/, ''); @@ -4859,6 +4886,7 @@ exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; exports.makeSelectSearchUris = makeSelectSearchUris; exports.makeSelectShortUrlForUri = makeSelectShortUrlForUri; exports.makeSelectStreamingUrlForUri = makeSelectStreamingUrlForUri; +exports.makeSelectSupportsForUri = makeSelectSupportsForUri; exports.makeSelectTagsForUri = makeSelectTagsForUri; exports.makeSelectThumbnailForUri = makeSelectThumbnailForUri; exports.makeSelectTitleForUri = makeSelectTitleForUri; @@ -4945,6 +4973,7 @@ exports.selectTakeOverAmount = selectTakeOverAmount; exports.selectToast = selectToast; exports.selectTotalBalance = selectTotalBalance; exports.selectTotalDownloadProgress = selectTotalDownloadProgress; +exports.selectTotalSupports = selectTotalSupports; exports.selectTransactionItems = selectTransactionItems; exports.selectTransactionListFilter = selectTransactionListFilter; exports.selectTransactionsById = selectTransactionsById; -- 2.45.2 From 22dc431ee0230e9b7455f6f7a1eaebdf93dab439 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 16 Aug 2019 01:16:04 -0400 Subject: [PATCH 113/371] remove mime --- dist/bundle.es.js | 36 +++++++++++++------------------- flow-typed/mime.js | 4 ---- package.json | 1 - src/lbry.js | 51 +++++++++++++++++++--------------------------- yarn.lock | 5 ----- 5 files changed, 35 insertions(+), 62 deletions(-) delete mode 100644 flow-typed/mime.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index baa40ce..fbd32c8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5,7 +5,6 @@ Object.defineProperty(exports, '__esModule', { value: true }); function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } require('proxy-polyfill'); -var mime = _interopDefault(require('mime')); var reselect = require('reselect'); var uuid = _interopDefault(require('uuid/v4')); @@ -692,29 +691,22 @@ const Lbry = { // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType, fileName) => { - const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book']]; + if (fileName) { + const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book']]; - const extName = mime.getExtension(contentType); - const fileExt = extName ? `.${extName}` : null; - const testString = fileName || fileExt; - - // Get mediaType from file extension - if (testString) { const res = formats.reduce((ret, testpair) => { - const [regex, mediaType] = testpair; - - return regex.test(ret) ? mediaType : ret; - }, testString); - - if (res !== testString) return res; - } - - // Get mediaType from contentType - if (contentType) { - const matches = /^[^/]+/.exec(contentType); - if (matches) { - return matches[0]; - } + switch (testpair[0].test(ret)) { + case true: + return testpair[1]; + default: + return ret; + } + }, fileName); + return res === fileName ? 'unknown' : res; + } else if (contentType) { + // $FlowFixMe + return (/^[^/]+/.exec(contentType)[0] + ); } return 'unknown'; diff --git a/flow-typed/mime.js b/flow-typed/mime.js deleted file mode 100644 index 476b179..0000000 --- a/flow-typed/mime.js +++ /dev/null @@ -1,4 +0,0 @@ -// @flow -declare module 'mime' { - declare module.exports: any; -} diff --git a/package.json b/package.json index 8cba56d..21b595f 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,6 @@ "format": "prettier 'src/**/*.{js,json}' --write" }, "dependencies": { - "mime": "^2.4.4", "proxy-polyfill": "0.1.6", "reselect": "^3.0.0", "uuid": "^3.3.2" diff --git a/src/lbry.js b/src/lbry.js index b87a8a2..6313063 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -1,6 +1,5 @@ // @flow import 'proxy-polyfill'; -import mime from 'mime'; const CHECK_DAEMON_STARTED_TRY_NUMBER = 200; // @@ -34,37 +33,29 @@ const Lbry: LbryTypes = { // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType?: string, fileName: ?string) => { - const formats = [ - [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], - [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], - [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], - [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], - [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], - [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], - [/\.(cbr|cbt|cbz)$/i, 'comic-book'], - ]; + if (fileName) { + const formats = [ + [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], + [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], + [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], + [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], + [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], + [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], + [/\.(cbr|cbt|cbz)$/i, 'comic-book'], + ]; - const extName = mime.getExtension(contentType); - const fileExt = extName ? `.${extName}` : null; - const testString = fileName || fileExt; - - // Get mediaType from file extension - if (testString) { const res = formats.reduce((ret, testpair) => { - const [regex, mediaType] = testpair; - - return regex.test(ret) ? mediaType : ret; - }, testString); - - if (res !== testString) return res; - } - - // Get mediaType from contentType - if (contentType) { - const matches = /^[^/]+/.exec(contentType); - if (matches) { - return matches[0]; - } + switch (testpair[0].test(ret)) { + case true: + return testpair[1]; + default: + return ret; + } + }, fileName); + return res === fileName ? 'unknown' : res; + } else if (contentType) { + // $FlowFixMe + return /^[^/]+/.exec(contentType)[0]; } return 'unknown'; diff --git a/yarn.lock b/yarn.lock index 182afdc..49dc513 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3523,11 +3523,6 @@ mime-types@^2.1.12, mime-types@~2.1.17: dependencies: mime-db "~1.33.0" -mime@^2.4.4: - version "2.4.4" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.4.4.tgz#bd7b91135fc6b01cde3e9bae33d659b63d8857e5" - integrity sha512-LRxmNwziLPT828z+4YkNzloCFC2YM4wrB99k+AV5ZbEyfGNWfG8SO1FUXLmLDBSo89NrJZ4DIWeLjy1CHGhMGA== - mimic-fn@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" -- 2.45.2 From 91f0e2ab54e8987780f8b19d7d69bee688caad90 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 16 Aug 2019 15:54:38 +0100 Subject: [PATCH 114/371] improve short format for balance credits >1K and >1M (#184) --- dist/bundle.es.js | 21 +++++++++++++++++---- src/util/format-credits.js | 23 +++++++++++++++++------ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index acca6d9..87e3694 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1724,7 +1724,7 @@ const selectFetchingClaimSearch = reselect.createSelector(selectFetchingClaimSea const selectClaimSearchByQuery = reselect.createSelector(selectState$2, state => state.claimSearchByQuery || {}); -const selectClaimSearchByQueryLastPageReached = reselect.createSelector(selectState$1, state => state.claimSearchByQueryLastPageReached || {}); +const selectClaimSearchByQueryLastPageReached = reselect.createSelector(selectState$2, state => state.claimSearchByQueryLastPageReached || {}); const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); @@ -1744,9 +1744,22 @@ const makeSelectSupportsForUri = uri => reselect.createSelector(selectSupportsBy return total; }); -function formatCredits(amount, precision) { - if (Number.isNaN(parseFloat(amount))) return '0'; - return parseFloat(amount).toFixed(precision || 1).replace(/\.?0+$/, ''); +function formatCredits(amount, precision, shortFormat = false) { + let actualAmount = parseFloat(amount), + suffix = ''; + if (Number.isNaN(actualAmount)) return '0'; + + if (shortFormat) { + if (actualAmount >= 1000000) { + actualAmount = actualAmount / 1000000; + suffix = 'M'; + } else if (actualAmount >= 1000) { + actualAmount = actualAmount / 1000; + suffix = 'K'; + } + } + + return actualAmount.toFixed(precision || 1).replace(/\.?0+$/, '') + suffix; } function formatFullPrice(amount, precision = 1) { diff --git a/src/util/format-credits.js b/src/util/format-credits.js index e32b2d8..fae1f44 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -1,8 +1,19 @@ -export function formatCredits(amount, precision) { - if (Number.isNaN(parseFloat(amount))) return '0'; - return parseFloat(amount) - .toFixed(precision || 1) - .replace(/\.?0+$/, ''); +export function formatCredits(amount, precision, shortFormat = false) { + let actualAmount = parseFloat(amount), + suffix = ''; + if (Number.isNaN(actualAmount)) return '0'; + + if (shortFormat) { + if (actualAmount >= 1000000) { + actualAmount = actualAmount / 1000000; + suffix = 'M'; + } else if (actualAmount >= 1000) { + actualAmount = actualAmount / 1000; + suffix = 'K'; + } + } + + return actualAmount.toFixed(precision || 1).replace(/\.?0+$/, '') + suffix; } export function formatFullPrice(amount, precision = 1) { @@ -13,7 +24,7 @@ export function formatFullPrice(amount, precision = 1) { if (fraction) { const decimals = fraction.split(''); - const first = decimals.filter((number) => number !== '0')[0]; + const first = decimals.filter(number => number !== '0')[0]; const index = decimals.indexOf(first); // Set format fraction -- 2.45.2 From 49479b4fd17a3f790ef873c79d16ea0d0c672230 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 13 Aug 2019 14:40:55 -0400 Subject: [PATCH 115/371] feat: 0.39 account balance basic API support Support for the available balance. Doesn't include any of the new fields. Enabled @flow support on wallet file, didn't fix other issues. --- dist/bundle.es.js | 7 +++++-- dist/flow-typed/Lbry.js | 11 +++++++++++ flow-typed/Lbry.js | 13 ++++++++++++- src/lbry.js | 2 +- src/redux/actions/wallet.js | 4 +++- 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 6ae34e2..2edcc0e 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -741,7 +741,7 @@ const Lbry = { blob_list: (params = {}) => daemonCallWithResult('blob_list', params), // Wallet utilities - account_balance: (params = {}) => daemonCallWithResult('account_balance', params), + account_balance: () => daemonCallWithResult('account_balance'), account_decrypt: () => daemonCallWithResult('account_decrypt', {}), account_encrypt: (params = {}) => daemonCallWithResult('account_encrypt', params), account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), @@ -1777,12 +1777,15 @@ function creditsToString(amount) { return creditString; } +// + function doUpdateBalance() { return (dispatch, getState) => { const { wallet: { balance: balanceInStore } } = getState(); - lbryProxy.account_balance().then(({ available }) => { + lbryProxy.account_balance().then(response => { + const { available } = response; const balance = parseFloat(available); if (balanceInStore !== balance) { dispatch({ diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index a403ffb..6f32b2b 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -63,6 +63,17 @@ declare type VersionResponse = { python_version: string, }; +declare type BalanceResponse = { + available: string, + reserved: string, + reserved_subtotals: ? { + claims: string, + supports: string, + tips: string, + }, + total: string, +}; + declare type ResolveResponse = { // Keys are the url(s) passed to resolve [string]: Claim | { error?: {} }, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index a403ffb..d9f1a7a 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -63,6 +63,17 @@ declare type VersionResponse = { python_version: string, }; +declare type BalanceResponse = { + available: string, + reserved: string, + reserved_subtotals: ?{ + claims: string, + supports: string, + tips: string, + }, + total: string, +}; + declare type ResolveResponse = { // Keys are the url(s) passed to resolve [string]: Claim | { error?: {} }, @@ -194,7 +205,7 @@ declare type LbryTypes = { comment_list: (params: {}) => Promise, comment_create: (params: {}) => Promise, // Wallet utilities - account_balance: (params: {}) => Promise, + account_balance: (params: {}) => Promise, account_decrypt: (prams: {}) => Promise, account_encrypt: (params: {}) => Promise, account_unlock: (params: {}) => Promise, diff --git a/src/lbry.js b/src/lbry.js index 6313063..44b57cd 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -90,7 +90,7 @@ const Lbry: LbryTypes = { blob_list: (params = {}) => daemonCallWithResult('blob_list', params), // Wallet utilities - account_balance: (params = {}) => daemonCallWithResult('account_balance', params), + account_balance: () => daemonCallWithResult('account_balance'), account_decrypt: () => daemonCallWithResult('account_decrypt', {}), account_encrypt: (params = {}) => daemonCallWithResult('account_encrypt', params), account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 8757422..55f0751 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -1,3 +1,4 @@ +// @flow import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import { doToast } from 'redux/actions/notifications'; @@ -10,7 +11,8 @@ export function doUpdateBalance() { const { wallet: { balance: balanceInStore }, } = getState(); - Lbry.account_balance().then(({ available }) => { + Lbry.account_balance().then((response: BalanceResponse) => { + const { available } = response; const balance = parseFloat(available); if (balanceInStore !== balance) { dispatch({ -- 2.45.2 From f5289f981145b5fb2867f4e369ef3ad9f3e913a6 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 20 Aug 2019 16:00:26 -0400 Subject: [PATCH 116/371] use canonical_url everywhere and update url parse/build functions to work with canonical_url's properly --- .flowconfig | 1 + dist/bundle.es.js | 364 ++++++++++++++++++++------------- dist/flow-typed/Claim.js | 1 + dist/flow-typed/Lbry.js | 2 +- dist/flow-typed/i18n.js | 2 + flow-typed/Claim.js | 1 + flow-typed/Lbry.js | 2 +- flow-typed/i18n.js | 2 + src/index.js | 1 + src/lbryURI.js | 341 ++++++++++++++++++------------ src/redux/actions/claims.js | 8 +- src/redux/actions/search.js | 24 ++- src/redux/reducers/claims.js | 33 ++- src/redux/selectors/claims.js | 38 ++-- src/redux/selectors/publish.js | 18 +- src/redux/selectors/search.js | 10 +- src/util/uri.js | 13 -- 17 files changed, 515 insertions(+), 346 deletions(-) create mode 100644 dist/flow-typed/i18n.js create mode 100644 flow-typed/i18n.js delete mode 100644 src/util/uri.js diff --git a/.flowconfig b/.flowconfig index aca52ab..64516a4 100644 --- a/.flowconfig +++ b/.flowconfig @@ -6,6 +6,7 @@ ./flow-typed [options] +suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe module.system.node.resolve_dirname=./src module.name_mapper='^redux\(.*\)$' -> '/src/redux\1' module.name_mapper='^util\(.*\)$' -> '/src/util\1' diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 6ae34e2..45fb468 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -897,45 +897,49 @@ const getSearchQueryString = (query, options = {}, includeUserOptions = false) = var _extends = 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 isProduction = process.env.NODE_ENV === 'production'; 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}]/u; const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; +const regexPartProtocol = '^((?:lbry://)?)'; +const regexPartStreamOrChannelName = '([^:$#/]*)'; +const regexPartModifierSeparator = '([:$#]?)([^/]*)'; /** * Parses a LBRY name into its component parts. Throws errors with user-friendly * messages for invalid names. * - * N.B. that "name" indicates the value in the name position of the URI. For - * claims for channel content, this will actually be the channel name, and - * the content name is in the path (e.g. lbry://@channel/content) - * - * In most situations, you'll want to use the contentName and channelName keys - * and ignore the name key. - * * Returns a dictionary with keys: - * - name (string): The value in the "name" position in the URI. Note that this - * could be either content name or channel name; see above. - * - path (string, if persent) - * - claimSequence (int, if present) - * - bidPosition (int, if present) - * - claimId (string, if present) + * - path (string) * - isChannel (boolean) - * - contentName (string): For anon claims, the name; for channel claims, the path - * - channelName (string, if present): Channel name without @ + * - streamName (string, if present) + * - streamClaimId (string, if present) + * - channelName (string, if present) + * - channelClaimId (string, if present) + * - primaryClaimSequence (int, if present) + * - secondaryClaimSequence (int, if present) + * - primaryBidPosition (int, if present) + * - secondaryBidPosition (int, if present) */ -function parseURI(URI, requireProto = false) { - // Break into components. Empty sub-matches are converted to null - const componentsRegex = new RegExp('^((?:lbry://)?)' + // protocol - '([^:$#/]*)' + // claim name (stops at the first separator or end) - '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) - '(/?)(.*)' // path separator, path - ); - const [proto, claimName, modSep, modVal, pathSep, path] = componentsRegex.exec(URI).slice(1).map(match => match || null); - let contentName; +function parseURI(URL, requireProto = false) { + // Break into components. Empty sub-matches are converted to null + const componentsRegex = new RegExp(regexPartProtocol + // protocol + regexPartStreamOrChannelName + // stream or channel name (stops at the first separator or end) + regexPartModifierSeparator + // modifier separator, modifier (stops at the first path separator or end) + '(/?)' + // path separator, there should only be one (optional) slash to separate the stream and channel parts + regexPartStreamOrChannelName + regexPartModifierSeparator); + + const regexMatch = componentsRegex.exec(URL) || []; + const [proto, ...rest] = regexMatch.slice(1).map(match => match || null); + const path = rest.join(''); + const [streamNameOrChannelName, primaryModSeparator, primaryModValue, pathSep, possibleStreamName, secondaryModSeparator, secondaryModValue] = rest; // Validate protocol if (requireProto && !proto) { @@ -943,14 +947,15 @@ function parseURI(URI, requireProto = false) { } // Validate and process name - if (!claimName) { + if (!streamNameOrChannelName) { throw new Error(__('URI does not include name.')); } - const isChannel = claimName.startsWith('@'); - const channelName = isChannel ? claimName.slice(1) : claimName; + const includesChannel = streamNameOrChannelName.startsWith('@'); + const isChannel = streamNameOrChannelName.startsWith('@') && !possibleStreamName; + const channelName = includesChannel && streamNameOrChannelName.slice(1); - if (isChannel) { + if (includesChannel) { if (!channelName) { throw new Error(__('No channel name after @.')); } @@ -958,30 +963,42 @@ function parseURI(URI, requireProto = false) { if (channelName.length < channelNameMinLength) { throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); } - - contentName = path; } - const nameBadChars = (channelName || claimName).match(regexInvalidURI); - if (nameBadChars) { - throw new Error(__(`Invalid character %s in name: %s.`, nameBadChars.length === 1 ? '' : 's', nameBadChars.join(', '))); - } + // Validate and process modifier + const [primaryClaimId, primaryClaimSequence, primaryBidPosition] = parseURIModifier(primaryModSeparator, primaryModValue); + const [secondaryClaimId, secondaryClaimSequence, secondaryBidPosition] = parseURIModifier(secondaryModSeparator, secondaryModValue); + const streamName = includesChannel ? possibleStreamName : streamNameOrChannelName; + const streamClaimId = includesChannel ? secondaryClaimId : primaryClaimId; + const channelClaimId = includesChannel && primaryClaimId; - // Validate and process modifier (claim ID, bid position or claim sequence) + return _extends({ + isChannel, + path + }, streamName ? { streamName } : {}, streamClaimId ? { streamClaimId } : {}, channelName ? { channelName } : {}, channelClaimId ? { channelClaimId } : {}, primaryClaimSequence ? { primaryClaimSequence: parseInt(primaryClaimSequence, 10) } : {}, secondaryClaimSequence ? { secondaryClaimSequence: parseInt(secondaryClaimSequence, 10) } : {}, primaryBidPosition ? { primaryBidPosition: parseInt(primaryBidPosition, 10) } : {}, secondaryBidPosition ? { secondaryBidPosition: parseInt(secondaryBidPosition, 10) } : {}, { + + // The values below should not be used for new uses of parseURI + // They will not work properly with canonical_urls + claimName: streamNameOrChannelName, + claimId: primaryClaimId + }, streamName ? { contentName: streamName } : {}); +} + +function parseURIModifier(modSeperator, modValue) { let claimId; let claimSequence; let bidPosition; - if (modSep) { - if (!modVal) { - throw new Error(__(`No modifier provided after separator %s.`, modSep)); + if (modSeperator) { + if (!modValue) { + throw new Error(__(`No modifier provided after separator %s.`, modSeperator)); } - if (modSep === '#') { - claimId = modVal; - } else if (modSep === ':') { - claimSequence = modVal; - } else if (modSep === '$') { - bidPosition = modVal; + if (modSeperator === '#') { + claimId = modValue; + } else if (modSeperator === ':') { + claimSequence = modValue; + } else if (modSeperator === '$') { + bidPosition = modValue; } } @@ -997,27 +1014,7 @@ function parseURI(URI, requireProto = false) { throw new Error(__('Bid position must be a number.')); } - // Validate and process path - if (path) { - if (!isChannel) { - throw new Error(__('Only channel URIs may have a path.')); - } - - const pathBadChars = path.match(regexInvalidURI); - if (pathBadChars) { - throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); - } - - contentName = path; - } else if (pathSep) { - throw new Error(__('No path provided after /')); - } - - return _extends({ - claimName, - path, - isChannel - }, contentName ? { contentName } : {}, channelName ? { channelName } : {}, claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}, bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}, claimId ? { claimId } : {}, path ? { path } : {}); + return [claimId, claimSequence, bidPosition]; } /** @@ -1025,67 +1022,119 @@ function parseURI(URI, requireProto = false) { * * The channelName key will accept names with or without the @ prefix. */ -function buildURI(URIObj, includeProto = true, protoDefault = 'lbry://') { - const { claimId, claimSequence, bidPosition, contentName, channelName } = URIObj; +function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { + const { + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryClaimSequence, + primaryBidPosition, + secondaryClaimSequence, + secondaryBidPosition + } = UrlObj, + deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); + const { claimId, claimName, contentName } = deprecatedParts; - let { claimName, path } = URIObj; - - if (channelName) { - const channelNameFormatted = channelName.startsWith('@') ? channelName : `@${channelName}`; - if (!claimName) { - claimName = channelNameFormatted; - } else if (claimName !== channelNameFormatted) { - throw new Error(__('Received a channel content URI, but claim name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.')); + if (!isProduction) { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); } } - if (contentName) { - if (!claimName) { - claimName = contentName; - } else if (!path) { - path = contentName; - } - if (path && path !== contentName) { - throw new Error(__('Path and contentName do not match. Only one is required; most likely you wanted contentName.')); - } + if (!claimName && !channelName && !streamName) { + throw new Error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } - return (includeProto ? protoDefault : '') + claimName + (claimId ? `#${claimId}` : '') + (claimSequence ? `:${claimSequence}` : '') + (bidPosition ? `${bidPosition}` : '') + (path ? `/${path}` : ''); + const formattedChannelName = channelName && (channelName.startsWith('@') ? channelName : `@${channelName}`); + const primaryClaimName = claimName || formattedChannelName || streamName; + const primaryClaimId = claimId || (formattedChannelName ? channelClaimId : streamClaimId); + const secondaryClaimName = !claimName && (formattedChannelName ? streamName : null); + const secondaryClaimId = secondaryClaimName && streamClaimId; + + return (includeProto ? protoDefault : '') + + // primaryClaimName will always exist here because we throw above if there is no "name" value passed in + // $FlowFixMe + primaryClaimName + (primaryClaimId ? `#${primaryClaimId}` : '') + (primaryClaimSequence ? `:${primaryClaimSequence}` : '') + (primaryBidPosition ? `${primaryBidPosition}` : '') + (secondaryClaimName ? `/${secondaryClaimName}` : '') + (secondaryClaimId ? `#${secondaryClaimId}` : '') + (secondaryClaimSequence ? `:${secondaryClaimSequence}` : '') + (secondaryBidPosition ? `${secondaryBidPosition}` : ''); } -/* Takes a parseable LBRY URI and converts it to standard, canonical format */ -function normalizeURI(URI) { - const { claimName, path, bidPosition, claimSequence, claimId } = parseURI(URI); - return buildURI({ claimName, path, claimSequence, bidPosition, claimId }); +/* Takes a parseable LBRY URL and converts it to standard, canonical format */ +function normalizeURI(URL) { + const { + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryClaimSequence, + primaryBidPosition, + secondaryClaimSequence, + secondaryBidPosition + } = parseURI(URL); + + return buildURI({ + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryClaimSequence, + primaryBidPosition, + secondaryClaimSequence, + secondaryBidPosition + }); } -function isURIValid(URI) { - let parts; +function isURIValid(URL) { try { - parts = parseURI(normalizeURI(URI)); + parseURI(normalizeURI(URL)); } catch (error) { return false; } - return parts && parts.claimName; + + return true; } function isNameValid(claimName) { return !regexInvalidURI.test(claimName); } -function isURIClaimable(URI) { +function isURIClaimable(URL) { let parts; try { - parts = parseURI(normalizeURI(URI)); + parts = parseURI(normalizeURI(URL)); } catch (error) { return false; } - return parts && parts.claimName && !parts.claimId && !parts.bidPosition && !parts.claimSequence && !parts.isChannel && !parts.path; + + return parts && parts.streamName && !parts.streamClaimId && !parts.isChannel; } -function convertToShareLink(URI) { - const { claimName, path, bidPosition, claimSequence, claimId } = parseURI(URI); - return buildURI({ claimName, path, claimSequence, bidPosition, claimId }, true, 'https://open.lbry.com/'); +function convertToShareLink(URL) { + const { + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryBidPosition, + primaryClaimSequence, + secondaryBidPosition, + secondaryClaimSequence + } = parseURI(URL); + return buildURI({ + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryBidPosition, + primaryClaimSequence, + secondaryBidPosition, + secondaryClaimSequence + }, true, 'https://open.lbry.com/'); } var _extends$1 = 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; }; @@ -1130,13 +1179,13 @@ const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selec let searchSuggestions = []; try { const uri = normalizeURI(query); - const { claimName, isChannel } = parseURI(uri); + const { channelName, streamName, isChannel } = parseURI(uri); searchSuggestions.push({ - value: claimName, + value: streamName, type: SEARCH_TYPES.SEARCH }, { value: uri, - shorthand: isChannel ? claimName.slice(1) : claimName, + shorthand: isChannel ? channelName : streamName, type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE }); } catch (e) { @@ -1157,11 +1206,11 @@ const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selec // determine if it's a channel try { const uri = normalizeURI(suggestion); - const { claimName, isChannel } = parseURI(uri); + const { channelName, streamName, isChannel } = parseURI(uri); return { value: uri, - shorthand: isChannel ? claimName.slice(1) : claimName, + shorthand: isChannel ? channelName : streamName, type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE }; } catch (e) { @@ -1377,7 +1426,7 @@ const selectTransactionListFilter = reselect.createSelector(selectState$1, state 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; } +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 matureTagMap = MATURE_TAGS.reduce((acc, tag) => _extends$2({}, acc, { [tag]: true }), {}); @@ -1404,7 +1453,7 @@ const isClaimNsfw = claim => { 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 rest = _objectWithoutProperties$1(options, ['page', 'release_time']); const query = JSON.stringify(rest); return query; } @@ -1445,8 +1494,10 @@ const selectPendingClaims = reselect.createSelector(selectState$2, state => Obje const makeSelectClaimIsPending = uri => reselect.createSelector(selectPendingById, pendingById => { let claimId; + try { - ({ claimId } = parseURI(uri)); + const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); + claimId = isChannel ? channelClaimId : streamClaimId; } catch (e) {} if (claimId) { @@ -1455,7 +1506,8 @@ const makeSelectClaimIsPending = uri => reselect.createSelector(selectPendingByI }); const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, pendingById => { - const { claimId } = parseURI(uri); + const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); + const claimId = isChannel ? channelClaimId : streamClaimId; return pendingById[claimId]; }); @@ -1464,13 +1516,16 @@ const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, // It won't be in claimsByUri because resolving it will return nothing let valid; - let claimId; + let channelClaimId; + let streamClaimId; + let isChannel; try { - ({ claimId } = parseURI(uri)); + ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); valid = true; } catch (e) {} if (valid) { + const claimId = isChannel ? channelClaimId : streamClaimId; const pendingClaim = pendingById[claimId]; if (pendingClaim) { @@ -1720,15 +1775,18 @@ const selectClaimSearchByQueryLastPageReached = reselect.createSelector(selectSt const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.short_url); +const makeSelectCanonicalUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.canonical_url); + const makeSelectSupportsForUri = uri => reselect.createSelector(selectSupportsByOutpoint, makeSelectClaimForUri(uri), (byOutpoint, claim) => { if (!claim || !claim.is_mine) { return null; } const { claim_id: claimId } = claim; - let total = parseFloat("0.0"); + let total = 0; Object.values(byOutpoint).forEach(support => { + // $FlowFixMe const { claim_id, amount } = support; total = claim_id === claimId && amount ? total + parseFloat(amount) : total; }); @@ -2433,10 +2491,10 @@ function doClaimSearch(options = { const success = data => { const resolveInfo = {}; - const uris = []; + const urls = []; data.items.forEach(stream => { - resolveInfo[stream.permanent_url] = { stream }; - uris.push(stream.permanent_url); + resolveInfo[stream.canonical_url] = { stream }; + urls.push(stream.canonical_url); }); dispatch({ @@ -2444,7 +2502,7 @@ function doClaimSearch(options = { data: { query, resolveInfo, - uris, + urls, append: options.page && options.page !== 1, pageSize: options.page_size } @@ -2858,12 +2916,12 @@ function doSetFileListSort(page, value) { }; } -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 selectState$5 = state => state.publish || {}; const selectPublishFormValues = reselect.createSelector(selectState$5, state => { - const formValues = _objectWithoutProperties$1(state, ['pendingPublish']); + const formValues = _objectWithoutProperties$2(state, ['pendingPublish']); return formValues; }); const makeSelectPublishFormValue = item => reselect.createSelector(selectState$5, state => state[item]); @@ -2876,8 +2934,16 @@ const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, pu return false; } - const { isChannel: currentIsChannel, claimName: currentClaimName, contentName: currentContentName } = parseURI(uri); - const { isChannel: editIsChannel, claimName: editClaimName, contentName: editContentName } = parseURI(editingURI); + const { + isChannel: currentIsChannel, + claimName: currentClaimName, + contentName: currentContentName + } = parseURI(uri); + const { + isChannel: editIsChannel, + claimName: editClaimName, + contentName: editContentName + } = parseURI(editingURI); // Depending on the previous/current use of a channel, we need to compare different things // ex: going from a channel to anonymous, the new uri won't return contentName, so we need to use claimName @@ -2904,7 +2970,7 @@ const selectIsResolvingPublishUris = reselect.createSelector(selectState$5, sele let isResolvingShortUri; if (isChannel) { - const shortUri = buildURI({ contentName: name }); + const shortUri = buildURI({ streamName: name }); isResolvingShortUri = resolvingUris.includes(shortUri); } @@ -3376,13 +3442,21 @@ from, isBackgroundSearch = false) => (dispatch, getState) => { const actions = []; data.forEach(result => { - if (result.name) { - const uri = buildURI({ - claimName: result.name, - claimId: result.claimId - }); - actions.push(doResolveUri(uri)); - uris.push(uri); + if (result) { + const { name, claimId } = result; + const urlObj = {}; + + if (name.startsWith('@')) { + urlObj.channelName = name; + urlObj.channelClaimId = claimId; + } else { + urlObj.streamName = name; + urlObj.streamClaimId = claimId; + } + + const url = buildURI(urlObj); + actions.push(doResolveUri(url)); + uris.push(url); } }); @@ -3561,26 +3635,25 @@ function handleClaimAction(state, action) { const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - Object.entries(resolveInfo).forEach(([uri, resolveResponse]) => { + Object.entries(resolveInfo).forEach(([url, resolveResponse]) => { // $FlowFixMe - if (resolveResponse.claimsInChannel) { - // $FlowFixMe - channelClaimCounts[uri] = resolveResponse.claimsInChannel; + const { claimsInChannel, stream, channel } = resolveResponse; + if (claimsInChannel) { + channelClaimCounts[url] = claimsInChannel; } - }); - // $FlowFixMe - Object.entries(resolveInfo).forEach(([uri, { channel, stream }]) => { if (stream) { byId[stream.claim_id] = stream; - byUri[uri] = stream.claim_id; + byUri[url] = stream.claim_id; } + if (channel) { byId[channel.claim_id] = channel; - byUri[stream ? channel.permanent_url : uri] = channel.claim_id; + byUri[stream ? channel.canonical_url : url] = channel.claim_id; } + if (!stream && !channel) { - byUri[uri] = null; + byUri[url] = null; } }); @@ -3792,17 +3865,17 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); const claimSearchByQuery = Object.assign({}, state.claimSearchByQuery); const claimSearchByQueryLastPageReached = Object.assign({}, state.claimSearchByQueryLastPageReached); - const { append, query, uris, pageSize } = action.data; + const { append, query, urls, pageSize } = action.data; if (append) { - // todo: check for duplicate uris when concatenating? - claimSearchByQuery[query] = claimSearchByQuery[query] && claimSearchByQuery[query].length ? claimSearchByQuery[query].concat(uris) : uris; + // todo: check for duplicate urls when concatenating? + claimSearchByQuery[query] = claimSearchByQuery[query] && claimSearchByQuery[query].length ? claimSearchByQuery[query].concat(urls) : urls; } else { - claimSearchByQuery[query] = uris; + claimSearchByQuery[query] = urls; } - // the returned number of uris is less than the page size, so we're on the last page - claimSearchByQueryLastPageReached[query] = uris.length < pageSize; + // the returned number of urls is less than the page size, so we're on the last page + claimSearchByQueryLastPageReached[query] = urls.length < pageSize; delete fetchingClaimSearchByQuery[query]; @@ -4232,7 +4305,7 @@ const notificationsReducer = handleActions({ var _extends$a = 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$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; } +function _objectWithoutProperties$3(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, @@ -4282,7 +4355,7 @@ const publishReducer = handleActions({ publishSuccess: true }), [DO_PREPARE_EDIT]: (state, action) => { - const publishData = _objectWithoutProperties$2(action.data, []); + const publishData = _objectWithoutProperties$3(action.data, []); const { channel, name, uri } = publishData; // The short uri is what is presented to the user @@ -4892,6 +4965,7 @@ exports.isNameValid = isNameValid; exports.isURIClaimable = isURIClaimable; exports.isURIValid = isURIValid; exports.makeSelectAmountForUri = makeSelectAmountForUri; +exports.makeSelectCanonicalUrlForUri = makeSelectCanonicalUrlForUri; exports.makeSelectChannelForClaimUri = makeSelectChannelForClaimUri; exports.makeSelectClaimForUri = makeSelectClaimForUri; exports.makeSelectClaimIsMine = makeSelectClaimIsMine; diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 1c61c10..54e414f 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -23,6 +23,7 @@ declare type GenericClaim = { decoded_claim: boolean, // Not available currently https://github.com/lbryio/lbry/issues/2044 timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed + is_mine: boolean, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index a403ffb..68ccc93 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -65,7 +65,7 @@ declare type VersionResponse = { declare type ResolveResponse = { // Keys are the url(s) passed to resolve - [string]: Claim | { error?: {} }, + [string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, claimsInChannel?: number }, }; declare type GetResponse = FileListItem & { error?: string }; diff --git a/dist/flow-typed/i18n.js b/dist/flow-typed/i18n.js new file mode 100644 index 0000000..050d684 --- /dev/null +++ b/dist/flow-typed/i18n.js @@ -0,0 +1,2 @@ +// @flow +declare function __(a: string, b?: string | number): string; diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 1c61c10..54e414f 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -23,6 +23,7 @@ declare type GenericClaim = { decoded_claim: boolean, // Not available currently https://github.com/lbryio/lbry/issues/2044 timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed + is_mine: boolean, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index a403ffb..68ccc93 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -65,7 +65,7 @@ declare type VersionResponse = { declare type ResolveResponse = { // Keys are the url(s) passed to resolve - [string]: Claim | { error?: {} }, + [string]: { error?: {}, stream?: StreamClaim, channel?: ChannelClaim, claimsInChannel?: number }, }; declare type GetResponse = FileListItem & { error?: string }; diff --git a/flow-typed/i18n.js b/flow-typed/i18n.js new file mode 100644 index 0000000..050d684 --- /dev/null +++ b/flow-typed/i18n.js @@ -0,0 +1,2 @@ +// @flow +declare function __(a: string, b?: string | number): string; diff --git a/src/index.js b/src/index.js index 88bdf74..1370c3c 100644 --- a/src/index.js +++ b/src/index.js @@ -172,6 +172,7 @@ export { makeSelectPendingByUri, makeSelectClaimsInChannelForCurrentPageState, makeSelectShortUrlForUri, + makeSelectCanonicalUrlForUri, makeSelectSupportsForUri, selectPendingById, selectClaimsById, diff --git a/src/lbryURI.js b/src/lbryURI.js index 72a6200..323d509 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -1,46 +1,77 @@ +// @flow +const isProduction = process.env.NODE_ENV === 'production'; 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}]/u; export const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; +const regexPartProtocol = '^((?:lbry://)?)'; +const regexPartStreamOrChannelName = '([^:$#/]*)'; +const regexPartModifierSeparator = '([:$#]?)([^/]*)'; /** * Parses a LBRY name into its component parts. Throws errors with user-friendly * messages for invalid names. * - * N.B. that "name" indicates the value in the name position of the URI. For - * claims for channel content, this will actually be the channel name, and - * the content name is in the path (e.g. lbry://@channel/content) - * - * In most situations, you'll want to use the contentName and channelName keys - * and ignore the name key. - * * Returns a dictionary with keys: - * - name (string): The value in the "name" position in the URI. Note that this - * could be either content name or channel name; see above. - * - path (string, if persent) - * - claimSequence (int, if present) - * - bidPosition (int, if present) - * - claimId (string, if present) + * - path (string) * - isChannel (boolean) - * - contentName (string): For anon claims, the name; for channel claims, the path - * - channelName (string, if present): Channel name without @ + * - streamName (string, if present) + * - streamClaimId (string, if present) + * - channelName (string, if present) + * - channelClaimId (string, if present) + * - primaryClaimSequence (int, if present) + * - secondaryClaimSequence (int, if present) + * - primaryBidPosition (int, if present) + * - secondaryBidPosition (int, if present) */ -export function parseURI(URI, requireProto = false) { + +type ChannelUrlObj = {}; + +type LbryUrlObj = { + // Path and channel will always exist when calling parseURI + // But they may not exist when code calls buildURI + isChannel?: boolean, + path?: string, + streamName?: string, + streamClaimId?: string, + channelName?: string, + channelClaimId?: string, + primaryClaimSequence?: number, + secondaryClaimSequence?: number, + primaryBidPosition?: number, + secondaryBidPosition?: number, + + // Below are considered deprecated and should not be used due to unreliableness with claim.canonical_url + claimName?: string, + claimId?: string, + contentName?: string, +}; + +export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj { // Break into components. Empty sub-matches are converted to null const componentsRegex = new RegExp( - '^((?:lbry://)?)' + // protocol - '([^:$#/]*)' + // claim name (stops at the first separator or end) - '([:$#]?)([^/]*)' + // modifier separator, modifier (stops at the first path separator or end) - '(/?)(.*)' // path separator, path + regexPartProtocol + // protocol + regexPartStreamOrChannelName + // stream or channel name (stops at the first separator or end) + regexPartModifierSeparator + // modifier separator, modifier (stops at the first path separator or end) + '(/?)' + // path separator, there should only be one (optional) slash to separate the stream and channel parts + regexPartStreamOrChannelName + + regexPartModifierSeparator ); - const [proto, claimName, modSep, modVal, pathSep, path] = componentsRegex - .exec(URI) - .slice(1) - .map(match => match || null); - let contentName; + const regexMatch = componentsRegex.exec(URL) || []; + const [proto, ...rest] = regexMatch.slice(1).map(match => match || null); + const path = rest.join(''); + const [ + streamNameOrChannelName, + primaryModSeparator, + primaryModValue, + pathSep, + possibleStreamName, + secondaryModSeparator, + secondaryModValue, + ] = rest; // Validate protocol if (requireProto && !proto) { @@ -48,14 +79,15 @@ export function parseURI(URI, requireProto = false) { } // Validate and process name - if (!claimName) { + if (!streamNameOrChannelName) { throw new Error(__('URI does not include name.')); } - const isChannel = claimName.startsWith('@'); - const channelName = isChannel ? claimName.slice(1) : claimName; + const includesChannel = streamNameOrChannelName.startsWith('@'); + const isChannel = streamNameOrChannelName.startsWith('@') && !possibleStreamName; + const channelName = includesChannel && streamNameOrChannelName.slice(1); - if (isChannel) { + if (includesChannel) { if (!channelName) { throw new Error(__('No channel name after @.')); } @@ -63,36 +95,58 @@ export function parseURI(URI, requireProto = false) { if (channelName.length < channelNameMinLength) { throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); } - - contentName = path; } - const nameBadChars = (channelName || claimName).match(regexInvalidURI); - if (nameBadChars) { - throw new Error( - __( - `Invalid character %s in name: %s.`, - nameBadChars.length === 1 ? '' : 's', - nameBadChars.join(', ') - ) - ); - } + // Validate and process modifier + const [primaryClaimId, primaryClaimSequence, primaryBidPosition] = parseURIModifier( + primaryModSeparator, + primaryModValue + ); + const [secondaryClaimId, secondaryClaimSequence, secondaryBidPosition] = parseURIModifier( + secondaryModSeparator, + secondaryModValue + ); + const streamName = includesChannel ? possibleStreamName : streamNameOrChannelName; + const streamClaimId = includesChannel ? secondaryClaimId : primaryClaimId; + const channelClaimId = includesChannel && primaryClaimId; - // Validate and process modifier (claim ID, bid position or claim sequence) + return { + isChannel, + path, + ...(streamName ? { streamName } : {}), + ...(streamClaimId ? { streamClaimId } : {}), + ...(channelName ? { channelName } : {}), + ...(channelClaimId ? { channelClaimId } : {}), + ...(primaryClaimSequence ? { primaryClaimSequence: parseInt(primaryClaimSequence, 10) } : {}), + ...(secondaryClaimSequence + ? { secondaryClaimSequence: parseInt(secondaryClaimSequence, 10) } + : {}), + ...(primaryBidPosition ? { primaryBidPosition: parseInt(primaryBidPosition, 10) } : {}), + ...(secondaryBidPosition ? { secondaryBidPosition: parseInt(secondaryBidPosition, 10) } : {}), + + // The values below should not be used for new uses of parseURI + // They will not work properly with canonical_urls + claimName: streamNameOrChannelName, + claimId: primaryClaimId, + ...(streamName ? { contentName: streamName } : {}), + }; +} + +function parseURIModifier(modSeperator: ?string, modValue: ?string) { let claimId; let claimSequence; let bidPosition; - if (modSep) { - if (!modVal) { - throw new Error(__(`No modifier provided after separator %s.`, modSep)); + if (modSeperator) { + if (!modValue) { + throw new Error(__(`No modifier provided after separator %s.`, modSeperator)); } - if (modSep === '#') { - claimId = modVal; - } else if (modSep === ':') { - claimSequence = modVal; - } else if (modSep === '$') { - bidPosition = modVal; + if (modSeperator === '#') { + claimId = modValue; + } else if (modSeperator === ':') { + claimSequence = modValue; + } else if (modSeperator === '$') { + bidPosition = modValue; } } @@ -108,33 +162,7 @@ export function parseURI(URI, requireProto = false) { throw new Error(__('Bid position must be a number.')); } - // Validate and process path - if (path) { - if (!isChannel) { - throw new Error(__('Only channel URIs may have a path.')); - } - - const pathBadChars = path.match(regexInvalidURI); - if (pathBadChars) { - throw new Error(__(`Invalid character in path: %s`, pathBadChars.join(', '))); - } - - contentName = path; - } else if (pathSep) { - throw new Error(__('No path provided after /')); - } - - return { - claimName, - path, - isChannel, - ...(contentName ? { contentName } : {}), - ...(channelName ? { channelName } : {}), - ...(claimSequence ? { claimSequence: parseInt(claimSequence, 10) } : {}), - ...(bidPosition ? { bidPosition: parseInt(bidPosition, 10) } : {}), - ...(claimId ? { claimId } : {}), - ...(path ? { path } : {}), - }; + return [claimId, claimSequence, bidPosition]; } /** @@ -142,91 +170,144 @@ export function parseURI(URI, requireProto = false) { * * The channelName key will accept names with or without the @ prefix. */ -export function buildURI(URIObj, includeProto = true, protoDefault = 'lbry://') { - const { claimId, claimSequence, bidPosition, contentName, channelName } = URIObj; +export function buildURI( + UrlObj: LbryUrlObj, + includeProto: boolean = true, + protoDefault: string = 'lbry://' +): string { + const { + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryClaimSequence, + primaryBidPosition, + secondaryClaimSequence, + secondaryBidPosition, + ...deprecatedParts + } = UrlObj; + const { claimId, claimName, contentName } = deprecatedParts; - let { claimName, path } = URIObj; - - if (channelName) { - const channelNameFormatted = channelName.startsWith('@') ? channelName : `@${channelName}`; - if (!claimName) { - claimName = channelNameFormatted; - } else if (claimName !== channelNameFormatted) { - throw new Error( + if (!isProduction) { + if (claimId) { + console.error( + __("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead") + ); + } + if (claimName) { + console.error( __( - 'Received a channel content URI, but claim name and channelName do not match. "name" represents the value in the name position of the URI (lbry://name...), which for channel content will be the channel name. In most cases, to construct a channel URI you should just pass channelName and contentName.' + "'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead" ) ); } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } } - if (contentName) { - if (!claimName) { - claimName = contentName; - } else if (!path) { - path = contentName; - } - if (path && path !== contentName) { - throw new Error( - __( - 'Path and contentName do not match. Only one is required; most likely you wanted contentName.' - ) - ); - } + if (!claimName && !channelName && !streamName) { + throw new Error( + __( + "'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url." + ) + ); } + const formattedChannelName = + channelName && (channelName.startsWith('@') ? channelName : `@${channelName}`); + const primaryClaimName = claimName || formattedChannelName || streamName; + const primaryClaimId = claimId || (formattedChannelName ? channelClaimId : streamClaimId); + const secondaryClaimName = !claimName && (formattedChannelName ? streamName : null); + const secondaryClaimId = secondaryClaimName && streamClaimId; + return ( (includeProto ? protoDefault : '') + - claimName + - (claimId ? `#${claimId}` : '') + - (claimSequence ? `:${claimSequence}` : '') + - (bidPosition ? `${bidPosition}` : '') + - (path ? `/${path}` : '') + // primaryClaimName will always exist here because we throw above if there is no "name" value passed in + // $FlowFixMe + primaryClaimName + + (primaryClaimId ? `#${primaryClaimId}` : '') + + (primaryClaimSequence ? `:${primaryClaimSequence}` : '') + + (primaryBidPosition ? `${primaryBidPosition}` : '') + + (secondaryClaimName ? `/${secondaryClaimName}` : '') + + (secondaryClaimId ? `#${secondaryClaimId}` : '') + + (secondaryClaimSequence ? `:${secondaryClaimSequence}` : '') + + (secondaryBidPosition ? `${secondaryBidPosition}` : '') ); } -/* Takes a parseable LBRY URI and converts it to standard, canonical format */ -export function normalizeURI(URI) { - const { claimName, path, bidPosition, claimSequence, claimId } = parseURI(URI); - return buildURI({ claimName, path, claimSequence, bidPosition, claimId }); +/* Takes a parseable LBRY URL and converts it to standard, canonical format */ +export function normalizeURI(URL: string) { + const { + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryClaimSequence, + primaryBidPosition, + secondaryClaimSequence, + secondaryBidPosition, + } = parseURI(URL); + + return buildURI({ + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryClaimSequence, + primaryBidPosition, + secondaryClaimSequence, + secondaryBidPosition, + }); } -export function isURIValid(URI) { - let parts; +export function isURIValid(URL: string): boolean { try { - parts = parseURI(normalizeURI(URI)); + parseURI(normalizeURI(URL)); } catch (error) { return false; } - return parts && parts.claimName; + + return true; } -export function isNameValid(claimName) { +export function isNameValid(claimName: string) { return !regexInvalidURI.test(claimName); } -export function isURIClaimable(URI) { +export function isURIClaimable(URL: string) { let parts; try { - parts = parseURI(normalizeURI(URI)); + parts = parseURI(normalizeURI(URL)); } catch (error) { return false; } - return ( - parts && - parts.claimName && - !parts.claimId && - !parts.bidPosition && - !parts.claimSequence && - !parts.isChannel && - !parts.path - ); + + return parts && parts.streamName && !parts.streamClaimId && !parts.isChannel; } -export function convertToShareLink(URI) { - const { claimName, path, bidPosition, claimSequence, claimId } = parseURI(URI); +export function convertToShareLink(URL: string) { + const { + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryBidPosition, + primaryClaimSequence, + secondaryBidPosition, + secondaryClaimSequence, + } = parseURI(URL); return buildURI( - { claimName, path, claimSequence, bidPosition, claimId }, + { + streamName, + streamClaimId, + channelName, + channelClaimId, + primaryBidPosition, + primaryClaimSequence, + secondaryBidPosition, + secondaryClaimSequence, + }, true, 'https://open.lbry.com/' ); diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 0f6e44e..ab03679 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -328,10 +328,10 @@ export function doClaimSearch( const success = (data: ClaimSearchResponse) => { const resolveInfo = {}; - const uris = []; + const urls = []; data.items.forEach((stream: Claim) => { - resolveInfo[stream.permanent_url] = { stream }; - uris.push(stream.permanent_url); + resolveInfo[stream.canonical_url] = { stream }; + urls.push(stream.canonical_url); }); dispatch({ @@ -339,7 +339,7 @@ export function doClaimSearch( data: { query, resolveInfo, - uris, + urls, append: options.page && options.page !== 1, pageSize: options.page_size, }, diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 8108e9c..2e134bc 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -112,18 +112,26 @@ export const doSearch = ( fetch(`${CONNECTION_STRING}search?${queryWithOptions}`) .then(handleFetchResponse) - .then((data: Array<{ name: String, claimId: string }>) => { + .then((data: Array<{ name: string, claimId: string }>) => { const uris = []; const actions = []; data.forEach(result => { - if (result.name) { - const uri = buildURI({ - claimName: result.name, - claimId: result.claimId, - }); - actions.push(doResolveUri(uri)); - uris.push(uri); + if (result) { + const { name, claimId } = result; + const urlObj = {}; + + if (name.startsWith('@')) { + urlObj.channelName = name; + urlObj.channelClaimId = claimId; + } else { + urlObj.streamName = name; + urlObj.streamClaimId = claimId; + } + + const url = buildURI(urlObj); + actions.push(doResolveUri(url)); + uris.push(url); } }); diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index ba94348..4aacad6 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -66,26 +66,25 @@ function handleClaimAction(state: State, action: any): State { const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - Object.entries(resolveInfo).forEach(([uri: string, resolveResponse: Claim]) => { + Object.entries(resolveInfo).forEach(([url: string, resolveResponse: ResolveResponse]) => { // $FlowFixMe - if (resolveResponse.claimsInChannel) { - // $FlowFixMe - channelClaimCounts[uri] = resolveResponse.claimsInChannel; + const { claimsInChannel, stream, channel } = resolveResponse; + if (claimsInChannel) { + channelClaimCounts[url] = claimsInChannel; } - }); - // $FlowFixMe - Object.entries(resolveInfo).forEach(([uri, { channel, stream }]) => { if (stream) { byId[stream.claim_id] = stream; - byUri[uri] = stream.claim_id; + byUri[url] = stream.claim_id; } + if (channel) { byId[channel.claim_id] = channel; - byUri[stream ? channel.permanent_url : uri] = channel.claim_id; + byUri[stream ? channel.canonical_url : url] = channel.claim_id; } + if (!stream && !channel) { - byUri[uri] = null; + byUri[url] = null; } }); @@ -305,20 +304,20 @@ reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => {}, state.claimSearchByQueryLastPageReached ); - const { append, query, uris, pageSize } = action.data; + const { append, query, urls, pageSize } = action.data; if (append) { - // todo: check for duplicate uris when concatenating? + // todo: check for duplicate urls when concatenating? claimSearchByQuery[query] = claimSearchByQuery[query] && claimSearchByQuery[query].length - ? claimSearchByQuery[query].concat(uris) - : uris; + ? claimSearchByQuery[query].concat(urls) + : urls; } else { - claimSearchByQuery[query] = uris; + claimSearchByQuery[query] = urls; } - // the returned number of uris is less than the page size, so we're on the last page - claimSearchByQueryLastPageReached[query] = uris.length < pageSize; + // the returned number of urls is less than the page size, so we're on the last page + claimSearchByQueryLastPageReached[query] = urls.length < pageSize; delete fetchingClaimSearchByQuery[query]; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 5a38364..26cbc7b 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -62,8 +62,10 @@ export const makeSelectClaimIsPending = (uri: string) => selectPendingById, pendingById => { let claimId; + try { - ({ claimId } = parseURI(uri)); + const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); + claimId = isChannel ? channelClaimId : streamClaimId; } catch (e) {} if (claimId) { @@ -76,7 +78,8 @@ export const makeSelectPendingByUri = (uri: string) => createSelector( selectPendingById, pendingById => { - const { claimId } = parseURI(uri); + const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); + const claimId = isChannel ? channelClaimId : streamClaimId; return pendingById[claimId]; } ); @@ -90,13 +93,16 @@ export const makeSelectClaimForUri = (uri: string) => // It won't be in claimsByUri because resolving it will return nothing let valid; - let claimId; + let channelClaimId; + let streamClaimId; + let isChannel; try { - ({ claimId } = parseURI(uri)); + ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); valid = true; } catch (e) {} if (valid) { + const claimId = isChannel ? channelClaimId : streamClaimId; const pendingClaim = pendingById[claimId]; if (pendingClaim) { @@ -521,23 +527,18 @@ export const selectClaimSearchByQueryLastPageReached = createSelector( state => state.claimSearchByQueryLastPageReached || {} ); -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 makeSelectCanonicalUrlForUri = (uri: string) => + createSelector( + makeSelectClaimForUri(uri), + claim => claim && claim.canonical_url + ); + export const makeSelectSupportsForUri = (uri: string) => createSelector( selectSupportsByOutpoint, @@ -548,11 +549,12 @@ export const makeSelectSupportsForUri = (uri: string) => } const { claim_id: claimId } = claim; - let total = parseFloat("0.0"); + let total = 0; Object.values(byOutpoint).forEach(support => { - const { claim_id, amount } = support - total = (claim_id === claimId && amount) ? total + parseFloat(amount) : total; + // $FlowFixMe + const { claim_id, amount } = support; + total = claim_id === claimId && amount ? total + parseFloat(amount) : total; }); return total; diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index 37f0dab..bfe4390 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -33,8 +33,16 @@ export const selectIsStillEditing = createSelector( return false; } - const { isChannel: currentIsChannel, claimName: currentClaimName, contentName: currentContentName } = parseURI(uri); - const { isChannel: editIsChannel, claimName: editClaimName, contentName: editContentName } = parseURI(editingURI); + const { + isChannel: currentIsChannel, + claimName: currentClaimName, + contentName: currentContentName, + } = parseURI(uri); + const { + isChannel: editIsChannel, + claimName: editClaimName, + contentName: editContentName, + } = parseURI(editingURI); // Depending on the previous/current use of a channel, we need to compare different things // ex: going from a channel to anonymous, the new uri won't return contentName, so we need to use claimName @@ -60,7 +68,9 @@ export const selectMyClaimForUri = createSelector( return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => - !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName + !contentName + ? claim.name === claimName + : claim.name === contentName || claim.name === claimName ); } ); @@ -75,7 +85,7 @@ export const selectIsResolvingPublishUris = createSelector( let isResolvingShortUri; if (isChannel) { - const shortUri = buildURI({ contentName: name }); + const shortUri = buildURI({ streamName: name }); isResolvingShortUri = resolvingUris.includes(shortUri); } diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index 660228f..e533af1 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -77,15 +77,15 @@ export const selectSearchSuggestions: Array = createSelector( let searchSuggestions = []; try { const uri = normalizeURI(query); - const { claimName, isChannel } = parseURI(uri); + const { channelName, streamName, isChannel } = parseURI(uri); searchSuggestions.push( { - value: claimName, + value: streamName, type: SEARCH_TYPES.SEARCH, }, { value: uri, - shorthand: isChannel ? claimName.slice(1) : claimName, + shorthand: isChannel ? channelName : streamName, type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE, } ); @@ -110,11 +110,11 @@ export const selectSearchSuggestions: Array = createSelector( // determine if it's a channel try { const uri = normalizeURI(suggestion); - const { claimName, isChannel } = parseURI(uri); + const { channelName, streamName, isChannel } = parseURI(uri); return { value: uri, - shorthand: isChannel ? claimName.slice(1) : claimName, + shorthand: isChannel ? channelName : streamName, type: isChannel ? SEARCH_TYPES.CHANNEL : SEARCH_TYPES.FILE, }; } catch (e) { diff --git a/src/util/uri.js b/src/util/uri.js deleted file mode 100644 index 238126a..0000000 --- a/src/util/uri.js +++ /dev/null @@ -1,13 +0,0 @@ -// @flow -import { parseURI } from 'lbryURI'; - -export const formatLbryUriForWeb = (uri: string) => { - const { claimName, claimId } = parseURI(uri); - - let webUrl = `/${claimName}`; - if (claimId) { - webUrl += `/${claimId}`; - } - - return webUrl; -}; -- 2.45.2 From 22879b2880d96fd8993ea0ca48f2582e32e9897c Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 22 Aug 2019 11:03:13 -0400 Subject: [PATCH 117/371] updates --- dist/bundle.es.js | 19 ++----------------- flow-typed/lbryURI.js | 20 ++++++++++++++++++++ package.json | 5 +++-- rollup.config.js | 8 ++++++++ src/lbryURI.js | 27 +++------------------------ src/redux/actions/search.js | 2 +- yarn.lock | 32 ++++++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 44 deletions(-) create mode 100644 flow-typed/lbryURI.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 45fb468..53a51a9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -898,9 +898,6 @@ const getSearchQueryString = (query, options = {}, includeUserOptions = false) = var _extends = 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 isProduction = process.env.NODE_ENV === 'production'; const channelNameMinLength = 1; const claimIdMaxLength = 40; @@ -1036,26 +1033,14 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - if (!isProduction) { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { throw new Error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } const formattedChannelName = channelName && (channelName.startsWith('@') ? channelName : `@${channelName}`); - const primaryClaimName = claimName || formattedChannelName || streamName; + const primaryClaimName = claimName || contentName || formattedChannelName || streamName; const primaryClaimId = claimId || (formattedChannelName ? channelClaimId : streamClaimId); - const secondaryClaimName = !claimName && (formattedChannelName ? streamName : null); + const secondaryClaimName = !claimName && contentName || (formattedChannelName ? streamName : null); const secondaryClaimId = secondaryClaimName && streamClaimId; return (includeProto ? protoDefault : '') + diff --git a/flow-typed/lbryURI.js b/flow-typed/lbryURI.js new file mode 100644 index 0000000..4365da3 --- /dev/null +++ b/flow-typed/lbryURI.js @@ -0,0 +1,20 @@ +// @flow +declare type LbryUrlObj = { + // Path and channel will always exist when calling parseURI + // But they may not exist when code calls buildURI + isChannel?: boolean, + path?: string, + streamName?: string, + streamClaimId?: string, + channelName?: string, + channelClaimId?: string, + primaryClaimSequence?: number, + secondaryClaimSequence?: number, + primaryBidPosition?: number, + secondaryBidPosition?: number, + + // Below are considered deprecated and should not be used due to unreliableness with claim.canonical_url + claimName?: string, + claimId?: string, + contentName?: string, +}; diff --git a/package.json b/package.json index 21b595f..ca6b815 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "main": "dist/bundle.es.js", "module": "dist/bundle.es.js", "scripts": { - "build": "rollup --config", + "build": "NODE_ENV=production rollup --config", "dev": "rollup --config --watch", "precommit": "flow check && lint-staged", "lint": "eslint 'src/**/*.js' --fix", @@ -59,7 +59,8 @@ "rollup-plugin-copy": "^1.1.0", "rollup-plugin-eslint": "^5.1.0", "rollup-plugin-flow": "^1.1.1", - "rollup-plugin-includepaths": "^0.2.3" + "rollup-plugin-includepaths": "^0.2.3", + "rollup-plugin-replace": "^2.2.0" }, "engines": { "yarn": "^1.3" diff --git a/rollup.config.js b/rollup.config.js index 30de832..2b898d6 100644 --- a/rollup.config.js +++ b/rollup.config.js @@ -2,6 +2,7 @@ import babel from 'rollup-plugin-babel'; import flow from 'rollup-plugin-flow'; import includePaths from 'rollup-plugin-includepaths'; import copy from 'rollup-plugin-copy'; +import replace from 'rollup-plugin-replace'; let includePathOptions = { include: {}, @@ -10,6 +11,8 @@ let includePathOptions = { extensions: ['.js'], }; +const production = process.env.NODE_ENV === 'production'; + export default { input: 'src/index.js', output: { @@ -24,5 +27,10 @@ export default { presets: ['stage-2'], }), copy({ targets: ['flow-typed'] }), + replace({ + 'process.env.NODE_ENV': production + ? JSON.stringify('production') + : JSON.stringify('development'), + }), ], }; diff --git a/src/lbryURI.js b/src/lbryURI.js index 323d509..3a67e6e 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -27,28 +27,6 @@ const regexPartModifierSeparator = '([:$#]?)([^/]*)'; * - secondaryBidPosition (int, if present) */ -type ChannelUrlObj = {}; - -type LbryUrlObj = { - // Path and channel will always exist when calling parseURI - // But they may not exist when code calls buildURI - isChannel?: boolean, - path?: string, - streamName?: string, - streamClaimId?: string, - channelName?: string, - channelClaimId?: string, - primaryClaimSequence?: number, - secondaryClaimSequence?: number, - primaryBidPosition?: number, - secondaryBidPosition?: number, - - // Below are considered deprecated and should not be used due to unreliableness with claim.canonical_url - claimName?: string, - claimId?: string, - contentName?: string, -}; - export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj { // Break into components. Empty sub-matches are converted to null const componentsRegex = new RegExp( @@ -216,9 +194,10 @@ export function buildURI( const formattedChannelName = channelName && (channelName.startsWith('@') ? channelName : `@${channelName}`); - const primaryClaimName = claimName || formattedChannelName || streamName; + const primaryClaimName = claimName || contentName || formattedChannelName || streamName; const primaryClaimId = claimId || (formattedChannelName ? channelClaimId : streamClaimId); - const secondaryClaimName = !claimName && (formattedChannelName ? streamName : null); + const secondaryClaimName = + (!claimName && contentName) || (formattedChannelName ? streamName : null); const secondaryClaimId = secondaryClaimName && streamClaimId; return ( diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 2e134bc..d5c6ce3 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -119,7 +119,7 @@ export const doSearch = ( data.forEach(result => { if (result) { const { name, claimId } = result; - const urlObj = {}; + const urlObj: LbryUrlObj = {}; if (name.startsWith('@')) { urlObj.channelName = name; diff --git a/yarn.lock b/yarn.lock index 49dc513..156e422 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1911,6 +1911,11 @@ estree-walker@^0.6.0: resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.0.tgz#5d865327c44a618dde5699f763891ae31f257dae" integrity sha512-peq1RfVAVzr3PU/jL31RaOjUKLoZJpObQWJJ+LgfcxDUifyLZ1RjPQZTl0pzj2uJ45b7A7XpyppXvxdEqzo4rw== +estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -3440,6 +3445,13 @@ lru-cache@^4.0.1: pseudomap "^1.0.2" yallist "^2.1.2" +magic-string@^0.25.2: + version "0.25.3" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.3.tgz#34b8d2a2c7fec9d9bdf9929a3fd81d271ef35be9" + integrity sha512-6QK0OpF/phMz0Q2AxILkX2mFhi7m+WMwTRg0LQKq/WBB0cDP4rYH3Wp4/d3OTXlrPLVJT/RFqj8tFeAR4nk8AA== + dependencies: + sourcemap-codec "^1.4.4" + make-dir@^1.0.0: version "1.2.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.2.0.tgz#6d6a49eead4aae296c53bbf3a1a008bd6c89469b" @@ -4379,6 +4391,14 @@ rollup-plugin-includepaths@^0.2.3: resolved "https://registry.yarnpkg.com/rollup-plugin-includepaths/-/rollup-plugin-includepaths-0.2.3.tgz#244d21b9669a0debe476d825e4a02ed08c06b258" integrity sha512-4QbSIZPDT+FL4SViEVCRi4cGCA64zQJu7u5qmCkO3ecHy+l9EQBsue15KfCpddfb6Br0q47V/v2+E2YUiqts9g== +rollup-plugin-replace@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/rollup-plugin-replace/-/rollup-plugin-replace-2.2.0.tgz#f41ae5372e11e7a217cde349c8b5d5fd115e70e3" + integrity sha512-/5bxtUPkDHyBJAKketb4NfaeZjL5yLZdeUihSfbF2PQMz+rSTEb8ARKoOl3UBT4m7/X+QOXJo3sLTcq+yMMYTA== + dependencies: + magic-string "^0.25.2" + rollup-pluginutils "^2.6.0" + rollup-pluginutils@^1.5.0, rollup-pluginutils@^1.5.1: version "1.5.2" resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz#1e156e778f94b7255bfa1b3d0178be8f5c552408" @@ -4395,6 +4415,13 @@ rollup-pluginutils@^2.3.0: estree-walker "^0.6.0" micromatch "^3.1.10" +rollup-pluginutils@^2.6.0: + version "2.8.1" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz#8fa6dd0697344938ef26c2c09d2488ce9e33ce97" + integrity sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg== + dependencies: + estree-walker "^0.6.1" + rollup@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/rollup/-/rollup-1.8.0.tgz#e3ce8b708ad4325166717f74f244f691595d35e2" @@ -4613,6 +4640,11 @@ source-map@^0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== +sourcemap-codec@^1.4.4: + version "1.4.6" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.6.tgz#e30a74f0402bad09807640d39e971090a08ce1e9" + integrity sha512-1ZooVLYFxC448piVLBbtOxFcXwnymH9oUF8nRd3CuYDVvkRBxRl6pB4Mtas5a4drtL+E8LDgFkQNcgIw6tc8Hg== + spdx-correct@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" -- 2.45.2 From 73f10d488d5fd5df7aa806b60c8df5c948ca3c9a Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 23 Aug 2019 09:10:07 +0100 Subject: [PATCH 118/371] fix: myClaims undefined in some cases where isSupport is false --- dist/bundle.es.js | 2 +- dist/flow-typed/Lbry.js | 4 ++-- dist/flow-typed/lbryURI.js | 20 ++++++++++++++++++++ src/redux/actions/wallet.js | 2 +- 4 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 dist/flow-typed/lbryURI.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 67b3e7c..3ca2288 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2020,7 +2020,7 @@ function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { const balance = selectBalance(state); const myClaims = selectMyClaimsRaw(state); - const shouldSupport = isSupport || myClaims.find(claim => claim.claim_id === claimId); + const shouldSupport = isSupport || (myClaims ? myClaims.find(claim => claim.claim_id === claimId) : false); if (balance - amount <= 0) { dispatch(doToast({ diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 855c3fd..73dff71 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -66,7 +66,7 @@ declare type VersionResponse = { declare type BalanceResponse = { available: string, reserved: string, - reserved_subtotals: ? { + reserved_subtotals: ?{ claims: string, supports: string, tips: string, @@ -205,7 +205,7 @@ declare type LbryTypes = { comment_list: (params: {}) => Promise, comment_create: (params: {}) => Promise, // Wallet utilities - account_balance: (params: {}) => Promise, + account_balance: (params: {}) => Promise, account_decrypt: (prams: {}) => Promise, account_encrypt: (params: {}) => Promise, account_unlock: (params: {}) => Promise, diff --git a/dist/flow-typed/lbryURI.js b/dist/flow-typed/lbryURI.js new file mode 100644 index 0000000..4365da3 --- /dev/null +++ b/dist/flow-typed/lbryURI.js @@ -0,0 +1,20 @@ +// @flow +declare type LbryUrlObj = { + // Path and channel will always exist when calling parseURI + // But they may not exist when code calls buildURI + isChannel?: boolean, + path?: string, + streamName?: string, + streamClaimId?: string, + channelName?: string, + channelClaimId?: string, + primaryClaimSequence?: number, + secondaryClaimSequence?: number, + primaryBidPosition?: number, + secondaryBidPosition?: number, + + // Below are considered deprecated and should not be used due to unreliableness with claim.canonical_url + claimName?: string, + claimId?: string, + contentName?: string, +}; diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 55f0751..d2bdb33 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -217,7 +217,7 @@ export function doSendTip(amount, claimId, isSupport, successCallback, errorCall const balance = selectBalance(state); const myClaims = selectMyClaimsRaw(state); - const shouldSupport = isSupport || myClaims.find(claim => claim.claim_id === claimId); + const shouldSupport = isSupport || (myClaims ? myClaims.find(claim => claim.claim_id === claimId) : false); if (balance - amount <= 0) { dispatch( -- 2.45.2 From 18ff574d0ea5769866efa84e946e16d689283566 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 27 Aug 2019 19:14:19 -0400 Subject: [PATCH 119/371] fix typo --- dist/bundle.es.js | 3 +-- src/redux/selectors/search.js | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3ca2288..7abfcfb 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1146,7 +1146,6 @@ const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selec if (!query) { return []; } - const queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://' || query === 'lbry://@'; if (queryIsPrefix) { @@ -1166,7 +1165,7 @@ const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selec const uri = normalizeURI(query); const { channelName, streamName, isChannel } = parseURI(uri); searchSuggestions.push({ - value: streamName, + value: query, type: SEARCH_TYPES.SEARCH }, { value: uri, diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index e533af1..aada012 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -56,7 +56,6 @@ export const selectSearchSuggestions: Array = createSelector( if (!query) { return []; } - const queryIsPrefix = query === 'lbry:' || query === 'lbry:/' || query === 'lbry://' || query === 'lbry://@'; @@ -80,7 +79,7 @@ export const selectSearchSuggestions: Array = createSelector( const { channelName, streamName, isChannel } = parseURI(uri); searchSuggestions.push( { - value: streamName, + value: query, type: SEARCH_TYPES.SEARCH, }, { -- 2.45.2 From b4e8cde4e3f61711acfbe3aeb219f5ba6f5de3be Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 27 Aug 2019 19:59:04 -0400 Subject: [PATCH 120/371] buildURI changes - contentName => streamName --- dist/bundle.es.js | 16 ++++++++++------ src/redux/reducers/publish.js | 4 ++-- src/redux/selectors/publish.js | 22 +++++++++++++--------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 7abfcfb..467b156 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2923,13 +2923,13 @@ const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, pu const { isChannel: currentIsChannel, - claimName: currentClaimName, - contentName: currentContentName + channelName: currentClaimName, + streamName: currentContentName } = parseURI(uri); const { isChannel: editIsChannel, - claimName: editClaimName, - contentName: editContentName + channelName: editClaimName, + streamName: editContentName } = parseURI(editingURI); // Depending on the previous/current use of a channel, we need to compare different things @@ -2968,8 +2968,12 @@ const selectIsResolvingPublishUris = reselect.createSelector(selectState$5, sele }); const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => { + if (!name) { + return null; + } + // We only care about the winning claim for the short uri - const shortUri = buildURI({ contentName: name }); + const shortUri = buildURI({ streamName: name }); const claimForShortUri = claimsByUri[shortUri]; if (!myClaimForUri && claimForShortUri) { @@ -4349,7 +4353,7 @@ const publishReducer = handleActions({ // The editingUri is the full uri with claim id const shortUri = buildURI({ channelName: channel, - contentName: name + streamName: name }); return _extends$a({}, defaultState$6, publishData, { diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js index 9cf1aae..93ae3e5 100644 --- a/src/redux/reducers/publish.js +++ b/src/redux/reducers/publish.js @@ -27,7 +27,7 @@ type PublishState = { bidError: ?string, otherLicenseDescription: string, licenseUrl: string, - tags: Array + tags: Array, }; const defaultState: PublishState = { @@ -94,7 +94,7 @@ export const publishReducer = handleActions( // The editingUri is the full uri with claim id const shortUri = buildURI({ channelName: channel, - contentName: name, + streamName: name, }); return { diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index bfe4390..8842e30 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -35,13 +35,13 @@ export const selectIsStillEditing = createSelector( const { isChannel: currentIsChannel, - claimName: currentClaimName, - contentName: currentContentName, + channelName: currentClaimName, + streamName: currentContentName, } = parseURI(uri); const { isChannel: editIsChannel, - claimName: editClaimName, - contentName: editContentName, + channelName: editClaimName, + streamName: editContentName, } = parseURI(editingURI); // Depending on the previous/current use of a channel, we need to compare different things @@ -68,10 +68,10 @@ export const selectMyClaimForUri = createSelector( return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => - !contentName - ? claim.name === claimName - : claim.name === contentName || claim.name === claimName - ); + !contentName + ? claim.name === claimName + : claim.name === contentName || claim.name === claimName + ); } ); @@ -101,8 +101,12 @@ export const selectTakeOverAmount = createSelector( selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => { + if (!name) { + return null; + } + // We only care about the winning claim for the short uri - const shortUri = buildURI({ contentName: name }); + const shortUri = buildURI({ streamName: name }); const claimForShortUri = claimsByUri[shortUri]; if (!myClaimForUri && claimForShortUri) { -- 2.45.2 From 3ebbb4470c6c64fdc730f071a94aa30fc4d8e60d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 28 Aug 2019 10:55:50 -0400 Subject: [PATCH 121/371] fix typo --- dist/bundle.es.js | 4 +--- src/redux/reducers/claims.js | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 467b156..913e358 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3636,9 +3636,7 @@ function handleClaimAction(state, action) { if (stream) { byId[stream.claim_id] = stream; byUri[url] = stream.claim_id; - } - - if (channel) { + } else if (channel) { byId[channel.claim_id] = channel; byUri[stream ? channel.canonical_url : url] = channel.claim_id; } diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 4aacad6..34bd4ed 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -76,9 +76,7 @@ function handleClaimAction(state: State, action: any): State { if (stream) { byId[stream.claim_id] = stream; byUri[url] = stream.claim_id; - } - - if (channel) { + } else if (channel) { byId[channel.claim_id] = channel; byUri[stream ? channel.canonical_url : url] = channel.claim_id; } -- 2.45.2 From e8c6efcea8612c1808a60a3003d9d95791e78686 Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 23 Aug 2019 22:43:49 -0400 Subject: [PATCH 122/371] parseURI separates querystrings --- dist/bundle.es.js | 13 ++++++++++++- src/lbryURI.js | 15 ++++++++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 913e358..4370ce0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -907,6 +907,8 @@ const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; const regexPartProtocol = '^((?:lbry://)?)'; const regexPartStreamOrChannelName = '([^:$#/]*)'; const regexPartModifierSeparator = '([:$#]?)([^/]*)'; +const queryStringBreaker = '^([\\S]+)([?][\\S]*)'; +const separateQuerystring = new RegExp(queryStringBreaker); /** * Parses a LBRY name into its component parts. Throws errors with user-friendly @@ -927,13 +929,21 @@ const regexPartModifierSeparator = '([:$#]?)([^/]*)'; function parseURI(URL, requireProto = false) { // Break into components. Empty sub-matches are converted to null + const componentsRegex = new RegExp(regexPartProtocol + // protocol regexPartStreamOrChannelName + // stream or channel name (stops at the first separator or end) regexPartModifierSeparator + // modifier separator, modifier (stops at the first path separator or end) '(/?)' + // path separator, there should only be one (optional) slash to separate the stream and channel parts regexPartStreamOrChannelName + regexPartModifierSeparator); + // chop off the querystring first + let QSStrippedURL, qs; + const qsRegexResult = separateQuerystring.exec(URL); + if (qsRegexResult) { + [QSStrippedURL, qs] = qsRegexResult.slice(1).map(match => match || null); + } - const regexMatch = componentsRegex.exec(URL) || []; + const cleanURL = QSStrippedURL || URL; + const regexMatch = componentsRegex.exec(cleanURL) || []; const [proto, ...rest] = regexMatch.slice(1).map(match => match || null); const path = rest.join(''); const [streamNameOrChannelName, primaryModSeparator, primaryModValue, pathSep, possibleStreamName, secondaryModSeparator, secondaryModValue] = rest; @@ -985,6 +995,7 @@ function parseURIModifier(modSeperator, modValue) { let claimId; let claimSequence; let bidPosition; + if (modSeperator) { if (!modValue) { throw new Error(__(`No modifier provided after separator %s.`, modSeperator)); diff --git a/src/lbryURI.js b/src/lbryURI.js index 3a67e6e..189c701 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -9,6 +9,10 @@ export const regexAddress = /^(b|r)(?=[^0OIl]{32,33})[0-9A-Za-z]{32,33}$/; const regexPartProtocol = '^((?:lbry://)?)'; const regexPartStreamOrChannelName = '([^:$#/]*)'; const regexPartModifierSeparator = '([:$#]?)([^/]*)'; +const queryStringBreaker = '^([\\S]+)([?][\\S]*)'; +const separateQuerystring = new RegExp( + queryStringBreaker +); /** * Parses a LBRY name into its component parts. Throws errors with user-friendly @@ -29,6 +33,7 @@ const regexPartModifierSeparator = '([:$#]?)([^/]*)'; export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj { // Break into components. Empty sub-matches are converted to null + const componentsRegex = new RegExp( regexPartProtocol + // protocol regexPartStreamOrChannelName + // stream or channel name (stops at the first separator or end) @@ -37,8 +42,15 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj regexPartStreamOrChannelName + regexPartModifierSeparator ); + // chop off the querystring first + let QSStrippedURL, qs; + const qsRegexResult = separateQuerystring.exec(URL) + if (qsRegexResult) { + [QSStrippedURL, qs] = qsRegexResult.slice(1).map(match => match || null); + } - const regexMatch = componentsRegex.exec(URL) || []; + const cleanURL = QSStrippedURL || URL; + const regexMatch = componentsRegex.exec(cleanURL) || []; const [proto, ...rest] = regexMatch.slice(1).map(match => match || null); const path = rest.join(''); const [ @@ -114,6 +126,7 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) { let claimId; let claimSequence; let bidPosition; + if (modSeperator) { if (!modValue) { throw new Error(__(`No modifier provided after separator %s.`, modSeperator)); -- 2.45.2 From 5f97dc03fd71bba01191310f0db33113810e87e2 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 28 Aug 2019 13:19:12 -0400 Subject: [PATCH 123/371] querystring param --- dist/bundle.es.js | 14 +++++++++++++- src/lbryURI.js | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4370ce0..1992b99 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -988,7 +988,7 @@ function parseURI(URL, requireProto = false) { // They will not work properly with canonical_urls claimName: streamNameOrChannelName, claimId: primaryClaimId - }, streamName ? { contentName: streamName } : {}); + }, streamName ? { contentName: streamName } : {}, qs ? { queryString: qs } : {}); } function parseURIModifier(modSeperator, modValue) { @@ -1044,6 +1044,18 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; + { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } + } + if (!claimName && !channelName && !streamName) { throw new Error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } diff --git a/src/lbryURI.js b/src/lbryURI.js index 189c701..c22dbbf 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -119,6 +119,7 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj claimName: streamNameOrChannelName, claimId: primaryClaimId, ...(streamName ? { contentName: streamName } : {}), + ...(qs ? { queryString: qs} : {}), }; } -- 2.45.2 From a9e2cc91838af340d4566b384b20d7b0af8e68df Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 28 Aug 2019 19:56:24 -0400 Subject: [PATCH 124/371] prod bundle --- dist/bundle.es.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1992b99..ee25f3d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1044,18 +1044,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { throw new Error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } -- 2.45.2 From 80d67a240bcd055d7740046b9ab04af5d253ba4d Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 29 Aug 2019 03:28:04 -0400 Subject: [PATCH 125/371] fix: canonical URL stuff Added cross-env to support compiling on Windows Channel name now returns the channel with @ updated remaining instances of claimid/contentname removed unused function that relied on parseURI --- dist/bundle.es.js | 118 ++++--------------------------- package.json | 3 +- src/index.js | 1 - src/lbryURI.js | 4 +- src/redux/reducers/claims.js | 2 +- src/redux/selectors/claims.js | 2 +- src/redux/selectors/file_info.js | 100 -------------------------- src/redux/selectors/publish.js | 16 ++--- yarn.lock | 10 ++- 9 files changed, 35 insertions(+), 221 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ee25f3d..924a275 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -898,7 +898,7 @@ const getSearchQueryString = (query, options = {}, includeUserOptions = false) = var _extends = 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 channelNameMinLength = 1; +const channelNameMinLength = 2; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls @@ -960,7 +960,7 @@ function parseURI(URL, requireProto = false) { const includesChannel = streamNameOrChannelName.startsWith('@'); const isChannel = streamNameOrChannelName.startsWith('@') && !possibleStreamName; - const channelName = includesChannel && streamNameOrChannelName.slice(1); + const channelName = includesChannel && streamNameOrChannelName; if (includesChannel) { if (!channelName) { @@ -1725,7 +1725,7 @@ const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSe let recommendedContent; if (claim) { // If we are at a vanity uri, build the full uri so we can properly filter - const currentUri = atVanityURI ? buildURI({ claimId: claim.claim_id, claimName: claim.name }) : uri; + const currentUri = atVanityURI ? buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }) : uri; const { title } = claim.value; @@ -2594,99 +2594,6 @@ const selectTotalDownloadProgress = reselect.createSelector(selectDownloadingFil return -1; }); -const selectSearchDownloadUris = query => reselect.createSelector(selectFileInfosDownloaded, selectClaimsById, (fileInfos, claimsById) => { - if (!query || !fileInfos.length) { - return null; - } - - const queryParts = query.toLowerCase().split(' '); - const searchQueryDictionary = {}; - queryParts.forEach(subQuery => { - searchQueryDictionary[subQuery] = subQuery; - }); - - const arrayContainsQueryPart = array => { - for (let i = 0; i < array.length; i += 1) { - const subQuery = array[i]; - if (searchQueryDictionary[subQuery]) { - return true; - } - } - return false; - }; - - const downloadResultsFromQuery = []; - fileInfos.forEach(fileInfo => { - const { channel_name: channelName, claim_name: claimName, metadata } = fileInfo; - const { author, description, title } = metadata; - - if (channelName) { - const lowerCaseChannel = channelName.toLowerCase(); - const strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ - if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - const nameParts = claimName.toLowerCase().split('-'); - if (arrayContainsQueryPart(nameParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - if (title) { - const titleParts = title.toLowerCase().split(' '); - if (arrayContainsQueryPart(titleParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - if (author) { - const authorParts = author.toLowerCase().split(' '); - if (arrayContainsQueryPart(authorParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - if (description) { - const descriptionParts = description.toLowerCase().split(' '); - if (arrayContainsQueryPart(descriptionParts)) { - downloadResultsFromQuery.push(fileInfo); - } - } - }); - - return downloadResultsFromQuery.length ? downloadResultsFromQuery.map(fileInfo => { - const { - channel_name: channelName, - claim_id: claimId, - claim_name: claimName - } = fileInfo; - - const uriParams = {}; - - if (channelName) { - const claim = claimsById[claimId]; - if (claim && claim.signing_channel) { - uriParams.claimId = claim.signing_channel.claim_id; - } else { - uriParams.claimId = claimId; - } - uriParams.channelName = channelName; - uriParams.contentName = claimName; - } else { - uriParams.claimId = claimId; - uriParams.claimName = claimName; - } - - const uri = buildURI(uriParams); - return uri; - }) : null; -}); - const selectFileListPublishedSort = reselect.createSelector(selectState$3, state => state.fileListPublishedSort); const selectFileListDownloadedSort = reselect.createSelector(selectState$3, state => state.fileListDownloadedSort); @@ -2934,13 +2841,13 @@ const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, pu const { isChannel: currentIsChannel, - channelName: currentClaimName, - streamName: currentContentName + streamName: currentClaimName, + channelName: currentContentName } = parseURI(uri); const { isChannel: editIsChannel, - channelName: editClaimName, - streamName: editContentName + streamName: editClaimName, + channelName: editContentName } = parseURI(editingURI); // Depending on the previous/current use of a channel, we need to compare different things @@ -2951,8 +2858,8 @@ const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, pu }); const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, selectIsStillEditing, selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => { - const { contentName, claimName } = parseURI(uri); - const { claimId: editClaimId } = parseURI(editingURI); + const { channelName: contentName, streamName: claimName } = parseURI(uri); + const { streamClaimId: editClaimId } = parseURI(editingURI); // If isStillEditing // They clicked "edit" from the file page @@ -2988,14 +2895,14 @@ const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClai const claimForShortUri = claimsByUri[shortUri]; if (!myClaimForUri && claimForShortUri) { - return claimForShortUri.effective_amount; + return claimForShortUri.meta.effective_amount; } else if (myClaimForUri && claimForShortUri) { // https://github.com/lbryio/lbry/issues/1476 // We should check the current effective_amount on my claim to see how much additional lbc // is needed to win the claim. Currently this is not possible during a takeover. // With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim" // For now just ignore supports. We will just show the winning claim's bid amount - return claimForShortUri.effective_amount || claimForShortUri.amount; + return claimForShortUri.meta.effective_amount || claimForShortUri.amount; } return null; @@ -3680,7 +3587,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { const pendingById = Object.assign({}, state.pendingById); claims.forEach(claim => { - const uri = buildURI({ claimName: claim.name, claimId: claim.claim_id }); + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); if (claim.type && claim.type.match(/claim|update/)) { if (claim.confirmations < 1) { @@ -5076,7 +4983,6 @@ exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; exports.selectResolvingUris = selectResolvingUris; exports.selectSearchBarFocused = selectSearchBarFocused; -exports.selectSearchDownloadUris = selectSearchDownloadUris; exports.selectSearchOptions = selectSearchOptions; exports.selectSearchState = selectState; exports.selectSearchSuggestions = selectSearchSuggestions; diff --git a/package.json b/package.json index ca6b815..b8214b4 100644 --- a/package.json +++ b/package.json @@ -21,7 +21,7 @@ "main": "dist/bundle.es.js", "module": "dist/bundle.es.js", "scripts": { - "build": "NODE_ENV=production rollup --config", + "build": "cross-env NODE_ENV=production rollup --config", "dev": "rollup --config --watch", "precommit": "flow check && lint-staged", "lint": "eslint 'src/**/*.js' --fix", @@ -40,6 +40,7 @@ "babel-plugin-transform-flow-comments": "^6.17.0", "babel-preset-env": "^1.6.1", "babel-preset-stage-2": "^6.18.0", + "cross-env": "^5.2.0", "eslint": "^5.16.0", "eslint-config-standard": "^12.0.0", "eslint-config-standard-jsx": "^6.0.2", diff --git a/src/index.js b/src/index.js index 1370c3c..754aa87 100644 --- a/src/index.js +++ b/src/index.js @@ -215,7 +215,6 @@ export { selectFileInfosDownloaded, selectDownloadingFileInfos, selectTotalDownloadProgress, - selectSearchDownloadUris, selectFileListDownloadedSort, selectFileListPublishedSort, selectDownloadedUris, diff --git a/src/lbryURI.js b/src/lbryURI.js index c22dbbf..9006055 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -1,6 +1,6 @@ // @flow const isProduction = process.env.NODE_ENV === 'production'; -const channelNameMinLength = 1; +const channelNameMinLength = 2; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls @@ -75,7 +75,7 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj const includesChannel = streamNameOrChannelName.startsWith('@'); const isChannel = streamNameOrChannelName.startsWith('@') && !possibleStreamName; - const channelName = includesChannel && streamNameOrChannelName.slice(1); + const channelName = includesChannel && streamNameOrChannelName; if (includesChannel) { if (!channelName) { diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 34bd4ed..0a0975b 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -112,7 +112,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); claims.forEach((claim: Claim) => { - const uri = buildURI({ claimName: claim.name, claimId: claim.claim_id }); + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); if (claim.type && claim.type.match(/claim|update/)) { if (claim.confirmations < 1) { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 26cbc7b..9fbea4d 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -458,7 +458,7 @@ export const makeSelectRecommendedContentForUri = (uri: string) => if (claim) { // If we are at a vanity uri, build the full uri so we can properly filter const currentUri = atVanityURI - ? buildURI({ claimId: claim.claim_id, claimName: claim.name }) + ? buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }) : uri; const { title } = claim.value; diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index c36bd76..d805eff 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -132,106 +132,6 @@ export const selectTotalDownloadProgress = createSelector( } ); -export const selectSearchDownloadUris = query => - createSelector( - selectFileInfosDownloaded, - selectClaimsById, - (fileInfos, claimsById) => { - if (!query || !fileInfos.length) { - return null; - } - - const queryParts = query.toLowerCase().split(' '); - const searchQueryDictionary = {}; - queryParts.forEach(subQuery => { - searchQueryDictionary[subQuery] = subQuery; - }); - - const arrayContainsQueryPart = array => { - for (let i = 0; i < array.length; i += 1) { - const subQuery = array[i]; - if (searchQueryDictionary[subQuery]) { - return true; - } - } - return false; - }; - - const downloadResultsFromQuery = []; - fileInfos.forEach(fileInfo => { - const { channel_name: channelName, claim_name: claimName, metadata } = fileInfo; - const { author, description, title } = metadata; - - if (channelName) { - const lowerCaseChannel = channelName.toLowerCase(); - const strippedOutChannelName = lowerCaseChannel.slice(1); // trim off the @ - if (searchQueryDictionary[channelName] || searchQueryDictionary[strippedOutChannelName]) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - const nameParts = claimName.toLowerCase().split('-'); - if (arrayContainsQueryPart(nameParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - - if (title) { - const titleParts = title.toLowerCase().split(' '); - if (arrayContainsQueryPart(titleParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - if (author) { - const authorParts = author.toLowerCase().split(' '); - if (arrayContainsQueryPart(authorParts)) { - downloadResultsFromQuery.push(fileInfo); - return; - } - } - - if (description) { - const descriptionParts = description.toLowerCase().split(' '); - if (arrayContainsQueryPart(descriptionParts)) { - downloadResultsFromQuery.push(fileInfo); - } - } - }); - - return downloadResultsFromQuery.length - ? downloadResultsFromQuery.map(fileInfo => { - const { - channel_name: channelName, - claim_id: claimId, - claim_name: claimName, - } = fileInfo; - - const uriParams = {}; - - if (channelName) { - const claim = claimsById[claimId]; - if (claim && claim.signing_channel) { - uriParams.claimId = claim.signing_channel.claim_id; - } else { - uriParams.claimId = claimId; - } - uriParams.channelName = channelName; - uriParams.contentName = claimName; - } else { - uriParams.claimId = claimId; - uriParams.claimName = claimName; - } - - const uri = buildURI(uriParams); - return uri; - }) - : null; - } - ); - export const selectFileListPublishedSort = createSelector( selectState, state => state.fileListPublishedSort diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index 8842e30..ac468c9 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -35,13 +35,13 @@ export const selectIsStillEditing = createSelector( const { isChannel: currentIsChannel, - channelName: currentClaimName, - streamName: currentContentName, + streamName: currentClaimName, + channelName: currentContentName, } = parseURI(uri); const { isChannel: editIsChannel, - channelName: editClaimName, - streamName: editContentName, + streamName: editClaimName, + channelName: editContentName, } = parseURI(editingURI); // Depending on the previous/current use of a channel, we need to compare different things @@ -58,8 +58,8 @@ export const selectMyClaimForUri = createSelector( selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => { - const { contentName, claimName } = parseURI(uri); - const { claimId: editClaimId } = parseURI(editingURI); + const { channelName: contentName, streamName: claimName } = parseURI(uri); + const { streamClaimId: editClaimId } = parseURI(editingURI); // If isStillEditing // They clicked "edit" from the file page @@ -110,14 +110,14 @@ export const selectTakeOverAmount = createSelector( const claimForShortUri = claimsByUri[shortUri]; if (!myClaimForUri && claimForShortUri) { - return claimForShortUri.effective_amount; + return claimForShortUri.meta.effective_amount; } else if (myClaimForUri && claimForShortUri) { // https://github.com/lbryio/lbry/issues/1476 // We should check the current effective_amount on my claim to see how much additional lbc // is needed to win the claim. Currently this is not possible during a takeover. // With this, we could say something like, "You have x lbc in support, if you bid y additional LBC you will control the claim" // For now just ignore supports. We will just show the winning claim's bid amount - return claimForShortUri.effective_amount || claimForShortUri.amount; + return claimForShortUri.meta.effective_amount || claimForShortUri.amount; } return null; diff --git a/yarn.lock b/yarn.lock index 156e422..eed6546 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1418,6 +1418,14 @@ cosmiconfig@^4.0.0: parse-json "^4.0.0" require-from-string "^2.0.1" +cross-env@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" + integrity sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg== + dependencies: + cross-spawn "^6.0.5" + is-windows "^1.0.0" + cross-spawn@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" @@ -2886,7 +2894,7 @@ is-utf8@^0.2.0: resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" integrity sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI= -is-windows@^1.0.2: +is-windows@^1.0.0, is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== -- 2.45.2 From ea3e1824e8dd9d73920afd9612335887d0389c3a Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 29 Aug 2019 12:38:00 -0400 Subject: [PATCH 126/371] revert: channel name without @ Will adjust on desktop side --- dist/bundle.es.js | 4 ++-- src/lbryURI.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 924a275..0ef3310 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -898,7 +898,7 @@ const getSearchQueryString = (query, options = {}, includeUserOptions = false) = var _extends = 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 channelNameMinLength = 2; +const channelNameMinLength = 1; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls @@ -960,7 +960,7 @@ function parseURI(URL, requireProto = false) { const includesChannel = streamNameOrChannelName.startsWith('@'); const isChannel = streamNameOrChannelName.startsWith('@') && !possibleStreamName; - const channelName = includesChannel && streamNameOrChannelName; + const channelName = includesChannel && streamNameOrChannelName.slice(1); if (includesChannel) { if (!channelName) { diff --git a/src/lbryURI.js b/src/lbryURI.js index 9006055..c22dbbf 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -1,6 +1,6 @@ // @flow const isProduction = process.env.NODE_ENV === 'production'; -const channelNameMinLength = 2; +const channelNameMinLength = 1; const claimIdMaxLength = 40; // see https://spec.lbry.com/#urls @@ -75,7 +75,7 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj const includesChannel = streamNameOrChannelName.startsWith('@'); const isChannel = streamNameOrChannelName.startsWith('@') && !possibleStreamName; - const channelName = includesChannel && streamNameOrChannelName; + const channelName = includesChannel && streamNameOrChannelName.slice(1); if (includesChannel) { if (!channelName) { -- 2.45.2 From 48dd46a9a837d81cff8700b7a571baa8081bf3aa Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 29 Aug 2019 19:09:15 -0400 Subject: [PATCH 127/371] fix: byURL for channel --- dist/bundle.es.js | 2 +- src/redux/reducers/claims.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 0ef3310..5b509f0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3556,7 +3556,7 @@ function handleClaimAction(state, action) { byUri[url] = stream.claim_id; } else if (channel) { byId[channel.claim_id] = channel; - byUri[stream ? channel.canonical_url : url] = channel.claim_id; + byUri[url] = channel.claim_id; } if (!stream && !channel) { diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 0a0975b..adeabca 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -78,7 +78,7 @@ function handleClaimAction(state: State, action: any): State { byUri[url] = stream.claim_id; } else if (channel) { byId[channel.claim_id] = channel; - byUri[stream ? channel.canonical_url : url] = channel.claim_id; + byUri[url] = channel.claim_id; } if (!stream && !channel) { -- 2.45.2 From 596a7ecee8961e3385a1b0be6fdeff57ef48bfb8 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 30 Aug 2019 09:56:03 -0400 Subject: [PATCH 128/371] add image to media types --- dist/bundle.es.js | 2 +- src/lbry.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 5b509f0..5c4d229 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -692,7 +692,7 @@ const Lbry = { // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType, fileName) => { if (fileName) { - const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book']]; + const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book']]; const res = formats.reduce((ret, testpair) => { switch (testpair[0].test(ret)) { diff --git a/src/lbry.js b/src/lbry.js index 44b57cd..f236989 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -37,6 +37,7 @@ const Lbry: LbryTypes = { const formats = [ [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], + [/\.(jpeg|jpg|png|gif)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], -- 2.45.2 From 40a8074626569266b278d216be90342d9c4900cb Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Sat, 31 Aug 2019 00:03:11 -0400 Subject: [PATCH 129/371] add application to media types --- dist/bundle.es.js | 2 +- src/lbry.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 5c4d229..f04595a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -692,7 +692,7 @@ const Lbry = { // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType, fileName) => { if (fileName) { - const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book']]; + const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; const res = formats.reduce((ret, testpair) => { switch (testpair[0].test(ret)) { diff --git a/src/lbry.js b/src/lbry.js index f236989..78132d9 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -43,6 +43,7 @@ const Lbry: LbryTypes = { [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], + [/\.(lbry)$/i, 'application'], ]; const res = formats.reduce((ret, testpair) => { -- 2.45.2 From 7a6e8ddabc03100943c1c49cf8c0501d6cdc9213 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Fri, 30 Aug 2019 12:28:36 -0400 Subject: [PATCH 130/371] fixes: recommended content + crashes --- dist/bundle.es.js | 8 ++++---- src/lbryURI.js | 2 +- src/redux/selectors/claims.js | 6 ++---- src/redux/selectors/publish.js | 2 +- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f04595a..1827e89 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1045,7 +1045,7 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { const { claimId, claimName, contentName } = deprecatedParts; if (!claimName && !channelName && !streamName) { - throw new Error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); + console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } const formattedChannelName = channelName && (channelName.startsWith('@') ? channelName : `@${channelName}`); @@ -1724,8 +1724,8 @@ const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSe let recommendedContent; if (claim) { - // If we are at a vanity uri, build the full uri so we can properly filter - const currentUri = atVanityURI ? buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }) : uri; + // always grab full URL - this can change once search returns canonical + const currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); const { title } = claim.value; @@ -2874,7 +2874,7 @@ const selectIsResolvingPublishUris = reselect.createSelector(selectState$5, sele const { isChannel } = parseURI(uri); let isResolvingShortUri; - if (isChannel) { + if (isChannel && name) { const shortUri = buildURI({ streamName: name }); isResolvingShortUri = resolvingUris.includes(shortUri); } diff --git a/src/lbryURI.js b/src/lbryURI.js index c22dbbf..aeeff2c 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -199,7 +199,7 @@ export function buildURI( } if (!claimName && !channelName && !streamName) { - throw new Error( + console.error( __( "'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url." ) diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 9fbea4d..6e983b9 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -456,10 +456,8 @@ export const makeSelectRecommendedContentForUri = (uri: string) => let recommendedContent; if (claim) { - // If we are at a vanity uri, build the full uri so we can properly filter - const currentUri = atVanityURI - ? buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }) - : uri; + // always grab full URL - this can change once search returns canonical + const currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); const { title } = claim.value; diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index ac468c9..ce0a20c 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -84,7 +84,7 @@ export const selectIsResolvingPublishUris = createSelector( const { isChannel } = parseURI(uri); let isResolvingShortUri; - if (isChannel) { + if (isChannel && name) { const shortUri = buildURI({ streamName: name }); isResolvingShortUri = resolvingUris.includes(shortUri); } -- 2.45.2 From a2ef019c694e7d3c415336b1362779e37f2dc8e4 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 4 Sep 2019 11:57:48 -0400 Subject: [PATCH 131/371] canonical_url fixes --- dist/bundle.es.js | 76 +++++++++++++++++++++-------------- src/index.js | 1 + src/lbry.js | 2 +- src/redux/actions/publish.js | 3 +- src/redux/actions/wallet.js | 6 +-- src/redux/reducers/claims.js | 60 +++++++++++++++++---------- src/redux/selectors/claims.js | 17 +++++--- 7 files changed, 101 insertions(+), 64 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1827e89..944df0c 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -692,7 +692,7 @@ const Lbry = { // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType, fileName) => { if (fileName) { - const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; + const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; const res = formats.reduce((ret, testpair) => { switch (testpair[0].test(ret)) { @@ -1747,13 +1747,12 @@ const makeSelectFirstRecommendedFileForUri = uri => reselect.createSelector(make // accepts a regular claim uri lbry://something // returns the channel uri that created this claim lbry://@channel const makeSelectChannelForClaimUri = (uri, includePrefix = false) => reselect.createSelector(makeSelectClaimForUri(uri), claim => { - if (!claim || !claim.signing_channel) { + if (!claim || !claim.signing_channel || !claim.canonical_url) { return null; } - const { claim_id: claimId, name } = claim.signing_channel; - let channel = `${name}#${claimId}`; - return includePrefix ? `lbry://${channel}` : channel; + const { canonical_url: canonicalUrl } = claim.signing_channel; + return includePrefix ? canonicalUrl : canonicalUrl.slice('lbry://'.length); }); const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => { @@ -1772,6 +1771,8 @@ const makeSelectShortUrlForUri = uri => reselect.createSelector(makeSelectClaimF const makeSelectCanonicalUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.canonical_url); +const makeSelectPermanentUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.permanent_url); + const makeSelectSupportsForUri = uri => reselect.createSelector(selectSupportsByOutpoint, makeSelectClaimForUri(uri), (byOutpoint, claim) => { if (!claim || !claim.is_mine) { return null; @@ -1830,8 +1831,6 @@ function creditsToString(amount) { return creditString; } -// - function doUpdateBalance() { return (dispatch, getState) => { const { @@ -3034,7 +3033,7 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter, fs, path) => di const doPrepareEdit = (claim, uri, fileInfo, fs) => dispatch => { const { name, amount, value = {} } = claim; - const channelName = claim && claim.signing_channel && claim.signing_channel.normalized_name || null; + const channelName = claim && claim.signing_channel && claim.signing_channel.name || null; const { author, description, @@ -3543,6 +3542,7 @@ function handleClaimAction(state, action) { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + let newResolvingUrls = new Set(state.resolvingUris); Object.entries(resolveInfo).forEach(([url, resolveResponse]) => { // $FlowFixMe @@ -3554,11 +3554,26 @@ function handleClaimAction(state, action) { if (stream) { byId[stream.claim_id] = stream; byUri[url] = stream.claim_id; - } else if (channel) { - byId[channel.claim_id] = channel; - byUri[url] = channel.claim_id; + // Also add the permanent_url here until lighthouse returns canonical_url for search results + byUri[stream.permanent_url] = stream.claim_id; + newResolvingUrls.delete(stream.canonical_url); + newResolvingUrls.delete(stream.permanent_url); } + if (channel) { + if (!stream) { + byUri[url] = channel.claim_id; + } + + byId[channel.claim_id] = channel; + // Also add the permanent_url here until lighthouse returns canonical_url for search results + byUri[channel.permanent_url] = channel.claim_id; + byUri[channel.canonical_url] = channel.claim_id; + newResolvingUrls.delete(channel.canonical_url); + newResolvingUrls.delete(channel.permanent_url); + } + + newResolvingUrls.delete(url); if (!stream && !channel) { byUri[url] = null; } @@ -3568,10 +3583,27 @@ function handleClaimAction(state, action) { byId, claimsByUri: byUri, channelClaimCounts, - resolvingUris: (state.resolvingUris || []).filter(uri => !resolveInfo[uri]) + resolvingUris: Array.from(newResolvingUrls) }); } +reducers[RESOLVE_URIS_STARTED] = (state, action) => { + const { uris } = action.data; + + const oldResolving = state.resolvingUris || []; + const newResolving = oldResolving.slice(); + + uris.forEach(uri => { + if (!newResolving.includes(uri)) { + newResolving.push(uri); + } + }); + + return Object.assign({}, state, { + resolvingUris: newResolving + }); +}; + reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { return _extends$5({}, handleClaimAction(state, action)); }; @@ -3669,7 +3701,7 @@ reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { allClaimIds.add(claim.claim_id); currentPageClaimIds.push(claim.claim_id); byId[claim.claim_id] = claim; - claimsByUri[`lbry://${claim.name}#${claim.claim_id}`] = claim.claim_id; + claimsByUri[claim.canonical_url] = claim.claim_id; }); } @@ -3742,23 +3774,6 @@ reducers[UPDATE_CHANNEL_COMPLETED] = (state, action) => { }); }; -reducers[RESOLVE_URIS_STARTED] = (state, action) => { - const { uris } = action.data; - - const oldResolving = state.resolvingUris || []; - const newResolving = oldResolving.slice(); - - uris.forEach(uri => { - if (!newResolving.includes(uri)) { - newResolving.push(uri); - } - }); - - return Object.assign({}, state, { - resolvingUris: newResolving - }); -}; - reducers[CLAIM_SEARCH_STARTED] = (state, action) => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); fetchingClaimSearchByQuery[action.data.query] = true; @@ -4900,6 +4915,7 @@ exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectPendingByUri = makeSelectPendingByUri; +exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; diff --git a/src/index.js b/src/index.js index 754aa87..fd11491 100644 --- a/src/index.js +++ b/src/index.js @@ -173,6 +173,7 @@ export { makeSelectClaimsInChannelForCurrentPageState, makeSelectShortUrlForUri, makeSelectCanonicalUrlForUri, + makeSelectPermanentUrlForUri, makeSelectSupportsForUri, selectPendingById, selectClaimsById, diff --git a/src/lbry.js b/src/lbry.js index 78132d9..ba47709 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -37,7 +37,7 @@ const Lbry: LbryTypes = { const formats = [ [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], - [/\.(jpeg|jpg|png|gif)$/i, 'image'], + [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 5db20c9..72232b6 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -173,8 +173,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis dispatch: Dispatch ) => { const { name, amount, value = {} } = claim; - const channelName = - (claim && claim.signing_channel && claim.signing_channel.normalized_name) || null; + const channelName = (claim && claim.signing_channel && claim.signing_channel.name) || null; const { author, description, diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index d2bdb33..1e8d05b 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -1,4 +1,3 @@ -// @flow import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import { doToast } from 'redux/actions/notifications'; @@ -11,7 +10,7 @@ export function doUpdateBalance() { const { wallet: { balance: balanceInStore }, } = getState(); - Lbry.account_balance().then((response: BalanceResponse) => { + Lbry.account_balance().then(response => { const { available } = response; const balance = parseFloat(available); if (balanceInStore !== balance) { @@ -217,7 +216,8 @@ export function doSendTip(amount, claimId, isSupport, successCallback, errorCall const balance = selectBalance(state); const myClaims = selectMyClaimsRaw(state); - const shouldSupport = isSupport || (myClaims ? myClaims.find(claim => claim.claim_id === claimId) : false); + const shouldSupport = + isSupport || (myClaims ? myClaims.find(claim => claim.claim_id === claimId) : false); if (balance - amount <= 0) { dispatch( diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index adeabca..337bfac 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -65,6 +65,7 @@ function handleClaimAction(state: State, action: any): State { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + let newResolvingUrls = new Set(state.resolvingUris); Object.entries(resolveInfo).forEach(([url: string, resolveResponse: ResolveResponse]) => { // $FlowFixMe @@ -76,11 +77,26 @@ function handleClaimAction(state: State, action: any): State { if (stream) { byId[stream.claim_id] = stream; byUri[url] = stream.claim_id; - } else if (channel) { - byId[channel.claim_id] = channel; - byUri[url] = channel.claim_id; + // Also add the permanent_url here until lighthouse returns canonical_url for search results + byUri[stream.permanent_url] = stream.claim_id; + newResolvingUrls.delete(stream.canonical_url); + newResolvingUrls.delete(stream.permanent_url); } + if (channel) { + if (!stream) { + byUri[url] = channel.claim_id; + } + + byId[channel.claim_id] = channel; + // Also add the permanent_url here until lighthouse returns canonical_url for search results + byUri[channel.permanent_url] = channel.claim_id; + byUri[channel.canonical_url] = channel.claim_id; + newResolvingUrls.delete(channel.canonical_url); + newResolvingUrls.delete(channel.permanent_url); + } + + newResolvingUrls.delete(url); if (!stream && !channel) { byUri[url] = null; } @@ -90,10 +106,27 @@ function handleClaimAction(state: State, action: any): State { byId, claimsByUri: byUri, channelClaimCounts, - resolvingUris: (state.resolvingUris || []).filter(uri => !resolveInfo[uri]), + resolvingUris: Array.from(newResolvingUrls), }); } +reducers[ACTIONS.RESOLVE_URIS_STARTED] = (state: State, action: any): State => { + const { uris }: { uris: Array } = action.data; + + const oldResolving = state.resolvingUris || []; + const newResolving = oldResolving.slice(); + + uris.forEach(uri => { + if (!newResolving.includes(uri)) { + newResolving.push(uri); + } + }); + + return Object.assign({}, state, { + resolvingUris: newResolving, + }); +}; + reducers[ACTIONS.RESOLVE_URIS_COMPLETED] = (state: State, action: any): State => { return { ...handleClaimAction(state, action), @@ -196,7 +229,7 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): allClaimIds.add(claim.claim_id); currentPageClaimIds.push(claim.claim_id); byId[claim.claim_id] = claim; - claimsByUri[`lbry://${claim.name}#${claim.claim_id}`] = claim.claim_id; + claimsByUri[claim.canonical_url] = claim.claim_id; }); } @@ -269,23 +302,6 @@ reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State }); }; -reducers[ACTIONS.RESOLVE_URIS_STARTED] = (state: State, action: any): State => { - const { uris }: { uris: Array } = action.data; - - const oldResolving = state.resolvingUris || []; - const newResolving = oldResolving.slice(); - - uris.forEach(uri => { - if (!newResolving.includes(uri)) { - newResolving.push(uri); - } - }); - - return Object.assign({}, state, { - resolvingUris: newResolving, - }); -}; - reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State, action: any): State => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); fetchingClaimSearchByQuery[action.data.query] = true; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 6e983b9..f2dd7aa 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -457,7 +457,7 @@ export const makeSelectRecommendedContentForUri = (uri: string) => let recommendedContent; if (claim) { // always grab full URL - this can change once search returns canonical - const currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); + const currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); const { title } = claim.value; @@ -486,14 +486,13 @@ export const makeSelectFirstRecommendedFileForUri = (uri: string) => export const makeSelectChannelForClaimUri = (uri: string, includePrefix: boolean = false) => createSelector( makeSelectClaimForUri(uri), - (claim: ?StreamClaim) => { - if (!claim || !claim.signing_channel) { + (claim: ?Claim) => { + if (!claim || !claim.signing_channel || !claim.canonical_url) { return null; } - const { claim_id: claimId, name } = claim.signing_channel; - let channel = `${name}#${claimId}`; - return includePrefix ? `lbry://${channel}` : channel; + const { canonical_url: canonicalUrl } = claim.signing_channel; + return includePrefix ? canonicalUrl : canonicalUrl.slice('lbry://'.length); } ); @@ -537,6 +536,12 @@ export const makeSelectCanonicalUrlForUri = (uri: string) => claim => claim && claim.canonical_url ); +export const makeSelectPermanentUrlForUri = (uri: string) => + createSelector( + makeSelectClaimForUri(uri), + claim => claim && claim.permanent_url + ); + export const makeSelectSupportsForUri = (uri: string) => createSelector( selectSupportsByOutpoint, -- 2.45.2 From 2b3a5a59907f34d4e1c005c4696282b58d626242 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 4 Sep 2019 12:56:24 -0400 Subject: [PATCH 132/371] check if canonical_url exists (won't if channel is invalid) --- 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 944df0c..b68b4f0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1747,7 +1747,7 @@ const makeSelectFirstRecommendedFileForUri = uri => reselect.createSelector(make // accepts a regular claim uri lbry://something // returns the channel uri that created this claim lbry://@channel const makeSelectChannelForClaimUri = (uri, includePrefix = false) => reselect.createSelector(makeSelectClaimForUri(uri), claim => { - if (!claim || !claim.signing_channel || !claim.canonical_url) { + if (!claim || !claim.signing_channel || !claim.signing_channel.canonical_url) { return null; } diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index f2dd7aa..b0c6a68 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -487,7 +487,7 @@ export const makeSelectChannelForClaimUri = (uri: string, includePrefix: boolean createSelector( makeSelectClaimForUri(uri), (claim: ?Claim) => { - if (!claim || !claim.signing_channel || !claim.canonical_url) { + if (!claim || !claim.signing_channel || !claim.signing_channel.canonical_url) { return null; } -- 2.45.2 From 123efacf4d45289ebda9dc291976d475de227a55 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Sun, 15 Sep 2019 12:00:14 +0100 Subject: [PATCH 133/371] add optionalParams to doCreateChannel. Update myClaims after fetching channels (#195) * add optionalParams to doCreateChannel. Update myClaims after fetching channels. * merge with master. change coverUrl and thumbnailUrl. * make optionalParams truly optional --- dist/bundle.es.js | 67 ++++++++++++++++++++++++++++++----- src/index.js | 2 ++ src/redux/actions/claims.js | 42 +++++++++++++++++----- src/redux/reducers/claims.js | 21 +++++++++++ src/redux/selectors/claims.js | 10 ++++++ 5 files changed, 126 insertions(+), 16 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b68b4f0..0eb8aac 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1790,6 +1790,10 @@ const makeSelectSupportsForUri = uri => reselect.createSelector(selectSupportsBy return total; }); +const selectUpdatingChannel = reselect.createSelector(selectState$2, state => state.updatingChannel); + +const selectUpdateChannelError = reselect.createSelector(selectState$2, state => state.updateChannelError); + function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount), suffix = ''; @@ -2393,16 +2397,42 @@ function doFetchClaimsByChannel(uri, page = 1) { }; } -function doCreateChannel(name, amount) { +function doCreateChannel(name, amount, optionalParams) { return dispatch => { dispatch({ type: CREATE_CHANNEL_STARTED }); - return lbryProxy.channel_create({ + const createParams = { name, bid: creditsToString(amount) - }) + }; + + if (optionalParams) { + if (optionalParams.title) { + createParams.title = optionalParams.title; + } + if (optionalParams.coverUrl) { + createParams.cover_url = optionalParams.coverUrl; + } + if (optionalParams.thumbnailUrl) { + createParams.thumbnail_url = optionalParams.thumbnailUrl; + } + if (optionalParams.description) { + createParams.description = optionalParams.description; + } + if (optionalParams.website) { + createParams.website_url = optionalParams.website; + } + if (optionalParams.email) { + createParams.email = optionalParams.email; + } + if (optionalParams.tags) { + createParams.tags = optionalParams.tags.map(tag => tag.name); + } + } + + return lbryProxy.channel_create(createParams) // outputs[0] is the certificate // outputs[1] is the change from the tx, not in the app currently .then(result => { @@ -2429,8 +2459,8 @@ function doUpdateChannel(params) { claim_id: params.claim_id, bid: creditsToString(params.amount), title: params.title, - cover_url: params.cover, - thumbnail_url: params.thumbnail, + cover_url: params.coverUrl, + thumbnail_url: params.thumbnailUrl, description: params.description, website_url: params.website, email: params.email, @@ -3532,7 +3562,9 @@ const defaultState = { claimSearchError: false, claimSearchByQuery: {}, claimSearchByQueryLastPageReached: {}, - fetchingClaimSearchByQuery: {} + fetchingClaimSearchByQuery: {}, + updateChannelError: '', + updatingChannel: false }; function handleClaimAction(state, action) { @@ -3665,7 +3697,8 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { return Object.assign({}, state, { byId, fetchingMyChannels: false, - myChannelClaims + myChannelClaims, + myClaims: claims }); }; @@ -3763,6 +3796,13 @@ reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { }); }; +reducers[UPDATE_CHANNEL_STARTED] = (state, action) => { + return Object.assign({}, state, { + updateChannelError: '', + updatingChannel: true + }); +}; + reducers[UPDATE_CHANNEL_COMPLETED] = (state, action) => { const channelClaim = action.data.channelClaim; const byId = Object.assign({}, state.byId); @@ -3770,7 +3810,16 @@ reducers[UPDATE_CHANNEL_COMPLETED] = (state, action) => { byId[channelClaim.claim_id] = channelClaim; return Object.assign({}, state, { - byId + byId, + updateChannelError: '', + updatingChannel: false + }); +}; + +reducers[UPDATE_CHANNEL_FAILED] = (state, action) => { + return Object.assign({}, state, { + updateChannelError: action.data.message, + updatingChannel: false }); }; @@ -5014,6 +5063,8 @@ exports.selectTransactionItems = selectTransactionItems; exports.selectTransactionListFilter = selectTransactionListFilter; exports.selectTransactionsById = selectTransactionsById; exports.selectUnfollowedTags = selectUnfollowedTags; +exports.selectUpdateChannelError = selectUpdateChannelError; +exports.selectUpdatingChannel = selectUpdatingChannel; exports.selectUrisLoading = selectUrisLoading; exports.selectWalletDecryptPending = selectWalletDecryptPending; exports.selectWalletDecryptResult = selectWalletDecryptResult; diff --git a/src/index.js b/src/index.js index fd11491..e77f9df 100644 --- a/src/index.js +++ b/src/index.js @@ -200,6 +200,8 @@ export { selectFetchingClaimSearchByQuery, selectClaimSearchByQuery, selectClaimSearchByQueryLastPageReached, + selectUpdatingChannel, + selectUpdateChannelError, } 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 ab03679..c285e02 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -226,17 +226,43 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { }; } -export function doCreateChannel(name: string, amount: number) { +export function doCreateChannel(name: string, amount: number, optionalParams: any) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CREATE_CHANNEL_STARTED, }); - + + const createParams = { + name, + bid: creditsToString(amount), + }; + + if (optionalParams) { + if (optionalParams.title) { + createParams.title = optionalParams.title; + } + if (optionalParams.coverUrl) { + createParams.cover_url = optionalParams.coverUrl; + } + if (optionalParams.thumbnailUrl) { + createParams.thumbnail_url = optionalParams.thumbnailUrl; + } + if (optionalParams.description) { + createParams.description = optionalParams.description; + } + if (optionalParams.website) { + createParams.website_url = optionalParams.website; + } + if (optionalParams.email) { + createParams.email = optionalParams.email; + } + if (optionalParams.tags) { + createParams.tags = optionalParams.tags.map(tag => tag.name); + } + } + return ( - Lbry.channel_create({ - name, - bid: creditsToString(amount), - }) + Lbry.channel_create(createParams) // outputs[0] is the certificate // outputs[1] is the change from the tx, not in the app currently .then((result: ChannelCreateResponse) => { @@ -265,8 +291,8 @@ export function doUpdateChannel(params: any) { claim_id: params.claim_id, bid: creditsToString(params.amount), title: params.title, - cover_url: params.cover, - thumbnail_url: params.thumbnail, + cover_url: params.coverUrl, + thumbnail_url: params.thumbnailUrl, description: params.description, website_url: params.website, email: params.email, diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 337bfac..8c8d4d7 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -30,6 +30,8 @@ type State = { [number]: Array, }, }, + updateChannelError: string, + updatingChannel: boolean, }; const reducers = {}; @@ -50,6 +52,8 @@ const defaultState = { claimSearchByQuery: {}, claimSearchByQueryLastPageReached: {}, fetchingClaimSearchByQuery: {}, + updateChannelError: '', + updatingChannel: false, }; function handleClaimAction(state: State, action: any): State { @@ -194,6 +198,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St byId, fetchingMyChannels: false, myChannelClaims, + myClaims: claims, }); }; @@ -291,6 +296,13 @@ reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State }); }; +reducers[ACTIONS.UPDATE_CHANNEL_STARTED] = (state: State, action: any): State => { + return Object.assign({}, state, { + updateChannelError: '', + updatingChannel: true, + }); +}; + reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { const channelClaim: ChannelClaim = action.data.channelClaim; const byId = Object.assign({}, state.byId); @@ -299,6 +311,15 @@ reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State return Object.assign({}, state, { byId, + updateChannelError: '', + updatingChannel: false, + }); +}; + +reducers[ACTIONS.UPDATE_CHANNEL_FAILED] = (state: State, action: any): State => { + return Object.assign({}, state, { + updateChannelError: action.data.message, + updatingChannel: false, }); }; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index b0c6a68..44fc310 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -563,3 +563,13 @@ export const makeSelectSupportsForUri = (uri: string) => return total; } ); + +export const selectUpdatingChannel = createSelector( + selectState, + state => state.updatingChannel +); + +export const selectUpdateChannelError = createSelector( + selectState, + state => state.updateChannelError +); -- 2.45.2 From 9d78fbb62d8b38c0ca36faf0cbe88ef4b581902b Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 27 Aug 2019 00:42:52 -0400 Subject: [PATCH 134/371] add selector for creatingchannel --- dist/bundle.es.js | 13 +++++++++++-- src/index.js | 1 + src/redux/reducers/claims.js | 8 ++++++++ src/redux/selectors/claims.js | 9 +++++++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 0eb8aac..bf9deee 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1461,6 +1461,8 @@ const selectClaimsById = reselect.createSelector(selectState$2, state => state.b const selectCurrentChannelPage = reselect.createSelector(selectState$2, state => state.currentChannelPage || 1); +const selectCreatingChannel = reselect.createSelector(selectState$2, state => state.creatingChannel); + const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { const byUri = state.claimsByUri || {}; const claims = {}; @@ -3564,7 +3566,8 @@ const defaultState = { claimSearchByQueryLastPageReached: {}, fetchingClaimSearchByQuery: {}, updateChannelError: '', - updatingChannel: false + updatingChannel: false, + creatingChannel: false }; function handleClaimAction(state, action) { @@ -3782,6 +3785,10 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; +reducers[CREATE_CHANNEL_STARTED] = state => _extends$5({}, state, { + creatingChannel: true +}); + reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { const channelClaim = action.data.channelClaim; const byId = Object.assign({}, state.byId); @@ -3792,7 +3799,8 @@ reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { return Object.assign({}, state, { byId, - myChannelClaims + myChannelClaims, + creatingChannel: false }); }; @@ -5001,6 +5009,7 @@ exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; +exports.selectCreatingChannel = selectCreatingChannel; exports.selectCurrentChannelPage = selectCurrentChannelPage; exports.selectDownloadedUris = selectDownloadedUris; exports.selectDownloadingByOutpoint = selectDownloadingByOutpoint; diff --git a/src/index.js b/src/index.js index e77f9df..83d11b3 100644 --- a/src/index.js +++ b/src/index.js @@ -202,6 +202,7 @@ export { selectClaimSearchByQueryLastPageReached, selectUpdatingChannel, selectUpdateChannelError, + selectCreatingChannel, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 8c8d4d7..ffb8573 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -24,6 +24,7 @@ type State = { fetchingClaimSearchByQuery: { [string]: boolean }, claimSearchByQuery: { [string]: Array }, claimSearchByQueryLastPageReached: { [string]: Array }, + creatingChannel: boolean, claimsByChannel: { [string]: { all: Array, @@ -54,6 +55,7 @@ const defaultState = { fetchingClaimSearchByQuery: {}, updateChannelError: '', updatingChannel: false, + creatingChannel: false, }; function handleClaimAction(state: State, action: any): State { @@ -282,6 +284,11 @@ reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State = }); }; +reducers[ACTIONS.CREATE_CHANNEL_STARTED] = (state: State): State => ({ + ...state, + creatingChannel: true, +}); + reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { const channelClaim: ChannelClaim = action.data.channelClaim; const byId = Object.assign({}, state.byId); @@ -293,6 +300,7 @@ reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State return Object.assign({}, state, { byId, myChannelClaims, + creatingChannel: false, }); }; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 44fc310..ecf0288 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -18,6 +18,11 @@ export const selectCurrentChannelPage = createSelector( state => state.currentChannelPage || 1 ); +export const selectCreatingChannel = createSelector( + selectState, + state => state.creatingChannel +); + export const selectClaimsByUri = createSelector( selectState, selectClaimsById, @@ -230,8 +235,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } -- 2.45.2 From 7954c1d5d06d1a9f067daaf311f4ed361072420b Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 9 Sep 2019 14:57:56 -0400 Subject: [PATCH 135/371] onboarding updates --- dist/bundle.es.js | 21 +++++++++++++++++++-- src/index.js | 6 +++++- src/lbry.js | 4 +++- src/redux/reducers/claims.js | 5 +++++ src/redux/reducers/tags.js | 11 ++++++++++- src/redux/selectors/tags.js | 12 +++++++++++- 6 files changed, 53 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index bf9deee..7145892 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -669,7 +669,9 @@ const Lbry = { isConnected: false, connectPromise: null, daemonConnectionString: 'http://localhost:5279', - apiRequestHeaders: { 'Content-Type': 'application/json-rpc' }, + apiRequestHeaders: { + 'Content-Type': 'application/json-rpc' + }, // Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) setDaemonConnectionString: value => { @@ -3803,6 +3805,11 @@ reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { creatingChannel: false }); }; +// reducers[ACTIONS.failedifeiowejiowfeiowef] = (state: State, action: any): State => { +// return Object.assign({}, state, { +// creatingChannel: false, +// }); +// }; reducers[UPDATE_CHANNEL_STARTED] = (state, action) => { return Object.assign({}, state, { @@ -4430,7 +4437,7 @@ function getDefaultKnownTags() { } const defaultState$8 = { - followedTags: DEFAULT_FOLLOWED_TAGS, + followedTags: [], knownTags: getDefaultKnownTags() }; @@ -4476,6 +4483,11 @@ const tagsReducer = handleActions({ knownTags: newKnownTags, followedTags: newFollowedTags }); + }, + USER_SETTINGS_POPULATE: (state, action) => { + return _extends$c({}, state, { + followedTags: action.data && action.data.app && action.data.app.tags || [] + }); } }, defaultState$8); @@ -4845,6 +4857,10 @@ const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, sele return tagsToReturn; }); +const makeSelectIsFollowingTag = tag => reselect.createSelector(selectFollowedTags, followedTags => { + return followedTags.some(followedTag => followedTag.name === tag.toLowerCase()); +}); + // const selectState$a = state => state.blocked || {}; @@ -4964,6 +4980,7 @@ exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; exports.makeSelectFileNameForUri = makeSelectFileNameForUri; exports.makeSelectFilePartlyDownloaded = makeSelectFilePartlyDownloaded; exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileForUri; +exports.makeSelectIsFollowingTag = makeSelectIsFollowingTag; exports.makeSelectIsUriResolving = makeSelectIsUriResolving; exports.makeSelectLoadingForUri = makeSelectLoadingForUri; exports.makeSelectMediaTypeForUri = makeSelectMediaTypeForUri; diff --git a/src/index.js b/src/index.js index 83d11b3..d2d98e5 100644 --- a/src/index.js +++ b/src/index.js @@ -282,7 +282,11 @@ export { selectTransactionListFilter, } from 'redux/selectors/wallet'; -export { selectFollowedTags, selectUnfollowedTags } from 'redux/selectors/tags'; +export { + selectFollowedTags, + selectUnfollowedTags, + makeSelectIsFollowingTag, +} from 'redux/selectors/tags'; export { selectBlockedChannels, diff --git a/src/lbry.js b/src/lbry.js index ba47709..4c96ed7 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -11,7 +11,9 @@ const Lbry: LbryTypes = { isConnected: false, connectPromise: null, daemonConnectionString: 'http://localhost:5279', - apiRequestHeaders: { 'Content-Type': 'application/json-rpc' }, + apiRequestHeaders: { + 'Content-Type': 'application/json-rpc', + }, // Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) setDaemonConnectionString: (value: string) => { diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index ffb8573..70dc1d9 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -303,6 +303,11 @@ reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State creatingChannel: false, }); }; +// reducers[ACTIONS.failedifeiowejiowfeiowef] = (state: State, action: any): State => { +// return Object.assign({}, state, { +// creatingChannel: false, +// }); +// }; reducers[ACTIONS.UPDATE_CHANNEL_STARTED] = (state: State, action: any): State => { return Object.assign({}, state, { diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index 79692ba..f0e04fc 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -14,7 +14,7 @@ function getDefaultKnownTags() { } const defaultState: TagState = { - followedTags: DEFAULT_FOLLOWED_TAGS, + followedTags: [], knownTags: getDefaultKnownTags(), }; @@ -65,6 +65,15 @@ export const tagsReducer = handleActions( followedTags: newFollowedTags, }; }, + USER_SETTINGS_POPULATE: ( + state: TagState, + action: { data: { app: { tags: Array } } } + ) => { + return { + ...state, + followedTags: (action.data && action.data.app && action.data.app.tags) || [], + }; + }, }, defaultState ); diff --git a/src/redux/selectors/tags.js b/src/redux/selectors/tags.js index ec805a0..ff202b3 100644 --- a/src/redux/selectors/tags.js +++ b/src/redux/selectors/tags.js @@ -16,7 +16,9 @@ export const selectFollowedTagsList = createSelector( export const selectFollowedTags = createSelector( selectFollowedTagsList, (followedTags: Array): Array => - followedTags.map(tag => ({ name: tag.toLowerCase() })).sort((a, b) => a.name.localeCompare(b.name)) + followedTags + .map(tag => ({ name: tag.toLowerCase() })) + .sort((a, b) => a.name.localeCompare(b.name)) ); export const selectUnfollowedTags = createSelector( @@ -36,3 +38,11 @@ export const selectUnfollowedTags = createSelector( return tagsToReturn; } ); + +export const makeSelectIsFollowingTag = (tag: string) => + createSelector( + selectFollowedTags, + followedTags => { + return followedTags.some(followedTag => followedTag.name === tag.toLowerCase()); + } + ); -- 2.45.2 From 45031668f0303b5453488cfcf85dc335619fbc03 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 10 Sep 2019 14:14:40 -0400 Subject: [PATCH 136/371] tags/subs sync --- dist/bundle.es.js | 266 ++++++++++++++++++++-------------- src/constants/action_types.js | 5 + src/index.js | 3 + src/lbry.js | 4 +- src/redux/actions/sync.js | 27 ++++ src/redux/reducers/claims.js | 15 +- src/redux/reducers/tags.js | 28 +++- src/redux/selectors/claims.js | 5 + 8 files changed, 237 insertions(+), 116 deletions(-) create mode 100644 src/redux/actions/sync.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 7145892..bf6be70 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -252,13 +252,18 @@ const FETCH_DATE = 'FETCH_DATE'; const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'; const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'; const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; + // Tags const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; const TAG_ADD = 'TAG_ADD'; const TAG_DELETE = 'TAG_DELETE'; + // Blocked Channels const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; +// Sync +const USER_SETTINGS_POPULATE = 'USER_SETTINGS_POPULATE'; + var action_types = /*#__PURE__*/Object.freeze({ WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, @@ -463,7 +468,8 @@ var action_types = /*#__PURE__*/Object.freeze({ TOGGLE_TAG_FOLLOW: TOGGLE_TAG_FOLLOW, TAG_ADD: TAG_ADD, TAG_DELETE: TAG_DELETE, - TOGGLE_BLOCK_CHANNEL: TOGGLE_BLOCK_CHANNEL + TOGGLE_BLOCK_CHANNEL: TOGGLE_BLOCK_CHANNEL, + USER_SETTINGS_POPULATE: USER_SETTINGS_POPULATE }); const CC_LICENSES = [{ @@ -669,9 +675,7 @@ const Lbry = { isConnected: false, connectPromise: null, daemonConnectionString: 'http://localhost:5279', - apiRequestHeaders: { - 'Content-Type': 'application/json-rpc' - }, + apiRequestHeaders: { 'Content-Type': 'application/json-rpc' }, // Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) setDaemonConnectionString: value => { @@ -1465,6 +1469,8 @@ const selectCurrentChannelPage = reselect.createSelector(selectState$2, state => const selectCreatingChannel = reselect.createSelector(selectState$2, state => state.creatingChannel); +const createChannelError = reselect.createSelector(selectState$2, state => state.createChannelError); + const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { const byUri = state.claimsByUri || {}; const claims = {}; @@ -3549,6 +3555,24 @@ const doToggleBlockChannel = uri => ({ var _extends$5 = 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 extractSettings(rawObj) { + if (rawObj && rawObj.version && rawObj.app) { + const { subscriptions, tags } = rawObj.app; + return _extends$5({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}); + } + + return {}; +} + +function doPopulateUserSettings(settings) { + return dispatch => { + const { subscriptions, tags } = extractSettings(settings); + dispatch({ type: USER_SETTINGS_POPULATE, data: { subscriptions, tags } }); + }; +} + +var _extends$6 = 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; }; + const reducers = {}; const defaultState = { byId: {}, @@ -3569,7 +3593,8 @@ const defaultState = { fetchingClaimSearchByQuery: {}, updateChannelError: '', updatingChannel: false, - creatingChannel: false + creatingChannel: false, + createChannelError: undefined }; function handleClaimAction(state, action) { @@ -3642,7 +3667,7 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$5({}, handleClaimAction(state, action)); + return _extends$6({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -3787,8 +3812,9 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; -reducers[CREATE_CHANNEL_STARTED] = state => _extends$5({}, state, { - creatingChannel: true +reducers[CREATE_CHANNEL_STARTED] = state => _extends$6({}, state, { + creatingChannel: true, + createChannelError: null }); reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { @@ -3805,11 +3831,13 @@ reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { creatingChannel: false }); }; -// reducers[ACTIONS.failedifeiowejiowfeiowef] = (state: State, action: any): State => { -// return Object.assign({}, state, { -// creatingChannel: false, -// }); -// }; + +reducers[CREATE_CHANNEL_FAILED] = (state, action) => { + return Object.assign({}, state, { + creatingChannel: false, + createChannelError: action.data + }); +}; reducers[UPDATE_CHANNEL_STARTED] = (state, action) => { return Object.assign({}, state, { @@ -3865,7 +3893,7 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { delete fetchingClaimSearchByQuery[query]; - return Object.assign({}, state, _extends$5({}, handleClaimAction(state, action), { + return Object.assign({}, state, _extends$6({}, handleClaimAction(state, action), { claimSearchByQuery, claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery @@ -3905,7 +3933,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -var _extends$6 = 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; }; +var _extends$7 = 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; }; const defaultState$1 = { byId: {}, @@ -3914,11 +3942,11 @@ const defaultState$1 = { }; const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$6({}, state, { + [COMMENT_CREATE_STARTED]: (state, action) => _extends$7({}, state, { isLoading: true }), - [COMMENT_CREATE_FAILED]: (state, action) => _extends$6({}, state, { + [COMMENT_CREATE_FAILED]: (state, action) => _extends$7({}, state, { isLoading: false }), @@ -3931,12 +3959,12 @@ const commentReducer = handleActions({ newComments.unshift(comment); byId[claimId] = newComments; - return _extends$6({}, state, { + return _extends$7({}, state, { byId }); }, - [COMMENT_LIST_STARTED]: state => _extends$6({}, state, { isLoading: true }), + [COMMENT_LIST_STARTED]: state => _extends$7({}, state, { isLoading: true }), [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; @@ -3947,19 +3975,19 @@ const commentReducer = handleActions({ byId[claimId] = comments['items']; commentsByUri[uri] = claimId; } - return _extends$6({}, state, { + return _extends$7({}, state, { byId, commentsByUri, isLoading: false }); }, - [COMMENT_LIST_FAILED]: (state, action) => _extends$6({}, state, { + [COMMENT_LIST_FAILED]: (state, action) => _extends$7({}, state, { isLoading: false }) }, defaultState$1); -var _extends$7 = 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; }; +var _extends$8 = 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; }; const reducers$1 = {}; const defaultState$2 = { @@ -3968,9 +3996,9 @@ const defaultState$2 = { reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$7({}, state, { - positions: _extends$7({}, state.positions, { - [claimId]: _extends$7({}, state.positions[claimId], { + return _extends$8({}, state, { + positions: _extends$8({}, state.positions, { + [claimId]: _extends$8({}, state.positions[claimId], { [outpoint]: position }) }) @@ -4137,7 +4165,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -var _extends$8 = 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; }; +var _extends$9 = 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; }; const reducers$3 = {}; const defaultState$4 = { @@ -4153,7 +4181,7 @@ reducers$3[PURCHASE_URI_STARTED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$8({}, state, { + return _extends$9({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: '' }); @@ -4171,7 +4199,7 @@ reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$8({}, state, { + return _extends$9({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, purchaseUriErrorMessage: '' @@ -4186,7 +4214,7 @@ reducers$3[PURCHASE_URI_FAILED] = (state, action) => { newFailedPurchaseUris.push(uri); } - return _extends$8({}, state, { + return _extends$9({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: error }); @@ -4199,7 +4227,7 @@ reducers$3[DELETE_PURCHASED_URI] = (state, action) => { newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); } - return _extends$8({}, state, { + return _extends$9({}, state, { purchasedUris: newPurchasedUris }); }; @@ -4210,7 +4238,7 @@ function fileReducer(state = defaultState$4, action) { return state; } -var _extends$9 = 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; }; +var _extends$a = 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; }; const defaultState$5 = { notifications: [], @@ -4225,7 +4253,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$9({}, state, { + return _extends$a({}, state, { toasts: newToasts }); }, @@ -4233,7 +4261,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$9({}, state, { + return _extends$a({}, state, { toasts: newToasts }); }, @@ -4244,7 +4272,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$9({}, state, { + return _extends$a({}, state, { notifications: newNotifications }); }, @@ -4255,7 +4283,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$9({}, state, { + return _extends$a({}, state, { notifications }); }, @@ -4264,7 +4292,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$9({}, state, { + return _extends$a({}, state, { notifications: newNotifications }); }, @@ -4275,7 +4303,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$9({}, state, { + return _extends$a({}, state, { errors: newErrors }); }, @@ -4283,13 +4311,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$9({}, state, { + return _extends$a({}, state, { errors: newErrors }); } }, defaultState$5); -var _extends$a = 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; }; +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$3(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; } @@ -4326,17 +4354,17 @@ const defaultState$6 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$a({}, state, data); + return _extends$b({}, state, data); }, - [CLEAR_PUBLISH]: () => _extends$a({}, defaultState$6), - [PUBLISH_START]: state => _extends$a({}, state, { + [CLEAR_PUBLISH]: () => _extends$b({}, defaultState$6), + [PUBLISH_START]: state => _extends$b({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$a({}, state, { + [PUBLISH_FAIL]: state => _extends$b({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$a({}, state, { + [PUBLISH_SUCCESS]: state => _extends$b({}, state, { publishing: false, publishSuccess: true }), @@ -4351,14 +4379,14 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$a({}, defaultState$6, publishData, { + return _extends$b({}, defaultState$6, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$6); -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; }; +var _extends$c = 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; }; const defaultState$7 = { isActive: false, // does the user have any typed text in the search input @@ -4378,29 +4406,29 @@ const defaultState$7 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$b({}, state, { + [SEARCH_START]: state => _extends$c({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$b({}, state, { + return _extends$c({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$b({}, state, { + [SEARCH_FAIL]: state => _extends$c({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$b({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$c({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$b({}, state, { - suggestions: _extends$b({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$c({}, state, { + suggestions: _extends$c({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -4408,36 +4436,36 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$b({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$c({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$b({}, state, { + [SEARCH_FOCUS]: state => _extends$c({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$b({}, state, { + [SEARCH_BLUR]: state => _extends$c({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$b({}, oldOptions, newOptions); - return _extends$b({}, state, { + const options = _extends$c({}, oldOptions, newOptions); + return _extends$c({}, state, { options }); } }, defaultState$7); -var _extends$c = 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; }; +var _extends$d = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$c({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$d({}, tagsMap, { [tag]: { name: tag } }), {}); } const defaultState$8 = { - followedTags: [], + followedTags: DEFAULT_FOLLOWED_TAGS, knownTags: getDefaultKnownTags() }; @@ -4454,7 +4482,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$c({}, state, { + return _extends$d({}, state, { followedTags: newFollowedTags }); }, @@ -4463,10 +4491,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$c({}, knownTags); + let newKnownTags = _extends$d({}, knownTags); newKnownTags[name] = { name }; - return _extends$c({}, state, { + return _extends$d({}, state, { knownTags: newKnownTags }); }, @@ -4475,19 +4503,41 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$c({}, knownTags); + let newKnownTags = _extends$d({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$c({}, state, { + return _extends$d({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); }, USER_SETTINGS_POPULATE: (state, action) => { - return _extends$c({}, state, { + // const tags = getValueFromSettingsSync('tags', action.data); + return _extends$d({}, state, { followedTags: action.data && action.data.app && action.data.app.tags || [] }); + }, + [USER_SETTINGS_POPULATE]: (state, action) => { + const { tags } = action.data; + let newTags; + + if (!tags) { + newTags = state.followedTags; + } else { + if (!state.followedTags || !state.followedTags.length) { + newTags = tags; + } else { + const map = {}; + newTags = tags.concat(state.followedTags).filter(tag => { + return map[tag] ? false : map[tag] = true; + }, {}); + } + } + + return _extends$d({}, state, { + followedTags: newTags + }); } }, defaultState$8); @@ -4515,7 +4565,7 @@ const blockedReducer = handleActions({ } }, defaultState$9); -var _extends$d = 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; }; +var _extends$e = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -4555,25 +4605,25 @@ const defaultState$a = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$d({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$e({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$d({}, state.transactions); + const byId = _extends$e({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$d({}, state, { + return _extends$e({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$d({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$e({}, state, { fetchingSupports: true }), @@ -4586,7 +4636,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$d({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$e({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -4595,7 +4645,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$d({}, state, { + return _extends$e({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -4608,56 +4658,56 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$d({}, state, { + return _extends$e({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$d({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$e({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$d({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$e({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$d({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$e({}, state, { balance: action.data.balance }), - [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$d({}, state, { + [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$e({}, state, { totalBalance: action.data.totalBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$d({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$e({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$d({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$e({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$d({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$e({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$d({}, state, { draftTransaction: newDraft }); + return _extends$e({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$d({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$e({}, oldDraft, { address: action.data.address }); - return _extends$d({}, state, { draftTransaction: newDraft }); + return _extends$e({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$d({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$e({}, state.draftTransaction, { sending: true }); - return _extends$d({}, state, { draftTransaction: newDraftTransaction }); + return _extends$e({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -4670,103 +4720,103 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$d({}, state, { draftTransaction: newDraftTransaction }); + return _extends$e({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$d({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$e({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$d({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$e({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$d({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$e({}, state, { error: action.data.error, sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$d({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$e({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$d({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$e({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$d({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$e({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$d({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$e({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$d({}, state, { + [WALLET_DECRYPT_START]: state => _extends$e({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$d({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$e({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$d({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$e({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$d({}, state, { + [WALLET_UNLOCK_START]: state => _extends$e({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$d({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$e({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$d({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$e({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$d({}, state, { + [WALLET_LOCK_START]: state => _extends$e({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$d({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$e({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$d({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$e({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$d({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$e({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$d({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$e({}, state, { latestBlock: action.data }) }, defaultState$a); @@ -4782,14 +4832,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$e = 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; }; +var _extends$f = 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; }; const selectState$7 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$7, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$e({ + return _extends$f({ id }, params); } @@ -4894,6 +4944,7 @@ exports.claimsReducer = claimsReducer; exports.commentReducer = commentReducer; exports.contentReducer = contentReducer; exports.convertToShareLink = convertToShareLink; +exports.createChannelError = createChannelError; exports.createNormalizedClaimSearchKey = createNormalizedClaimSearchKey; exports.creditsToString = creditsToString; exports.doAbandonClaim = doAbandonClaim; @@ -4922,6 +4973,7 @@ exports.doFileGet = doFileGet; exports.doFileList = doFileList; exports.doFocusSearchInput = doFocusSearchInput; exports.doGetNewAddress = doGetNewAddress; +exports.doPopulateUserSettings = doPopulateUserSettings; exports.doPrepareEdit = doPrepareEdit; exports.doPublish = doPublish; exports.doPurchaseUri = doPurchaseUri; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index be13241..22400e4 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -229,9 +229,14 @@ export const FETCH_DATE = 'FETCH_DATE'; export const FETCH_COST_INFO_STARTED = 'FETCH_COST_INFO_STARTED'; export const FETCH_COST_INFO_COMPLETED = 'FETCH_COST_INFO_COMPLETED'; export const FETCH_COST_INFO_FAILED = 'FETCH_COST_INFO_FAILED'; + // Tags export const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; export const TAG_ADD = 'TAG_ADD'; export const TAG_DELETE = 'TAG_DELETE'; + // Blocked Channels export const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; + +// Sync +export const USER_SETTINGS_POPULATE = 'USER_SETTINGS_POPULATE'; diff --git a/src/index.js b/src/index.js index d2d98e5..7cd7dc8 100644 --- a/src/index.js +++ b/src/index.js @@ -113,6 +113,8 @@ export { doCommentList, doCommentCreate } from 'redux/actions/comments'; export { doToggleBlockChannel } from 'redux/actions/blocked'; +export { doPopulateUserSettings } from 'redux/actions/sync'; + // utils export { batchActions } from 'util/batch-actions'; export { parseQueryParams, toQueryString } from 'util/query-params'; @@ -203,6 +205,7 @@ export { selectUpdatingChannel, selectUpdateChannelError, selectCreatingChannel, + createChannelError, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/lbry.js b/src/lbry.js index 4c96ed7..ba47709 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -11,9 +11,7 @@ const Lbry: LbryTypes = { isConnected: false, connectPromise: null, daemonConnectionString: 'http://localhost:5279', - apiRequestHeaders: { - 'Content-Type': 'application/json-rpc', - }, + apiRequestHeaders: { 'Content-Type': 'application/json-rpc' }, // Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) setDaemonConnectionString: (value: string) => { diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js new file mode 100644 index 0000000..2c0a95e --- /dev/null +++ b/src/redux/actions/sync.js @@ -0,0 +1,27 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; + +function extractSettings(rawObj: { + version: string, + app: {}, +}): { + subscriptions?: Array, + tags?: Array, +} { + if (rawObj && rawObj.version && rawObj.app) { + const { subscriptions, tags } = rawObj.app; + return { + ...(subscriptions ? { subscriptions } : {}), + ...(tags ? { tags } : {}), + }; + } + + return {}; +} + +export function doPopulateUserSettings(settings: any) { + return dispatch => { + const { subscriptions, tags } = extractSettings(settings); + dispatch({ type: ACTIONS.USER_SETTINGS_POPULATE, data: { subscriptions, tags } }); + }; +} diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 70dc1d9..d3eac46 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -12,6 +12,7 @@ import * as ACTIONS from 'constants/action_types'; import { buildURI, parseURI } from 'lbryURI'; type State = { + createChannelError: ?string, channelClaimCounts: { [string]: number }, claimsByUri: { [string]: string }, byId: { [string]: Claim }, @@ -56,6 +57,7 @@ const defaultState = { updateChannelError: '', updatingChannel: false, creatingChannel: false, + createChannelError: undefined, }; function handleClaimAction(state: State, action: any): State { @@ -287,6 +289,7 @@ reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State = reducers[ACTIONS.CREATE_CHANNEL_STARTED] = (state: State): State => ({ ...state, creatingChannel: true, + createChannelError: null, }); reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { @@ -303,11 +306,13 @@ reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State creatingChannel: false, }); }; -// reducers[ACTIONS.failedifeiowejiowfeiowef] = (state: State, action: any): State => { -// return Object.assign({}, state, { -// creatingChannel: false, -// }); -// }; + +reducers[ACTIONS.CREATE_CHANNEL_FAILED] = (state: State, action: any): State => { + return Object.assign({}, state, { + creatingChannel: false, + createChannelError: action.data, + }); +}; reducers[ACTIONS.UPDATE_CHANNEL_STARTED] = (state: State, action: any): State => { return Object.assign({}, state, { diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index f0e04fc..759a894 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -14,7 +14,7 @@ function getDefaultKnownTags() { } const defaultState: TagState = { - followedTags: [], + followedTags: DEFAULT_FOLLOWED_TAGS, knownTags: getDefaultKnownTags(), }; @@ -69,11 +69,37 @@ export const tagsReducer = handleActions( state: TagState, action: { data: { app: { tags: Array } } } ) => { + // const tags = getValueFromSettingsSync('tags', action.data); return { ...state, followedTags: (action.data && action.data.app && action.data.app.tags) || [], }; }, + [ACTIONS.USER_SETTINGS_POPULATE]: ( + state: TagState, + action: { data: { tags: ?Array } } + ) => { + const { tags } = action.data; + let newTags; + + if (!tags) { + newTags = state.followedTags; + } else { + if (!state.followedTags || !state.followedTags.length) { + newTags = tags; + } else { + const map = {}; + newTags = tags.concat(state.followedTags).filter(tag => { + return map[tag] ? false : (map[tag] = true); + }, {}); + } + } + + return { + ...state, + followedTags: newTags, + }; + }, }, defaultState ); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index ecf0288..429137a 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -23,6 +23,11 @@ export const selectCreatingChannel = createSelector( state => state.creatingChannel ); +export const createChannelError = createSelector( + selectState, + state => state.createChannelError +); + export const selectClaimsByUri = createSelector( selectState, selectClaimsById, -- 2.45.2 From 220b717fc123c0f436fb534b0d6bbe000568f710 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 10 Sep 2019 15:44:16 -0400 Subject: [PATCH 137/371] fix default tags with sync --- dist/bundle.es.js | 10 ++-------- src/redux/reducers/tags.js | 14 ++------------ 2 files changed, 4 insertions(+), 20 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index bf6be70..0e5ee26 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4465,7 +4465,7 @@ function getDefaultKnownTags() { } const defaultState$8 = { - followedTags: DEFAULT_FOLLOWED_TAGS, + followedTags: [], knownTags: getDefaultKnownTags() }; @@ -4512,18 +4512,12 @@ const tagsReducer = handleActions({ followedTags: newFollowedTags }); }, - USER_SETTINGS_POPULATE: (state, action) => { - // const tags = getValueFromSettingsSync('tags', action.data); - return _extends$d({}, state, { - followedTags: action.data && action.data.app && action.data.app.tags || [] - }); - }, [USER_SETTINGS_POPULATE]: (state, action) => { const { tags } = action.data; let newTags; if (!tags) { - newTags = state.followedTags; + newTags = state.followedTags || DEFAULT_FOLLOWED_TAGS; } else { if (!state.followedTags || !state.followedTags.length) { newTags = tags; diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index 759a894..29480e1 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -14,7 +14,7 @@ function getDefaultKnownTags() { } const defaultState: TagState = { - followedTags: DEFAULT_FOLLOWED_TAGS, + followedTags: [], knownTags: getDefaultKnownTags(), }; @@ -65,16 +65,6 @@ export const tagsReducer = handleActions( followedTags: newFollowedTags, }; }, - USER_SETTINGS_POPULATE: ( - state: TagState, - action: { data: { app: { tags: Array } } } - ) => { - // const tags = getValueFromSettingsSync('tags', action.data); - return { - ...state, - followedTags: (action.data && action.data.app && action.data.app.tags) || [], - }; - }, [ACTIONS.USER_SETTINGS_POPULATE]: ( state: TagState, action: { data: { tags: ?Array } } @@ -83,7 +73,7 @@ export const tagsReducer = handleActions( let newTags; if (!tags) { - newTags = state.followedTags; + newTags = state.followedTags || DEFAULT_FOLLOWED_TAGS; } else { if (!state.followedTags || !state.followedTags.length) { newTags = tags; -- 2.45.2 From 5ff2491e7864f546ee925252529a7b6205b86de0 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 13 Sep 2019 15:52:52 -0400 Subject: [PATCH 138/371] improvements --- dist/bundle.es.js | 51 ++++++++++++++++++++--------------- src/constants/action_types.js | 2 +- src/index.js | 2 +- src/redux/actions/claims.js | 2 +- src/redux/actions/sync.js | 24 +++++++++-------- src/redux/reducers/claims.js | 23 ++++++++++------ src/redux/reducers/tags.js | 6 ++--- src/redux/selectors/claims.js | 13 +++++---- src/redux/selectors/tags.js | 1 - 9 files changed, 72 insertions(+), 52 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 0e5ee26..3a8a746 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -262,7 +262,7 @@ const TAG_DELETE = 'TAG_DELETE'; const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; // Sync -const USER_SETTINGS_POPULATE = 'USER_SETTINGS_POPULATE'; +const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ WINDOW_FOCUSED: WINDOW_FOCUSED, @@ -469,7 +469,7 @@ var action_types = /*#__PURE__*/Object.freeze({ TAG_ADD: TAG_ADD, TAG_DELETE: TAG_DELETE, TOGGLE_BLOCK_CHANNEL: TOGGLE_BLOCK_CHANNEL, - USER_SETTINGS_POPULATE: USER_SETTINGS_POPULATE + USER_STATE_POPULATE: USER_STATE_POPULATE }); const CC_LICENSES = [{ @@ -1469,7 +1469,7 @@ const selectCurrentChannelPage = reselect.createSelector(selectState$2, state => const selectCreatingChannel = reselect.createSelector(selectState$2, state => state.creatingChannel); -const createChannelError = reselect.createSelector(selectState$2, state => state.createChannelError); +const selectCreateChannelError = reselect.createSelector(selectState$2, state => state.createChannelError); const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { const byUri = state.claimsByUri || {}; @@ -1668,9 +1668,12 @@ const selectMyClaimsOutpoints = reselect.createSelector(selectMyClaims, myClaims const selectFetchingMyChannels = reselect.createSelector(selectState$2, state => state.fetchingMyChannels); const selectMyChannelClaims = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { - const ids = state.myChannelClaims || []; - const claims = []; + const ids = state.myChannelClaims; + if (!ids) { + return ids; + } + const claims = []; ids.forEach(id => { if (byId[id]) { // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544 @@ -2454,7 +2457,7 @@ function doCreateChannel(name, amount, optionalParams) { }).catch(error => { dispatch({ type: CREATE_CHANNEL_FAILED, - data: error + data: error.message }); }); }; @@ -3556,8 +3559,8 @@ const doToggleBlockChannel = uri => ({ var _extends$5 = 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 extractSettings(rawObj) { - if (rawObj && rawObj.version && rawObj.app) { - const { subscriptions, tags } = rawObj.app; + if (rawObj && rawObj.version === '0' && rawObj.shared) { + const { subscriptions, tags } = rawObj.shared; return _extends$5({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}); } @@ -3567,7 +3570,7 @@ function extractSettings(rawObj) { function doPopulateUserSettings(settings) { return dispatch => { const { subscriptions, tags } = extractSettings(settings); - dispatch({ type: USER_SETTINGS_POPULATE, data: { subscriptions, tags } }); + dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags } }); }; } @@ -3583,7 +3586,7 @@ const defaultState = { resolvingUris: [], // This should not be a Set // Storing sets in reducers can cause issues - myChannelClaims: new Set(), + myChannelClaims: undefined, fetchingMyChannels: false, abandoningById: {}, pendingById: {}, @@ -3716,13 +3719,20 @@ reducers[FETCH_CHANNEL_LIST_STARTED] = state => Object.assign({}, state, { fetch reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { const { claims } = action.data; - const myChannelClaims = new Set(state.myChannelClaims); - const byId = Object.assign({}, state.byId); - claims.forEach(claim => { - myChannelClaims.add(claim.claim_id); - byId[claim.claim_id] = claim; - }); + let myChannelClaims; + let byId = Object.assign({}, state.byId); + if (!claims.length) { + // $FlowFixMe + myChannelClaims = null; + } else { + myChannelClaims = new Set(state.myChannelClaims); + claims.forEach(claim => { + // $FlowFixMe + myChannelClaims.add(claim.claim_id); + byId[claim.claim_id] = claim; + }); + } return Object.assign({}, state, { byId, @@ -4512,14 +4522,14 @@ const tagsReducer = handleActions({ followedTags: newFollowedTags }); }, - [USER_SETTINGS_POPULATE]: (state, action) => { + [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; let newTags; if (!tags) { - newTags = state.followedTags || DEFAULT_FOLLOWED_TAGS; + newTags = state.followedTags.length ? state.followedTags : DEFAULT_FOLLOWED_TAGS; } else { - if (!state.followedTags || !state.followedTags.length) { + if (!state.followedTags.length) { newTags = tags; } else { const map = {}; @@ -4890,7 +4900,6 @@ const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, follo const selectUnfollowedTags = reselect.createSelector(selectKnownTagsByName, selectFollowedTagsList, (tagsByName, followedTags) => { const followedTagsSet = new Set(followedTags); let tagsToReturn = []; - Object.keys(tagsByName).forEach(key => { if (!followedTagsSet.has(key)) { const { name } = tagsByName[key]; @@ -4938,7 +4947,6 @@ exports.claimsReducer = claimsReducer; exports.commentReducer = commentReducer; exports.contentReducer = contentReducer; exports.convertToShareLink = convertToShareLink; -exports.createChannelError = createChannelError; exports.createNormalizedClaimSearchKey = createNormalizedClaimSearchKey; exports.creditsToString = creditsToString; exports.doAbandonClaim = doAbandonClaim; @@ -5072,6 +5080,7 @@ exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; +exports.selectCreateChannelError = selectCreateChannelError; exports.selectCreatingChannel = selectCreatingChannel; exports.selectCurrentChannelPage = selectCurrentChannelPage; exports.selectDownloadedUris = selectDownloadedUris; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 22400e4..a852537 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -239,4 +239,4 @@ export const TAG_DELETE = 'TAG_DELETE'; export const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; // Sync -export const USER_SETTINGS_POPULATE = 'USER_SETTINGS_POPULATE'; +export const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; diff --git a/src/index.js b/src/index.js index 7cd7dc8..a954ee9 100644 --- a/src/index.js +++ b/src/index.js @@ -205,7 +205,7 @@ export { selectUpdatingChannel, selectUpdateChannelError, selectCreatingChannel, - createChannelError, + selectCreateChannelError, } 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 c285e02..215daba 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -275,7 +275,7 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an .catch(error => { dispatch({ type: ACTIONS.CREATE_CHANNEL_FAILED, - data: error, + data: error.message, }); }) ); diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 2c0a95e..e0b13e4 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -1,15 +1,17 @@ // @flow import * as ACTIONS from 'constants/action_types'; -function extractSettings(rawObj: { - version: string, - app: {}, -}): { - subscriptions?: Array, - tags?: Array, -} { - if (rawObj && rawObj.version && rawObj.app) { - const { subscriptions, tags } = rawObj.app; +type v0Data = { + version: '0', + shared: { + subscriptions?: Array, + tags?: Array, + }, +}; + +function extractSettings(rawObj: v0Data) { + if (rawObj && rawObj.version === '0' && rawObj.shared) { + const { subscriptions, tags } = rawObj.shared; return { ...(subscriptions ? { subscriptions } : {}), ...(tags ? { tags } : {}), @@ -20,8 +22,8 @@ function extractSettings(rawObj: { } export function doPopulateUserSettings(settings: any) { - return dispatch => { + return (dispatch: Dispatch) => { const { subscriptions, tags } = extractSettings(settings); - dispatch({ type: ACTIONS.USER_SETTINGS_POPULATE, data: { subscriptions, tags } }); + dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags } }); }; } diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index d3eac46..cdac7d9 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -18,7 +18,7 @@ type State = { byId: { [string]: Claim }, resolvingUris: Array, pendingById: { [string]: Claim }, - myChannelClaims: Set, + myChannelClaims: ?Set, abandoningById: { [string]: boolean }, fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, @@ -46,7 +46,7 @@ const defaultState = { resolvingUris: [], // This should not be a Set // Storing sets in reducers can cause issues - myChannelClaims: new Set(), + myChannelClaims: undefined, fetchingMyChannels: false, abandoningById: {}, pendingById: {}, @@ -190,13 +190,20 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_STARTED] = (state: State): State => reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): State => { const { claims }: { claims: Array } = action.data; - const myChannelClaims = new Set(state.myChannelClaims); - const byId = Object.assign({}, state.byId); - claims.forEach(claim => { - myChannelClaims.add(claim.claim_id); - byId[claim.claim_id] = claim; - }); + let myChannelClaims; + let byId = Object.assign({}, state.byId); + if (!claims.length) { + // $FlowFixMe + myChannelClaims = null; + } else { + myChannelClaims = new Set(state.myChannelClaims); + claims.forEach(claim => { + // $FlowFixMe + myChannelClaims.add(claim.claim_id); + byId[claim.claim_id] = claim; + }); + } return Object.assign({}, state, { byId, diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index 29480e1..187e751 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -65,7 +65,7 @@ export const tagsReducer = handleActions( followedTags: newFollowedTags, }; }, - [ACTIONS.USER_SETTINGS_POPULATE]: ( + [ACTIONS.USER_STATE_POPULATE]: ( state: TagState, action: { data: { tags: ?Array } } ) => { @@ -73,9 +73,9 @@ export const tagsReducer = handleActions( let newTags; if (!tags) { - newTags = state.followedTags || DEFAULT_FOLLOWED_TAGS; + newTags = state.followedTags.length ? state.followedTags : DEFAULT_FOLLOWED_TAGS; } else { - if (!state.followedTags || !state.followedTags.length) { + if (!state.followedTags.length) { newTags = tags; } else { const map = {}; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 429137a..7cff061 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -23,7 +23,7 @@ export const selectCreatingChannel = createSelector( state => state.creatingChannel ); -export const createChannelError = createSelector( +export const selectCreateChannelError = createSelector( selectState, state => state.createChannelError ); @@ -240,8 +240,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -360,9 +360,12 @@ export const selectMyChannelClaims = createSelector( selectState, selectClaimsById, (state, byId) => { - const ids = state.myChannelClaims || []; - const claims = []; + const ids = state.myChannelClaims; + if (!ids) { + return ids; + } + const claims = []; ids.forEach(id => { if (byId[id]) { // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544 diff --git a/src/redux/selectors/tags.js b/src/redux/selectors/tags.js index ff202b3..f46151b 100644 --- a/src/redux/selectors/tags.js +++ b/src/redux/selectors/tags.js @@ -27,7 +27,6 @@ export const selectUnfollowedTags = createSelector( (tagsByName: KnownTags, followedTags: Array): Array => { const followedTagsSet = new Set(followedTags); let tagsToReturn = []; - Object.keys(tagsByName).forEach(key => { if (!followedTagsSet.has(key)) { const { name } = tagsByName[key]; -- 2.45.2 From 6bd56492ad15a0e761b087db29a5441e9b9a04f0 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 20 Sep 2019 11:22:21 -0400 Subject: [PATCH 139/371] pr feedback --- dist/bundle.es.js | 28 +++++++--------------------- src/index.js | 2 +- src/redux/actions/sync.js | 11 ++++++----- src/redux/reducers/tags.js | 17 +---------------- 4 files changed, 15 insertions(+), 43 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3a8a746..21f2290 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3558,18 +3558,19 @@ const doToggleBlockChannel = uri => ({ var _extends$5 = 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 extractSettings(rawObj) { - if (rawObj && rawObj.version === '0' && rawObj.shared) { +function extractUserState(rawObj) { + if (rawObj && rawObj.version === '0.1' && rawObj.shared) { const { subscriptions, tags } = rawObj.shared; + return _extends$5({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}); } return {}; } -function doPopulateUserSettings(settings) { +function doPopulateSharedUserState(settings) { return dispatch => { - const { subscriptions, tags } = extractSettings(settings); + const { subscriptions, tags } = extractUserState(settings); dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags } }); }; } @@ -4524,23 +4525,8 @@ const tagsReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; - let newTags; - - if (!tags) { - newTags = state.followedTags.length ? state.followedTags : DEFAULT_FOLLOWED_TAGS; - } else { - if (!state.followedTags.length) { - newTags = tags; - } else { - const map = {}; - newTags = tags.concat(state.followedTags).filter(tag => { - return map[tag] ? false : map[tag] = true; - }, {}); - } - } - return _extends$d({}, state, { - followedTags: newTags + followedTags: tags && tags.length ? tags : DEFAULT_FOLLOWED_TAGS }); } }, defaultState$8); @@ -4975,7 +4961,7 @@ exports.doFileGet = doFileGet; exports.doFileList = doFileList; exports.doFocusSearchInput = doFocusSearchInput; exports.doGetNewAddress = doGetNewAddress; -exports.doPopulateUserSettings = doPopulateUserSettings; +exports.doPopulateSharedUserState = doPopulateSharedUserState; exports.doPrepareEdit = doPrepareEdit; exports.doPublish = doPublish; exports.doPurchaseUri = doPurchaseUri; diff --git a/src/index.js b/src/index.js index a954ee9..3dc3abe 100644 --- a/src/index.js +++ b/src/index.js @@ -113,7 +113,7 @@ export { doCommentList, doCommentCreate } from 'redux/actions/comments'; export { doToggleBlockChannel } from 'redux/actions/blocked'; -export { doPopulateUserSettings } from 'redux/actions/sync'; +export { doPopulateSharedUserState } from 'redux/actions/sync'; // utils export { batchActions } from 'util/batch-actions'; diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index e0b13e4..ffcf2e7 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -2,16 +2,17 @@ import * as ACTIONS from 'constants/action_types'; type v0Data = { - version: '0', + version: '0.1', shared: { subscriptions?: Array, tags?: Array, }, }; -function extractSettings(rawObj: v0Data) { - if (rawObj && rawObj.version === '0' && rawObj.shared) { +function extractUserState(rawObj: v0Data) { + if (rawObj && rawObj.version === '0.1' && rawObj.shared) { const { subscriptions, tags } = rawObj.shared; + return { ...(subscriptions ? { subscriptions } : {}), ...(tags ? { tags } : {}), @@ -21,9 +22,9 @@ function extractSettings(rawObj: v0Data) { return {}; } -export function doPopulateUserSettings(settings: any) { +export function doPopulateSharedUserState(settings: any) { return (dispatch: Dispatch) => { - const { subscriptions, tags } = extractSettings(settings); + const { subscriptions, tags } = extractUserState(settings); dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags } }); }; } diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index 187e751..1bb6430 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -70,24 +70,9 @@ export const tagsReducer = handleActions( action: { data: { tags: ?Array } } ) => { const { tags } = action.data; - let newTags; - - if (!tags) { - newTags = state.followedTags.length ? state.followedTags : DEFAULT_FOLLOWED_TAGS; - } else { - if (!state.followedTags.length) { - newTags = tags; - } else { - const map = {}; - newTags = tags.concat(state.followedTags).filter(tag => { - return map[tag] ? false : (map[tag] = true); - }, {}); - } - } - return { ...state, - followedTags: newTags, + followedTags: tags && tags.length ? tags : DEFAULT_FOLLOWED_TAGS, }; }, }, -- 2.45.2 From 9fd930564ecba56c82e77d9a60dbd31ed079270c Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 12 Sep 2019 15:06:49 -0400 Subject: [PATCH 140/371] adds channelImport --- dist/bundle.es.js | 54 ++++++++++++++++++++++++++++++++++- dist/flow-typed/Lbry.js | 1 + flow-typed/Lbry.js | 1 + src/constants/action_types.js | 3 ++ src/index.js | 2 ++ src/lbry.js | 1 + src/redux/actions/claims.js | 23 +++++++++++++++ src/redux/reducers/claims.js | 10 +++++++ src/redux/selectors/claims.js | 9 ++++-- 9 files changed, 101 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 21f2290..8b4e319 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -106,6 +106,9 @@ const CREATE_CHANNEL_FAILED = 'CREATE_CHANNEL_FAILED'; const UPDATE_CHANNEL_STARTED = 'UPDATE_CHANNEL_STARTED'; const UPDATE_CHANNEL_COMPLETED = 'UPDATE_CHANNEL_COMPLETED'; const UPDATE_CHANNEL_FAILED = 'UPDATE_CHANNEL_FAILED'; +const IMPORT_CHANNEL_STARTED = 'IMPORT_CHANNEL_STARTED'; +const IMPORT_CHANNEL_COMPLETED = 'IMPORT_CHANNEL_COMPLETED'; +const IMPORT_CHANNEL_FAILED = 'IMPORT_CHANNEL_FAILED'; const PUBLISH_STARTED = 'PUBLISH_STARTED'; const PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; const PUBLISH_FAILED = 'PUBLISH_FAILED'; @@ -342,6 +345,9 @@ var action_types = /*#__PURE__*/Object.freeze({ UPDATE_CHANNEL_STARTED: UPDATE_CHANNEL_STARTED, UPDATE_CHANNEL_COMPLETED: UPDATE_CHANNEL_COMPLETED, UPDATE_CHANNEL_FAILED: UPDATE_CHANNEL_FAILED, + IMPORT_CHANNEL_STARTED: IMPORT_CHANNEL_STARTED, + IMPORT_CHANNEL_COMPLETED: IMPORT_CHANNEL_COMPLETED, + IMPORT_CHANNEL_FAILED: IMPORT_CHANNEL_FAILED, PUBLISH_STARTED: PUBLISH_STARTED, PUBLISH_COMPLETED: PUBLISH_COMPLETED, PUBLISH_FAILED: PUBLISH_FAILED, @@ -734,6 +740,7 @@ const Lbry = { claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), channel_update: params => daemonCallWithResult('channel_update', params), + channel_import: params => daemonCallWithResult('channel_import', params), channel_list: params => daemonCallWithResult('channel_list', params), stream_abandon: params => daemonCallWithResult('stream_abandon', params), channel_abandon: params => daemonCallWithResult('channel_abandon', params), @@ -1050,6 +1057,18 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; + { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } + } + if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -1686,6 +1705,8 @@ const selectMyChannelClaims = reselect.createSelector(selectState$2, selectClaim const selectResolvingUris = reselect.createSelector(selectState$2, state => state.resolvingUris || []); +const selectChannelImportPending = reselect.createSelector(selectState$2, state => state.pendingChannelImport); + const makeSelectIsUriResolving = uri => reselect.createSelector(selectResolvingUris, resolvingUris => resolvingUris && resolvingUris.indexOf(uri) !== -1); const selectPlayingUri = reselect.createSelector(selectState$2, state => state.playingUri); @@ -2502,6 +2523,27 @@ function doUpdateChannel(params) { }; } +function doImportChannel(id, certificate) { + return dispatch => { + dispatch({ + type: IMPORT_CHANNEL_STARTED, + data: id + }); + + return lbryProxy.channel_import({ channel_data: certificate }).then(result => { + dispatch({ + type: IMPORT_CHANNEL_COMPLETED, + data: { result } // "Added channel signing key for @name." + }); + }).catch(error => { + dispatch({ + type: IMPORT_CHANNEL_FAILED, + data: error + }); + }); + }; +} + function doFetchChannelListMine() { return dispatch => { dispatch({ @@ -3598,7 +3640,8 @@ const defaultState = { updateChannelError: '', updatingChannel: false, creatingChannel: false, - createChannelError: undefined + createChannelError: undefined, + pendingChannelImport: false }; function handleClaimAction(state, action) { @@ -3877,6 +3920,13 @@ reducers[UPDATE_CHANNEL_FAILED] = (state, action) => { }); }; +reducers[IMPORT_CHANNEL_STARTED] = (state, action) => { + const channelId = action.data.id; + return Object.assign({}, state, { pendingChannelImports: channelId }); +}; + +reducers[IMPORT_CHANNEL_COMPLETED] = state => Object.assign({}, state, { pendingChannelImports: false }); + reducers[CLAIM_SEARCH_STARTED] = (state, action) => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); fetchingClaimSearchByQuery[action.data.query] = true; @@ -4961,6 +5011,7 @@ exports.doFileGet = doFileGet; exports.doFileList = doFileList; exports.doFocusSearchInput = doFocusSearchInput; exports.doGetNewAddress = doGetNewAddress; +exports.doImportChannel = doImportChannel; exports.doPopulateSharedUserState = doPopulateSharedUserState; exports.doPrepareEdit = doPrepareEdit; exports.doPublish = doPublish; @@ -5061,6 +5112,7 @@ exports.selectBlockedChannels = selectBlockedChannels; exports.selectBlockedChannelsCount = selectBlockedChannelsCount; exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; +exports.selectChannelImportPending = selectChannelImportPending; exports.selectChannelIsBlocked = selectChannelIsBlocked; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 73dff71..a6adaca 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -190,6 +190,7 @@ declare type LbryTypes = { claim_list: (params?: {}) => Promise, channel_create: (params: {}) => Promise, channel_update: (params: {}) => Promise, + channel_import: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 73dff71..a6adaca 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -190,6 +190,7 @@ declare type LbryTypes = { claim_list: (params?: {}) => Promise, channel_create: (params: {}) => Promise, channel_update: (params: {}) => Promise, + channel_import: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index a852537..a52c756 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -83,6 +83,9 @@ export const CREATE_CHANNEL_FAILED = 'CREATE_CHANNEL_FAILED'; export const UPDATE_CHANNEL_STARTED = 'UPDATE_CHANNEL_STARTED'; export const UPDATE_CHANNEL_COMPLETED = 'UPDATE_CHANNEL_COMPLETED'; export const UPDATE_CHANNEL_FAILED = 'UPDATE_CHANNEL_FAILED'; +export const IMPORT_CHANNEL_STARTED = 'IMPORT_CHANNEL_STARTED'; +export const IMPORT_CHANNEL_COMPLETED = 'IMPORT_CHANNEL_COMPLETED'; +export const IMPORT_CHANNEL_FAILED = 'IMPORT_CHANNEL_FAILED'; export const PUBLISH_STARTED = 'PUBLISH_STARTED'; export const PUBLISH_COMPLETED = 'PUBLISH_COMPLETED'; export const PUBLISH_FAILED = 'PUBLISH_FAILED'; diff --git a/src/index.js b/src/index.js index 3dc3abe..c26402b 100644 --- a/src/index.js +++ b/src/index.js @@ -55,6 +55,7 @@ export { doCreateChannel, doUpdateChannel, doClaimSearch, + doImportChannel, } from 'redux/actions/claims'; export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -206,6 +207,7 @@ export { selectUpdateChannelError, selectCreatingChannel, selectCreateChannelError, + selectChannelImportPending, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/lbry.js b/src/lbry.js index ba47709..4854c75 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -79,6 +79,7 @@ const Lbry: LbryTypes = { claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), channel_update: params => daemonCallWithResult('channel_update', params), + channel_import: params => daemonCallWithResult('channel_import', params), channel_list: params => daemonCallWithResult('channel_list', params), stream_abandon: params => daemonCallWithResult('stream_abandon', params), channel_abandon: params => daemonCallWithResult('channel_abandon', params), diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 215daba..8bd6318 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -323,6 +323,29 @@ export function doUpdateChannel(params: any) { }; } +export function doImportChannel(id: string, certificate: string) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.IMPORT_CHANNEL_STARTED, + data: id, + }); + + return Lbry.channel_import({ channel_data: certificate }) + .then((result: string) => { + dispatch({ + type: ACTIONS.IMPORT_CHANNEL_COMPLETED, + data: { result }, // "Added channel signing key for @name." + }); + }) + .catch(error => { + dispatch({ + type: ACTIONS.IMPORT_CHANNEL_FAILED, + data: error, + }); + }); + }; +} + export function doFetchChannelListMine() { return (dispatch: Dispatch) => { dispatch({ diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index cdac7d9..f160509 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -34,6 +34,7 @@ type State = { }, updateChannelError: string, updatingChannel: boolean, + pendingChannelImport: string | boolean, }; const reducers = {}; @@ -58,6 +59,7 @@ const defaultState = { updatingChannel: false, creatingChannel: false, createChannelError: undefined, + pendingChannelImport: false, }; function handleClaimAction(state: State, action: any): State { @@ -348,6 +350,14 @@ reducers[ACTIONS.UPDATE_CHANNEL_FAILED] = (state: State, action: any): State => }); }; +reducers[ACTIONS.IMPORT_CHANNEL_STARTED] = (state: State, action: any): State => { + const channelId: string = action.data.id; + return Object.assign({}, state, { pendingChannelImports: channelId }); +}; + +reducers[ACTIONS.IMPORT_CHANNEL_COMPLETED] = (state: State): State => + Object.assign({}, state, { pendingChannelImports: false }); + reducers[ACTIONS.CLAIM_SEARCH_STARTED] = (state: State, action: any): State => { const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); fetchingClaimSearchByQuery[action.data.query] = true; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 7cff061..723f8d3 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -240,8 +240,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -382,6 +382,11 @@ export const selectResolvingUris = createSelector( state => state.resolvingUris || [] ); +export const selectChannelImportPending = createSelector( + selectState, + state => state.pendingChannelImport +); + export const makeSelectIsUriResolving = (uri: string) => createSelector( selectResolvingUris, -- 2.45.2 From 3e1871e170e89ae9f79c80624a9d383c3b35df5e Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 16 Sep 2019 14:46:41 -0400 Subject: [PATCH 141/371] remove id --- src/redux/actions/claims.js | 4 +--- src/redux/reducers/claims.js | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 8bd6318..622847d 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -323,18 +323,16 @@ export function doUpdateChannel(params: any) { }; } -export function doImportChannel(id: string, certificate: string) { +export function doImportChannel(certificate: string) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.IMPORT_CHANNEL_STARTED, - data: id, }); return Lbry.channel_import({ channel_data: certificate }) .then((result: string) => { dispatch({ type: ACTIONS.IMPORT_CHANNEL_COMPLETED, - data: { result }, // "Added channel signing key for @name." }); }) .catch(error => { diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index f160509..1ade6d3 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -350,10 +350,8 @@ reducers[ACTIONS.UPDATE_CHANNEL_FAILED] = (state: State, action: any): State => }); }; -reducers[ACTIONS.IMPORT_CHANNEL_STARTED] = (state: State, action: any): State => { - const channelId: string = action.data.id; - return Object.assign({}, state, { pendingChannelImports: channelId }); -}; +reducers[ACTIONS.IMPORT_CHANNEL_STARTED] = (state: State): State => + Object.assign({}, state, { pendingChannelImports: true }); reducers[ACTIONS.IMPORT_CHANNEL_COMPLETED] = (state: State): State => Object.assign({}, state, { pendingChannelImports: false }); -- 2.45.2 From d837e72169752f855be0bf6bfcc5fa05fd82a7e5 Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 17 Sep 2019 13:48:41 -0400 Subject: [PATCH 142/371] adds Lbry.address_list --- dist/bundle.es.js | 1 + dist/flow-typed/Lbry.js | 1 + flow-typed/Lbry.js | 1 + src/lbry.js | 1 + 4 files changed, 4 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8b4e319..f447bff 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -763,6 +763,7 @@ const Lbry = { account_set: (params = {}) => daemonCallWithResult('account_set', params), address_is_mine: (params = {}) => daemonCallWithResult('address_is_mine', params), address_unused: (params = {}) => daemonCallWithResult('address_unused', params), + address_list: (params = {}) => daemonCallWithResult('address_list', params), transaction_list: (params = {}) => daemonCallWithResult('transaction_list', params), utxo_release: (params = {}) => daemonCallWithResult('utxo_release', params), support_abandon: (params = {}) => daemonCallWithResult('support_abandon', params), diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index a6adaca..9bbde01 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -215,6 +215,7 @@ declare type LbryTypes = { account_set: (params: {}) => Promise, address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address + address_list: (params: {}) => Promise, transaction_list: (params: {}) => Promise, support_abandon: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index a6adaca..9bbde01 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -215,6 +215,7 @@ declare type LbryTypes = { account_set: (params: {}) => Promise, address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address + address_list: (params: {}) => Promise, transaction_list: (params: {}) => Promise, support_abandon: (params: {}) => Promise, diff --git a/src/lbry.js b/src/lbry.js index 4854c75..f776871 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -102,6 +102,7 @@ const Lbry: LbryTypes = { account_set: (params = {}) => daemonCallWithResult('account_set', params), address_is_mine: (params = {}) => daemonCallWithResult('address_is_mine', params), address_unused: (params = {}) => daemonCallWithResult('address_unused', params), + address_list: (params = {}) => daemonCallWithResult('address_list', params), transaction_list: (params = {}) => daemonCallWithResult('transaction_list', params), utxo_release: (params = {}) => daemonCallWithResult('utxo_release', params), support_abandon: (params = {}) => daemonCallWithResult('support_abandon', params), -- 2.45.2 From 1127282ec1841057df83cdc01933bc5538271aea Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 17 Sep 2019 17:08:02 -0400 Subject: [PATCH 143/371] youtube import actions --- dist/bundle.es.js | 6 ++++++ src/constants/action_types.js | 3 +++ 2 files changed, 9 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f447bff..2f22b7d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -203,6 +203,9 @@ const USER_INVITE_STATUS_FETCH_FAILURE = 'USER_INVITE_STATUS_FETCH_FAILURE'; const USER_INVITE_NEW_STARTED = 'USER_INVITE_NEW_STARTED'; const USER_INVITE_NEW_SUCCESS = 'USER_INVITE_NEW_SUCCESS'; const USER_INVITE_NEW_FAILURE = 'USER_INVITE_NEW_FAILURE'; +const USER_YOUTUBE_IMPORT_STARTED = 'USER_YOUTUBE_IMPORT_STARTED'; +const USER_YOUTUBE_IMPORT_COMPLETED = 'USER_YOUTUBE_IMPORT_COMPLETED'; +const USER_YOUTUBE_IMPORT_FAILURE = 'USER_YOUTUBE_IMPORT_FAILURE'; const FETCH_ACCESS_TOKEN_SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS'; // Rewards @@ -432,6 +435,9 @@ var action_types = /*#__PURE__*/Object.freeze({ USER_INVITE_NEW_STARTED: USER_INVITE_NEW_STARTED, USER_INVITE_NEW_SUCCESS: USER_INVITE_NEW_SUCCESS, USER_INVITE_NEW_FAILURE: USER_INVITE_NEW_FAILURE, + USER_YOUTUBE_IMPORT_STARTED: USER_YOUTUBE_IMPORT_STARTED, + USER_YOUTUBE_IMPORT_COMPLETED: USER_YOUTUBE_IMPORT_COMPLETED, + USER_YOUTUBE_IMPORT_FAILURE: USER_YOUTUBE_IMPORT_FAILURE, FETCH_ACCESS_TOKEN_SUCCESS: FETCH_ACCESS_TOKEN_SUCCESS, FETCH_REWARDS_STARTED: FETCH_REWARDS_STARTED, FETCH_REWARDS_COMPLETED: FETCH_REWARDS_COMPLETED, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index a52c756..0a36611 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -180,6 +180,9 @@ export const USER_INVITE_STATUS_FETCH_FAILURE = 'USER_INVITE_STATUS_FETCH_FAILUR export const USER_INVITE_NEW_STARTED = 'USER_INVITE_NEW_STARTED'; export const USER_INVITE_NEW_SUCCESS = 'USER_INVITE_NEW_SUCCESS'; export const USER_INVITE_NEW_FAILURE = 'USER_INVITE_NEW_FAILURE'; +export const USER_YOUTUBE_IMPORT_STARTED = 'USER_YOUTUBE_IMPORT_STARTED'; +export const USER_YOUTUBE_IMPORT_COMPLETED = 'USER_YOUTUBE_IMPORT_COMPLETED'; +export const USER_YOUTUBE_IMPORT_FAILURE = 'USER_YOUTUBE_IMPORT_FAILURE'; export const FETCH_ACCESS_TOKEN_SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS'; // Rewards -- 2.45.2 From 01614094dae83263e213e03319573e34cc922995 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 23 Sep 2019 11:06:02 -0400 Subject: [PATCH 144/371] remove unused constant --- dist/bundle.es.js | 31 ++++--------------------------- src/constants/action_types.js | 3 --- 2 files changed, 4 insertions(+), 30 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2f22b7d..2e5712a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -203,9 +203,6 @@ const USER_INVITE_STATUS_FETCH_FAILURE = 'USER_INVITE_STATUS_FETCH_FAILURE'; const USER_INVITE_NEW_STARTED = 'USER_INVITE_NEW_STARTED'; const USER_INVITE_NEW_SUCCESS = 'USER_INVITE_NEW_SUCCESS'; const USER_INVITE_NEW_FAILURE = 'USER_INVITE_NEW_FAILURE'; -const USER_YOUTUBE_IMPORT_STARTED = 'USER_YOUTUBE_IMPORT_STARTED'; -const USER_YOUTUBE_IMPORT_COMPLETED = 'USER_YOUTUBE_IMPORT_COMPLETED'; -const USER_YOUTUBE_IMPORT_FAILURE = 'USER_YOUTUBE_IMPORT_FAILURE'; const FETCH_ACCESS_TOKEN_SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS'; // Rewards @@ -435,9 +432,6 @@ var action_types = /*#__PURE__*/Object.freeze({ USER_INVITE_NEW_STARTED: USER_INVITE_NEW_STARTED, USER_INVITE_NEW_SUCCESS: USER_INVITE_NEW_SUCCESS, USER_INVITE_NEW_FAILURE: USER_INVITE_NEW_FAILURE, - USER_YOUTUBE_IMPORT_STARTED: USER_YOUTUBE_IMPORT_STARTED, - USER_YOUTUBE_IMPORT_COMPLETED: USER_YOUTUBE_IMPORT_COMPLETED, - USER_YOUTUBE_IMPORT_FAILURE: USER_YOUTUBE_IMPORT_FAILURE, FETCH_ACCESS_TOKEN_SUCCESS: FETCH_ACCESS_TOKEN_SUCCESS, FETCH_REWARDS_STARTED: FETCH_REWARDS_STARTED, FETCH_REWARDS_COMPLETED: FETCH_REWARDS_COMPLETED, @@ -1064,18 +1058,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -2530,17 +2512,15 @@ function doUpdateChannel(params) { }; } -function doImportChannel(id, certificate) { +function doImportChannel(certificate) { return dispatch => { dispatch({ - type: IMPORT_CHANNEL_STARTED, - data: id + type: IMPORT_CHANNEL_STARTED }); return lbryProxy.channel_import({ channel_data: certificate }).then(result => { dispatch({ - type: IMPORT_CHANNEL_COMPLETED, - data: { result } // "Added channel signing key for @name." + type: IMPORT_CHANNEL_COMPLETED }); }).catch(error => { dispatch({ @@ -3927,10 +3907,7 @@ reducers[UPDATE_CHANNEL_FAILED] = (state, action) => { }); }; -reducers[IMPORT_CHANNEL_STARTED] = (state, action) => { - const channelId = action.data.id; - return Object.assign({}, state, { pendingChannelImports: channelId }); -}; +reducers[IMPORT_CHANNEL_STARTED] = state => Object.assign({}, state, { pendingChannelImports: true }); reducers[IMPORT_CHANNEL_COMPLETED] = state => Object.assign({}, state, { pendingChannelImports: false }); diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 0a36611..a52c756 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -180,9 +180,6 @@ export const USER_INVITE_STATUS_FETCH_FAILURE = 'USER_INVITE_STATUS_FETCH_FAILUR export const USER_INVITE_NEW_STARTED = 'USER_INVITE_NEW_STARTED'; export const USER_INVITE_NEW_SUCCESS = 'USER_INVITE_NEW_SUCCESS'; export const USER_INVITE_NEW_FAILURE = 'USER_INVITE_NEW_FAILURE'; -export const USER_YOUTUBE_IMPORT_STARTED = 'USER_YOUTUBE_IMPORT_STARTED'; -export const USER_YOUTUBE_IMPORT_COMPLETED = 'USER_YOUTUBE_IMPORT_COMPLETED'; -export const USER_YOUTUBE_IMPORT_FAILURE = 'USER_YOUTUBE_IMPORT_FAILURE'; export const FETCH_ACCESS_TOKEN_SUCCESS = 'FETCH_ACCESS_TOKEN_SUCCESS'; // Rewards -- 2.45.2 From 3fdec3cb62356f2022119971f429f77252c21dbc Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 24 Sep 2019 20:57:51 +0100 Subject: [PATCH 145/371] concatenate unique claims after fetching owned claims or channel list --- dist/bundle.es.js | 25 +++++++++++++++++++++++-- src/redux/reducers/claims.js | 9 +++++++-- src/util/claim.js | 18 ++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2e5712a..071040d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1467,6 +1467,24 @@ function createNormalizedClaimSearchKey(options) { return query; } +function concatClaims(claimList = [], concatClaimList = []) { + if (!claimList || claimList.length === 0) { + if (!concatClaimList) { + return []; + } + return concatClaimList.slice(); + } + + const claims = claimList.slice(); + concatClaimList.forEach(claim => { + if (!claims.some(item => item.claim_id === claim.claim_id)) { + claims.push(claim); + } + }); + + return claims; +} + // const selectState$2 = state => state.claims || {}; @@ -3617,6 +3635,7 @@ const defaultState = { // This should not be a Set // Storing sets in reducers can cause issues myChannelClaims: undefined, + myClaims: undefined, fetchingMyChannels: false, abandoningById: {}, pendingById: {}, @@ -3713,6 +3732,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById = Object.assign({}, state.pendingById); + const myClaims = state.myClaims || []; claims.forEach(claim => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); @@ -3739,7 +3759,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { return Object.assign({}, state, { isFetchingClaimListMine: false, - myClaims: claims, + myClaims: concatClaims(myClaims, claims), byId, claimsByUri: byUri, pendingById @@ -3750,6 +3770,7 @@ reducers[FETCH_CHANNEL_LIST_STARTED] = state => Object.assign({}, state, { fetch reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { const { claims } = action.data; + const myClaims = state.myClaims || []; let myChannelClaims; let byId = Object.assign({}, state.byId); @@ -3769,7 +3790,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { byId, fetchingMyChannels: false, myChannelClaims, - myClaims: claims + myClaims: concatClaims(myClaims, claims) }); }; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 1ade6d3..bef8797 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -10,6 +10,7 @@ import * as ACTIONS from 'constants/action_types'; import { buildURI, parseURI } from 'lbryURI'; +import { concatClaims } from 'util/claim'; type State = { createChannelError: ?string, @@ -18,6 +19,7 @@ type State = { byId: { [string]: Claim }, resolvingUris: Array, pendingById: { [string]: Claim }, + myClaims: ?Array, myChannelClaims: ?Set, abandoningById: { [string]: boolean }, fetchingChannelClaims: { [string]: number }, @@ -48,6 +50,7 @@ const defaultState = { // This should not be a Set // Storing sets in reducers can cause issues myChannelClaims: undefined, + myClaims: undefined, fetchingMyChannels: false, abandoningById: {}, pendingById: {}, @@ -153,6 +156,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); + const myClaims = state.myClaims || []; claims.forEach((claim: Claim) => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); @@ -180,7 +184,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): return Object.assign({}, state, { isFetchingClaimListMine: false, - myClaims: claims, + myClaims: concatClaims(myClaims, claims), byId, claimsByUri: byUri, pendingById, @@ -192,6 +196,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_STARTED] = (state: State): State => reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): State => { const { claims }: { claims: Array } = action.data; + const myClaims = state.myClaims || []; let myChannelClaims; let byId = Object.assign({}, state.byId); @@ -211,7 +216,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St byId, fetchingMyChannels: false, myChannelClaims, - myClaims: claims, + myClaims: concatClaims(myClaims, claims), }); }; diff --git a/src/util/claim.js b/src/util/claim.js index ece6fc7..5ed1a42 100644 --- a/src/util/claim.js +++ b/src/util/claim.js @@ -30,3 +30,21 @@ export function createNormalizedClaimSearchKey(options: { page?: number, release const query = JSON.stringify(rest); return query; } + +export function concatClaims(claimList: Array = [], concatClaimList: Array = []): Array { + if (!claimList || claimList.length === 0) { + if (!concatClaimList) { + return []; + } + return concatClaimList.slice(); + } + + const claims = claimList.slice(); + concatClaimList.forEach(claim => { + if (!claims.some(item => item.claim_id === claim.claim_id)) { + claims.push(claim); + } + }); + + return claims; +} -- 2.45.2 From 45e585c9cf9caee9b64cdd223a22582f21a08f3a Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Mon, 23 Sep 2019 18:56:53 -0400 Subject: [PATCH 146/371] feat: granular balances + We were not using the total balances stuff I removed -that was an attempt by Akin at one point to work around the SDK cross account balance issue. + Decided to keep `balance` as is so we don't have to change it everywhere else...still makes sense I think. --- dist/bundle.es.js | 77 ++++++++++++++++------------------- src/index.js | 6 ++- src/lbry.js | 2 +- src/redux/actions/wallet.js | 49 ++++++---------------- src/redux/reducers/wallet.js | 19 ++++++--- src/redux/selectors/wallet.js | 20 +++++++++ 6 files changed, 86 insertions(+), 87 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 071040d..141d1b3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -754,7 +754,7 @@ const Lbry = { blob_list: (params = {}) => daemonCallWithResult('blob_list', params), // Wallet utilities - account_balance: () => daemonCallWithResult('account_balance'), + account_balance: (params = {}) => daemonCallWithResult('account_balance', params), account_decrypt: () => daemonCallWithResult('account_decrypt', {}), account_encrypt: (params = {}) => daemonCallWithResult('account_encrypt', params), account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), @@ -1317,6 +1317,14 @@ const selectBalance = reselect.createSelector(selectState$1, state => state.bala const selectTotalBalance = reselect.createSelector(selectState$1, state => state.totalBalance); +const selectReservedBalance = reselect.createSelector(selectState$1, state => state.reservedBalance); + +const selectClaimsBalance = reselect.createSelector(selectState$1, state => state.claimsBalance); + +const selectSupportsBalance = reselect.createSelector(selectState$1, state => state.supportsBalance); + +const selectTipsBalance = reselect.createSelector(selectState$1, state => state.tipsBalance); + const selectTransactionsById = reselect.createSelector(selectState$1, state => state.transactions || {}); const selectSupportsByOutpoint = reselect.createSelector(selectState$1, state => state.supports || {}); @@ -1879,37 +1887,22 @@ function creditsToString(amount) { function doUpdateBalance() { return (dispatch, getState) => { const { - wallet: { balance: balanceInStore } + wallet: { total: totalInStore } } = getState(); - lbryProxy.account_balance().then(response => { - const { available } = response; - const balance = parseFloat(available); - if (balanceInStore !== balance) { + lbryProxy.account_balance({ reserved_subtotals: true }).then(response => { + const { available, reserved, reserved_subtotals, total } = response; + const { claims, supports, tips } = reserved_subtotals; + const totalFloat = parseFloat(total); + if (totalInStore !== totalFloat) { dispatch({ type: UPDATE_BALANCE, data: { - balance - } - }); - } - }); - }; -} - -function doUpdateTotalBalance() { - return (dispatch, getState) => { - const { - wallet: { totalBalance: totalBalanceInStore } - } = getState(); - lbryProxy.account_list().then(accountList => { - const { lbc_mainnet: accounts } = accountList; - const totalSatoshis = accounts.length === 1 ? accounts[0].satoshis : accounts.reduce((a, b) => a.satoshis + b.satoshis); - const totalBalance = (Number.isNaN(totalSatoshis) ? 0 : totalSatoshis) / Math.pow(10, 8); - if (totalBalanceInStore !== totalBalance) { - dispatch({ - type: UPDATE_TOTAL_BALANCE, - data: { - totalBalance + totalBalance: totalFloat, + balance: parseFloat(available), + reservedBalance: parseFloat(reserved), + claimsBalance: parseFloat(claims), + supportsBalance: parseFloat(supports), + tipsBalance: parseFloat(tips) } }); } @@ -1924,13 +1917,6 @@ function doBalanceSubscribe() { }; } -function doTotalBalanceSubscribe() { - return dispatch => { - dispatch(doUpdateTotalBalance()); - setInterval(() => dispatch(doUpdateTotalBalance()), 5000); - }; -} - function doFetchTransactions() { return dispatch => { dispatch(doFetchSupports()); @@ -4624,6 +4610,10 @@ const buildDraftTransaction = () => ({ const defaultState$a = { balance: undefined, totalBalance: undefined, + reservedBalance: undefined, + claimsBalance: undefined, + supportsBalance: undefined, + tipsBalance: undefined, latestBlock: undefined, transactions: {}, fetchingTransactions: false, @@ -4720,11 +4710,12 @@ const walletReducer = handleActions({ }, [UPDATE_BALANCE]: (state, action) => _extends$e({}, state, { - balance: action.data.balance - }), - - [UPDATE_TOTAL_BALANCE]: (state, action) => _extends$e({}, state, { - totalBalance: action.data.totalBalance + totalBalance: action.data.totalBalance, + balance: action.data.balance, + reservedBalance: action.data.reservedBalance, + claimsBalance: action.data.claimsBalance, + supportsBalance: action.data.supportsBalance, + tipsBalance: action.data.tipsBalance }), [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$e({}, state, { @@ -5034,14 +5025,12 @@ exports.doSetTransactionListFilter = doSetTransactionListFilter; exports.doToast = doToast; exports.doToggleBlockChannel = doToggleBlockChannel; exports.doToggleTagFollow = doToggleTagFollow; -exports.doTotalBalanceSubscribe = doTotalBalanceSubscribe; exports.doUpdateBalance = doUpdateBalance; exports.doUpdateBlockHeight = doUpdateBlockHeight; exports.doUpdateChannel = doUpdateChannel; exports.doUpdatePublishForm = doUpdatePublishForm; exports.doUpdateSearchOptions = doUpdateSearchOptions; exports.doUpdateSearchQuery = doUpdateSearchQuery; -exports.doUpdateTotalBalance = doUpdateTotalBalance; exports.doUploadThumbnail = doUploadThumbnail; exports.doWalletDecrypt = doWalletDecrypt; exports.doWalletEncrypt = doWalletEncrypt; @@ -5121,6 +5110,7 @@ exports.selectChannelImportPending = selectChannelImportPending; exports.selectChannelIsBlocked = selectChannelIsBlocked; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; +exports.selectClaimsBalance = selectClaimsBalance; exports.selectClaimsById = selectClaimsById; exports.selectClaimsByUri = selectClaimsByUri; exports.selectCreateChannelError = selectCreateChannelError; @@ -5170,6 +5160,7 @@ exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; +exports.selectReservedBalance = selectReservedBalance; exports.selectResolvingUris = selectResolvingUris; exports.selectSearchBarFocused = selectSearchBarFocused; exports.selectSearchOptions = selectSearchOptions; @@ -5177,8 +5168,10 @@ exports.selectSearchState = selectState; exports.selectSearchSuggestions = selectSearchSuggestions; exports.selectSearchUrisByQuery = selectSearchUrisByQuery; exports.selectSearchValue = selectSearchValue; +exports.selectSupportsBalance = selectSupportsBalance; exports.selectSupportsByOutpoint = selectSupportsByOutpoint; exports.selectTakeOverAmount = selectTakeOverAmount; +exports.selectTipsBalance = selectTipsBalance; exports.selectToast = selectToast; exports.selectTotalBalance = selectTotalBalance; exports.selectTotalDownloadProgress = selectTotalDownloadProgress; diff --git a/src/index.js b/src/index.js index c26402b..ce4c00a 100644 --- a/src/index.js +++ b/src/index.js @@ -91,8 +91,6 @@ export { savePosition } from 'redux/actions/content'; export { doUpdateBalance, doBalanceSubscribe, - doUpdateTotalBalance, - doTotalBalanceSubscribe, doFetchTransactions, doGetNewAddress, doCheckAddressIsMine, @@ -258,6 +256,10 @@ export { export { selectBalance, selectTotalBalance, + selectReservedBalance, + selectClaimsBalance, + selectSupportsBalance, + selectTipsBalance, selectTransactionsById, selectSupportsByOutpoint, selectTotalSupports, diff --git a/src/lbry.js b/src/lbry.js index f776871..dfdbbf2 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -93,7 +93,7 @@ const Lbry: LbryTypes = { blob_list: (params = {}) => daemonCallWithResult('blob_list', params), // Wallet utilities - account_balance: () => daemonCallWithResult('account_balance'), + account_balance: (params = {}) => daemonCallWithResult('account_balance', params), account_decrypt: () => daemonCallWithResult('account_decrypt', {}), account_encrypt: (params = {}) => daemonCallWithResult('account_encrypt', params), account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 1e8d05b..18a40b7 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -8,40 +8,22 @@ import { selectMyClaimsRaw } from 'redux/selectors/claims'; export function doUpdateBalance() { return (dispatch, getState) => { const { - wallet: { balance: balanceInStore }, + wallet: { total: totalInStore }, } = getState(); - Lbry.account_balance().then(response => { - const { available } = response; - const balance = parseFloat(available); - if (balanceInStore !== balance) { + Lbry.account_balance({reserved_subtotals: true}).then((response: BalanceResponse) => { + const { available, reserved, reserved_subtotals, total } = response; + const { claims, supports, tips } = reserved_subtotals; + const totalFloat = parseFloat(total); + if (totalInStore !== totalFloat) { dispatch({ type: ACTIONS.UPDATE_BALANCE, data: { - balance, - }, - }); - } - }); - }; -} - -export function doUpdateTotalBalance() { - return (dispatch, getState) => { - const { - wallet: { totalBalance: totalBalanceInStore }, - } = getState(); - Lbry.account_list().then(accountList => { - const { lbc_mainnet: accounts } = accountList; - const totalSatoshis = - accounts.length === 1 - ? accounts[0].satoshis - : accounts.reduce((a, b) => a.satoshis + b.satoshis); - const totalBalance = (Number.isNaN(totalSatoshis) ? 0 : totalSatoshis) / 10 ** 8; - if (totalBalanceInStore !== totalBalance) { - dispatch({ - type: ACTIONS.UPDATE_TOTAL_BALANCE, - data: { - totalBalance, + totalBalance: totalFloat, + balance: parseFloat(available), + reservedBalance: parseFloat(reserved), + claimsBalance: parseFloat(claims), + supportsBalance: parseFloat(supports), + tipsBalance: parseFloat(tips), }, }); } @@ -56,13 +38,6 @@ export function doBalanceSubscribe() { }; } -export function doTotalBalanceSubscribe() { - return dispatch => { - dispatch(doUpdateTotalBalance()); - setInterval(() => dispatch(doUpdateTotalBalance()), 5000); - }; -} - export function doFetchTransactions() { return dispatch => { dispatch(doFetchSupports()); diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index 9d6762d..2be54ff 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -16,6 +16,11 @@ type ActionResult = { type WalletState = { balance: any, + totalBalance: any, + reservedBalance: any, + claimsBalance: any, + supportsBalance: any, + tipsBalance: any, latestBlock: ?number, transactions: { [string]: Transaction }, supports: { [string]: Support }, @@ -42,6 +47,10 @@ type WalletState = { const defaultState = { balance: undefined, totalBalance: undefined, + reservedBalance: undefined, + claimsBalance: undefined, + supportsBalance: undefined, + tipsBalance: undefined, latestBlock: undefined, transactions: {}, fetchingTransactions: false, @@ -145,13 +154,13 @@ export const walletReducer = handleActions( }, [ACTIONS.UPDATE_BALANCE]: (state: WalletState, action) => ({ - ...state, - balance: action.data.balance, - }), - - [ACTIONS.UPDATE_TOTAL_BALANCE]: (state: WalletState, action) => ({ ...state, totalBalance: action.data.totalBalance, + balance: action.data.balance, + reservedBalance: action.data.reservedBalance, + claimsBalance: action.data.claimsBalance, + supportsBalance: action.data.supportsBalance, + tipsBalance: action.data.tipsBalance, }), [ACTIONS.CHECK_ADDRESS_IS_MINE_STARTED]: (state: WalletState) => ({ diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 6ca8b77..4deab20 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -80,6 +80,26 @@ export const selectTotalBalance = createSelector( state => state.totalBalance ); +export const selectReservedBalance = createSelector( + selectState, + state => state.reservedBalance +); + +export const selectClaimsBalance = createSelector( + selectState, + state => state.claimsBalance +); + +export const selectSupportsBalance = createSelector( + selectState, + state => state.supportsBalance +); + +export const selectTipsBalance = createSelector( + selectState, + state => state.tipsBalance +); + export const selectTransactionsById = createSelector( selectState, state => state.transactions || {} -- 2.45.2 From fe4ae1568e1f2ad890334bcc34df5ba2ebcfab35 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Wed, 25 Sep 2019 01:37:02 -0400 Subject: [PATCH 147/371] fix: totalBalance whoops! --- dist/bundle.es.js | 2 +- src/redux/actions/wallet.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 141d1b3..f2f4831 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1887,7 +1887,7 @@ function creditsToString(amount) { function doUpdateBalance() { return (dispatch, getState) => { const { - wallet: { total: totalInStore } + wallet: { totalBalance: totalInStore } } = getState(); lbryProxy.account_balance({ reserved_subtotals: true }).then(response => { const { available, reserved, reserved_subtotals, total } = response; diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 18a40b7..7ae4855 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -8,7 +8,7 @@ import { selectMyClaimsRaw } from 'redux/selectors/claims'; export function doUpdateBalance() { return (dispatch, getState) => { const { - wallet: { total: totalInStore }, + wallet: { totalBalance: totalInStore }, } = getState(); Lbry.account_balance({reserved_subtotals: true}).then((response: BalanceResponse) => { const { available, reserved, reserved_subtotals, total } = response; -- 2.45.2 From 66462144b2daad690abf607e698807e9520c3024 Mon Sep 17 00:00:00 2001 From: jessop Date: Sun, 22 Sep 2019 22:25:12 -0400 Subject: [PATCH 148/371] transaction pagination selectors --- dist/bundle.es.js | 19 +++++++++++++++++++ src/index.js | 3 +++ src/redux/selectors/wallet.js | 31 +++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f2f4831..d52b81e 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1283,6 +1283,8 @@ function doDismissError() { }; } +// + const selectState$1 = state => state.wallet || {}; const selectWalletState = selectState$1; @@ -1441,6 +1443,20 @@ const selectCurrentHeight = reselect.createSelector(selectState$1, state => stat const selectTransactionListFilter = reselect.createSelector(selectState$1, state => state.transactionListFilter || ''); +const selectFilteredTransactions = reselect.createSelector(selectTransactionItems, selectTransactionListFilter, (transactions, filter) => { + return transactions.filter(transaction => { + return filter === ALL || filter === transaction.type; + }); +}); + +const makeSelectFilteredTransactionsForPage = (page = 1) => reselect.createSelector(selectFilteredTransactions, filteredTransactions => { + const start = (Number(page) - 1) * Number(PAGE_SIZE); + const end = Number(page) * Number(PAGE_SIZE); + return filteredTransactions && filteredTransactions.length ? filteredTransactions.slice(start, end) : []; +}); + +const selectFilteredTransactionCount = reselect.createSelector(selectFilteredTransactions, filteredTransactions => filteredTransactions.length); + 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$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; } @@ -5064,6 +5080,7 @@ exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; exports.makeSelectFileNameForUri = makeSelectFileNameForUri; exports.makeSelectFilePartlyDownloaded = makeSelectFilePartlyDownloaded; +exports.makeSelectFilteredTransactionsForPage = makeSelectFilteredTransactionsForPage; exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileForUri; exports.makeSelectIsFollowingTag = makeSelectIsFollowingTag; exports.makeSelectIsUriResolving = makeSelectIsUriResolving; @@ -5132,6 +5149,8 @@ exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; exports.selectFileListDownloadedSort = selectFileListDownloadedSort; exports.selectFileListPublishedSort = selectFileListPublishedSort; +exports.selectFilteredTransactionCount = selectFilteredTransactionCount; +exports.selectFilteredTransactions = selectFilteredTransactions; exports.selectFollowedTags = selectFollowedTags; exports.selectGettingNewAddress = selectGettingNewAddress; exports.selectHasTransactions = selectHasTransactions; diff --git a/src/index.js b/src/index.js index ce4c00a..22370ec 100644 --- a/src/index.js +++ b/src/index.js @@ -287,6 +287,9 @@ export { selectWalletUnlockSucceeded, selectWalletUnlockResult, selectTransactionListFilter, + selectFilteredTransactions, + makeSelectFilteredTransactionsForPage, + selectFilteredTransactionCount, } from 'redux/selectors/wallet'; export { diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 4deab20..22e887d 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -1,5 +1,8 @@ +// @flow + import { createSelector } from 'reselect'; import * as TRANSACTIONS from 'constants/transaction_types'; +import { PAGE_SIZE } from 'constants/claim'; export const selectState = state => state.wallet || {}; @@ -214,6 +217,8 @@ export const selectTransactionItems = createSelector( } ); + + export const selectRecentTransactions = createSelector( selectTransactionItems, transactions => { @@ -288,3 +293,29 @@ export const selectTransactionListFilter = createSelector( selectState, state => state.transactionListFilter || '' ); + +export const selectFilteredTransactions = createSelector( + selectTransactionItems, + selectTransactionListFilter, + (transactions, filter) => { + return transactions.filter(transaction => { + return filter === TRANSACTIONS.ALL || filter === transaction.type; + }); + }); + +export const makeSelectFilteredTransactionsForPage = (page: number = 1): Array => + createSelector( + selectFilteredTransactions, + filteredTransactions => { + const start = (Number(page) - 1) * Number(PAGE_SIZE); + const end = (Number(page) * Number(PAGE_SIZE)); + return (filteredTransactions && filteredTransactions.length) + ? filteredTransactions.slice(start, end) + : []; + } + ); + +export const selectFilteredTransactionCount = createSelector( + selectFilteredTransactions, + filteredTransactions => filteredTransactions.length +); -- 2.45.2 From f02c6b7a2719ceead03f1c45b4bbf26b2069a20e Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 25 Sep 2019 12:30:26 -0400 Subject: [PATCH 149/371] tx page size cleanup --- dist/bundle.es.js | 12 ++++++++++-- src/constants/transaction_list.js | 2 ++ src/index.js | 2 ++ src/redux/selectors/wallet.js | 4 +--- 4 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 src/constants/transaction_list.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d52b81e..ba1f354 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -643,6 +643,13 @@ var transaction_types = /*#__PURE__*/Object.freeze({ ABANDON: ABANDON }); +// PAGE SIZE +const PAGE_SIZE$1 = 50; + +var transaction_list = /*#__PURE__*/Object.freeze({ + PAGE_SIZE: PAGE_SIZE$1 +}); + const SEARCH_TYPES = { FILE: 'file', CHANNEL: 'channel', @@ -1450,8 +1457,8 @@ const selectFilteredTransactions = reselect.createSelector(selectTransactionItem }); const makeSelectFilteredTransactionsForPage = (page = 1) => reselect.createSelector(selectFilteredTransactions, filteredTransactions => { - const start = (Number(page) - 1) * Number(PAGE_SIZE); - const end = Number(page) * Number(PAGE_SIZE); + const start = (Number(page) - 1) * Number(PAGE_SIZE$1); + const end = Number(page) * Number(PAGE_SIZE$1); return filteredTransactions && filteredTransactions.length ? filteredTransactions.slice(start, end) : []; }); @@ -4988,6 +4995,7 @@ exports.SETTINGS = settings; exports.SORT_OPTIONS = sort_options; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; +exports.TX_LIST = transaction_list; exports.batchActions = batchActions; exports.blockedReducer = blockedReducer; exports.buildURI = buildURI; diff --git a/src/constants/transaction_list.js b/src/constants/transaction_list.js new file mode 100644 index 0000000..c609b05 --- /dev/null +++ b/src/constants/transaction_list.js @@ -0,0 +1,2 @@ +// PAGE SIZE +export const PAGE_SIZE = 50; diff --git a/src/index.js b/src/index.js index 22370ec..e7f118a 100644 --- a/src/index.js +++ b/src/index.js @@ -6,6 +6,7 @@ import * as SETTINGS from 'constants/settings'; import * as SORT_OPTIONS from 'constants/sort_options'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as TRANSACTIONS from 'constants/transaction_types'; +import * as TX_LIST from 'constants/transaction_list'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS } from 'constants/tags'; import Lbry from 'lbry'; @@ -21,6 +22,7 @@ export { SEARCH_OPTIONS, SETTINGS, TRANSACTIONS, + TX_LIST, SORT_OPTIONS, PAGES, DEFAULT_KNOWN_TAGS, diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 22e887d..05074f3 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -2,7 +2,7 @@ import { createSelector } from 'reselect'; import * as TRANSACTIONS from 'constants/transaction_types'; -import { PAGE_SIZE } from 'constants/claim'; +import { PAGE_SIZE } from 'constants/transaction_list'; export const selectState = state => state.wallet || {}; @@ -217,8 +217,6 @@ export const selectTransactionItems = createSelector( } ); - - export const selectRecentTransactions = createSelector( selectTransactionItems, transactions => { -- 2.45.2 From 2cdc43b271d828d917a81d31f701ea3214be41cd Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 23 Sep 2019 13:00:12 -0400 Subject: [PATCH 150/371] selectors for library and download pagination --- dist/bundle.es.js | 21 ++++++++++++++++++++- src/index.js | 4 ++++ src/redux/selectors/claims.js | 19 ++++++++++++++++++- src/redux/selectors/file_info.js | 18 ++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f2f4831..798a3b2 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1494,7 +1494,6 @@ function concatClaims(claimList = [], concatClaimList = []) { } // - const selectState$2 = state => state.claims || {}; const selectClaimsById = reselect.createSelector(selectState$2, state => state.byId || {}); @@ -1843,6 +1842,14 @@ const selectUpdatingChannel = reselect.createSelector(selectState$2, state => st const selectUpdateChannelError = reselect.createSelector(selectState$2, state => state.updateChannelError); +const makeSelectMyStreamUrisForPage = (page = 0) => reselect.createSelector(selectMyClaimUrisWithoutChannels, uris => { + const start = Number(page) * Number(PAGE_SIZE); + const end = (Number(page) + 1) * Number(PAGE_SIZE); + return uris && uris.length ? uris.slice(start, end) : []; +}); + +const selectMyStreamUrisCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); + function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount), suffix = ''; @@ -2707,6 +2714,14 @@ const makeSelectFileNameForUri = uri => reselect.createSelector(makeSelectFileIn return fileInfo && fileInfo.file_name; }); +const makeSelectDownloadUrisForPage = (page = 0) => reselect.createSelector(selectDownloadedUris, uris => { + const start = Number(page) * Number(PAGE_SIZE); + const end = (Number(page) + 1) * Number(PAGE_SIZE); + return uris && uris.length ? uris.slice(start, end) : []; +}); + +const selectDownloadUrisCount = reselect.createSelector(selectDownloadedUris, uris => uris.length); + // const selectState$4 = state => state.file || {}; @@ -5059,6 +5074,7 @@ exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; exports.makeSelectCoverForUri = makeSelectCoverForUri; exports.makeSelectDateForUri = makeSelectDateForUri; exports.makeSelectDownloadPathForUri = makeSelectDownloadPathForUri; +exports.makeSelectDownloadUrisForPage = makeSelectDownloadUrisForPage; exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; @@ -5071,6 +5087,7 @@ exports.makeSelectLoadingForUri = makeSelectLoadingForUri; exports.makeSelectMediaTypeForUri = makeSelectMediaTypeForUri; exports.makeSelectMetadataForUri = makeSelectMetadataForUri; exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri; +exports.makeSelectMyStreamUrisForPage = makeSelectMyStreamUrisForPage; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectPendingByUri = makeSelectPendingByUri; @@ -5116,6 +5133,7 @@ exports.selectClaimsByUri = selectClaimsByUri; exports.selectCreateChannelError = selectCreateChannelError; exports.selectCreatingChannel = selectCreatingChannel; exports.selectCurrentChannelPage = selectCurrentChannelPage; +exports.selectDownloadUrisCount = selectDownloadUrisCount; exports.selectDownloadedUris = selectDownloadedUris; exports.selectDownloadingByOutpoint = selectDownloadingByOutpoint; exports.selectDownloadingFileInfos = selectDownloadingFileInfos; @@ -5152,6 +5170,7 @@ exports.selectMyClaims = selectMyClaims; exports.selectMyClaimsOutpoints = selectMyClaimsOutpoints; exports.selectMyClaimsRaw = selectMyClaimsRaw; exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; +exports.selectMyStreamUrisCount = selectMyStreamUrisCount; exports.selectPendingById = selectPendingById; exports.selectPendingClaims = selectPendingClaims; exports.selectPlayingUri = selectPlayingUri; diff --git a/src/index.js b/src/index.js index ce4c00a..290d53c 100644 --- a/src/index.js +++ b/src/index.js @@ -206,6 +206,8 @@ export { selectCreatingChannel, selectCreateChannelError, selectChannelImportPending, + makeSelectMyStreamUrisForPage, + selectMyStreamUrisCount, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; @@ -230,6 +232,8 @@ export { makeSelectDownloadPathForUri, makeSelectFileNameForUri, makeSelectFilePartlyDownloaded, + makeSelectDownloadUrisForPage, + selectDownloadUrisCount, } from 'redux/selectors/file_info'; export { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 723f8d3..23785df 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -5,7 +5,7 @@ import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { createSelector } from 'reselect'; import { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; import { getSearchQueryString } from 'util/query-params'; - +import { PAGE_SIZE } from 'constants/claim'; const selectState = state => state.claims || {}; export const selectClaimsById = createSelector( @@ -591,3 +591,20 @@ export const selectUpdateChannelError = createSelector( selectState, state => state.updateChannelError ); + +export const makeSelectMyStreamUrisForPage = (page: number = 0) => + createSelector( + selectMyClaimUrisWithoutChannels, + uris => { + const start = (Number(page) * Number(PAGE_SIZE)); + const end = ((Number(page) + 1) * Number(PAGE_SIZE)); + return (uris && uris.length) + ? uris.slice(start, end) + : []; + } + ); + +export const selectMyStreamUrisCount = createSelector( + selectMyClaimUrisWithoutChannels, + channels => channels.length +); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index d805eff..f9d209f 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -9,6 +9,7 @@ import { import { createSelector } from 'reselect'; import { buildURI } from 'lbryURI'; import Lbry from 'lbry'; +import { PAGE_SIZE } from 'constants/claim'; export const selectState = state => state.fileInfo || {}; @@ -202,3 +203,20 @@ export const makeSelectFileNameForUri = uri => return fileInfo && fileInfo.file_name; } ); + +export const makeSelectDownloadUrisForPage = (page = 0) => + createSelector( + selectDownloadedUris, + uris => { + const start = (Number(page) * Number(PAGE_SIZE)); + const end = ((Number(page) + 1) * Number(PAGE_SIZE)); + return (uris && uris.length) + ? uris.slice(start, end) + : []; + } + ); + +export const selectDownloadUrisCount = createSelector( + selectDownloadedUris, + uris => uris.length +); -- 2.45.2 From 41d10218337e6d21fd0473d451ce8fc1337afbbe Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 25 Sep 2019 17:16:27 -0400 Subject: [PATCH 151/371] off by 1 modifications --- dist/bundle.es.js | 12 ++++++------ src/redux/selectors/claims.js | 6 +++--- src/redux/selectors/file_info.js | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 798a3b2..31792c8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1842,9 +1842,9 @@ const selectUpdatingChannel = reselect.createSelector(selectState$2, state => st const selectUpdateChannelError = reselect.createSelector(selectState$2, state => state.updateChannelError); -const makeSelectMyStreamUrisForPage = (page = 0) => reselect.createSelector(selectMyClaimUrisWithoutChannels, uris => { - const start = Number(page) * Number(PAGE_SIZE); - const end = (Number(page) + 1) * Number(PAGE_SIZE); +const makeSelectMyStreamUrisForPage = (page = 1) => reselect.createSelector(selectMyClaimUrisWithoutChannels, uris => { + const start = (Number(page) - 1) * Number(PAGE_SIZE); + const end = Number(page) * Number(PAGE_SIZE); return uris && uris.length ? uris.slice(start, end) : []; }); @@ -2714,9 +2714,9 @@ const makeSelectFileNameForUri = uri => reselect.createSelector(makeSelectFileIn return fileInfo && fileInfo.file_name; }); -const makeSelectDownloadUrisForPage = (page = 0) => reselect.createSelector(selectDownloadedUris, uris => { - const start = Number(page) * Number(PAGE_SIZE); - const end = (Number(page) + 1) * Number(PAGE_SIZE); +const makeSelectDownloadUrisForPage = (page = 1) => reselect.createSelector(selectDownloadedUris, uris => { + const start = (Number(page) - 1) * Number(PAGE_SIZE); + const end = Number(page) * Number(PAGE_SIZE); return uris && uris.length ? uris.slice(start, end) : []; }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 23785df..eb9757a 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -592,12 +592,12 @@ export const selectUpdateChannelError = createSelector( state => state.updateChannelError ); -export const makeSelectMyStreamUrisForPage = (page: number = 0) => +export const makeSelectMyStreamUrisForPage = (page: number = 1) => createSelector( selectMyClaimUrisWithoutChannels, uris => { - const start = (Number(page) * Number(PAGE_SIZE)); - const end = ((Number(page) + 1) * Number(PAGE_SIZE)); + const start = ((Number(page) - 1) * Number(PAGE_SIZE)); + const end = (Number(page) * Number(PAGE_SIZE)); return (uris && uris.length) ? uris.slice(start, end) : []; diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index f9d209f..484b3fd 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -204,12 +204,12 @@ export const makeSelectFileNameForUri = uri => } ); -export const makeSelectDownloadUrisForPage = (page = 0) => +export const makeSelectDownloadUrisForPage = (page = 1) => createSelector( selectDownloadedUris, uris => { - const start = (Number(page) * Number(PAGE_SIZE)); - const end = ((Number(page) + 1) * Number(PAGE_SIZE)); + const start = ((Number(page) - 1) * Number(PAGE_SIZE)); + const end = (Number(page) * Number(PAGE_SIZE)); return (uris && uris.length) ? uris.slice(start, end) : []; -- 2.45.2 From 64383d57873ce59dea9df7216ee6cf52c4e95dc6 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 25 Sep 2019 17:37:21 -0400 Subject: [PATCH 152/371] uri to url --- dist/bundle.es.js | 20 ++++++++++---------- src/index.js | 8 ++++---- src/redux/selectors/claims.js | 10 +++++----- src/redux/selectors/file_info.js | 10 +++++----- 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 31792c8..5350c64 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1842,13 +1842,13 @@ const selectUpdatingChannel = reselect.createSelector(selectState$2, state => st const selectUpdateChannelError = reselect.createSelector(selectState$2, state => state.updateChannelError); -const makeSelectMyStreamUrisForPage = (page = 1) => reselect.createSelector(selectMyClaimUrisWithoutChannels, uris => { +const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(selectMyClaimUrisWithoutChannels, urls => { const start = (Number(page) - 1) * Number(PAGE_SIZE); const end = Number(page) * Number(PAGE_SIZE); - return uris && uris.length ? uris.slice(start, end) : []; + return urls && urls.length ? urls.slice(start, end) : []; }); -const selectMyStreamUrisCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); +const selectMyStreamUrlsCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount), @@ -2714,13 +2714,13 @@ const makeSelectFileNameForUri = uri => reselect.createSelector(makeSelectFileIn return fileInfo && fileInfo.file_name; }); -const makeSelectDownloadUrisForPage = (page = 1) => reselect.createSelector(selectDownloadedUris, uris => { +const makeSelectDownloadUrlsForPage = (page = 1) => reselect.createSelector(selectDownloadedUris, urls => { const start = (Number(page) - 1) * Number(PAGE_SIZE); const end = Number(page) * Number(PAGE_SIZE); - return uris && uris.length ? uris.slice(start, end) : []; + return urls && urls.length ? urls.slice(start, end) : []; }); -const selectDownloadUrisCount = reselect.createSelector(selectDownloadedUris, uris => uris.length); +const selectDownloadUrlsCount = reselect.createSelector(selectDownloadedUris, uris => uris.length); // @@ -5074,7 +5074,7 @@ exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; exports.makeSelectCoverForUri = makeSelectCoverForUri; exports.makeSelectDateForUri = makeSelectDateForUri; exports.makeSelectDownloadPathForUri = makeSelectDownloadPathForUri; -exports.makeSelectDownloadUrisForPage = makeSelectDownloadUrisForPage; +exports.makeSelectDownloadUrlsForPage = makeSelectDownloadUrlsForPage; exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; @@ -5087,7 +5087,7 @@ exports.makeSelectLoadingForUri = makeSelectLoadingForUri; exports.makeSelectMediaTypeForUri = makeSelectMediaTypeForUri; exports.makeSelectMetadataForUri = makeSelectMetadataForUri; exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri; -exports.makeSelectMyStreamUrisForPage = makeSelectMyStreamUrisForPage; +exports.makeSelectMyStreamUrlsForPage = makeSelectMyStreamUrlsForPage; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectPendingByUri = makeSelectPendingByUri; @@ -5133,7 +5133,7 @@ exports.selectClaimsByUri = selectClaimsByUri; exports.selectCreateChannelError = selectCreateChannelError; exports.selectCreatingChannel = selectCreatingChannel; exports.selectCurrentChannelPage = selectCurrentChannelPage; -exports.selectDownloadUrisCount = selectDownloadUrisCount; +exports.selectDownloadUrlsCount = selectDownloadUrlsCount; exports.selectDownloadedUris = selectDownloadedUris; exports.selectDownloadingByOutpoint = selectDownloadingByOutpoint; exports.selectDownloadingFileInfos = selectDownloadingFileInfos; @@ -5170,7 +5170,7 @@ exports.selectMyClaims = selectMyClaims; exports.selectMyClaimsOutpoints = selectMyClaimsOutpoints; exports.selectMyClaimsRaw = selectMyClaimsRaw; exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; -exports.selectMyStreamUrisCount = selectMyStreamUrisCount; +exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount; exports.selectPendingById = selectPendingById; exports.selectPendingClaims = selectPendingClaims; exports.selectPlayingUri = selectPlayingUri; diff --git a/src/index.js b/src/index.js index 290d53c..94dc1b8 100644 --- a/src/index.js +++ b/src/index.js @@ -206,8 +206,8 @@ export { selectCreatingChannel, selectCreateChannelError, selectChannelImportPending, - makeSelectMyStreamUrisForPage, - selectMyStreamUrisCount, + makeSelectMyStreamUrlsForPage, + selectMyStreamUrlsCount, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; @@ -232,8 +232,8 @@ export { makeSelectDownloadPathForUri, makeSelectFileNameForUri, makeSelectFilePartlyDownloaded, - makeSelectDownloadUrisForPage, - selectDownloadUrisCount, + makeSelectDownloadUrlsForPage, + selectDownloadUrlsCount, } from 'redux/selectors/file_info'; export { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index eb9757a..bc67fe1 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -592,19 +592,19 @@ export const selectUpdateChannelError = createSelector( state => state.updateChannelError ); -export const makeSelectMyStreamUrisForPage = (page: number = 1) => +export const makeSelectMyStreamUrlsForPage = (page: number = 1) => createSelector( selectMyClaimUrisWithoutChannels, - uris => { + urls => { const start = ((Number(page) - 1) * Number(PAGE_SIZE)); const end = (Number(page) * Number(PAGE_SIZE)); - return (uris && uris.length) - ? uris.slice(start, end) + return (urls && urls.length) + ? urls.slice(start, end) : []; } ); -export const selectMyStreamUrisCount = createSelector( +export const selectMyStreamUrlsCount = createSelector( selectMyClaimUrisWithoutChannels, channels => channels.length ); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 484b3fd..195150a 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -204,19 +204,19 @@ export const makeSelectFileNameForUri = uri => } ); -export const makeSelectDownloadUrisForPage = (page = 1) => +export const makeSelectDownloadUrlsForPage = (page = 1) => createSelector( selectDownloadedUris, - uris => { + urls => { const start = ((Number(page) - 1) * Number(PAGE_SIZE)); const end = (Number(page) * Number(PAGE_SIZE)); - return (uris && uris.length) - ? uris.slice(start, end) + return (urls && urls.length) + ? urls.slice(start, end) : []; } ); -export const selectDownloadUrisCount = createSelector( +export const selectDownloadUrlsCount = createSelector( selectDownloadedUris, uris => uris.length ); -- 2.45.2 From 7ec72a737bcd336f000c5f5085891643110298c3 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Thu, 26 Sep 2019 23:56:55 +0100 Subject: [PATCH 153/371] add check before calling find --- dist/bundle.es.js | 2 +- src/redux/actions/publish.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2e5712a..b5fd08d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3204,7 +3204,7 @@ const doPublish = (success, fail) => (dispatch, getState) => { } // get the claim id from the channel name, we will use that instead - const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); + const namedChannelClaim = myChannels ? myChannels.find(myChannel => myChannel.name === channel) : null; const channelId = namedChannelClaim ? namedChannelClaim.claim_id : ''; const publishPayload = { diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 72232b6..fde7503 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -275,7 +275,7 @@ export const doPublish = (success: Function, fail: Function) => ( } // get the claim id from the channel name, we will use that instead - const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); + const namedChannelClaim = myChannels ? myChannels.find(myChannel => myChannel.name === channel) : null; const channelId = namedChannelClaim ? namedChannelClaim.claim_id : ''; const publishPayload: { -- 2.45.2 From 23bcde0539a27fb19bf3a7d87683279194e02046 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 30 Sep 2019 22:52:41 +0100 Subject: [PATCH 154/371] shared user state with preferences_get and preferences_set --- dist/bundle.es.js | 59 +++++++++++++++++++ dist/flow-typed/Lbry.js | 4 ++ flow-typed/Lbry.js | 4 ++ src/index.js | 7 ++- src/lbry.js | 4 ++ src/redux/actions/sync.js | 60 +++++++++++++++++++ src/util/deep-equal.js | 117 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 src/util/deep-equal.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 65b2192..d3b93dc 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -7,6 +7,7 @@ function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'defau require('proxy-polyfill'); var reselect = require('reselect'); var uuid = _interopDefault(require('uuid/v4')); +var isEqual = _interopDefault(require('utils/deep-equal')); const MINIMUM_PUBLISH_BID = 0.00000001; @@ -778,6 +779,10 @@ const Lbry = { sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), + // Preferences + preference_get: (params = {}) => daemonCallWithResult('preference_get', params), + preference_set: (params = {}) => daemonCallWithResult('preference_set', params), + // Comments comment_list: (params = {}) => daemonCallWithResult('comment_list', params), comment_create: (params = {}) => daemonCallWithResult('comment_create', params), @@ -3646,6 +3651,57 @@ function doPopulateSharedUserState(settings) { }; } +function sharedStateSubscriber(state, filters, localCache, accountId, walletId) { + Object.keys(filters).forEach(key => { + const filter = filters[key]; + const { source, property, transform } = filter; + let value = state[source][property]; + if (transform) { + value = transform(value); + } + + let cacheKey = key; + if (accountId) { + cacheKey = `${cacheKey}_${accountId}`; + } + if (walletId) { + cacheKey = `${cacheKey}_${walletId}`; + } + + if (!isEqual(localCache[cacheKey], value)) { + // only update if the preference changed from last call in the same session + doPreferenceSet(key, value, accountId, walletId); + } + }); +} + +function doPreferenceSet(key, value, accountId, walletId, success, fail) { + const preference = { + type: typeof value, + value + }; + + lbryProxy.preference_set({ key, value: JSON.stringify(preference), account_id: accountId, wallet_id: walletId }).then(() => { + success(value); + }).catch(() => { + if (fail) { + fail(); + } + }); +} + +function doPreferenceGet(key, accountId, walletId, success, fail) { + lbryProxy.preference_get({ key, account_id: accountId, wallet_id: walletId }).then(result => { + const preference = JSON.parse(result); + const { value } = normalized; + success(value); + }).catch(() => { + if (fail) { + fail(); + } + }); +} + var _extends$6 = 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; }; const reducers = {}; @@ -5048,6 +5104,8 @@ exports.doFocusSearchInput = doFocusSearchInput; exports.doGetNewAddress = doGetNewAddress; exports.doImportChannel = doImportChannel; exports.doPopulateSharedUserState = doPopulateSharedUserState; +exports.doPreferenceGet = doPreferenceGet; +exports.doPreferenceSet = doPreferenceSet; exports.doPrepareEdit = doPrepareEdit; exports.doPublish = doPublish; exports.doPurchaseUri = doPurchaseUri; @@ -5241,6 +5299,7 @@ exports.selectWalletUnlockPending = selectWalletUnlockPending; exports.selectWalletUnlockResult = selectWalletUnlockResult; exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded; exports.setSearchApi = setSearchApi; +exports.sharedStateSubscriber = sharedStateSubscriber; exports.tagsReducer = tagsReducer; exports.toQueryString = toQueryString; exports.walletReducer = walletReducer; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 9bbde01..86691bc 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -202,6 +202,10 @@ declare type LbryTypes = { blob_delete: (params: {}) => Promise, blob_list: (params: {}) => Promise, + // Preferences + preference_get: (params: {}) => Promise, + preference_set: (params: {}) => Promise, + // Commenting comment_list: (params: {}) => Promise, comment_create: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 9bbde01..86691bc 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -202,6 +202,10 @@ declare type LbryTypes = { blob_delete: (params: {}) => Promise, blob_list: (params: {}) => Promise, + // Preferences + preference_get: (params: {}) => Promise, + preference_set: (params: {}) => Promise, + // Commenting comment_list: (params: {}) => Promise, comment_create: (params: {}) => Promise, diff --git a/src/index.js b/src/index.js index ced22a0..650da90 100644 --- a/src/index.js +++ b/src/index.js @@ -114,7 +114,12 @@ export { doCommentList, doCommentCreate } from 'redux/actions/comments'; export { doToggleBlockChannel } from 'redux/actions/blocked'; -export { doPopulateSharedUserState } from 'redux/actions/sync'; +export { + doPopulateSharedUserState, + doPreferenceGet, + doPreferenceSet, + sharedStateSubscriber +} from 'redux/actions/sync'; // utils export { batchActions } from 'util/batch-actions'; diff --git a/src/lbry.js b/src/lbry.js index dfdbbf2..36db557 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -110,6 +110,10 @@ const Lbry: LbryTypes = { sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), + // Preferences + preference_get: (params = {}) => daemonCallWithResult('preference_get', params), + preference_set: (params = {}) => daemonCallWithResult('preference_set', params), + // Comments comment_list: (params = {}) => daemonCallWithResult('comment_list', params), comment_create: (params = {}) => daemonCallWithResult('comment_create', params), diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index ffcf2e7..6528f95 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -1,5 +1,7 @@ // @flow import * as ACTIONS from 'constants/action_types'; +import Lbry from 'lbry'; +import isEqual from 'util/deep-equal'; type v0Data = { version: '0.1', @@ -28,3 +30,61 @@ export function doPopulateSharedUserState(settings: any) { dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags } }); }; } + +export function sharedStateSubscriber( + state: any, + filters: any, + localCache: any, + accountId: string, + walletId: string) +{ + Object.keys(filters).forEach(key => { + const filter = filters[key]; + const { source, property, transform } = filter; + let value = state[source][property]; + if (transform) { + value = transform(value); + } + + let cacheKey = key; + if (accountId) { + cacheKey = `${cacheKey}_${accountId}`; + } + if (walletId) { + cacheKey = `${cacheKey}_${walletId}`; + } + + if (!isEqual(localCache[cacheKey], value)) { + // only update if the preference changed from last call in the same session + doPreferenceSet(key, value, accountId, walletId); + } + }); +} + +export function doPreferenceSet(key: string, value: any, accountId: string, walletId: string, success: Function, fail: Function) { + const preference = { + type: (typeof value), + value + }; + + Lbry.preference_set({ key, value: JSON.stringify(preference), account_id: accountId, wallet_id: walletId }).then(() => { + success(value); + }).catch(() => { + if (fail) { fail(); } + }); +} + +export function doPreferenceGet(key: string, accountId: string, walletId: string, success: Function, fail: Function) { + Lbry.preference_get({ key, account_id: accountId, wallet_id: walletId }).then(result => { + if (result) { + const preference = JSON.parse(result); + const { value } = preference; + return success(value); + } + + // Or fail instead? + return success(null); + }).catch(() => { + if (fail) { fail(); } + }); +} diff --git a/src/util/deep-equal.js b/src/util/deep-equal.js new file mode 100644 index 0000000..1925763 --- /dev/null +++ b/src/util/deep-equal.js @@ -0,0 +1,117 @@ +/* eslint-disable */ +// underscore's deep equal function +// https://github.com/jashkenas/underscore/blob/master/underscore.js#L1189 + +export default function isEqual(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // `null` or `undefined` only equal to itself (strict comparison). + if (a == null || b == null) return false; + // `NaN`s are equivalent, but non-reflexive. + if (a !== a) return b !== b; + // Exhaust primitive checks + var type = typeof a; + if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; + return deepEq(a, b, aStack, bStack); +} + +function deepEq(a, b, aStack, bStack) { + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN. + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + case '[object Symbol]': + return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, + bCtor = b.constructor; + if ( + aCtor !== bCtor && + !( + typeof aCtor === 'function' && + aCtor instanceof aCtor && + typeof bCtor === 'function' && + bCtor instanceof bCtor + ) && + ('constructor' in a && 'constructor' in b) + ) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!isEqual(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = Object.keys(a), + key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (Object.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(has(b, key) && isEqual(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; +} + +function has(obj, path) { + return obj != null && hasOwnProperty.call(obj, path); +} +/* eslint-enable */ -- 2.45.2 From f2d46c359a7e02492b7bd60c3e4e0d236161f65d Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 1 Oct 2019 15:49:38 +0100 Subject: [PATCH 155/371] remove localCache argument. add version argument. --- dist/bundle.es.js | 130 ++++++++++++++++++++++++++++++++++++-- src/redux/actions/sync.js | 33 +++++++--- 2 files changed, 148 insertions(+), 15 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d3b93dc..8625e4b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -7,7 +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 isEqual = _interopDefault(require('utils/deep-equal')); const MINIMUM_PUBLISH_BID = 0.00000001; @@ -3632,8 +3631,119 @@ const doToggleBlockChannel = uri => ({ } }); +/* eslint-disable */ +// underscore's deep equal function +// https://github.com/jashkenas/underscore/blob/master/underscore.js#L1189 + +function isEqual(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // `null` or `undefined` only equal to itself (strict comparison). + if (a == null || b == null) return false; + // `NaN`s are equivalent, but non-reflexive. + if (a !== a) return b !== b; + // Exhaust primitive checks + var type = typeof a; + if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; + return deepEq(a, b, aStack, bStack); +} + +function deepEq(a, b, aStack, bStack) { + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN. + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + case '[object Symbol]': + return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, + bCtor = b.constructor; + if (aCtor !== bCtor && !(typeof aCtor === 'function' && aCtor instanceof aCtor && typeof bCtor === 'function' && bCtor instanceof bCtor) && 'constructor' in a && 'constructor' in b) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!isEqual(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = Object.keys(a), + key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (Object.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(has(b, key) && isEqual(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; +} + +function has(obj, path) { + return obj != null && hasOwnProperty.call(obj, path); +} +/* eslint-enable */ + var _extends$5 = 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; }; +const stateCache = {}; + function extractUserState(rawObj) { if (rawObj && rawObj.version === '0.1' && rawObj.shared) { const { subscriptions, tags } = rawObj.shared; @@ -3651,7 +3761,7 @@ function doPopulateSharedUserState(settings) { }; } -function sharedStateSubscriber(state, filters, localCache, accountId, walletId) { +function sharedStateSubscriber(state, filters, accountId, walletId) { Object.keys(filters).forEach(key => { const filter = filters[key]; const { source, property, transform } = filter; @@ -3668,16 +3778,17 @@ function sharedStateSubscriber(state, filters, localCache, accountId, walletId) cacheKey = `${cacheKey}_${walletId}`; } - if (!isEqual(localCache[cacheKey], value)) { + if (!isEqual(stateCache[cacheKey], value)) { // only update if the preference changed from last call in the same session doPreferenceSet(key, value, accountId, walletId); } }); } -function doPreferenceSet(key, value, accountId, walletId, success, fail) { +function doPreferenceSet(key, value, version, accountId, walletId, success, fail) { const preference = { type: typeof value, + version, value }; @@ -3692,9 +3803,14 @@ function doPreferenceSet(key, value, accountId, walletId, success, fail) { function doPreferenceGet(key, accountId, walletId, success, fail) { lbryProxy.preference_get({ key, account_id: accountId, wallet_id: walletId }).then(result => { - const preference = JSON.parse(result); - const { value } = normalized; - success(value); + if (result) { + const preference = JSON.parse(result); + const { value, version } = preference; + return success(value, version); + } + + // Or fail instead? + return success(null, null); }).catch(() => { if (fail) { fail(); diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 6528f95..0a0ee62 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -11,6 +11,8 @@ type v0Data = { }, }; +const stateCache = {}; + function extractUserState(rawObj: v0Data) { if (rawObj && rawObj.version === '0.1' && rawObj.shared) { const { subscriptions, tags } = rawObj.shared; @@ -34,7 +36,7 @@ export function doPopulateSharedUserState(settings: any) { export function sharedStateSubscriber( state: any, filters: any, - localCache: any, + version: string, accountId: string, walletId: string) { @@ -54,16 +56,25 @@ export function sharedStateSubscriber( cacheKey = `${cacheKey}_${walletId}`; } - if (!isEqual(localCache[cacheKey], value)) { + if (!isEqual(stateCache[cacheKey], value)) { // only update if the preference changed from last call in the same session - doPreferenceSet(key, value, accountId, walletId); + doPreferenceSet(key, value, version, accountId, walletId); } }); } -export function doPreferenceSet(key: string, value: any, accountId: string, walletId: string, success: Function, fail: Function) { +export function doPreferenceSet( + key: string, + value: any, + version: string, + accountId: string, + walletId: string, + success: Function, + fail: Function +) { const preference = { type: (typeof value), + version, value }; @@ -74,16 +85,22 @@ export function doPreferenceSet(key: string, value: any, accountId: string, wall }); } -export function doPreferenceGet(key: string, accountId: string, walletId: string, success: Function, fail: Function) { +export function doPreferenceGet( + key: string, + accountId: string, + walletId: string, + success: Function, + fail: Function +) { Lbry.preference_get({ key, account_id: accountId, wallet_id: walletId }).then(result => { if (result) { const preference = JSON.parse(result); - const { value } = preference; - return success(value); + const { value, version } = preference; + return success(value, version); } // Or fail instead? - return success(null); + return success(null, null); }).catch(() => { if (fail) { fail(); } }); -- 2.45.2 From 664a41a19df3eaeb158557c87bd97ec07fd1256c Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 1 Oct 2019 19:00:59 -0400 Subject: [PATCH 156/371] feat: add blocking + fixes --- dist/bundle.es.js | 44 ++++++++++++++++++++++++----------- src/redux/actions/claims.js | 35 ++++++++++++++++++++++------ src/redux/actions/publish.js | 8 ++++++- src/redux/actions/wallet.js | 1 + src/redux/selectors/claims.js | 8 ++----- 5 files changed, 69 insertions(+), 27 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 65b2192..62abc47 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1673,16 +1673,12 @@ 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 null; - } - - return thumbnail.url.trim(); + return thumbnail && thumbnail.url ? thumbnail.url.trim() : undefined; }); const makeSelectCoverForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { const cover = claim && claim.value && claim.value.cover; - return cover ? cover.url : undefined; + return cover && cover.url ? cover.url.trim() : undefined; }); const selectIsFetchingClaimListMine = reselect.createSelector(selectState$2, state => state.isFetchingClaimListMine); @@ -2141,7 +2137,8 @@ function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { lbryProxy.support_create({ claim_id: claimId, amount: creditsToString(amount), - tip: !shouldSupport + tip: !shouldSupport, + blocking: true }).then(success, error); }; } @@ -2462,7 +2459,8 @@ function doCreateChannel(name, amount, optionalParams) { const createParams = { name, - bid: creditsToString(amount) + bid: creditsToString(amount), + blocking: true }; if (optionalParams) { @@ -2508,10 +2506,14 @@ function doCreateChannel(name, amount, optionalParams) { } function doUpdateChannel(params) { - return dispatch => { + return (dispatch, getState) => { dispatch({ type: UPDATE_CHANNEL_STARTED }); + const state = getState(); + const myChannels = selectMyChannelClaims(state); + const channelClaim = myChannels.find(myChannel => myChannel.claim_id === params.claim_id); + const updateParams = { claim_id: params.claim_id, bid: creditsToString(params.amount), @@ -2521,15 +2523,26 @@ function doUpdateChannel(params) { description: params.description, website_url: params.website, email: params.email, + tags: [], replace: true, - tags: [] + languages: [], + locations: [], + blocking: true }; if (params.tags) { updateParams.tags = params.tags.map(tag => tag.name); } - // TODO add languages and locations as above + //we'll need to remove these once we add locations/channels to channel page edit/create options + + if (channelClaim && channelClaim.value && channelClaim.value.locations) { + updateParams.locations = channelClaim.value.locations; + } + + if (channelClaim && channelClaim.value && channelClaim.value.languages) { + updateParams.languages = channelClaim.value.languages; + } return lbryProxy.channel_update(updateParams).then(result => { const channelClaim = result.outputs[0]; @@ -3253,11 +3266,12 @@ const doPublish = (success, fail) => (dispatch, getState) => { name, title, description, - locations: locations, + locations: [], bid: creditsToString(bid), languages: [language], tags: tags && tags.map(tag => tag.name), - thumbnail_url: thumbnail + thumbnail_url: thumbnail, + blocking: true }; // Temporary solution to keep the same publish flow with the new tags api // Eventually we will allow users to enter their own tags on publish @@ -3288,6 +3302,10 @@ const doPublish = (success, fail) => (dispatch, getState) => { publishPayload.channel_id = channelId; } + if (myClaimForUri && myClaimForUri.value && myClaimForUri.value.locations) { + publishPayload.locations = myClaimForUri.value.locations; + } + if (!contentIsFree && fee && fee.currency && Number(fee.amount) > 0) { publishPayload.fee_currency = fee.currency; publishPayload.fee_amount = creditsToString(fee.amount); diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 622847d..60f3ed8 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -3,7 +3,12 @@ import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import { normalizeURI } from 'lbryURI'; import { doToast } from 'redux/actions/notifications'; -import { selectMyClaimsRaw, selectResolvingUris, selectClaimsByUri } from 'redux/selectors/claims'; +import { + selectMyClaimsRaw, + selectResolvingUris, + selectClaimsByUri, + selectMyChannelClaims, +} from 'redux/selectors/claims'; import { doFetchTransactions } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { creditsToString } from 'util/format-credits'; @@ -231,12 +236,13 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an dispatch({ type: ACTIONS.CREATE_CHANNEL_STARTED, }); - + const createParams = { name, bid: creditsToString(amount), + blocking: true, }; - + if (optionalParams) { if (optionalParams.title) { createParams.title = optionalParams.title; @@ -260,7 +266,7 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an createParams.tags = optionalParams.tags.map(tag => tag.name); } } - + return ( Lbry.channel_create(createParams) // outputs[0] is the certificate @@ -283,10 +289,14 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an } export function doUpdateChannel(params: any) { - return (dispatch: Dispatch) => { + return (dispatch: Dispatch, getState: GetState) => { dispatch({ type: ACTIONS.UPDATE_CHANNEL_STARTED, }); + const state = getState(); + const myChannels = selectMyChannelClaims(state); + const channelClaim = myChannels.find(myChannel => myChannel.claim_id === params.claim_id); + const updateParams = { claim_id: params.claim_id, bid: creditsToString(params.amount), @@ -296,15 +306,26 @@ export function doUpdateChannel(params: any) { description: params.description, website_url: params.website, email: params.email, - replace: true, tags: [], + replace: true, + languages: [], + locations: [], + blocking: true, }; if (params.tags) { updateParams.tags = params.tags.map(tag => tag.name); } - // TODO add languages and locations as above + //we'll need to remove these once we add locations/channels to channel page edit/create options + + if (channelClaim && channelClaim.value && channelClaim.value.locations) { + updateParams.locations = channelClaim.value.locations; + } + + if (channelClaim && channelClaim.value && channelClaim.value.languages) { + updateParams.languages = channelClaim.value.languages; + } return Lbry.channel_update(updateParams) .then((result: ChannelUpdateResponse) => { diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index fde7503..e622cfb 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -294,15 +294,17 @@ export const doPublish = (success: Function, fail: Function) => ( languages?: Array, tags: Array, locations?: Array, + blocking: boolean, } = { name, title, description, - locations: locations, + locations: [], bid: creditsToString(bid), languages: [language], tags: tags && tags.map(tag => tag.name), thumbnail_url: thumbnail, + blocking: true, }; // Temporary solution to keep the same publish flow with the new tags api // Eventually we will allow users to enter their own tags on publish @@ -333,6 +335,10 @@ export const doPublish = (success: Function, fail: Function) => ( publishPayload.channel_id = channelId; } + if (myClaimForUri && myClaimForUri.value && myClaimForUri.value.locations) { + publishPayload.locations = myClaimForUri.value.locations; + } + if (!contentIsFree && fee && (fee.currency && Number(fee.amount) > 0)) { publishPayload.fee_currency = fee.currency; publishPayload.fee_amount = creditsToString(fee.amount); diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 7ae4855..cff22d7 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -252,6 +252,7 @@ export function doSendTip(amount, claimId, isSupport, successCallback, errorCall claim_id: claimId, amount: creditsToString(amount), tip: !shouldSupport, + blocking: true, }).then(success, error); }; } diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index bc67fe1..d90936e 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -272,11 +272,7 @@ export const makeSelectThumbnailForUri = (uri: string) => makeSelectClaimForUri(uri), claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; - if (!thumbnail || !thumbnail.url) { - return null; - } - - return thumbnail.url.trim(); + return thumbnail && thumbnail.url ? thumbnail.url.trim() : undefined; } ); @@ -285,7 +281,7 @@ export const makeSelectCoverForUri = (uri: string) => makeSelectClaimForUri(uri), claim => { const cover = claim && claim.value && claim.value.cover; - return cover ? cover.url : undefined; + return cover && cover.url ? cover.url.trim() : undefined; } ); -- 2.45.2 From 13ae65bd46aa82c0f46c24a76307831c6937fbe9 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 2 Oct 2019 10:27:09 +0100 Subject: [PATCH 157/371] use shared key for saved user state --- dist/bundle.es.js | 45 ++++++++++++++++----------------- src/redux/actions/sync.js | 52 +++++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 51 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8625e4b..989c7ac 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3742,11 +3742,12 @@ function has(obj, path) { var _extends$5 = 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; }; -const stateCache = {}; +let oldShared; +const sharedPreferenceKey = 'shared'; function extractUserState(rawObj) { - if (rawObj && rawObj.version === '0.1' && rawObj.shared) { - const { subscriptions, tags } = rawObj.shared; + if (rawObj && rawObj.version === '0.1' && rawObj.value) { + const { subscriptions, tags } = rawObj.value; return _extends$5({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}); } @@ -3761,7 +3762,10 @@ function doPopulateSharedUserState(settings) { }; } -function sharedStateSubscriber(state, filters, accountId, walletId) { +function sharedStateSubscriber(state, filters, version, accountId, walletId) { + // the shared object that will be saved + const shared = {}; + Object.keys(filters).forEach(key => { const filter = filters[key]; const { source, property, transform } = filter; @@ -3770,19 +3774,14 @@ function sharedStateSubscriber(state, filters, accountId, walletId) { value = transform(value); } - let cacheKey = key; - if (accountId) { - cacheKey = `${cacheKey}_${accountId}`; - } - if (walletId) { - cacheKey = `${cacheKey}_${walletId}`; - } - - if (!isEqual(stateCache[cacheKey], value)) { - // only update if the preference changed from last call in the same session - doPreferenceSet(key, value, accountId, walletId); - } + shared[key] = value; }); + + if (!isEqual(oldShared, shared)) { + // only update if the preference changed from last call in the same session + oldShared = shared; + doPreferenceSet(sharedPreferenceKey, shared, version, accountId, walletId); + } } function doPreferenceSet(key, value, version, accountId, walletId, success, fail) { @@ -3793,7 +3792,7 @@ function doPreferenceSet(key, value, version, accountId, walletId, success, fail }; lbryProxy.preference_set({ key, value: JSON.stringify(preference), account_id: accountId, wallet_id: walletId }).then(() => { - success(value); + success(preference); }).catch(() => { if (fail) { fail(); @@ -3804,16 +3803,14 @@ function doPreferenceSet(key, value, version, accountId, walletId, success, fail function doPreferenceGet(key, accountId, walletId, success, fail) { lbryProxy.preference_get({ key, account_id: accountId, wallet_id: walletId }).then(result => { if (result) { - const preference = JSON.parse(result); - const { value, version } = preference; - return success(value, version); + const preference = result[key]; + return success(preference); } - // Or fail instead? - return success(null, null); - }).catch(() => { + return success(null); + }).catch(err => { if (fail) { - fail(); + fail(err); } }); } diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 0a0ee62..0bde0d6 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -3,19 +3,20 @@ import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import isEqual from 'util/deep-equal'; -type v0Data = { +type sharedData = { version: '0.1', - shared: { + value: { subscriptions?: Array, tags?: Array, }, }; -const stateCache = {}; +let oldShared; +const sharedPreferenceKey = 'shared'; -function extractUserState(rawObj: v0Data) { - if (rawObj && rawObj.version === '0.1' && rawObj.shared) { - const { subscriptions, tags } = rawObj.shared; +function extractUserState(rawObj: sharedData) { + if (rawObj && rawObj.version === '0.1' && rawObj.value) { + const { subscriptions, tags } = rawObj.value; return { ...(subscriptions ? { subscriptions } : {}), @@ -40,6 +41,9 @@ export function sharedStateSubscriber( accountId: string, walletId: string) { + // the shared object that will be saved + const shared = {}; + Object.keys(filters).forEach(key => { const filter = filters[key]; const { source, property, transform } = filter; @@ -48,19 +52,15 @@ export function sharedStateSubscriber( value = transform(value); } - let cacheKey = key; - if (accountId) { - cacheKey = `${cacheKey}_${accountId}`; - } - if (walletId) { - cacheKey = `${cacheKey}_${walletId}`; - } - - if (!isEqual(stateCache[cacheKey], value)) { - // only update if the preference changed from last call in the same session - doPreferenceSet(key, value, version, accountId, walletId); - } + shared[key] = value; }); + + + if (!isEqual(oldShared, shared)) { + // only update if the preference changed from last call in the same session + oldShared = shared; + doPreferenceSet(sharedPreferenceKey, shared, version, accountId, walletId); + } } export function doPreferenceSet( @@ -75,11 +75,11 @@ export function doPreferenceSet( const preference = { type: (typeof value), version, - value + value, }; Lbry.preference_set({ key, value: JSON.stringify(preference), account_id: accountId, wallet_id: walletId }).then(() => { - success(value); + success(preference); }).catch(() => { if (fail) { fail(); } }); @@ -94,14 +94,12 @@ export function doPreferenceGet( ) { Lbry.preference_get({ key, account_id: accountId, wallet_id: walletId }).then(result => { if (result) { - const preference = JSON.parse(result); - const { value, version } = preference; - return success(value, version); + const preference = result[key]; + return success(preference); } - // Or fail instead? - return success(null, null); - }).catch(() => { - if (fail) { fail(); } + return success(null); + }).catch(err => { + if (fail) { fail(err); } }); } -- 2.45.2 From 439407ab0344b09806cc8f8b17346bfc57acd020 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 2 Oct 2019 16:20:48 -0400 Subject: [PATCH 158/371] return a promise with doUpdateBalance --- dist/bundle.es.js | 2 +- src/redux/actions/wallet.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 62abc47..c3ab516 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1915,7 +1915,7 @@ function doUpdateBalance() { const { wallet: { totalBalance: totalInStore } } = getState(); - lbryProxy.account_balance({ reserved_subtotals: true }).then(response => { + return lbryProxy.account_balance({ reserved_subtotals: true }).then(response => { const { available, reserved, reserved_subtotals, total } = response; const { claims, supports, tips } = reserved_subtotals; const totalFloat = parseFloat(total); diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index cff22d7..7d42dca 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -10,7 +10,7 @@ export function doUpdateBalance() { const { wallet: { totalBalance: totalInStore }, } = getState(); - Lbry.account_balance({reserved_subtotals: true}).then((response: BalanceResponse) => { + return Lbry.account_balance({ reserved_subtotals: true }).then((response: BalanceResponse) => { const { available, reserved, reserved_subtotals, total } = response; const { claims, supports, tips } = reserved_subtotals; const totalFloat = parseFloat(total); -- 2.45.2 From a9bdf53deef6da117ac174871700011a33ab1d1d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 3 Oct 2019 15:05:04 -0400 Subject: [PATCH 159/371] update link instructions --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d464b1c..00fdddf 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ Add `lbry-redux` as a dependency to your `package.json` file. If you intend to make changes to the module and test immediately, you can use `npm link` to add the package to your `node_modules` folder. This will create a symlink to the folder where `lbry-redux` was cloned to. ``` cd lbry-redux -sudo npm link -cd ////node_modules -npm link lbry-redux +yarn link +cd /// (ex: cd ~/lbry-desktop) +yarn link lbry-redux ```` ### Build -- 2.45.2 From b998637435de484e466aaa940d89f5237afaca4b Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 30 Sep 2019 17:58:15 -0400 Subject: [PATCH 160/371] add commas to formatCredits --- dist/bundle.es.js | 16 ++++++++++------ dist/flow-typed/i18n.js | 2 +- flow-typed/i18n.js | 2 +- src/redux/selectors/wallet.js | 11 +++++------ src/util/format-credits.js | 12 +++++++++--- 5 files changed, 26 insertions(+), 17 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c3ab516..cad833c 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1290,8 +1290,6 @@ function doDismissError() { }; } -// - const selectState$1 = state => state.wallet || {}; const selectWalletState = selectState$1; @@ -1339,7 +1337,7 @@ const selectTransactionsById = reselect.createSelector(selectState$1, state => s const selectSupportsByOutpoint = reselect.createSelector(selectState$1, state => state.supports || {}); const selectTotalSupports = reselect.createSelector(selectSupportsByOutpoint, byOutpoint => { - let total = parseFloat("0.0"); + let total = parseFloat('0.0'); Object.values(byOutpoint).forEach(support => { const { amount } = support; @@ -1869,22 +1867,28 @@ const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(sele const selectMyStreamUrlsCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); +function numberWithCommas(x) { + var parts = x.toString().split('.'); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); + return parts.join('.'); +} + function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount), suffix = ''; if (Number.isNaN(actualAmount)) return '0'; if (shortFormat) { - if (actualAmount >= 1000000) { + if (actualAmount >= 1000000 && precision <= 7) { actualAmount = actualAmount / 1000000; suffix = 'M'; - } else if (actualAmount >= 1000) { + } else if (actualAmount >= 1000 && precision <= 4) { actualAmount = actualAmount / 1000; suffix = 'K'; } } - return actualAmount.toFixed(precision || 1).replace(/\.?0+$/, '') + suffix; + return numberWithCommas(actualAmount.toFixed(precision || 1).replace(/\.?0+$/, '')) + suffix; } function formatFullPrice(amount, precision = 1) { diff --git a/dist/flow-typed/i18n.js b/dist/flow-typed/i18n.js index 050d684..de97c0c 100644 --- a/dist/flow-typed/i18n.js +++ b/dist/flow-typed/i18n.js @@ -1,2 +1,2 @@ // @flow -declare function __(a: string, b?: string | number): string; +declare function __(a: string, b?: {}): string; diff --git a/flow-typed/i18n.js b/flow-typed/i18n.js index 050d684..de97c0c 100644 --- a/flow-typed/i18n.js +++ b/flow-typed/i18n.js @@ -1,2 +1,2 @@ // @flow -declare function __(a: string, b?: string | number): string; +declare function __(a: string, b?: {}): string; diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 05074f3..d050aef 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -1,5 +1,3 @@ -// @flow - import { createSelector } from 'reselect'; import * as TRANSACTIONS from 'constants/transaction_types'; import { PAGE_SIZE } from 'constants/transaction_list'; @@ -116,7 +114,7 @@ export const selectSupportsByOutpoint = createSelector( export const selectTotalSupports = createSelector( selectSupportsByOutpoint, byOutpoint => { - let total = parseFloat("0.0"); + let total = parseFloat('0.0'); Object.values(byOutpoint).forEach(support => { const { amount } = support; @@ -299,15 +297,16 @@ export const selectFilteredTransactions = createSelector( return transactions.filter(transaction => { return filter === TRANSACTIONS.ALL || filter === transaction.type; }); - }); + } +); export const makeSelectFilteredTransactionsForPage = (page: number = 1): Array => createSelector( selectFilteredTransactions, filteredTransactions => { const start = (Number(page) - 1) * Number(PAGE_SIZE); - const end = (Number(page) * Number(PAGE_SIZE)); - return (filteredTransactions && filteredTransactions.length) + const end = Number(page) * Number(PAGE_SIZE); + return filteredTransactions && filteredTransactions.length ? filteredTransactions.slice(start, end) : []; } diff --git a/src/util/format-credits.js b/src/util/format-credits.js index fae1f44..4f23280 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -1,19 +1,25 @@ +function numberWithCommas(x) { + var parts = x.toString().split('.'); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); + return parts.join('.'); +} + export function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount), suffix = ''; if (Number.isNaN(actualAmount)) return '0'; if (shortFormat) { - if (actualAmount >= 1000000) { + if (actualAmount >= 1000000 && precision <= 7) { actualAmount = actualAmount / 1000000; suffix = 'M'; - } else if (actualAmount >= 1000) { + } else if (actualAmount >= 1000 && precision <= 4) { actualAmount = actualAmount / 1000; suffix = 'K'; } } - return actualAmount.toFixed(precision || 1).replace(/\.?0+$/, '') + suffix; + return numberWithCommas(actualAmount.toFixed(precision || 1).replace(/\.?0+$/, '')) + suffix; } export function formatFullPrice(amount, precision = 1) { -- 2.45.2 From d770011057c40c6290d7eacabf71564107d41b6f Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 2 Oct 2019 00:10:19 -0400 Subject: [PATCH 161/371] reduce precision for larger numbers --- dist/bundle.es.js | 32 ++++++++++++++++++++++---------- src/util/format-credits.js | 36 ++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 20 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index cad833c..ecf0990 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1874,21 +1874,33 @@ function numberWithCommas(x) { } function formatCredits(amount, precision, shortFormat = false) { - let actualAmount = parseFloat(amount), - suffix = ''; + let actualAmount = parseFloat(amount); + let actualPrecision = parseFloat(precision); + let suffix = ''; + if (Number.isNaN(actualAmount)) return '0'; - if (shortFormat) { - if (actualAmount >= 1000000 && precision <= 7) { - actualAmount = actualAmount / 1000000; - suffix = 'M'; - } else if (actualAmount >= 1000 && precision <= 4) { - actualAmount = actualAmount / 1000; - suffix = 'K'; + if (actualAmount >= 1000000) { + if (precision <= 7) { + if (shortFormat) { + actualAmount = actualAmount / 1000000; + suffix = 'M'; + } else { + actualPrecision -= 7; + } + } + } else if (actualAmount >= 1000) { + if (precision <= 4) { + if (shortFormat) { + actualAmount = actualAmount / 1000; + suffix = 'K'; + } else { + actualPrecision -= 4; + } } } - return numberWithCommas(actualAmount.toFixed(precision || 1).replace(/\.?0+$/, '')) + suffix; + return numberWithCommas(actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\..*0+$/, '')) + suffix; } function formatFullPrice(amount, precision = 1) { diff --git a/src/util/format-credits.js b/src/util/format-credits.js index 4f23280..8a52733 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -5,21 +5,37 @@ function numberWithCommas(x) { } export function formatCredits(amount, precision, shortFormat = false) { - let actualAmount = parseFloat(amount), - suffix = ''; + let actualAmount = parseFloat(amount); + let actualPrecision = parseFloat(precision); + let suffix = ''; + if (Number.isNaN(actualAmount)) return '0'; - if (shortFormat) { - if (actualAmount >= 1000000 && precision <= 7) { - actualAmount = actualAmount / 1000000; - suffix = 'M'; - } else if (actualAmount >= 1000 && precision <= 4) { - actualAmount = actualAmount / 1000; - suffix = 'K'; + if (actualAmount >= 1000000) { + if (precision <= 7) { + if (shortFormat) { + actualAmount = actualAmount / 1000000; + suffix = 'M'; + } else { + actualPrecision -= 7; + } + } + } else if (actualAmount >= 1000) { + if (precision <= 4) { + if (shortFormat) { + actualAmount = actualAmount / 1000; + suffix = 'K'; + } else { + actualPrecision -= 4; + } } } - return numberWithCommas(actualAmount.toFixed(precision || 1).replace(/\.?0+$/, '')) + suffix; + return ( + numberWithCommas( + actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\..*0+$/, '') + ) + suffix + ); } export function formatFullPrice(amount, precision = 1) { -- 2.45.2 From 85fe532d69704a283fd2ec640ad6e3b8dacd6d0d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 2 Oct 2019 23:36:45 -0400 Subject: [PATCH 162/371] add new channel to pending channels and fix format-credits --- dist/bundle.es.js | 11 ++++++++++- src/redux/actions/wallet.js | 1 + src/redux/reducers/claims.js | 8 ++++++++ src/util/format-credits.js | 2 +- 4 files changed, 20 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ecf0990..58df29a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1900,7 +1900,7 @@ function formatCredits(amount, precision, shortFormat = false) { } } - return numberWithCommas(actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\..*0+$/, '')) + suffix; + return numberWithCommas(actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\.*0+$/, '')) + suffix; } function formatFullPrice(amount, precision = 1) { @@ -1935,6 +1935,7 @@ function doUpdateBalance() { const { available, reserved, reserved_subtotals, total } = response; const { claims, supports, tips } = reserved_subtotals; const totalFloat = parseFloat(total); + if (totalInStore !== totalFloat) { dispatch({ type: UPDATE_BALANCE, @@ -3829,6 +3830,7 @@ reducers[FETCH_CHANNEL_LIST_STARTED] = state => Object.assign({}, state, { fetch reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { const { claims } = action.data; const myClaims = state.myClaims || []; + const pendingById = Object.assign(state.pendingById); let myChannelClaims; let byId = Object.assign({}, state.byId); @@ -3841,6 +3843,10 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { // $FlowFixMe myChannelClaims.add(claim.claim_id); byId[claim.claim_id] = claim; + + if (pendingById[claim.claim_id] && claim.confirmations > 0) { + delete pendingById[claim.claim_id]; + } }); } @@ -3940,13 +3946,16 @@ reducers[CREATE_CHANNEL_STARTED] = state => _extends$6({}, state, { reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { const channelClaim = action.data.channelClaim; const byId = Object.assign({}, state.byId); + const pendingById = Object.assign({}, state.pendingById); const myChannelClaims = new Set(state.myChannelClaims); byId[channelClaim.claim_id] = channelClaim; + pendingById[channelClaim.claim_id] = channelClaim; myChannelClaims.add(channelClaim.claim_id); return Object.assign({}, state, { byId, + pendingById, myChannelClaims, creatingChannel: false }); diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 7d42dca..fc1a7ba 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -14,6 +14,7 @@ export function doUpdateBalance() { const { available, reserved, reserved_subtotals, total } = response; const { claims, supports, tips } = reserved_subtotals; const totalFloat = parseFloat(total); + if (totalInStore !== totalFloat) { dispatch({ type: ACTIONS.UPDATE_BALANCE, diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index bef8797..b82b56a 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -197,6 +197,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_STARTED] = (state: State): State => reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): State => { const { claims }: { claims: Array } = action.data; const myClaims = state.myClaims || []; + const pendingById = Object.assign(state.pendingById); let myChannelClaims; let byId = Object.assign({}, state.byId); @@ -209,6 +210,10 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St // $FlowFixMe myChannelClaims.add(claim.claim_id); byId[claim.claim_id] = claim; + + if (pendingById[claim.claim_id] && claim.confirmations > 0) { + delete pendingById[claim.claim_id]; + } }); } @@ -309,13 +314,16 @@ reducers[ACTIONS.CREATE_CHANNEL_STARTED] = (state: State): State => ({ reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { const channelClaim: ChannelClaim = action.data.channelClaim; const byId = Object.assign({}, state.byId); + const pendingById = Object.assign({}, state.pendingById); const myChannelClaims = new Set(state.myChannelClaims); byId[channelClaim.claim_id] = channelClaim; + pendingById[channelClaim.claim_id] = channelClaim; myChannelClaims.add(channelClaim.claim_id); return Object.assign({}, state, { byId, + pendingById, myChannelClaims, creatingChannel: false, }); diff --git a/src/util/format-credits.js b/src/util/format-credits.js index 8a52733..745ff57 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -33,7 +33,7 @@ export function formatCredits(amount, precision, shortFormat = false) { return ( numberWithCommas( - actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\..*0+$/, '') + actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\.*0+$/, '') ) + suffix ); } -- 2.45.2 From b0ffa82c093a537985147aa13efbfb79700f7b5a Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Thu, 3 Oct 2019 17:14:35 -0400 Subject: [PATCH 163/371] add selectors for download queries --- dist/bundle.es.js | 36 +++++++++++++++++++--- src/index.js | 3 +- src/redux/selectors/file_info.js | 51 ++++++++++++++++++++++++-------- 3 files changed, 73 insertions(+), 17 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c3ab516..63513dc 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,6 +15,7 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ + __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -268,6 +269,7 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ + __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -504,6 +506,7 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ + __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -534,6 +537,7 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ + __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -578,6 +582,7 @@ const FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; const KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; var settings = /*#__PURE__*/Object.freeze({ + __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -600,6 +605,7 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ + __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -613,6 +619,7 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ + __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -632,6 +639,7 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ + __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -647,6 +655,7 @@ var transaction_types = /*#__PURE__*/Object.freeze({ const PAGE_SIZE$1 = 50; var transaction_list = /*#__PURE__*/Object.freeze({ + __proto__: null, PAGE_SIZE: PAGE_SIZE$1 }); @@ -2750,13 +2759,31 @@ const makeSelectFileNameForUri = uri => reselect.createSelector(makeSelectFileIn return fileInfo && fileInfo.file_name; }); -const makeSelectDownloadUrlsForPage = (page = 1) => reselect.createSelector(selectDownloadedUris, urls => { +const selectDownloadUrlsCount = reselect.createSelector(selectDownloadedUris, uris => uris.length); + +function filterFileInfos(fileInfos, query) { + if (query) { + const queryMatchRegExp = new RegExp(query, 'i'); + return fileInfos.filter(fileInfo => { + const { metadata } = fileInfo; + return metadata.title && metadata.title.match(queryMatchRegExp) || fileInfo.channel_name && fileInfo.channel_name.match(queryMatchRegExp) || fileInfo.claim_name && fileInfo.claim_name.match(queryMatchRegExp); + }); + } + + return fileInfos; +} + +const makeSelectSearchDownloadUrlsForPage = (query, page = 1) => reselect.createSelector(selectFileInfosDownloaded, fileInfos => { + const matchingFileInfos = filterFileInfos(fileInfos, query); const start = (Number(page) - 1) * Number(PAGE_SIZE); const end = Number(page) * Number(PAGE_SIZE); - return urls && urls.length ? urls.slice(start, end) : []; + + return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos.slice(start, end).map(fileInfo => buildURI({ streamName: fileInfo.claim_name, channelName: fileInfo.channel_name, channelClaimId: fileInfo.channel_claim_id })) : []; }); -const selectDownloadUrlsCount = reselect.createSelector(selectDownloadedUris, uris => uris.length); +const makeSelectSearchDownloadUrlsCount = query => reselect.createSelector(selectFileInfosDownloaded, fileInfos => { + return fileInfos && fileInfos.length ? filterFileInfos(fileInfos, query).length : 0; +}); // @@ -5116,7 +5143,6 @@ exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; exports.makeSelectCoverForUri = makeSelectCoverForUri; exports.makeSelectDateForUri = makeSelectDateForUri; exports.makeSelectDownloadPathForUri = makeSelectDownloadPathForUri; -exports.makeSelectDownloadUrlsForPage = makeSelectDownloadUrlsForPage; exports.makeSelectDownloadingForUri = makeSelectDownloadingForUri; exports.makeSelectFetchingChannelClaims = makeSelectFetchingChannelClaims; exports.makeSelectFileInfoForUri = makeSelectFileInfoForUri; @@ -5138,6 +5164,8 @@ exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; +exports.makeSelectSearchDownloadUrlsCount = makeSelectSearchDownloadUrlsCount; +exports.makeSelectSearchDownloadUrlsForPage = makeSelectSearchDownloadUrlsForPage; exports.makeSelectSearchUris = makeSelectSearchUris; exports.makeSelectShortUrlForUri = makeSelectShortUrlForUri; exports.makeSelectStreamingUrlForUri = makeSelectStreamingUrlForUri; diff --git a/src/index.js b/src/index.js index ced22a0..1456a3c 100644 --- a/src/index.js +++ b/src/index.js @@ -234,7 +234,8 @@ export { makeSelectDownloadPathForUri, makeSelectFileNameForUri, makeSelectFilePartlyDownloaded, - makeSelectDownloadUrlsForPage, + makeSelectSearchDownloadUrlsForPage, + makeSelectSearchDownloadUrlsCount, selectDownloadUrlsCount, } from 'redux/selectors/file_info'; diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 195150a..1431004 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -204,19 +204,46 @@ export const makeSelectFileNameForUri = uri => } ); -export const makeSelectDownloadUrlsForPage = (page = 1) => - createSelector( - selectDownloadedUris, - urls => { - const start = ((Number(page) - 1) * Number(PAGE_SIZE)); - const end = (Number(page) * Number(PAGE_SIZE)); - return (urls && urls.length) - ? urls.slice(start, end) - : []; - } - ); - export const selectDownloadUrlsCount = createSelector( selectDownloadedUris, uris => uris.length ); + +function filterFileInfos(fileInfos, query) { + if (query) { + const queryMatchRegExp = new RegExp(query, 'i'); + return fileInfos.filter(fileInfo => { + const { metadata } = fileInfo; + return (metadata.title && metadata.title.match(queryMatchRegExp)) || + (fileInfo.channel_name && fileInfo.channel_name.match(queryMatchRegExp)) || + (fileInfo.claim_name && fileInfo.claim_name.match(queryMatchRegExp)); + }); + } + + return fileInfos; +} + +export const makeSelectSearchDownloadUrlsForPage = (query, page = 1) => + createSelector( + selectFileInfosDownloaded, + fileInfos => { + const matchingFileInfos = filterFileInfos(fileInfos, query); + const start = ((Number(page) - 1) * Number(PAGE_SIZE)); + const end = (Number(page) * Number(PAGE_SIZE)); + + return (matchingFileInfos && matchingFileInfos.length) + ? matchingFileInfos.slice(start, end).map(fileInfo => + buildURI({ streamName: fileInfo.claim_name, channelName: fileInfo.channel_name, channelClaimId: fileInfo.channel_claim_id })) + : []; + } + ); + +export const makeSelectSearchDownloadUrlsCount = (query) => + createSelector( + selectFileInfosDownloaded, + fileInfos => { + return fileInfos && fileInfos.length + ? filterFileInfos(fileInfos, query).length + : 0; + } + ); -- 2.45.2 From 22c601ab9baac5bad328912954f1d62e1a5e3ce9 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 8 Oct 2019 10:14:50 -0400 Subject: [PATCH 164/371] error on space characters in parseURI --- dist/bundle.es.js | 13 ++++++++++--- src/lbryURI.js | 21 +++++++++++++-------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 58df29a..47f44cc 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -971,14 +971,20 @@ function parseURI(URL, requireProto = false) { // Validate protocol if (requireProto && !proto) { - throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); + throw new Error(__('LBRY URLs must include a protocol prefix (lbry://).')); } // Validate and process name if (!streamNameOrChannelName) { - throw new Error(__('URI does not include name.')); + throw new Error(__('URL does not include name.')); } + rest.forEach(urlPiece => { + if (urlPiece && urlPiece.includes(' ')) { + throw new Error('URL can not include a space'); + } + }); + const includesChannel = streamNameOrChannelName.startsWith('@'); const isChannel = streamNameOrChannelName.startsWith('@') && !possibleStreamName; const channelName = includesChannel && streamNameOrChannelName.slice(1); @@ -1108,7 +1114,8 @@ function normalizeURI(URL) { function isURIValid(URL) { try { - parseURI(normalizeURI(URL)); + let parts = parseURI(normalizeURI(URL)); + console.log('parts', parts); } catch (error) { return false; } diff --git a/src/lbryURI.js b/src/lbryURI.js index aeeff2c..678b1dd 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -10,9 +10,7 @@ const regexPartProtocol = '^((?:lbry://)?)'; const regexPartStreamOrChannelName = '([^:$#/]*)'; const regexPartModifierSeparator = '([:$#]?)([^/]*)'; const queryStringBreaker = '^([\\S]+)([?][\\S]*)'; -const separateQuerystring = new RegExp( - queryStringBreaker -); +const separateQuerystring = new RegExp(queryStringBreaker); /** * Parses a LBRY name into its component parts. Throws errors with user-friendly @@ -44,7 +42,7 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj ); // chop off the querystring first let QSStrippedURL, qs; - const qsRegexResult = separateQuerystring.exec(URL) + const qsRegexResult = separateQuerystring.exec(URL); if (qsRegexResult) { [QSStrippedURL, qs] = qsRegexResult.slice(1).map(match => match || null); } @@ -65,14 +63,20 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj // Validate protocol if (requireProto && !proto) { - throw new Error(__('LBRY URIs must include a protocol prefix (lbry://).')); + throw new Error(__('LBRY URLs must include a protocol prefix (lbry://).')); } // Validate and process name if (!streamNameOrChannelName) { - throw new Error(__('URI does not include name.')); + throw new Error(__('URL does not include name.')); } + rest.forEach(urlPiece => { + if (urlPiece && urlPiece.includes(' ')) { + throw new Error('URL can not include a space'); + } + }); + const includesChannel = streamNameOrChannelName.startsWith('@'); const isChannel = streamNameOrChannelName.startsWith('@') && !possibleStreamName; const channelName = includesChannel && streamNameOrChannelName.slice(1); @@ -119,7 +123,7 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj claimName: streamNameOrChannelName, claimId: primaryClaimId, ...(streamName ? { contentName: streamName } : {}), - ...(qs ? { queryString: qs} : {}), + ...(qs ? { queryString: qs } : {}), }; } @@ -256,7 +260,8 @@ export function normalizeURI(URL: string) { export function isURIValid(URL: string): boolean { try { - parseURI(normalizeURI(URL)); + let parts = parseURI(normalizeURI(URL)); + console.log('parts', parts); } catch (error) { return false; } -- 2.45.2 From 0a1c95a08835a6b892d853b156d4934e469c9589 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 8 Oct 2019 10:15:51 -0400 Subject: [PATCH 165/371] fix typo --- src/lbryURI.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/lbryURI.js b/src/lbryURI.js index 678b1dd..cd93959 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -260,8 +260,7 @@ export function normalizeURI(URL: string) { export function isURIValid(URL: string): boolean { try { - let parts = parseURI(normalizeURI(URL)); - console.log('parts', parts); + parseURI(normalizeURI(URL)); } catch (error) { return false; } -- 2.45.2 From b459b3937ec05b7112e485a87af470f37f3c0111 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 8 Oct 2019 15:03:09 -0400 Subject: [PATCH 166/371] fix flow errors --- dist/bundle.es.js | 11 ++++++----- src/lbryURI.js | 10 +++++++--- src/redux/actions/claims.js | 15 +++++++++++++-- 3 files changed, 26 insertions(+), 10 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 47f44cc..f02d84a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -995,7 +995,9 @@ function parseURI(URL, requireProto = false) { } if (channelName.length < channelNameMinLength) { - throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); + throw new Error(__(`Channel names must be at least %channelNameMinLength% characters.`, { + channelNameMinLength + })); } } @@ -1025,7 +1027,7 @@ function parseURIModifier(modSeperator, modValue) { if (modSeperator) { if (!modValue) { - throw new Error(__(`No modifier provided after separator %s.`, modSeperator)); + throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); } if (modSeperator === '#') { @@ -1038,7 +1040,7 @@ function parseURIModifier(modSeperator, modValue) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__(`Invalid claim ID %s.`, claimId)); + throw new Error(__(`Invalid claim ID %claimId%.`, { claimId })); } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { @@ -1114,8 +1116,7 @@ function normalizeURI(URL) { function isURIValid(URL) { try { - let parts = parseURI(normalizeURI(URL)); - console.log('parts', parts); + parseURI(normalizeURI(URL)); } catch (error) { return false; } diff --git a/src/lbryURI.js b/src/lbryURI.js index cd93959..a019418 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -87,7 +87,11 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj } if (channelName.length < channelNameMinLength) { - throw new Error(__(`Channel names must be at least %s characters.`, channelNameMinLength)); + throw new Error( + __(`Channel names must be at least %channelNameMinLength% characters.`, { + channelNameMinLength, + }) + ); } } @@ -134,7 +138,7 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) { if (modSeperator) { if (!modValue) { - throw new Error(__(`No modifier provided after separator %s.`, modSeperator)); + throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); } if (modSeperator === '#') { @@ -147,7 +151,7 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__(`Invalid claim ID %s.`, claimId)); + throw new Error(__(`Invalid claim ID %claimId%.`, { claimId })); } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 60f3ed8..298a675 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -237,7 +237,18 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an type: ACTIONS.CREATE_CHANNEL_STARTED, }); - const createParams = { + const createParams: { + name: string, + bid: string, + blocking: true, + title?: string, + cover_url?: string, + thumbnail_url?: string, + description?: string, + website_url?: string, + email?: string, + tags?: Array, + } = { name, bid: creditsToString(amount), blocking: true, @@ -317,7 +328,7 @@ export function doUpdateChannel(params: any) { updateParams.tags = params.tags.map(tag => tag.name); } - //we'll need to remove these once we add locations/channels to channel page edit/create options + // we'll need to remove these once we add locations/channels to channel page edit/create options if (channelClaim && channelClaim.value && channelClaim.value.locations) { updateParams.locations = channelClaim.value.locations; -- 2.45.2 From d6865fda33b03c544366c582145604fcd89dfc7d Mon Sep 17 00:00:00 2001 From: Nikita Titov Date: Wed, 9 Oct 2019 00:20:32 +0300 Subject: [PATCH 167/371] bump year in license --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 1973ea2..200acb5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017-2018 LBRY Inc +Copyright (c) 2017-2019 LBRY Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, -- 2.45.2 From 55e72a2597da69735f7b87e2efbeaf4b34f6d0de Mon Sep 17 00:00:00 2001 From: Nikita Titov Date: Wed, 9 Oct 2019 00:21:18 +0300 Subject: [PATCH 168/371] fixed broben link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 00fdddf..2538f62 100644 --- a/README.md +++ b/README.md @@ -27,4 +27,4 @@ We :heart: contributions from everyone! We welcome [bug reports](https://github. ## License -This module is released under the [MIT License](license) +This module is released under the [MIT License](LICENSE) -- 2.45.2 From dff1ecb195a03c5443526329116058b94d7391f7 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 11 Oct 2019 17:42:06 +0100 Subject: [PATCH 169/371] fix: formatCredits zero value --- dist/bundle.es.js | 4 ++-- src/util/format-credits.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2ba0411..ce02aa1 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1890,7 +1890,7 @@ function formatCredits(amount, precision, shortFormat = false) { let actualPrecision = parseFloat(precision); let suffix = ''; - if (Number.isNaN(actualAmount)) return '0'; + if (Number.isNaN(actualAmount) || actualAmount === 0) return '0'; if (actualAmount >= 1000000) { if (precision <= 7) { @@ -2563,7 +2563,7 @@ function doUpdateChannel(params) { updateParams.tags = params.tags.map(tag => tag.name); } - //we'll need to remove these once we add locations/channels to channel page edit/create options + // we'll need to remove these once we add locations/channels to channel page edit/create options if (channelClaim && channelClaim.value && channelClaim.value.locations) { updateParams.locations = channelClaim.value.locations; diff --git a/src/util/format-credits.js b/src/util/format-credits.js index 745ff57..a090a33 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -9,7 +9,7 @@ export function formatCredits(amount, precision, shortFormat = false) { let actualPrecision = parseFloat(precision); let suffix = ''; - if (Number.isNaN(actualAmount)) return '0'; + if (Number.isNaN(actualAmount) || actualAmount === 0) return '0'; if (actualAmount >= 1000000) { if (precision <= 7) { -- 2.45.2 From e048b2aff3daf1e3c99caea7159150f72fe402e4 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 11 Oct 2019 13:28:05 -0400 Subject: [PATCH 170/371] fix for lbrytv: only pass account_id/wallet_id if they are passed into prefGet/prefSet --- dist/bundle.es.js | 15 ++++++++-- src/redux/actions/sync.js | 62 ++++++++++++++++++++++++++------------- 2 files changed, 53 insertions(+), 24 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2ba0411..3c517c4 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2563,7 +2563,7 @@ function doUpdateChannel(params) { updateParams.tags = params.tags.map(tag => tag.name); } - //we'll need to remove these once we add locations/channels to channel page edit/create options + // we'll need to remove these once we add locations/channels to channel page edit/create options if (channelClaim && channelClaim.value && channelClaim.value.locations) { updateParams.locations = channelClaim.value.locations; @@ -3834,7 +3834,12 @@ function doPreferenceSet(key, value, version, accountId, walletId, success, fail value }; - lbryProxy.preference_set({ key, value: JSON.stringify(preference), account_id: accountId, wallet_id: walletId }).then(() => { + const options = _extends$5({ + key, + value: JSON.stringify(preference) + }, accountId ? { account_id: accountId } : {}, walletId ? { wallet_id: walletId } : {}); + + lbryProxy.preference_set(options).then(() => { success(preference); }).catch(() => { if (fail) { @@ -3844,7 +3849,11 @@ function doPreferenceSet(key, value, version, accountId, walletId, success, fail } function doPreferenceGet(key, accountId, walletId, success, fail) { - lbryProxy.preference_get({ key, account_id: accountId, wallet_id: walletId }).then(result => { + const options = _extends$5({ + key + }, accountId ? { account_id: accountId } : {}, walletId ? { wallet_id: walletId } : {}); + + lbryProxy.preference_get(options).then(result => { if (result) { const preference = result[key]; return success(preference); diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 0bde0d6..41c289d 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -39,8 +39,8 @@ export function sharedStateSubscriber( filters: any, version: string, accountId: string, - walletId: string) -{ + walletId: string +) { // the shared object that will be saved const shared = {}; @@ -55,7 +55,6 @@ export function sharedStateSubscriber( shared[key] = value; }); - if (!isEqual(oldShared, shared)) { // only update if the preference changed from last call in the same session oldShared = shared; @@ -73,33 +72,54 @@ export function doPreferenceSet( fail: Function ) { const preference = { - type: (typeof value), + type: typeof value, version, value, }; - Lbry.preference_set({ key, value: JSON.stringify(preference), account_id: accountId, wallet_id: walletId }).then(() => { - success(preference); - }).catch(() => { - if (fail) { fail(); } - }); + const options = { + key, + value: JSON.stringify(preference), + ...(accountId ? { account_id: accountId } : {}), + ...(walletId ? { wallet_id: walletId } : {}), + }; + + Lbry.preference_set(options) + .then(() => { + success(preference); + }) + .catch(() => { + if (fail) { + fail(); + } + }); } export function doPreferenceGet( key: string, - accountId: string, - walletId: string, + accountId?: string, + walletId?: string, success: Function, - fail: Function + fail?: Function ) { - Lbry.preference_get({ key, account_id: accountId, wallet_id: walletId }).then(result => { - if (result) { - const preference = result[key]; - return success(preference); - } + const options = { + key, + ...(accountId ? { account_id: accountId } : {}), + ...(walletId ? { wallet_id: walletId } : {}), + }; - return success(null); - }).catch(err => { - if (fail) { fail(err); } - }); + Lbry.preference_get(options) + .then(result => { + if (result) { + const preference = result[key]; + return success(preference); + } + + return success(null); + }) + .catch(err => { + if (fail) { + fail(err); + } + }); } -- 2.45.2 From 5aea83537ad5a64e3bfbd0dbea8ba0c327f4180d Mon Sep 17 00:00:00 2001 From: jessop Date: Sat, 12 Oct 2019 13:11:23 -0400 Subject: [PATCH 171/371] returns channel create result for use outside lbry-redux --- dist/bundle.es.js | 2 ++ src/redux/actions/claims.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 62abc47..3069a46 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2496,11 +2496,13 @@ function doCreateChannel(name, amount, optionalParams) { type: CREATE_CHANNEL_COMPLETED, data: { channelClaim } }); + return channelClaim; }).catch(error => { dispatch({ type: CREATE_CHANNEL_FAILED, data: error.message }); + return error; }); }; } diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 60f3ed8..2bd08a0 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -277,12 +277,14 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an type: ACTIONS.CREATE_CHANNEL_COMPLETED, data: { channelClaim }, }); + return channelClaim; }) .catch(error => { dispatch({ type: ACTIONS.CREATE_CHANNEL_FAILED, data: error.message, }); + return error; }) ); }; -- 2.45.2 From 0f331cc362bbb88be9acd08d69386196d9f0aede Mon Sep 17 00:00:00 2001 From: saksham taneja Date: Sun, 13 Oct 2019 19:52:06 +0530 Subject: [PATCH 172/371] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2538f62..5486461 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ yarn link lbry-redux ```` ### Build -Run `$ yarn build`. If the symlink does not work, just build the file and move the `bundle.js` file in to the `node_modules/` folder. +Run `$ yarn build`. If the symlink does not work, just build the file and move the `bundle.js` file into the `node_modules/` folder. ## Contributing We :heart: contributions from everyone! We welcome [bug reports](https://github.com/lbryio/lbry-redux/issues/), [bug fixes](https://github.com/lbryio/lbry-redux/pulls) and feedback on the module is always appreciated. -- 2.45.2 From 2a9263c89d33cfa92911dd09862202d26b5c4849 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 14 Oct 2019 23:35:38 -0400 Subject: [PATCH 173/371] use middleware for preference setting --- dist/bundle.es.js | 515 ++++++++++++++------------- dist/flow-typed/Lbry.js | 4 +- flow-typed/Lbry.js | 4 +- src/index.js | 10 +- src/lbry.js | 4 +- src/redux/actions/sync.js | 54 +-- src/redux/actions/wallet.js | 4 +- src/redux/middleware/shared-state.js | 51 +++ src/redux/reducers/blocked.js | 11 + 9 files changed, 350 insertions(+), 307 deletions(-) create mode 100644 src/redux/middleware/shared-state.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3c517c4..909cc06 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -761,12 +761,12 @@ const Lbry = { blob_list: (params = {}) => daemonCallWithResult('blob_list', params), // Wallet utilities - account_balance: (params = {}) => daemonCallWithResult('account_balance', params), + wallet_balance: (params = {}) => daemonCallWithResult('wallet_balance', params), account_decrypt: () => daemonCallWithResult('account_decrypt', {}), account_encrypt: (params = {}) => daemonCallWithResult('account_encrypt', params), account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), account_list: (params = {}) => daemonCallWithResult('account_list', params), - account_send: (params = {}) => daemonCallWithResult('account_send', params), + wallet_send: (params = {}) => daemonCallWithResult('wallet_send', params), account_set: (params = {}) => daemonCallWithResult('account_set', params), address_is_mine: (params = {}) => daemonCallWithResult('address_is_mine', params), address_unused: (params = {}) => daemonCallWithResult('address_unused', params), @@ -1265,6 +1265,218 @@ const makeSelectQueryWithOptions = (customQuery, customSize, customFrom, isBackg return queryString; }); +/* eslint-disable */ +// underscore's deep equal function +// https://github.com/jashkenas/underscore/blob/master/underscore.js#L1189 + +function isEqual(a, b, aStack, bStack) { + // Identical objects are equal. `0 === -0`, but they aren't identical. + // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). + if (a === b) return a !== 0 || 1 / a === 1 / b; + // `null` or `undefined` only equal to itself (strict comparison). + if (a == null || b == null) return false; + // `NaN`s are equivalent, but non-reflexive. + if (a !== a) return b !== b; + // Exhaust primitive checks + var type = typeof a; + if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; + return deepEq(a, b, aStack, bStack); +} + +function deepEq(a, b, aStack, bStack) { + // Compare `[[Class]]` names. + var className = toString.call(a); + if (className !== toString.call(b)) return false; + switch (className) { + // Strings, numbers, regular expressions, dates, and booleans are compared by value. + case '[object RegExp]': + // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') + case '[object String]': + // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is + // equivalent to `new String("5")`. + return '' + a === '' + b; + case '[object Number]': + // `NaN`s are equivalent, but non-reflexive. + // Object(NaN) is equivalent to NaN. + if (+a !== +a) return +b !== +b; + // An `egal` comparison is performed for other numeric values. + return +a === 0 ? 1 / +a === 1 / b : +a === +b; + case '[object Date]': + case '[object Boolean]': + // Coerce dates and booleans to numeric primitive values. Dates are compared by their + // millisecond representations. Note that invalid dates with millisecond representations + // of `NaN` are not equivalent. + return +a === +b; + case '[object Symbol]': + return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); + } + + var areArrays = className === '[object Array]'; + if (!areArrays) { + if (typeof a != 'object' || typeof b != 'object') return false; + + // Objects with different constructors are not equivalent, but `Object`s or `Array`s + // from different frames are. + var aCtor = a.constructor, + bCtor = b.constructor; + if (aCtor !== bCtor && !(typeof aCtor === 'function' && aCtor instanceof aCtor && typeof bCtor === 'function' && bCtor instanceof bCtor) && 'constructor' in a && 'constructor' in b) { + return false; + } + } + // Assume equality for cyclic structures. The algorithm for detecting cyclic + // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. + + // Initializing stack of traversed objects. + // It's done here since we only need them for objects and arrays comparison. + aStack = aStack || []; + bStack = bStack || []; + var length = aStack.length; + while (length--) { + // Linear search. Performance is inversely proportional to the number of + // unique nested structures. + if (aStack[length] === a) return bStack[length] === b; + } + + // Add the first object to the stack of traversed objects. + aStack.push(a); + bStack.push(b); + + // Recursively compare objects and arrays. + if (areArrays) { + // Compare array lengths to determine if a deep comparison is necessary. + length = a.length; + if (length !== b.length) return false; + // Deep compare the contents, ignoring non-numeric properties. + while (length--) { + if (!isEqual(a[length], b[length], aStack, bStack)) return false; + } + } else { + // Deep compare objects. + var keys = Object.keys(a), + key; + length = keys.length; + // Ensure that both objects contain the same number of properties before comparing deep equality. + if (Object.keys(b).length !== length) return false; + while (length--) { + // Deep compare each member + key = keys[length]; + if (!(has(b, key) && isEqual(a[key], b[key], aStack, bStack))) return false; + } + } + // Remove the first object from the stack of traversed objects. + aStack.pop(); + bStack.pop(); + return true; +} + +function has(obj, path) { + return obj != null && hasOwnProperty.call(obj, path); +} +/* eslint-enable */ + +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 extractUserState(rawObj) { + if (rawObj && rawObj.version === '0.1' && rawObj.value) { + const { subscriptions, tags, blockedChannels } = rawObj.value; + + return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blockedChannels ? { blockedChannels } : {}); + } + + return {}; +} + +function doPopulateSharedUserState(settings) { + return dispatch => { + const { subscriptions, tags } = extractUserState(settings); + dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags } }); + }; +} + +function doPreferenceSet(key, value, version, success, fail) { + const preference = { + type: typeof value, + version, + value + }; + + const options = { + key, + value: JSON.stringify(preference) + }; + + lbryProxy.preference_set(options).then(() => { + success(preference); + }).catch(() => { + if (fail) { + fail(); + } + }); +} + +function doPreferenceGet(key, success, fail) { + const options = { + key + }; + + lbryProxy.preference_get(options).then(result => { + if (result) { + const preference = result[key]; + return success(preference); + } + + return success(null); + }).catch(err => { + if (fail) { + fail(err); + } + }); +} + +// + +const SHARED_PREFERENCE_KEY = 'shared'; +const SHARED_PREFERENCE_VERSION = '0.1'; +let oldShared = {}; + +const buildSharedStateMiddleware = (actions, sharedStateFilters, sharedStateCb) => ({ getState, dispatch }) => next => action => { + const currentState = getState(); + + // We don't care if sync is disabled here, we always want to backup preferences to the wallet + if (!actions.includes(action.type)) { + return next(action); + } + + const actionResult = next(action); + // Call `getState` after calling `next` to ensure the state has updated in response to the action + const nextState = getState(); + const shared = {}; + + Object.keys(sharedStateFilters).forEach(key => { + const filter = sharedStateFilters[key]; + const { source, property, transform } = filter; + let value = nextState[source][property]; + if (transform) { + value = transform(value); + } + + shared[key] = value; + }); + + if (!isEqual(oldShared, shared)) { + // only update if the preference changed from last call in the same session + oldShared = shared; + doPreferenceSet(SHARED_PREFERENCE_KEY, shared, SHARED_PREFERENCE_VERSION); + + if (sharedStateCb) { + // Pass dispatch to the callback to consumers can dispatch actions in response to preference set + sharedStateCb(dispatch); + } + } + + return actionResult; +}; + // function doToast(params) { @@ -1474,11 +1686,11 @@ const makeSelectFilteredTransactionsForPage = (page = 1) => reselect.createSelec const selectFilteredTransactionCount = reselect.createSelector(selectFilteredTransactions, filteredTransactions => filteredTransactions.length); -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; }; +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 _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 matureTagMap = MATURE_TAGS.reduce((acc, tag) => _extends$2({}, acc, { [tag]: true }), {}); +const matureTagMap = MATURE_TAGS.reduce((acc, tag) => _extends$3({}, acc, { [tag]: true }), {}); const isClaimNsfw = claim => { if (!claim) { @@ -1943,7 +2155,7 @@ function doUpdateBalance() { const { wallet: { totalBalance: totalInStore } } = getState(); - return lbryProxy.account_balance({ reserved_subtotals: true }).then(response => { + return lbryProxy.wallet_balance({ reserved_subtotals: true }).then(response => { const { available, reserved, reserved_subtotals, total } = response; const { claims, supports, tips } = reserved_subtotals; const totalFloat = parseFloat(total); @@ -2088,7 +2300,7 @@ function doSendDraftTransaction(address, amount) { })); }; - lbryProxy.account_send({ + lbryProxy.wallet_send({ addresses: [address], amount: creditsToString(amount) }).then(successCallback, errorCallback); @@ -2281,7 +2493,7 @@ function batchActions(...actions) { }; } -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; }; +var _extends$4 = 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) { return (dispatch, getState) => { @@ -2321,7 +2533,7 @@ function doResolveUris(uris, returnCachedClaims = false) { // https://github.com/facebook/flow/issues/2221 if (uriResolveInfo) { if (uriResolveInfo.error) { - resolveInfo[uri] = _extends$3({}, fallbackResolveInfo); + resolveInfo[uri] = _extends$4({}, fallbackResolveInfo); } else { let result = {}; if (uriResolveInfo.value_type === 'channel') { @@ -3063,7 +3275,7 @@ const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClai return null; }); -var _extends$4 = 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; }; +var _extends$5 = 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; }; const doResetThumbnailStatus = () => dispatch => { dispatch({ @@ -3101,7 +3313,7 @@ const doClearPublish = () => dispatch => { const doUpdatePublishForm = publishFormValue => dispatch => dispatch({ type: UPDATE_PUBLISH_FORM, - data: _extends$4({}, publishFormValue) + data: _extends$5({}, publishFormValue) }); const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter, fs, path) => dispatch => { @@ -3674,199 +3886,6 @@ const doToggleBlockChannel = uri => ({ } }); -/* eslint-disable */ -// underscore's deep equal function -// https://github.com/jashkenas/underscore/blob/master/underscore.js#L1189 - -function isEqual(a, b, aStack, bStack) { - // Identical objects are equal. `0 === -0`, but they aren't identical. - // See the [Harmony `egal` proposal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). - if (a === b) return a !== 0 || 1 / a === 1 / b; - // `null` or `undefined` only equal to itself (strict comparison). - if (a == null || b == null) return false; - // `NaN`s are equivalent, but non-reflexive. - if (a !== a) return b !== b; - // Exhaust primitive checks - var type = typeof a; - if (type !== 'function' && type !== 'object' && typeof b != 'object') return false; - return deepEq(a, b, aStack, bStack); -} - -function deepEq(a, b, aStack, bStack) { - // Compare `[[Class]]` names. - var className = toString.call(a); - if (className !== toString.call(b)) return false; - switch (className) { - // Strings, numbers, regular expressions, dates, and booleans are compared by value. - case '[object RegExp]': - // RegExps are coerced to strings for comparison (Note: '' + /a/i === '/a/i') - case '[object String]': - // Primitives and their corresponding object wrappers are equivalent; thus, `"5"` is - // equivalent to `new String("5")`. - return '' + a === '' + b; - case '[object Number]': - // `NaN`s are equivalent, but non-reflexive. - // Object(NaN) is equivalent to NaN. - if (+a !== +a) return +b !== +b; - // An `egal` comparison is performed for other numeric values. - return +a === 0 ? 1 / +a === 1 / b : +a === +b; - case '[object Date]': - case '[object Boolean]': - // Coerce dates and booleans to numeric primitive values. Dates are compared by their - // millisecond representations. Note that invalid dates with millisecond representations - // of `NaN` are not equivalent. - return +a === +b; - case '[object Symbol]': - return SymbolProto.valueOf.call(a) === SymbolProto.valueOf.call(b); - } - - var areArrays = className === '[object Array]'; - if (!areArrays) { - if (typeof a != 'object' || typeof b != 'object') return false; - - // Objects with different constructors are not equivalent, but `Object`s or `Array`s - // from different frames are. - var aCtor = a.constructor, - bCtor = b.constructor; - if (aCtor !== bCtor && !(typeof aCtor === 'function' && aCtor instanceof aCtor && typeof bCtor === 'function' && bCtor instanceof bCtor) && 'constructor' in a && 'constructor' in b) { - return false; - } - } - // Assume equality for cyclic structures. The algorithm for detecting cyclic - // structures is adapted from ES 5.1 section 15.12.3, abstract operation `JO`. - - // Initializing stack of traversed objects. - // It's done here since we only need them for objects and arrays comparison. - aStack = aStack || []; - bStack = bStack || []; - var length = aStack.length; - while (length--) { - // Linear search. Performance is inversely proportional to the number of - // unique nested structures. - if (aStack[length] === a) return bStack[length] === b; - } - - // Add the first object to the stack of traversed objects. - aStack.push(a); - bStack.push(b); - - // Recursively compare objects and arrays. - if (areArrays) { - // Compare array lengths to determine if a deep comparison is necessary. - length = a.length; - if (length !== b.length) return false; - // Deep compare the contents, ignoring non-numeric properties. - while (length--) { - if (!isEqual(a[length], b[length], aStack, bStack)) return false; - } - } else { - // Deep compare objects. - var keys = Object.keys(a), - key; - length = keys.length; - // Ensure that both objects contain the same number of properties before comparing deep equality. - if (Object.keys(b).length !== length) return false; - while (length--) { - // Deep compare each member - key = keys[length]; - if (!(has(b, key) && isEqual(a[key], b[key], aStack, bStack))) return false; - } - } - // Remove the first object from the stack of traversed objects. - aStack.pop(); - bStack.pop(); - return true; -} - -function has(obj, path) { - return obj != null && hasOwnProperty.call(obj, path); -} -/* eslint-enable */ - -var _extends$5 = 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; }; - -let oldShared; -const sharedPreferenceKey = 'shared'; - -function extractUserState(rawObj) { - if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags } = rawObj.value; - - return _extends$5({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}); - } - - return {}; -} - -function doPopulateSharedUserState(settings) { - return dispatch => { - const { subscriptions, tags } = extractUserState(settings); - dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags } }); - }; -} - -function sharedStateSubscriber(state, filters, version, accountId, walletId) { - // the shared object that will be saved - const shared = {}; - - Object.keys(filters).forEach(key => { - const filter = filters[key]; - const { source, property, transform } = filter; - let value = state[source][property]; - if (transform) { - value = transform(value); - } - - shared[key] = value; - }); - - if (!isEqual(oldShared, shared)) { - // only update if the preference changed from last call in the same session - oldShared = shared; - doPreferenceSet(sharedPreferenceKey, shared, version, accountId, walletId); - } -} - -function doPreferenceSet(key, value, version, accountId, walletId, success, fail) { - const preference = { - type: typeof value, - version, - value - }; - - const options = _extends$5({ - key, - value: JSON.stringify(preference) - }, accountId ? { account_id: accountId } : {}, walletId ? { wallet_id: walletId } : {}); - - lbryProxy.preference_set(options).then(() => { - success(preference); - }).catch(() => { - if (fail) { - fail(); - } - }); -} - -function doPreferenceGet(key, accountId, walletId, success, fail) { - const options = _extends$5({ - key - }, accountId ? { account_id: accountId } : {}, walletId ? { wallet_id: walletId } : {}); - - lbryProxy.preference_get(options).then(result => { - if (result) { - const preference = result[key]; - return success(preference); - } - - return success(null); - }).catch(err => { - if (fail) { - fail(err); - } - }); -} - var _extends$6 = 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; }; const reducers = {}; @@ -4839,7 +4858,7 @@ const tagsReducer = handleActions({ } }, defaultState$8); -// +var _extends$e = 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; }; const defaultState$9 = { blockedChannels: [] @@ -4860,10 +4879,16 @@ const blockedReducer = handleActions({ return { blockedChannels: newBlockedChannels }; + }, + [USER_STATE_POPULATE]: (state, action) => { + const { blockedChannels } = action.data; + return _extends$e({}, state, { + blockedChannels: blockedChannels && blockedChannels.length ? blockedChannels : state.blockedChannels + }); } }, defaultState$9); -var _extends$e = 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; }; +var _extends$f = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -4907,25 +4932,25 @@ const defaultState$a = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$e({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$f({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$e({}, state.transactions); + const byId = _extends$f({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$e({}, state, { + return _extends$f({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$e({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$f({}, state, { fetchingSupports: true }), @@ -4938,7 +4963,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$e({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$f({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -4947,7 +4972,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$e({}, state, { + return _extends$f({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -4960,23 +4985,23 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$e({}, state, { + return _extends$f({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$e({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$f({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$e({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$f({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$e({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$f({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -4985,32 +5010,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$e({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$f({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$e({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$f({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$e({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$f({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$e({}, state, { draftTransaction: newDraft }); + return _extends$f({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$e({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$f({}, oldDraft, { address: action.data.address }); - return _extends$e({}, state, { draftTransaction: newDraft }); + return _extends$f({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$e({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$f({}, state.draftTransaction, { sending: true }); - return _extends$e({}, state, { draftTransaction: newDraftTransaction }); + return _extends$f({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -5023,103 +5048,103 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$e({}, state, { draftTransaction: newDraftTransaction }); + return _extends$f({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$e({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$f({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$e({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$f({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$e({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$f({}, state, { error: action.data.error, sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$f({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$e({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$f({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$f({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$e({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$f({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$e({}, state, { + [WALLET_DECRYPT_START]: state => _extends$f({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$f({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$e({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$f({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$e({}, state, { + [WALLET_UNLOCK_START]: state => _extends$f({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$f({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$e({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$f({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$e({}, state, { + [WALLET_LOCK_START]: state => _extends$f({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$e({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$f({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$e({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$f({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$e({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$f({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$e({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$f({}, state, { latestBlock: action.data }) }, defaultState$a); @@ -5135,14 +5160,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$f = 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; }; +var _extends$g = 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; }; const selectState$7 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$7, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$f({ + return _extends$g({ id }, params); } @@ -5242,6 +5267,7 @@ exports.TRANSACTIONS = transaction_types; exports.TX_LIST = transaction_list; exports.batchActions = batchActions; exports.blockedReducer = blockedReducer; +exports.buildSharedStateMiddleware = buildSharedStateMiddleware; exports.buildURI = buildURI; exports.claimsReducer = claimsReducer; exports.commentReducer = commentReducer; @@ -5472,7 +5498,6 @@ exports.selectWalletUnlockPending = selectWalletUnlockPending; exports.selectWalletUnlockResult = selectWalletUnlockResult; exports.selectWalletUnlockSucceeded = selectWalletUnlockSucceeded; exports.setSearchApi = setSearchApi; -exports.sharedStateSubscriber = sharedStateSubscriber; exports.tagsReducer = tagsReducer; exports.toQueryString = toQueryString; exports.walletReducer = walletReducer; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 86691bc..1db0dc8 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -210,12 +210,12 @@ declare type LbryTypes = { comment_list: (params: {}) => Promise, comment_create: (params: {}) => Promise, // Wallet utilities - account_balance: (params: {}) => Promise, + wallet_balance: (params: {}) => Promise, account_decrypt: (prams: {}) => Promise, account_encrypt: (params: {}) => Promise, account_unlock: (params: {}) => Promise, account_list: (params: {}) => Promise, - account_send: (params: {}) => Promise, + wallet_send: (params: {}) => Promise, account_set: (params: {}) => Promise, address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 86691bc..1db0dc8 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -210,12 +210,12 @@ declare type LbryTypes = { comment_list: (params: {}) => Promise, comment_create: (params: {}) => Promise, // Wallet utilities - account_balance: (params: {}) => Promise, + wallet_balance: (params: {}) => Promise, account_decrypt: (prams: {}) => Promise, account_encrypt: (params: {}) => Promise, account_unlock: (params: {}) => Promise, account_list: (params: {}) => Promise, - account_send: (params: {}) => Promise, + wallet_send: (params: {}) => Promise, account_set: (params: {}) => Promise, address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address diff --git a/src/index.js b/src/index.js index 650da90..59abad9 100644 --- a/src/index.js +++ b/src/index.js @@ -44,6 +44,9 @@ export { convertToShareLink, } from 'lbryURI'; +// middlware +export { buildSharedStateMiddleware } from 'redux/middleware/shared-state'; + // actions export { doToast, doDismissToast, doError, doDismissError } from 'redux/actions/notifications'; @@ -114,12 +117,7 @@ export { doCommentList, doCommentCreate } from 'redux/actions/comments'; export { doToggleBlockChannel } from 'redux/actions/blocked'; -export { - doPopulateSharedUserState, - doPreferenceGet, - doPreferenceSet, - sharedStateSubscriber -} from 'redux/actions/sync'; +export { doPopulateSharedUserState, doPreferenceGet, doPreferenceSet } from 'redux/actions/sync'; // utils export { batchActions } from 'util/batch-actions'; diff --git a/src/lbry.js b/src/lbry.js index 36db557..f13e945 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -93,12 +93,12 @@ const Lbry: LbryTypes = { blob_list: (params = {}) => daemonCallWithResult('blob_list', params), // Wallet utilities - account_balance: (params = {}) => daemonCallWithResult('account_balance', params), + wallet_balance: (params = {}) => daemonCallWithResult('wallet_balance', params), account_decrypt: () => daemonCallWithResult('account_decrypt', {}), account_encrypt: (params = {}) => daemonCallWithResult('account_encrypt', params), account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), account_list: (params = {}) => daemonCallWithResult('account_list', params), - account_send: (params = {}) => daemonCallWithResult('account_send', params), + wallet_send: (params = {}) => daemonCallWithResult('wallet_send', params), account_set: (params = {}) => daemonCallWithResult('account_set', params), address_is_mine: (params = {}) => daemonCallWithResult('address_is_mine', params), address_unused: (params = {}) => daemonCallWithResult('address_unused', params), diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 41c289d..7adf1d9 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -1,26 +1,24 @@ // @flow import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; -import isEqual from 'util/deep-equal'; -type sharedData = { +type SharedData = { version: '0.1', value: { subscriptions?: Array, tags?: Array, + blockedChannels?: Array, }, }; -let oldShared; -const sharedPreferenceKey = 'shared'; - -function extractUserState(rawObj: sharedData) { +function extractUserState(rawObj: SharedData) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags } = rawObj.value; + const { subscriptions, tags, blockedChannels } = rawObj.value; return { ...(subscriptions ? { subscriptions } : {}), ...(tags ? { tags } : {}), + ...(blockedChannels ? { blockedChannels } : {}), }; } @@ -34,40 +32,10 @@ export function doPopulateSharedUserState(settings: any) { }; } -export function sharedStateSubscriber( - state: any, - filters: any, - version: string, - accountId: string, - walletId: string -) { - // the shared object that will be saved - const shared = {}; - - Object.keys(filters).forEach(key => { - const filter = filters[key]; - const { source, property, transform } = filter; - let value = state[source][property]; - if (transform) { - value = transform(value); - } - - shared[key] = value; - }); - - if (!isEqual(oldShared, shared)) { - // only update if the preference changed from last call in the same session - oldShared = shared; - doPreferenceSet(sharedPreferenceKey, shared, version, accountId, walletId); - } -} - export function doPreferenceSet( key: string, value: any, version: string, - accountId: string, - walletId: string, success: Function, fail: Function ) { @@ -80,8 +48,6 @@ export function doPreferenceSet( const options = { key, value: JSON.stringify(preference), - ...(accountId ? { account_id: accountId } : {}), - ...(walletId ? { wallet_id: walletId } : {}), }; Lbry.preference_set(options) @@ -95,17 +61,9 @@ export function doPreferenceSet( }); } -export function doPreferenceGet( - key: string, - accountId?: string, - walletId?: string, - success: Function, - fail?: Function -) { +export function doPreferenceGet(key: string, success: Function, fail?: Function) { const options = { key, - ...(accountId ? { account_id: accountId } : {}), - ...(walletId ? { wallet_id: walletId } : {}), }; Lbry.preference_get(options) diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index fc1a7ba..4078649 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -10,7 +10,7 @@ export function doUpdateBalance() { const { wallet: { totalBalance: totalInStore }, } = getState(); - return Lbry.account_balance({ reserved_subtotals: true }).then((response: BalanceResponse) => { + return Lbry.wallet_balance({ reserved_subtotals: true }).then(response => { const { available, reserved, reserved_subtotals, total } = response; const { claims, supports, tips } = reserved_subtotals; const totalFloat = parseFloat(total); @@ -165,7 +165,7 @@ export function doSendDraftTransaction(address, amount) { ); }; - Lbry.account_send({ + Lbry.wallet_send({ addresses: [address], amount: creditsToString(amount), }).then(successCallback, errorCallback); diff --git a/src/redux/middleware/shared-state.js b/src/redux/middleware/shared-state.js new file mode 100644 index 0000000..7ca42c9 --- /dev/null +++ b/src/redux/middleware/shared-state.js @@ -0,0 +1,51 @@ +// @flow +import isEqual from 'util/deep-equal'; +import { doPreferenceSet } from 'redux/actions/sync'; + +const SHARED_PREFERENCE_KEY = 'shared'; +const SHARED_PREFERENCE_VERSION = '0.1'; +let oldShared = {}; + +export const buildSharedStateMiddleware = ( + actions: Array, + sharedStateFilters: {}, + sharedStateCb?: any => void +) => ({ getState, dispatch }: { getState: () => {}, dispatch: any => void }) => ( + next: ({}) => void +) => (action: { type: string, data: any }) => { + const currentState = getState(); + + // We don't care if sync is disabled here, we always want to backup preferences to the wallet + if (!actions.includes(action.type)) { + return next(action); + } + + const actionResult = next(action); + // Call `getState` after calling `next` to ensure the state has updated in response to the action + const nextState = getState(); + const shared = {}; + + Object.keys(sharedStateFilters).forEach(key => { + const filter = sharedStateFilters[key]; + const { source, property, transform } = filter; + let value = nextState[source][property]; + if (transform) { + value = transform(value); + } + + shared[key] = value; + }); + + if (!isEqual(oldShared, shared)) { + // only update if the preference changed from last call in the same session + oldShared = shared; + doPreferenceSet(SHARED_PREFERENCE_KEY, shared, SHARED_PREFERENCE_VERSION); + + if (sharedStateCb) { + // Pass dispatch to the callback to consumers can dispatch actions in response to preference set + sharedStateCb(dispatch); + } + } + + return actionResult; +}; diff --git a/src/redux/reducers/blocked.js b/src/redux/reducers/blocked.js index 4855fe0..7a9fd85 100644 --- a/src/redux/reducers/blocked.js +++ b/src/redux/reducers/blocked.js @@ -26,6 +26,17 @@ export const blockedReducer = handleActions( blockedChannels: newBlockedChannels, }; }, + [ACTIONS.USER_STATE_POPULATE]: ( + state: BlocklistState, + action: { data: { blockedChannels: ?Array } } + ) => { + const { blockedChannels } = action.data; + return { + ...state, + blockedChannels: + blockedChannels && blockedChannels.length ? blockedChannels : state.blockedChannels, + }; + }, }, defaultState ); -- 2.45.2 From 48bc1e18f9111e30b672138a8a3fa630371681e6 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 14 Oct 2019 23:56:14 -0400 Subject: [PATCH 174/371] pass getState to calback too --- dist/bundle.es.js | 2 +- src/redux/middleware/shared-state.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 909cc06..d9fb456 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1470,7 +1470,7 @@ const buildSharedStateMiddleware = (actions, sharedStateFilters, sharedStateCb) if (sharedStateCb) { // Pass dispatch to the callback to consumers can dispatch actions in response to preference set - sharedStateCb(dispatch); + sharedStateCb({ dispatch, getState }); } } diff --git a/src/redux/middleware/shared-state.js b/src/redux/middleware/shared-state.js index 7ca42c9..010638b 100644 --- a/src/redux/middleware/shared-state.js +++ b/src/redux/middleware/shared-state.js @@ -43,7 +43,7 @@ export const buildSharedStateMiddleware = ( if (sharedStateCb) { // Pass dispatch to the callback to consumers can dispatch actions in response to preference set - sharedStateCb(dispatch); + sharedStateCb({ dispatch, getState }); } } -- 2.45.2 From cd69946d4ca016c896639aa401d8f6b87d3e410e Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 15 Oct 2019 00:01:21 -0400 Subject: [PATCH 175/371] add back default followed tags --- dist/bundle.es.js | 2 +- src/redux/reducers/tags.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d9fb456..60d63d9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4803,7 +4803,7 @@ function getDefaultKnownTags() { } const defaultState$8 = { - followedTags: [], + followedTags: DEFAULT_FOLLOWED_TAGS, knownTags: getDefaultKnownTags() }; diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index 1bb6430..206abf6 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -14,7 +14,7 @@ function getDefaultKnownTags() { } const defaultState: TagState = { - followedTags: [], + followedTags: DEFAULT_FOLLOWED_TAGS, knownTags: getDefaultKnownTags(), }; -- 2.45.2 From c5aea33d82f111ce0717e7f3126e687d83eab6e1 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 15 Oct 2019 13:03:07 +0100 Subject: [PATCH 176/371] add SHOW_URI_BAR_SUGGESTIONS setting constant --- dist/bundle.es.js | 4 +++- src/constants/settings.js | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ecb9221..c7e96e3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -576,6 +576,7 @@ const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; const FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; const KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; +const SHOW_URI_BAR_SUGGESTIONS = 'showUriBarSuggestions'; var settings = /*#__PURE__*/Object.freeze({ CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, @@ -591,7 +592,8 @@ var settings = /*#__PURE__*/Object.freeze({ AUTOMATIC_DARK_MODE_ENABLED: AUTOMATIC_DARK_MODE_ENABLED, BACKGROUND_PLAY_ENABLED: BACKGROUND_PLAY_ENABLED, FOREGROUND_NOTIFICATION_ENABLED: FOREGROUND_NOTIFICATION_ENABLED, - KEEP_DAEMON_RUNNING: KEEP_DAEMON_RUNNING + KEEP_DAEMON_RUNNING: KEEP_DAEMON_RUNNING, + SHOW_URI_BAR_SUGGESTIONS: SHOW_URI_BAR_SUGGESTIONS }); const DATE_NEW = 'dateNew'; diff --git a/src/constants/settings.js b/src/constants/settings.js index 0c5f88b..767791c 100644 --- a/src/constants/settings.js +++ b/src/constants/settings.js @@ -17,3 +17,4 @@ export const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; export const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; export const FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; export const KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; +export const SHOW_URI_BAR_SUGGESTIONS = 'showUriBarSuggestions'; -- 2.45.2 From 6edcf747e10919605b05b905214fe1d3286898e3 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 15 Oct 2019 11:20:00 -0400 Subject: [PATCH 177/371] always call callback if matching action is fired --- dist/bundle.es.js | 8 ++++---- src/redux/middleware/shared-state.js | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c7e96e3..f860318 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1469,11 +1469,11 @@ const buildSharedStateMiddleware = (actions, sharedStateFilters, sharedStateCb) // only update if the preference changed from last call in the same session oldShared = shared; doPreferenceSet(SHARED_PREFERENCE_KEY, shared, SHARED_PREFERENCE_VERSION); + } - if (sharedStateCb) { - // Pass dispatch to the callback to consumers can dispatch actions in response to preference set - sharedStateCb({ dispatch, getState }); - } + if (sharedStateCb) { + // Pass dispatch to the callback to consumers can dispatch actions in response to preference set + sharedStateCb({ dispatch, getState }); } return actionResult; diff --git a/src/redux/middleware/shared-state.js b/src/redux/middleware/shared-state.js index 010638b..a211b16 100644 --- a/src/redux/middleware/shared-state.js +++ b/src/redux/middleware/shared-state.js @@ -40,11 +40,11 @@ export const buildSharedStateMiddleware = ( // only update if the preference changed from last call in the same session oldShared = shared; doPreferenceSet(SHARED_PREFERENCE_KEY, shared, SHARED_PREFERENCE_VERSION); + } - if (sharedStateCb) { - // Pass dispatch to the callback to consumers can dispatch actions in response to preference set - sharedStateCb({ dispatch, getState }); - } + if (sharedStateCb) { + // Pass dispatch to the callback to consumers can dispatch actions in response to preference set + sharedStateCb({ dispatch, getState }); } return actionResult; -- 2.45.2 From 0090f195eb88f4620db7d038f7b01eaa76119836 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 15 Oct 2019 13:56:28 -0400 Subject: [PATCH 178/371] fix: formatCredits on large numbers --- dist/bundle.es.js | 14 ++++++-------- src/util/format-credits.js | 16 ++++++---------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f860318..ee9fc34 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2093,18 +2093,12 @@ const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(sele const selectMyStreamUrlsCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); -function numberWithCommas(x) { - var parts = x.toString().split('.'); - parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); - return parts.join('.'); -} - function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount); let actualPrecision = parseFloat(precision); let suffix = ''; - if (Number.isNaN(actualAmount) || actualAmount === 0) return '0'; + if (!amount || Number.isNaN(actualAmount) || actualAmount === 0) return '0'; if (actualAmount >= 1000000) { if (precision <= 7) { @@ -2126,7 +2120,11 @@ function formatCredits(amount, precision, shortFormat = false) { } } - return numberWithCommas(actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\.*0+$/, '')) + suffix; + const number = actualAmount.toString().replace(/\.*0+$/, ''); + + return new Intl.NumberFormat('en-IN', { + maximumSignificantDigits: actualPrecision >= 0 ? actualPrecision : 1 + }).format(number) + suffix; } function formatFullPrice(amount, precision = 1) { diff --git a/src/util/format-credits.js b/src/util/format-credits.js index a090a33..bb0b1b4 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -1,15 +1,9 @@ -function numberWithCommas(x) { - var parts = x.toString().split('.'); - parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); - return parts.join('.'); -} - export function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount); let actualPrecision = parseFloat(precision); let suffix = ''; - if (Number.isNaN(actualAmount) || actualAmount === 0) return '0'; + if (!amount || Number.isNaN(actualAmount) || actualAmount === 0) return '0'; if (actualAmount >= 1000000) { if (precision <= 7) { @@ -31,10 +25,12 @@ export function formatCredits(amount, precision, shortFormat = false) { } } + const number = actualAmount.toString().replace(/\.*0+$/, ''); + return ( - numberWithCommas( - actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\.*0+$/, '') - ) + suffix + new Intl.NumberFormat('en-IN', { + maximumSignificantDigits: actualPrecision >= 0 ? actualPrecision : 1, + }).format(number) + suffix ); } -- 2.45.2 From 98723e0c3cc48340d5a1c7100700fcae69298a2e Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 15 Oct 2019 23:11:03 +0100 Subject: [PATCH 179/371] change account_* sdk calls to wallet_* --- dist/bundle.es.js | 16 ++++++++-------- dist/flow-typed/Lbry.js | 38 +++++++++++-------------------------- flow-typed/Lbry.js | 38 +++++++++++-------------------------- src/lbry.js | 10 +++++----- src/redux/actions/wallet.js | 6 +++--- 5 files changed, 38 insertions(+), 70 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ee9fc34..bc8a50a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -764,12 +764,12 @@ const Lbry = { // Wallet utilities wallet_balance: (params = {}) => daemonCallWithResult('wallet_balance', params), - account_decrypt: () => daemonCallWithResult('account_decrypt', {}), - account_encrypt: (params = {}) => daemonCallWithResult('account_encrypt', params), - account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), - account_list: (params = {}) => daemonCallWithResult('account_list', params), + wallet_decrypt: () => daemonCallWithResult('wallet_decrypt', {}), + wallet_encrypt: (params = {}) => daemonCallWithResult('wallet_encrypt', params), + wallet_unlock: (params = {}) => daemonCallWithResult('wallet_unlock', params), + wallet_list: (params = {}) => daemonCallWithResult('wallet_list', params), wallet_send: (params = {}) => daemonCallWithResult('wallet_send', params), - account_set: (params = {}) => daemonCallWithResult('account_set', params), + wallet_status: (params = {}) => daemonCallWithResult('wallet_status', params), address_is_mine: (params = {}) => daemonCallWithResult('address_is_mine', params), address_unused: (params = {}) => daemonCallWithResult('address_unused', params), address_list: (params = {}) => daemonCallWithResult('address_list', params), @@ -2390,7 +2390,7 @@ function doWalletEncrypt(newPassword) { type: WALLET_ENCRYPT_START }); - lbryProxy.account_encrypt({ new_password: newPassword }).then(result => { + lbryProxy.wallet_encrypt({ new_password: newPassword }).then(result => { if (result === true) { dispatch({ type: WALLET_ENCRYPT_COMPLETED, @@ -2412,7 +2412,7 @@ function doWalletUnlock(password) { type: WALLET_UNLOCK_START }); - lbryProxy.account_unlock({ password }).then(result => { + lbryProxy.wallet_unlock({ password }).then(result => { if (result === true) { dispatch({ type: WALLET_UNLOCK_COMPLETED, @@ -2434,7 +2434,7 @@ function doWalletDecrypt() { type: WALLET_DECRYPT_START }); - lbryProxy.account_decrypt().then(result => { + lbryProxy.wallet_decrypt().then(result => { if (result === true) { dispatch({ type: WALLET_DECRYPT_COMPLETED, diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 1db0dc8..200acce 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -129,37 +129,21 @@ declare type TxListResponse = Array; declare type BlobListResponse = Array; -declare type AccountListResponse = Array<{ +declare type WalletListResponse = Array<{ id: string, - is_default: string, - ledger: string, name: string, - seed: string, - encrypted: string, - private_key: string, - public_key: string, - address_generator: string, - modified_on: string, }>; +declare type WalletStatusResponse = { + is_encrypted: boolean, + is_locked: boolean, +}; + declare type SyncApplyResponse = { hash: string, data: string, }; -declare type AccountSetResponse = Array<{ - id: string, - is_default: string, - ledger: string, - name: string, - seed: string, - encrypted: string, - private_key: string, - public_key: string, - address_generator: string, - modified_on: string, -}>; - declare type SupportAbandonResponse = GenericTxResponse; // @@ -211,12 +195,12 @@ declare type LbryTypes = { comment_create: (params: {}) => Promise, // Wallet utilities wallet_balance: (params: {}) => Promise, - account_decrypt: (prams: {}) => Promise, - account_encrypt: (params: {}) => Promise, - account_unlock: (params: {}) => Promise, - account_list: (params: {}) => Promise, + wallet_decrypt: (prams: {}) => Promise, + wallet_encrypt: (params: {}) => Promise, + wallet_unlock: (params: {}) => Promise, + wallet_list: (params: {}) => Promise, wallet_send: (params: {}) => Promise, - account_set: (params: {}) => Promise, + wallet_status: (params: {}) => Promise, address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address address_list: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 1db0dc8..200acce 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -129,37 +129,21 @@ declare type TxListResponse = Array; declare type BlobListResponse = Array; -declare type AccountListResponse = Array<{ +declare type WalletListResponse = Array<{ id: string, - is_default: string, - ledger: string, name: string, - seed: string, - encrypted: string, - private_key: string, - public_key: string, - address_generator: string, - modified_on: string, }>; +declare type WalletStatusResponse = { + is_encrypted: boolean, + is_locked: boolean, +}; + declare type SyncApplyResponse = { hash: string, data: string, }; -declare type AccountSetResponse = Array<{ - id: string, - is_default: string, - ledger: string, - name: string, - seed: string, - encrypted: string, - private_key: string, - public_key: string, - address_generator: string, - modified_on: string, -}>; - declare type SupportAbandonResponse = GenericTxResponse; // @@ -211,12 +195,12 @@ declare type LbryTypes = { comment_create: (params: {}) => Promise, // Wallet utilities wallet_balance: (params: {}) => Promise, - account_decrypt: (prams: {}) => Promise, - account_encrypt: (params: {}) => Promise, - account_unlock: (params: {}) => Promise, - account_list: (params: {}) => Promise, + wallet_decrypt: (prams: {}) => Promise, + wallet_encrypt: (params: {}) => Promise, + wallet_unlock: (params: {}) => Promise, + wallet_list: (params: {}) => Promise, wallet_send: (params: {}) => Promise, - account_set: (params: {}) => Promise, + wallet_status: (params: {}) => Promise, address_is_mine: (params: {}) => Promise, address_unused: (params: {}) => Promise, // New address address_list: (params: {}) => Promise, diff --git a/src/lbry.js b/src/lbry.js index f13e945..8761c72 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -94,12 +94,12 @@ const Lbry: LbryTypes = { // Wallet utilities wallet_balance: (params = {}) => daemonCallWithResult('wallet_balance', params), - account_decrypt: () => daemonCallWithResult('account_decrypt', {}), - account_encrypt: (params = {}) => daemonCallWithResult('account_encrypt', params), - account_unlock: (params = {}) => daemonCallWithResult('account_unlock', params), - account_list: (params = {}) => daemonCallWithResult('account_list', params), + wallet_decrypt: () => daemonCallWithResult('wallet_decrypt', {}), + wallet_encrypt: (params = {}) => daemonCallWithResult('wallet_encrypt', params), + wallet_unlock: (params = {}) => daemonCallWithResult('wallet_unlock', params), + wallet_list: (params = {}) => daemonCallWithResult('wallet_list', params), wallet_send: (params = {}) => daemonCallWithResult('wallet_send', params), - account_set: (params = {}) => daemonCallWithResult('account_set', params), + wallet_status: (params = {}) => daemonCallWithResult('wallet_status', params), address_is_mine: (params = {}) => daemonCallWithResult('address_is_mine', params), address_unused: (params = {}) => daemonCallWithResult('address_unused', params), address_list: (params = {}) => daemonCallWithResult('address_list', params), diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 4078649..2f4f87b 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -264,7 +264,7 @@ export function doWalletEncrypt(newPassword) { type: ACTIONS.WALLET_ENCRYPT_START, }); - Lbry.account_encrypt({ new_password: newPassword }).then(result => { + Lbry.wallet_encrypt({ new_password: newPassword }).then(result => { if (result === true) { dispatch({ type: ACTIONS.WALLET_ENCRYPT_COMPLETED, @@ -286,7 +286,7 @@ export function doWalletUnlock(password) { type: ACTIONS.WALLET_UNLOCK_START, }); - Lbry.account_unlock({ password }).then(result => { + Lbry.wallet_unlock({ password }).then(result => { if (result === true) { dispatch({ type: ACTIONS.WALLET_UNLOCK_COMPLETED, @@ -330,7 +330,7 @@ export function doWalletDecrypt() { type: ACTIONS.WALLET_DECRYPT_START, }); - Lbry.account_decrypt().then(result => { + Lbry.wallet_decrypt().then(result => { if (result === true) { dispatch({ type: ACTIONS.WALLET_DECRYPT_COMPLETED, -- 2.45.2 From 9919a8150998822ca997cd23418f023d64d4a3da Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 16 Oct 2019 10:05:31 -0400 Subject: [PATCH 180/371] Revert "fix: formatCredits on large numbers" This reverts commit 0090f195eb88f4620db7d038f7b01eaa76119836. --- dist/bundle.es.js | 14 ++++++++------ src/util/format-credits.js | 16 ++++++++++------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index bc8a50a..e177391 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2093,12 +2093,18 @@ const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(sele const selectMyStreamUrlsCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); +function numberWithCommas(x) { + var parts = x.toString().split('.'); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); + return parts.join('.'); +} + function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount); let actualPrecision = parseFloat(precision); let suffix = ''; - if (!amount || Number.isNaN(actualAmount) || actualAmount === 0) return '0'; + if (Number.isNaN(actualAmount) || actualAmount === 0) return '0'; if (actualAmount >= 1000000) { if (precision <= 7) { @@ -2120,11 +2126,7 @@ function formatCredits(amount, precision, shortFormat = false) { } } - const number = actualAmount.toString().replace(/\.*0+$/, ''); - - return new Intl.NumberFormat('en-IN', { - maximumSignificantDigits: actualPrecision >= 0 ? actualPrecision : 1 - }).format(number) + suffix; + return numberWithCommas(actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\.*0+$/, '')) + suffix; } function formatFullPrice(amount, precision = 1) { diff --git a/src/util/format-credits.js b/src/util/format-credits.js index bb0b1b4..a090a33 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -1,9 +1,15 @@ +function numberWithCommas(x) { + var parts = x.toString().split('.'); + parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); + return parts.join('.'); +} + export function formatCredits(amount, precision, shortFormat = false) { let actualAmount = parseFloat(amount); let actualPrecision = parseFloat(precision); let suffix = ''; - if (!amount || Number.isNaN(actualAmount) || actualAmount === 0) return '0'; + if (Number.isNaN(actualAmount) || actualAmount === 0) return '0'; if (actualAmount >= 1000000) { if (precision <= 7) { @@ -25,12 +31,10 @@ export function formatCredits(amount, precision, shortFormat = false) { } } - const number = actualAmount.toString().replace(/\.*0+$/, ''); - return ( - new Intl.NumberFormat('en-IN', { - maximumSignificantDigits: actualPrecision >= 0 ? actualPrecision : 1, - }).format(number) + suffix + numberWithCommas( + actualAmount.toFixed(actualPrecision >= 0 ? actualPrecision : 1).replace(/\.*0+$/, '') + ) + suffix ); } -- 2.45.2 From b11eb3262b0ce1256bd7cb9543cdfc162697c357 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Mon, 14 Oct 2019 22:08:37 -0400 Subject: [PATCH 181/371] fix: comment create without existing channel --- dist/bundle.es.js | 2 +- src/redux/actions/comments.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e177391..8717d44 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3854,7 +3854,7 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { type: COMMENT_CREATE_STARTED }); const myChannels = selectMyChannelClaims(state); - const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); + const namedChannelClaim = myChannels && myChannels.find(myChannel => myChannel.name === channel); const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null; return lbryProxy.comment_create({ comment, diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 3de70e6..61e9f6b 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -48,7 +48,8 @@ export function doCommentCreate( type: ACTIONS.COMMENT_CREATE_STARTED, }); const myChannels = selectMyChannelClaims(state); - const namedChannelClaim = myChannels.find(myChannel => myChannel.name === channel); + const namedChannelClaim = + myChannels && myChannels.find(myChannel => myChannel.name === channel); const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null; return Lbry.comment_create({ comment, -- 2.45.2 From 0aeb6e175f3bfbf8730c904171b42b21d1ecc908 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 16 Oct 2019 13:32:50 -0400 Subject: [PATCH 182/371] update myclaims on Abandon Succeeded --- dist/bundle.es.js | 19 ++++++++++++++++--- src/redux/actions/claims.js | 2 +- src/redux/reducers/claims.js | 5 +++-- 3 files changed, 20 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8717d44..4ef8b57 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1079,6 +1079,18 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; + { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } + } + if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -2605,7 +2617,7 @@ function doAbandonClaim(txid, nout) { const isClaim = !!claimToAbandon; const startedActionType = isClaim ? ABANDON_CLAIM_STARTED : ABANDON_SUPPORT_STARTED; - const completedActionType = isClaim ? ABANDON_CLAIM_STARTED : ABANDON_SUPPORT_COMPLETED; + const completedActionType = isClaim ? ABANDON_CLAIM_SUCCEEDED : ABANDON_SUPPORT_COMPLETED; dispatch({ type: startedActionType, @@ -4000,7 +4012,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById = Object.assign({}, state.pendingById); - const myClaims = state.myClaims || []; + const myClaims = state.myClaims ? state.myClaims.slice() : []; claims.forEach(claim => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); @@ -4131,6 +4143,7 @@ reducers[ABANDON_CLAIM_STARTED] = (state, action) => { reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { const { claimId } = action.data; const byId = Object.assign({}, state.byId); + const newMyClaims = state.myClaims ? state.myClaims.slice() : []; const claimsByUri = Object.assign({}, state.claimsByUri); Object.keys(claimsByUri).forEach(uri => { @@ -4138,7 +4151,7 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { delete claimsByUri[uri]; } }); - + const myClaims = newMyClaims.filter(i => i.claim_id && i.claim_id !== claimId); delete byId[claimId]; return Object.assign({}, state, { diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 02e19b5..3dffd6b 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -137,7 +137,7 @@ export function doAbandonClaim(txid: string, nout: number) { ? ACTIONS.ABANDON_CLAIM_STARTED : ACTIONS.ABANDON_SUPPORT_STARTED; const completedActionType = isClaim - ? ACTIONS.ABANDON_CLAIM_STARTED + ? ACTIONS.ABANDON_CLAIM_SUCCEEDED : ACTIONS.ABANDON_SUPPORT_COMPLETED; dispatch({ diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index b82b56a..8f08dc3 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -156,7 +156,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); - const myClaims = state.myClaims || []; + const myClaims = state.myClaims ? state.myClaims.slice() : []; claims.forEach((claim: Claim) => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); @@ -289,6 +289,7 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State => reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State => { const { claimId }: { claimId: string } = action.data; const byId = Object.assign({}, state.byId); + const newMyClaims = state.myClaims ? state.myClaims.slice() : []; const claimsByUri = Object.assign({}, state.claimsByUri); Object.keys(claimsByUri).forEach(uri => { @@ -296,7 +297,7 @@ reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State = delete claimsByUri[uri]; } }); - + const myClaims = newMyClaims.filter(i => i.claim_id && i.claim_id !== claimId); delete byId[claimId]; return Object.assign({}, state, { -- 2.45.2 From 69f8022b1f855a0efa67bdd1591f9505672ab225 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 16 Oct 2019 19:53:25 -0400 Subject: [PATCH 183/371] build --- dist/bundle.es.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4ef8b57..509bc03 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1079,18 +1079,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } -- 2.45.2 From eaea420aad7d64d2a971ffbae10e2b1f1bc46f4f Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Thu, 17 Oct 2019 11:36:39 -0400 Subject: [PATCH 184/371] fix: wallet encryption status for the settings page --- dist/bundle.es.js | 6 +++--- src/redux/actions/wallet.js | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 509bc03..17ab31d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2458,11 +2458,11 @@ function doWalletStatus() { type: WALLET_STATUS_START }); - lbryProxy.status().then(status => { - if (status && status.wallet) { + lbryProxy.wallet_status().then(status => { + if (status) { dispatch({ type: WALLET_STATUS_COMPLETED, - result: status.wallet.is_encrypted + result: status.is_encrypted }); } }); diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 2f4f87b..2b9032f 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -352,11 +352,11 @@ export function doWalletStatus() { type: ACTIONS.WALLET_STATUS_START, }); - Lbry.status().then(status => { - if (status && status.wallet) { + Lbry.wallet_status().then(status => { + if (status) { dispatch({ type: ACTIONS.WALLET_STATUS_COMPLETED, - result: status.wallet.is_encrypted, + result: status.is_encrypted, }); } }); -- 2.45.2 From 9028aecfe1932b0e06625a8d0e2b782ea33e95ab Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 17 Oct 2019 14:05:33 -0400 Subject: [PATCH 185/371] returns myClaims in reducer --- dist/bundle.es.js | 1 + src/redux/reducers/claims.js | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 509bc03..776971b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4143,6 +4143,7 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { delete byId[claimId]; return Object.assign({}, state, { + myClaims, byId, claimsByUri }); diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 8f08dc3..f828645 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -301,6 +301,7 @@ reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State = delete byId[claimId]; return Object.assign({}, state, { + myClaims, byId, claimsByUri, }); -- 2.45.2 From 5ee22d42d6d976cf293e5cea55d866399e593c59 Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 30 Sep 2019 15:16:38 -0400 Subject: [PATCH 186/371] tv publish --- dist/bundle.es.js | 38 ++++++++++++++++++++++++++++++++---- dist/flow-typed/Lbry.js | 2 +- flow-typed/Lbry.js | 2 +- src/constants/headers.js | 1 + src/constants/speech_urls.js | 2 ++ src/index.js | 2 ++ src/lbry.js | 11 ++++++++++- src/redux/actions/publish.js | 7 ++++--- 8 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 src/constants/headers.js create mode 100644 src/constants/speech_urls.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e31750c..e30f9b3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -652,6 +652,12 @@ var transaction_list = /*#__PURE__*/Object.freeze({ PAGE_SIZE: PAGE_SIZE$1 }); +const AUTH_TOKEN = 'X-Lbry-Auth-Token'; + +var headers = /*#__PURE__*/Object.freeze({ + AUTH_TOKEN: AUTH_TOKEN +}); + const SEARCH_TYPES = { FILE: 'file', CHANNEL: 'channel', @@ -709,6 +715,7 @@ const Lbry = { setOverride: (methodName, newMethod) => { Lbry.overrides[methodName] = newMethod; }, + getApiRequestHeaders: () => Lbry.apiRequestHeaders, // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType, fileName) => { @@ -744,7 +751,6 @@ const Lbry = { // Claim fetching and manipulation resolve: params => daemonCallWithResult('resolve', params), get: params => daemonCallWithResult('get', params), - publish: params => daemonCallWithResult('publish', params), claim_search: params => daemonCallWithResult('claim_search', params), claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), @@ -814,6 +820,14 @@ const Lbry = { } }; +Lbry.publish = (params = {}) => new Promise((resolve, reject) => { + if (Lbry.overrides.publish) { + Lbry.overrides.publish(params).then(resolve, reject); + } else { + apiCall('publish', params, resolve, reject); + } +}); + function checkAndParse(response) { if (response.status >= 200 && response.status < 300) { return response.json(); @@ -1079,6 +1093,18 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; + { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } + } + if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -3192,6 +3218,9 @@ function doSetFileListSort(page, value) { }; } +const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; +const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; + 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 selectState$5 = state => state.publish || {}; @@ -3289,7 +3318,7 @@ const doResetThumbnailStatus = () => dispatch => { } }); - return fetch('https://spee.ch/api/config/site/publishing').then(res => res.json()).then(status => { + return fetch(SPEECH_STATUS).then(res => res.json()).then(status => { if (status.disabled) { throw Error(); } @@ -3358,7 +3387,7 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter, fs, path) => di // $FlowFixMe data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); - return fetch('https://spee.ch/api/claim/publish', { + return fetch(SPEECH_PUBLISH, { method: 'POST', body: data }).then(response => response.json()).then(json => json.success ? dispatch({ @@ -3390,7 +3419,7 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter, fs, path) => di data.append('name', name); data.append('file', file); - return fetch('https://spee.ch/api/claim/publish', { + return fetch(SPEECH_PUBLISH, { method: 'POST', body: data }).then(response => response.json()).then(json => json.success ? dispatch({ @@ -5260,6 +5289,7 @@ exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; exports.DEFAULT_FOLLOWED_TAGS = DEFAULT_FOLLOWED_TAGS; exports.DEFAULT_KNOWN_TAGS = DEFAULT_KNOWN_TAGS; +exports.HEADERS = headers; exports.LICENSES = licenses; exports.Lbry = lbryProxy; exports.MATURE_TAGS = MATURE_TAGS; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 200acce..c38b59e 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -168,7 +168,7 @@ declare type LbryTypes = { version: () => Promise, resolve: (params: {}) => Promise, get: (params: {}) => Promise, - publish: (params: {}) => Promise, + publish?: (params: {}) => Promise, claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 200acce..c38b59e 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -168,7 +168,7 @@ declare type LbryTypes = { version: () => Promise, resolve: (params: {}) => Promise, get: (params: {}) => Promise, - publish: (params: {}) => Promise, + publish?: (params: {}) => Promise, claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, diff --git a/src/constants/headers.js b/src/constants/headers.js new file mode 100644 index 0000000..84aead8 --- /dev/null +++ b/src/constants/headers.js @@ -0,0 +1 @@ +export const AUTH_TOKEN = 'X-Lbry-Auth-Token'; diff --git a/src/constants/speech_urls.js b/src/constants/speech_urls.js new file mode 100644 index 0000000..d61abab --- /dev/null +++ b/src/constants/speech_urls.js @@ -0,0 +1,2 @@ +export const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; +export const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; diff --git a/src/index.js b/src/index.js index 59abad9..47f7022 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import * as SORT_OPTIONS from 'constants/sort_options'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as TRANSACTIONS from 'constants/transaction_types'; import * as TX_LIST from 'constants/transaction_list'; +import * as HEADERS from 'constants/headers'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS } from 'constants/tags'; import Lbry from 'lbry'; @@ -28,6 +29,7 @@ export { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS, + HEADERS, }; // common diff --git a/src/lbry.js b/src/lbry.js index 8761c72..f54ad42 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -30,6 +30,7 @@ const Lbry: LbryTypes = { setOverride: (methodName, newMethod) => { Lbry.overrides[methodName] = newMethod; }, + getApiRequestHeaders: () => Lbry.apiRequestHeaders, // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType?: string, fileName: ?string) => { @@ -74,7 +75,6 @@ const Lbry: LbryTypes = { // Claim fetching and manipulation resolve: params => daemonCallWithResult('resolve', params), get: params => daemonCallWithResult('get', params), - publish: params => daemonCallWithResult('publish', params), claim_search: params => daemonCallWithResult('claim_search', params), claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), @@ -146,6 +146,15 @@ const Lbry: LbryTypes = { }, }; +Lbry.publish = (params = {}) => + new Promise((resolve, reject) => { + if (Lbry.overrides.publish) { + Lbry.overrides.publish(params).then(resolve, reject); + } else { + apiCall('publish', params, resolve, reject); + } + }); + function checkAndParse(response) { if (response.status >= 200 && response.status < 300) { return response.json(); diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index e622cfb..a00aca0 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -1,5 +1,6 @@ // @flow import { CC_LICENSES, COPYRIGHT, OTHER, NONE, PUBLIC_DOMAIN } from 'constants/licenses'; +import { SPEECH_STATUS, SPEECH_PUBLISH } from 'constants/speech_urls'; import * as ACTIONS from 'constants/action_types'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import Lbry from 'lbry'; @@ -22,7 +23,7 @@ export const doResetThumbnailStatus = () => (dispatch: Dispatch) => { }, }); - return fetch('https://spee.ch/api/config/site/publishing') + return fetch(SPEECH_STATUS) .then(res => res.json()) .then(status => { if (status.disabled) { @@ -110,7 +111,7 @@ export const doUploadThumbnail = ( // $FlowFixMe data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); - return fetch('https://spee.ch/api/claim/publish', { + return fetch(SPEECH_PUBLISH, { method: 'POST', body: data, }) @@ -149,7 +150,7 @@ export const doUploadThumbnail = ( data.append('name', name); data.append('file', file); - return fetch('https://spee.ch/api/claim/publish', { + return fetch(SPEECH_PUBLISH, { method: 'POST', body: data, }) -- 2.45.2 From 4aa1f6f379061becf4485380416ec00faed3be6c Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 7 Oct 2019 12:33:06 -0400 Subject: [PATCH 187/371] doUploadThumbnail signature takes local path OR File() object --- dist/bundle.es.js | 40 ++++++++++++------------------------ src/constants/headers.js | 1 - src/index.js | 4 ++-- src/redux/actions/publish.js | 23 ++++++++++----------- 4 files changed, 26 insertions(+), 42 deletions(-) delete mode 100644 src/constants/headers.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e30f9b3..dc02455 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -652,10 +652,12 @@ var transaction_list = /*#__PURE__*/Object.freeze({ PAGE_SIZE: PAGE_SIZE$1 }); -const AUTH_TOKEN = 'X-Lbry-Auth-Token'; +const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; +const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; -var headers = /*#__PURE__*/Object.freeze({ - AUTH_TOKEN: AUTH_TOKEN +var speech_urls = /*#__PURE__*/Object.freeze({ + SPEECH_STATUS: SPEECH_STATUS, + SPEECH_PUBLISH: SPEECH_PUBLISH }); const SEARCH_TYPES = { @@ -1093,18 +1095,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -3218,9 +3208,6 @@ function doSetFileListSort(page, value) { }; } -const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; -const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; - 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 selectState$5 = state => state.publish || {}; @@ -3349,7 +3336,7 @@ const doUpdatePublishForm = publishFormValue => dispatch => dispatch({ data: _extends$5({}, publishFormValue) }); -const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter, fs, path) => dispatch => { +const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => dispatch => { let thumbnail, fileExt, fileName, fileType; const makeid = () => { @@ -3399,23 +3386,22 @@ const doUploadThumbnail = (filePath, thumbnailBuffer, fsAdapter, fs, path) => di }) : uploadError(json.message)).catch(err => uploadError(err.message)); }); } else { - if (filePath) { + if (filePath && fs && path) { thumbnail = fs.readFileSync(filePath); fileExt = path.extname(filePath); fileName = path.basename(filePath); fileType = `image/${fileExt.slice(1)}`; - } else if (thumbnailBuffer) { - thumbnail = thumbnailBuffer; - fileExt = '.png'; - fileName = 'thumbnail.png'; - fileType = 'image/png'; + } else if (thumbnailBlob) { + fileExt = `.${thumbnailBlob.type && thumbnailBlob.type.split('/')[1]}`; + fileName = thumbnailBlob.name; + fileType = thumbnailBlob.type; } else { return null; } const data = new FormData(); const name = makeid(); - const file = new File([thumbnail], fileName, { type: fileType }); + const file = thumbnailBlob || thumbnail && new File([thumbnail], fileName, { type: fileType }); data.append('name', name); data.append('file', file); @@ -5289,7 +5275,6 @@ exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; exports.DEFAULT_FOLLOWED_TAGS = DEFAULT_FOLLOWED_TAGS; exports.DEFAULT_KNOWN_TAGS = DEFAULT_KNOWN_TAGS; -exports.HEADERS = headers; exports.LICENSES = licenses; exports.Lbry = lbryProxy; exports.MATURE_TAGS = MATURE_TAGS; @@ -5298,6 +5283,7 @@ exports.SEARCH_OPTIONS = SEARCH_OPTIONS; exports.SEARCH_TYPES = SEARCH_TYPES; exports.SETTINGS = settings; exports.SORT_OPTIONS = sort_options; +exports.SPEECH_URLS = speech_urls; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; exports.TX_LIST = transaction_list; diff --git a/src/constants/headers.js b/src/constants/headers.js deleted file mode 100644 index 84aead8..0000000 --- a/src/constants/headers.js +++ /dev/null @@ -1 +0,0 @@ -export const AUTH_TOKEN = 'X-Lbry-Auth-Token'; diff --git a/src/index.js b/src/index.js index 47f7022..3543f5f 100644 --- a/src/index.js +++ b/src/index.js @@ -7,7 +7,7 @@ import * as SORT_OPTIONS from 'constants/sort_options'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as TRANSACTIONS from 'constants/transaction_types'; import * as TX_LIST from 'constants/transaction_list'; -import * as HEADERS from 'constants/headers'; +import * as SPEECH_URLS from 'constants/speech_urls'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS } from 'constants/tags'; import Lbry from 'lbry'; @@ -29,7 +29,7 @@ export { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS, - HEADERS, + SPEECH_URLS, }; // common diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index a00aca0..78d6503 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -63,11 +63,11 @@ export const doUpdatePublishForm = (publishFormValue: UpdatePublishFormData) => }); export const doUploadThumbnail = ( - filePath: string, - thumbnailBuffer: Uint8Array, - fsAdapter: any, - fs: any, - path: any + filePath?: string, + thumbnailBlob?: File, + fsAdapter?: any, + fs?: any, + path?: any ) => (dispatch: Dispatch) => { let thumbnail, fileExt, fileName, fileType; @@ -130,23 +130,22 @@ export const doUploadThumbnail = ( .catch(err => uploadError(err.message)); }); } else { - if (filePath) { + if (filePath && fs && path) { thumbnail = fs.readFileSync(filePath); fileExt = path.extname(filePath); fileName = path.basename(filePath); fileType = `image/${fileExt.slice(1)}`; - } else if (thumbnailBuffer) { - thumbnail = thumbnailBuffer; - fileExt = '.png'; - fileName = 'thumbnail.png'; - fileType = 'image/png'; + } else if (thumbnailBlob) { + fileExt = `.${thumbnailBlob.type && thumbnailBlob.type.split('/')[1]}`; + fileName = thumbnailBlob.name; + fileType = thumbnailBlob.type; } else { return null; } const data = new FormData(); const name = makeid(); - const file = new File([thumbnail], fileName, { type: fileType }); + const file = thumbnailBlob || (thumbnail && new File([thumbnail], fileName, { type: fileType })); data.append('name', name); data.append('file', file); -- 2.45.2 From f25659a1f77912998d73cce4533a8c1def62d601 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Thu, 24 Oct 2019 11:31:59 +0100 Subject: [PATCH 188/371] add constants for mobile notification settings --- dist/bundle.es.js | 10 +++++++++- src/constants/settings.js | 4 ++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index dc02455..aa0ef84 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -577,6 +577,10 @@ const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; const FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; const KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; const SHOW_URI_BAR_SUGGESTIONS = 'showUriBarSuggestions'; +const RECEIVE_SUBSCRIPTION_NOTIFICATIONS = 'receiveSubscriptionNotifications'; +const RECEIVE_REWARD_NOTIFICATIONS = 'receiveRewardNotifications'; +const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; +const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, @@ -593,7 +597,11 @@ var settings = /*#__PURE__*/Object.freeze({ BACKGROUND_PLAY_ENABLED: BACKGROUND_PLAY_ENABLED, FOREGROUND_NOTIFICATION_ENABLED: FOREGROUND_NOTIFICATION_ENABLED, KEEP_DAEMON_RUNNING: KEEP_DAEMON_RUNNING, - SHOW_URI_BAR_SUGGESTIONS: SHOW_URI_BAR_SUGGESTIONS + SHOW_URI_BAR_SUGGESTIONS: SHOW_URI_BAR_SUGGESTIONS, + RECEIVE_SUBSCRIPTION_NOTIFICATIONS: RECEIVE_SUBSCRIPTION_NOTIFICATIONS, + RECEIVE_REWARD_NOTIFICATIONS: RECEIVE_REWARD_NOTIFICATIONS, + RECEIVE_INTERESTS_NOTIFICATIONS: RECEIVE_INTERESTS_NOTIFICATIONS, + RECEIVE_CREATOR_NOTIFICATIONS: RECEIVE_CREATOR_NOTIFICATIONS }); const DATE_NEW = 'dateNew'; diff --git a/src/constants/settings.js b/src/constants/settings.js index 767791c..f0edbe5 100644 --- a/src/constants/settings.js +++ b/src/constants/settings.js @@ -18,3 +18,7 @@ export const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; export const FOREGROUND_NOTIFICATION_ENABLED = 'foregroundNotificationEnabled'; export const KEEP_DAEMON_RUNNING = 'keepDaemonRunning'; export const SHOW_URI_BAR_SUGGESTIONS = 'showUriBarSuggestions'; +export const RECEIVE_SUBSCRIPTION_NOTIFICATIONS = 'receiveSubscriptionNotifications'; +export const RECEIVE_REWARD_NOTIFICATIONS = 'receiveRewardNotifications'; +export const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; +export const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; -- 2.45.2 From d4ea2ca385d0a6a65ec3b4aaba345b3fbda35706 Mon Sep 17 00:00:00 2001 From: "hack.ily" Date: Wed, 30 Oct 2019 00:55:15 -0700 Subject: [PATCH 189/371] feat(wallet): Add new action and reducer to clear support transaction --- dist/bundle.es.js | 22 +++++++++++++--------- src/constants/action_types.js | 1 + src/index.js | 1 + src/redux/actions/wallet.js | 6 ++++++ src/redux/reducers/wallet.js | 5 +++++ 5 files changed, 26 insertions(+), 9 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 869e378..e764a29 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,7 +15,6 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ - __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -71,6 +70,7 @@ const SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'; const SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED'; const SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED'; const SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED'; +const CLEAR_SUPPORT_TRANSACTION = 'CLEAR_SUPPORT_TRANSACTION'; const WALLET_ENCRYPT_START = 'WALLET_ENCRYPT_START'; const WALLET_ENCRYPT_COMPLETED = 'WALLET_ENCRYPT_COMPLETED'; const WALLET_ENCRYPT_FAILED = 'WALLET_ENCRYPT_FAILED'; @@ -269,7 +269,6 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ - __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -313,6 +312,7 @@ var action_types = /*#__PURE__*/Object.freeze({ SUPPORT_TRANSACTION_STARTED: SUPPORT_TRANSACTION_STARTED, SUPPORT_TRANSACTION_COMPLETED: SUPPORT_TRANSACTION_COMPLETED, SUPPORT_TRANSACTION_FAILED: SUPPORT_TRANSACTION_FAILED, + CLEAR_SUPPORT_TRANSACTION: CLEAR_SUPPORT_TRANSACTION, WALLET_ENCRYPT_START: WALLET_ENCRYPT_START, WALLET_ENCRYPT_COMPLETED: WALLET_ENCRYPT_COMPLETED, WALLET_ENCRYPT_FAILED: WALLET_ENCRYPT_FAILED, @@ -506,7 +506,6 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ - __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -537,7 +536,6 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ - __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -587,7 +585,6 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ - __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -615,7 +612,6 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -629,7 +625,6 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -649,7 +644,6 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ - __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -665,7 +659,6 @@ var transaction_types = /*#__PURE__*/Object.freeze({ const PAGE_SIZE$1 = 50; var transaction_list = /*#__PURE__*/Object.freeze({ - __proto__: null, PAGE_SIZE: PAGE_SIZE$1 }); @@ -2419,6 +2412,12 @@ function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { }; } +function doClearSupport() { + return { + type: CLEAR_SUPPORT_TRANSACTION + }; +} + function doWalletEncrypt(newPassword) { return dispatch => { dispatch({ @@ -5120,6 +5119,10 @@ const walletReducer = handleActions({ sendingSupport: false }), + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$f({}, state, { + sendingSupport: false + }), + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$f({}, state, { walletIsEncrypted: action.result }), @@ -5340,6 +5343,7 @@ exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doClaimSearch = doClaimSearch; exports.doClearPublish = doClearPublish; +exports.doClearSupport = doClearSupport; exports.doCommentCreate = doCommentCreate; exports.doCommentList = doCommentList; exports.doCreateChannel = doCreateChannel; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index a52c756..4e0e334 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -47,6 +47,7 @@ export const SEND_TRANSACTION_FAILED = 'SEND_TRANSACTION_FAILED'; export const SUPPORT_TRANSACTION_STARTED = 'SUPPORT_TRANSACTION_STARTED'; export const SUPPORT_TRANSACTION_COMPLETED = 'SUPPORT_TRANSACTION_COMPLETED'; export const SUPPORT_TRANSACTION_FAILED = 'SUPPORT_TRANSACTION_FAILED'; +export const CLEAR_SUPPORT_TRANSACTION = 'CLEAR_SUPPORT_TRANSACTION'; export const WALLET_ENCRYPT_START = 'WALLET_ENCRYPT_START'; export const WALLET_ENCRYPT_COMPLETED = 'WALLET_ENCRYPT_COMPLETED'; export const WALLET_ENCRYPT_FAILED = 'WALLET_ENCRYPT_FAILED'; diff --git a/src/index.js b/src/index.js index f598c68..851c9b6 100644 --- a/src/index.js +++ b/src/index.js @@ -111,6 +111,7 @@ export { doWalletStatus, doSetTransactionListFilter, doUpdateBlockHeight, + doClearSupport, } from 'redux/actions/wallet'; export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 2b9032f..f592f56 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -258,6 +258,12 @@ export function doSendTip(amount, claimId, isSupport, successCallback, errorCall }; } +export function doClearSupport() { + return { + type: ACTIONS.CLEAR_SUPPORT_TRANSACTION, + }; +} + export function doWalletEncrypt(newPassword) { return dispatch => { dispatch({ diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index 2be54ff..ae7511d 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -223,6 +223,11 @@ export const walletReducer = handleActions( sendingSupport: false, }), + [ACTIONS.CLEAR_SUPPORT_TRANSACTION]: (state: WalletState) => ({ + ...state, + sendingSupport: false, + }), + [ACTIONS.WALLET_STATUS_COMPLETED]: (state: WalletState, action) => ({ ...state, walletIsEncrypted: action.result, -- 2.45.2 From d3a9b267873c94589003afa62a5097907b990372 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 31 Oct 2019 07:46:42 -0400 Subject: [PATCH 190/371] exposes api call for use by tv update --- dist/bundle.es.js | 1 + src/index.js | 4 ++-- src/lbry.js | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e764a29..5b427e3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5325,6 +5325,7 @@ exports.SPEECH_URLS = speech_urls; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; exports.TX_LIST = transaction_list; +exports.apiCall = apiCall; exports.batchActions = batchActions; exports.blockedReducer = blockedReducer; exports.buildSharedStateMiddleware = buildSharedStateMiddleware; diff --git a/src/index.js b/src/index.js index 851c9b6..3b81feb 100644 --- a/src/index.js +++ b/src/index.js @@ -10,7 +10,7 @@ import * as TX_LIST from 'constants/transaction_list'; import * as SPEECH_URLS from 'constants/speech_urls'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS } from 'constants/tags'; -import Lbry from 'lbry'; +import Lbry, { apiCall } from 'lbry'; import { selectState as selectSearchState } from 'redux/selectors/search'; // constants @@ -33,7 +33,7 @@ export { }; // common -export { Lbry }; +export { Lbry, apiCall }; export { regexInvalidURI, regexAddress, diff --git a/src/lbry.js b/src/lbry.js index f54ad42..426be41 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -171,7 +171,7 @@ function checkAndParse(response) { }); } -function apiCall(method: string, params: ?{}, resolve: Function, reject: Function) { +export function apiCall(method: string, params: ?{}, resolve: Function, reject: Function) { const counter = new Date().getTime(); const options = { method: 'POST', -- 2.45.2 From 2157834ff6640af78e24ab002f68e1815661492b Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Fri, 1 Nov 2019 13:17:55 -0400 Subject: [PATCH 191/371] WIP API improvements --- dist/bundle.es.js | 32 +++++++++++++------------------ src/constants/transaction_list.js | 1 + src/index.js | 2 +- src/redux/actions/claims.js | 12 ++++++++++-- src/redux/actions/publish.js | 2 +- src/redux/actions/wallet.js | 6 +++--- src/redux/selectors/wallet.js | 26 ++++++++++--------------- 7 files changed, 39 insertions(+), 42 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e764a29..61c6054 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -657,9 +657,11 @@ var transaction_types = /*#__PURE__*/Object.freeze({ // PAGE SIZE const PAGE_SIZE$1 = 50; +const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ - PAGE_SIZE: PAGE_SIZE$1 + PAGE_SIZE: PAGE_SIZE$1, + LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; @@ -1664,18 +1666,6 @@ const selectTransactionItems = reselect.createSelector(selectTransactionsById, b }); }); -const selectRecentTransactions = reselect.createSelector(selectTransactionItems, transactions => { - const threshold = new Date(); - threshold.setDate(threshold.getDate() - 7); - return transactions.filter(transaction => { - if (!transaction.date) { - return true; // pending transaction - } - - return transaction.date > threshold; - }); -}); - const selectHasTransactions = reselect.createSelector(selectTransactionItems, transactions => transactions && transactions.length > 0); const selectIsFetchingTransactions = reselect.createSelector(selectState$1, state => state.fetchingTransactions); @@ -1712,6 +1702,10 @@ const makeSelectFilteredTransactionsForPage = (page = 1) => reselect.createSelec return filteredTransactions && filteredTransactions.length ? filteredTransactions.slice(start, end) : []; }); +const makeSelectLatestTransactions = reselect.createSelector(selectTransactionItems, transactions => { + return transactions && transactions.length ? transactions.slice(transactions.length < LATEST_PAGE_SIZE ? transactions.length : LATEST_PAGE_SIZE) : []; +}); + const selectFilteredTransactionCount = reselect.createSelector(selectFilteredTransactions, filteredTransactions => filteredTransactions.length); 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; }; @@ -2212,14 +2206,14 @@ function doBalanceSubscribe() { }; } -function doFetchTransactions() { +function doFetchTransactions(page, pageSize) { return dispatch => { dispatch(doFetchSupports()); dispatch({ type: FETCH_TRANSACTIONS_STARTED }); - - lbryProxy.utxo_release().then(() => lbryProxy.transaction_list()).then(results => { + debugger; + lbryProxy.utxo_release().then(() => lbryProxy.transaction_list({ page: page, page_size: pageSize })).then(results => { dispatch({ type: FETCH_TRANSACTIONS_COMPLETED, data: { @@ -2673,7 +2667,7 @@ function doAbandonClaim(txid, nout) { // After abandoning, call claim_list to show the claim as abandoned // Also fetch transactions to show the new abandon transaction if (isClaim) dispatch(doFetchClaimListMine()); - dispatch(doFetchTransactions()); + dispatch(doFetchTransactions(1, 2)); }; const abandonParams = { @@ -3624,7 +3618,7 @@ const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { let publishCheckInterval; const checkFileList = () => { - lbryProxy.claim_list().then(claims => { + lbryProxy.stream_list({ page: 1, page_size: 5 }).then(claims => { // $FlowFixMe claims.forEach(claim => { // If it's confirmed, check if it was pending previously @@ -5425,6 +5419,7 @@ exports.makeSelectFilteredTransactionsForPage = makeSelectFilteredTransactionsFo exports.makeSelectFirstRecommendedFileForUri = makeSelectFirstRecommendedFileForUri; exports.makeSelectIsFollowingTag = makeSelectIsFollowingTag; exports.makeSelectIsUriResolving = makeSelectIsUriResolving; +exports.makeSelectLatestTransactions = makeSelectLatestTransactions; exports.makeSelectLoadingForUri = makeSelectLoadingForUri; exports.makeSelectMediaTypeForUri = makeSelectMediaTypeForUri; exports.makeSelectMetadataForUri = makeSelectMetadataForUri; @@ -5524,7 +5519,6 @@ exports.selectPublishFormValues = selectPublishFormValues; exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; -exports.selectRecentTransactions = selectRecentTransactions; exports.selectReservedBalance = selectReservedBalance; exports.selectResolvingUris = selectResolvingUris; exports.selectSearchBarFocused = selectSearchBarFocused; diff --git a/src/constants/transaction_list.js b/src/constants/transaction_list.js index c609b05..aabba4b 100644 --- a/src/constants/transaction_list.js +++ b/src/constants/transaction_list.js @@ -1,2 +1,3 @@ // PAGE SIZE export const PAGE_SIZE = 50; +export const LATEST_PAGE_SIZE = 20; diff --git a/src/index.js b/src/index.js index 851c9b6..f197c20 100644 --- a/src/index.js +++ b/src/index.js @@ -277,7 +277,6 @@ export { selectSupportsByOutpoint, selectTotalSupports, selectTransactionItems, - selectRecentTransactions, selectHasTransactions, selectIsFetchingTransactions, selectIsSendingSupport, @@ -301,6 +300,7 @@ export { selectWalletUnlockResult, selectTransactionListFilter, selectFilteredTransactions, + makeSelectLatestTransactions, makeSelectFilteredTransactionsForPage, selectFilteredTransactionCount, } from 'redux/selectors/wallet'; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 3dffd6b..b37dbdd 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -178,7 +178,7 @@ export function doAbandonClaim(txid: string, nout: number) { // After abandoning, call claim_list to show the claim as abandoned // Also fetch transactions to show the new abandon transaction if (isClaim) dispatch(doFetchClaimListMine()); - dispatch(doFetchTransactions()); + dispatch(doFetchTransactions(1,2)); }; const abandonParams = { @@ -396,7 +396,15 @@ export function doFetchChannelListMine() { } export function doClaimSearch( - options: { tags?: Array, page?: number, page_size?: number, release_time?: string } = { + options: { page_size: number, + page: number, + no_totals: boolean, + any_tags?: Array, + channel_ids?: Array, + not_channel_ids?: Array, + not_tags?: Array, + order_by?: Array, + release_time?: string, } = { page_size: 10, } ) { diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 78d6503..f0d86d6 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -366,7 +366,7 @@ export const doCheckPendingPublishes = (onConfirmed: Function) => ( let publishCheckInterval; const checkFileList = () => { - Lbry.claim_list().then(claims => { + Lbry.stream_list( { page: 1, page_size: 5}).then(claims => { // $FlowFixMe claims.forEach(claim => { // If it's confirmed, check if it was pending previously diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index f592f56..a6cef91 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -39,15 +39,15 @@ export function doBalanceSubscribe() { }; } -export function doFetchTransactions() { +export function doFetchTransactions(page, pageSize) { return dispatch => { dispatch(doFetchSupports()); dispatch({ type: ACTIONS.FETCH_TRANSACTIONS_STARTED, }); - + debugger; Lbry.utxo_release() - .then(() => Lbry.transaction_list()) + .then(() => Lbry.transaction_list({ page: page, page_size: pageSize})) .then(results => { dispatch({ type: ACTIONS.FETCH_TRANSACTIONS_COMPLETED, diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index d050aef..a987612 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -1,6 +1,6 @@ import { createSelector } from 'reselect'; import * as TRANSACTIONS from 'constants/transaction_types'; -import { PAGE_SIZE } from 'constants/transaction_list'; +import { PAGE_SIZE, LATEST_PAGE_SIZE } from 'constants/transaction_list'; export const selectState = state => state.wallet || {}; @@ -215,21 +215,6 @@ export const selectTransactionItems = createSelector( } ); -export const selectRecentTransactions = createSelector( - selectTransactionItems, - transactions => { - const threshold = new Date(); - threshold.setDate(threshold.getDate() - 7); - return transactions.filter(transaction => { - if (!transaction.date) { - return true; // pending transaction - } - - return transaction.date > threshold; - }); - } -); - export const selectHasTransactions = createSelector( selectTransactionItems, transactions => transactions && transactions.length > 0 @@ -312,6 +297,15 @@ export const makeSelectFilteredTransactionsForPage = (page: number = 1): Array { + return transactions && transactions.length + ? transactions.slice( transactions.length < LATEST_PAGE_SIZE ? transactions.length : LATEST_PAGE_SIZE ) + : []; + } + ); + export const selectFilteredTransactionCount = createSelector( selectFilteredTransactions, filteredTransactions => filteredTransactions.length -- 2.45.2 From 861880a029a748bb4300bec9b16b7136ac51c5c3 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 1 Nov 2019 15:08:42 -0400 Subject: [PATCH 192/371] cleanup --- dist/bundle.es.js | 99 ++++++++++++++++++++--------------- dist/flow-typed/Lbry.js | 9 ++-- flow-typed/Lbry.js | 9 ++-- src/lbry.js | 19 +++---- src/redux/actions/claims.js | 24 ++++++--- src/redux/actions/publish.js | 15 ++++-- src/redux/actions/wallet.js | 54 +++++++++++-------- src/redux/selectors/wallet.js | 16 +++--- src/util/claim.js | 11 ++-- 9 files changed, 151 insertions(+), 105 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 61c6054..3cc1426 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -772,6 +772,7 @@ const Lbry = { channel_import: params => daemonCallWithResult('channel_import', params), channel_list: params => daemonCallWithResult('channel_list', params), stream_abandon: params => daemonCallWithResult('stream_abandon', params), + stream_list: params => daemonCallWithResult('stream_list', params), channel_abandon: params => daemonCallWithResult('channel_abandon', params), support_create: params => daemonCallWithResult('support_create', params), @@ -831,16 +832,16 @@ const Lbry = { // Flow thinks this could be empty, but it will always reuturn a promise // $FlowFixMe return Lbry.connectPromise; - } -}; + }, -Lbry.publish = (params = {}) => new Promise((resolve, reject) => { - if (Lbry.overrides.publish) { - Lbry.overrides.publish(params).then(resolve, reject); - } else { - apiCall('publish', params, resolve, reject); - } -}); + publish: (params = {}) => new Promise((resolve, reject) => { + if (Lbry.overrides.publish) { + Lbry.overrides.publish(params).then(resolve, reject); + } else { + apiCall('publish', params, resolve, reject); + } + }) +}; function checkAndParse(response) { if (response.status >= 200 && response.status < 300) { @@ -1703,7 +1704,7 @@ const makeSelectFilteredTransactionsForPage = (page = 1) => reselect.createSelec }); const makeSelectLatestTransactions = reselect.createSelector(selectTransactionItems, transactions => { - return transactions && transactions.length ? transactions.slice(transactions.length < LATEST_PAGE_SIZE ? transactions.length : LATEST_PAGE_SIZE) : []; + return transactions && transactions.length ? transactions.slice(0, LATEST_PAGE_SIZE) : []; }); const selectFilteredTransactionCount = reselect.createSelector(selectFilteredTransactions, filteredTransactions => filteredTransactions.length); @@ -2172,30 +2173,38 @@ function creditsToString(amount) { return creditString; } +let walletBalancePromise = null; function doUpdateBalance() { return (dispatch, getState) => { const { wallet: { totalBalance: totalInStore } } = getState(); - return lbryProxy.wallet_balance({ reserved_subtotals: true }).then(response => { - const { available, reserved, reserved_subtotals, total } = response; - const { claims, supports, tips } = reserved_subtotals; - const totalFloat = parseFloat(total); - if (totalInStore !== totalFloat) { - dispatch({ - type: UPDATE_BALANCE, - data: { - totalBalance: totalFloat, - balance: parseFloat(available), - reservedBalance: parseFloat(reserved), - claimsBalance: parseFloat(claims), - supportsBalance: parseFloat(supports), - tipsBalance: parseFloat(tips) - } - }); - } - }); + if (walletBalancePromise === null) { + walletBalancePromise = lbryProxy.wallet_balance({ reserved_subtotals: true }).then(response => { + walletBalancePromise = null; + + const { available, reserved, reserved_subtotals, total } = response; + const { claims, supports, tips } = reserved_subtotals; + const totalFloat = parseFloat(total); + + if (totalInStore !== totalFloat) { + dispatch({ + type: UPDATE_BALANCE, + data: { + totalBalance: totalFloat, + balance: parseFloat(available), + reservedBalance: parseFloat(reserved), + claimsBalance: parseFloat(claims), + supportsBalance: parseFloat(supports), + tipsBalance: parseFloat(tips) + } + }); + } + }); + } + + return walletBalancePromise; }; } @@ -2206,18 +2215,18 @@ function doBalanceSubscribe() { }; } -function doFetchTransactions(page, pageSize) { +function doFetchTransactions(page = 1, pageSize = 99999) { return dispatch => { dispatch(doFetchSupports()); dispatch({ type: FETCH_TRANSACTIONS_STARTED }); - debugger; - lbryProxy.utxo_release().then(() => lbryProxy.transaction_list({ page: page, page_size: pageSize })).then(results => { + + lbryProxy.utxo_release().then(() => lbryProxy.transaction_list({ page, page_size: pageSize })).then(result => { dispatch({ type: FETCH_TRANSACTIONS_COMPLETED, data: { - transactions: results + transactions: result.items } }); }); @@ -2593,13 +2602,15 @@ function doResolveUri(uri) { return doResolveUris([uri]); } -function doFetchClaimListMine() { +function doFetchClaimListMine(page = 1, pageSize = 9999) { return dispatch => { dispatch({ type: FETCH_CLAIM_LIST_MINE_STARTED }); - lbryProxy.claim_list().then(claims => { + lbryProxy.claim_list({ page, page_size: pageSize }).then(result => { + const claims = result.items; + dispatch({ type: FETCH_CLAIM_LIST_MINE_COMPLETED, data: { @@ -2664,10 +2675,12 @@ function doAbandonClaim(txid, nout) { message: abandonMessage })); - // After abandoning, call claim_list to show the claim as abandoned - // Also fetch transactions to show the new abandon transaction - if (isClaim) dispatch(doFetchClaimListMine()); - dispatch(doFetchTransactions(1, 2)); + // After abandoning, fetch transactions to show the new abandon transaction + // Only fetch the latest few transactions since we don't care about old ones + // Not very robust, but better than calling the entire list for large wallets + const page = 1; + const pageSize = 10; + dispatch(doFetchTransactions(page, pageSize)); }; const abandonParams = { @@ -2867,7 +2880,9 @@ function doFetchChannelListMine() { } function doClaimSearch(options = { - page_size: 10 + no_totals: true, + page_size: 10, + page: 1 }) { const query = createNormalizedClaimSearchKey(options); return dispatch => { @@ -3431,6 +3446,7 @@ const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => disp const name = makeid(); const file = thumbnailBlob || thumbnail && new File([thumbnail], fileName, { type: fileType }); data.append('name', name); + // $FlowFixMe data.append('file', file); return fetch(SPEECH_PUBLISH, { @@ -3618,8 +3634,9 @@ const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { let publishCheckInterval; const checkFileList = () => { - lbryProxy.stream_list({ page: 1, page_size: 5 }).then(claims => { - // $FlowFixMe + lbryProxy.stream_list({ page: 1, page_size: 10 }).then(result => { + const claims = result.items; + claims.forEach(claim => { // If it's confirmed, check if it was pending previously if (claim.confirmations > 0 && pendingById[claim.claim_id]) { diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index c38b59e..e967a97 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -107,7 +107,7 @@ declare type ClaimSearchResponse = { }; declare type ClaimListResponse = { - claims: Array, + items: Array, }; declare type ChannelCreateResponse = GenericTxResponse & { @@ -125,7 +125,7 @@ declare type ChannelListResponse = Array; declare type FileListResponse = Array; -declare type TxListResponse = Array; +declare type TxListResponse = { items: Array }; declare type BlobListResponse = Array; @@ -146,6 +146,8 @@ declare type SyncApplyResponse = { declare type SupportAbandonResponse = GenericTxResponse; +declare type StreamListResponse = { items: Array }; + // // Types used in the generic Lbry object that is exported // @@ -168,7 +170,7 @@ declare type LbryTypes = { version: () => Promise, resolve: (params: {}) => Promise, get: (params: {}) => Promise, - publish?: (params: {}) => Promise, + publish: (params: {}) => Promise, claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, @@ -177,6 +179,7 @@ declare type LbryTypes = { channel_import: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, + stream_list: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, support_create: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index c38b59e..e967a97 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -107,7 +107,7 @@ declare type ClaimSearchResponse = { }; declare type ClaimListResponse = { - claims: Array, + items: Array, }; declare type ChannelCreateResponse = GenericTxResponse & { @@ -125,7 +125,7 @@ declare type ChannelListResponse = Array; declare type FileListResponse = Array; -declare type TxListResponse = Array; +declare type TxListResponse = { items: Array }; declare type BlobListResponse = Array; @@ -146,6 +146,8 @@ declare type SyncApplyResponse = { declare type SupportAbandonResponse = GenericTxResponse; +declare type StreamListResponse = { items: Array }; + // // Types used in the generic Lbry object that is exported // @@ -168,7 +170,7 @@ declare type LbryTypes = { version: () => Promise, resolve: (params: {}) => Promise, get: (params: {}) => Promise, - publish?: (params: {}) => Promise, + publish: (params: {}) => Promise, claim_search: (params: {}) => Promise, claim_list: (params?: {}) => Promise, @@ -177,6 +179,7 @@ declare type LbryTypes = { channel_import: (params: {}) => Promise, channel_list: () => Promise, stream_abandon: (params: {}) => Promise, + stream_list: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, support_create: (params: {}) => Promise, diff --git a/src/lbry.js b/src/lbry.js index f54ad42..ed7ad7d 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -82,6 +82,7 @@ const Lbry: LbryTypes = { channel_import: params => daemonCallWithResult('channel_import', params), channel_list: params => daemonCallWithResult('channel_list', params), stream_abandon: params => daemonCallWithResult('stream_abandon', params), + stream_list: params => daemonCallWithResult('stream_list', params), channel_abandon: params => daemonCallWithResult('channel_abandon', params), support_create: params => daemonCallWithResult('support_create', params), @@ -144,16 +145,16 @@ const Lbry: LbryTypes = { // $FlowFixMe return Lbry.connectPromise; }, -}; -Lbry.publish = (params = {}) => - new Promise((resolve, reject) => { - if (Lbry.overrides.publish) { - Lbry.overrides.publish(params).then(resolve, reject); - } else { - apiCall('publish', params, resolve, reject); - } - }); + publish: (params = {}) => + new Promise((resolve, reject) => { + if (Lbry.overrides.publish) { + Lbry.overrides.publish(params).then(resolve, reject); + } else { + apiCall('publish', params, resolve, reject); + } + }), +}; function checkAndParse(response) { if (response.status >= 200 && response.status < 300) { diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index b37dbdd..5c296a1 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -94,13 +94,15 @@ export function doResolveUri(uri: string) { return doResolveUris([uri]); } -export function doFetchClaimListMine() { +export function doFetchClaimListMine(page: number = 1, pageSize: number = 9999) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED, }); - Lbry.claim_list().then((claims: ClaimListResponse) => { + Lbry.claim_list({ page, page_size: pageSize }).then((result: ClaimListResponse) => { + const claims = result.items; + dispatch({ type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, data: { @@ -175,10 +177,12 @@ export function doAbandonClaim(txid: string, nout: number) { }) ); - // After abandoning, call claim_list to show the claim as abandoned - // Also fetch transactions to show the new abandon transaction - if (isClaim) dispatch(doFetchClaimListMine()); - dispatch(doFetchTransactions(1,2)); + // After abandoning, fetch transactions to show the new abandon transaction + // Only fetch the latest few transactions since we don't care about old ones + // Not very robust, but better than calling the entire list for large wallets + const page = 1; + const pageSize = 10; + dispatch(doFetchTransactions(page, pageSize)); }; const abandonParams = { @@ -396,7 +400,8 @@ export function doFetchChannelListMine() { } export function doClaimSearch( - options: { page_size: number, + options: { + page_size: number, page: number, no_totals: boolean, any_tags?: Array, @@ -404,8 +409,11 @@ export function doClaimSearch( not_channel_ids?: Array, not_tags?: Array, order_by?: Array, - release_time?: string, } = { + release_time?: string, + } = { + no_totals: true, page_size: 10, + page: 1, } ) { const query = createNormalizedClaimSearchKey(options); diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index f0d86d6..214174b 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -145,8 +145,10 @@ export const doUploadThumbnail = ( const data = new FormData(); const name = makeid(); - const file = thumbnailBlob || (thumbnail && new File([thumbnail], fileName, { type: fileType })); + const file = + thumbnailBlob || (thumbnail && new File([thumbnail], fileName, { type: fileType })); data.append('name', name); + // $FlowFixMe data.append('file', file); return fetch(SPEECH_PUBLISH, { @@ -275,7 +277,9 @@ export const doPublish = (success: Function, fail: Function) => ( } // get the claim id from the channel name, we will use that instead - const namedChannelClaim = myChannels ? myChannels.find(myChannel => myChannel.name === channel) : null; + const namedChannelClaim = myChannels + ? myChannels.find(myChannel => myChannel.name === channel) + : null; const channelId = namedChannelClaim ? namedChannelClaim.claim_id : ''; const publishPayload: { @@ -336,7 +340,7 @@ export const doPublish = (success: Function, fail: Function) => ( } if (myClaimForUri && myClaimForUri.value && myClaimForUri.value.locations) { - publishPayload.locations = myClaimForUri.value.locations; + publishPayload.locations = myClaimForUri.value.locations; } if (!contentIsFree && fee && (fee.currency && Number(fee.amount) > 0)) { @@ -366,8 +370,9 @@ export const doCheckPendingPublishes = (onConfirmed: Function) => ( let publishCheckInterval; const checkFileList = () => { - Lbry.stream_list( { page: 1, page_size: 5}).then(claims => { - // $FlowFixMe + Lbry.stream_list({ page: 1, page_size: 10 }).then(result => { + const claims = result.items; + claims.forEach(claim => { // If it's confirmed, check if it was pending previously if (claim.confirmations > 0 && pendingById[claim.claim_id]) { diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index a6cef91..047c306 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -5,30 +5,38 @@ import { selectBalance } from 'redux/selectors/wallet'; import { creditsToString } from 'util/format-credits'; import { selectMyClaimsRaw } from 'redux/selectors/claims'; +let walletBalancePromise = null; export function doUpdateBalance() { return (dispatch, getState) => { const { wallet: { totalBalance: totalInStore }, } = getState(); - return Lbry.wallet_balance({ reserved_subtotals: true }).then(response => { - const { available, reserved, reserved_subtotals, total } = response; - const { claims, supports, tips } = reserved_subtotals; - const totalFloat = parseFloat(total); - if (totalInStore !== totalFloat) { - dispatch({ - type: ACTIONS.UPDATE_BALANCE, - data: { - totalBalance: totalFloat, - balance: parseFloat(available), - reservedBalance: parseFloat(reserved), - claimsBalance: parseFloat(claims), - supportsBalance: parseFloat(supports), - tipsBalance: parseFloat(tips), - }, - }); - } - }); + if (walletBalancePromise === null) { + walletBalancePromise = Lbry.wallet_balance({ reserved_subtotals: true }).then(response => { + walletBalancePromise = null; + + const { available, reserved, reserved_subtotals, total } = response; + const { claims, supports, tips } = reserved_subtotals; + const totalFloat = parseFloat(total); + + if (totalInStore !== totalFloat) { + dispatch({ + type: ACTIONS.UPDATE_BALANCE, + data: { + totalBalance: totalFloat, + balance: parseFloat(available), + reservedBalance: parseFloat(reserved), + claimsBalance: parseFloat(claims), + supportsBalance: parseFloat(supports), + tipsBalance: parseFloat(tips), + }, + }); + } + }); + } + + return walletBalancePromise; }; } @@ -39,20 +47,20 @@ export function doBalanceSubscribe() { }; } -export function doFetchTransactions(page, pageSize) { +export function doFetchTransactions(page = 1, pageSize = 99999) { return dispatch => { dispatch(doFetchSupports()); dispatch({ type: ACTIONS.FETCH_TRANSACTIONS_STARTED, }); - debugger; + Lbry.utxo_release() - .then(() => Lbry.transaction_list({ page: page, page_size: pageSize})) - .then(results => { + .then(() => Lbry.transaction_list({ page, page_size: pageSize })) + .then(result => { dispatch({ type: ACTIONS.FETCH_TRANSACTIONS_COMPLETED, data: { - transactions: results, + transactions: result.items, }, }); }); diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index a987612..a2c1c0f 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -285,7 +285,7 @@ export const selectFilteredTransactions = createSelector( } ); -export const makeSelectFilteredTransactionsForPage = (page: number = 1): Array => +export const makeSelectFilteredTransactionsForPage = (page = 1) => createSelector( selectFilteredTransactions, filteredTransactions => { @@ -297,14 +297,12 @@ export const makeSelectFilteredTransactionsForPage = (page: number = 1): Array { - return transactions && transactions.length - ? transactions.slice( transactions.length < LATEST_PAGE_SIZE ? transactions.length : LATEST_PAGE_SIZE ) - : []; - } - ); +export const makeSelectLatestTransactions = createSelector( + selectTransactionItems, + transactions => { + return transactions && transactions.length ? transactions.slice(0, LATEST_PAGE_SIZE) : []; + } +); export const selectFilteredTransactionCount = createSelector( selectFilteredTransactions, diff --git a/src/util/claim.js b/src/util/claim.js index 5ed1a42..cfde696 100644 --- a/src/util/claim.js +++ b/src/util/claim.js @@ -23,7 +23,7 @@ export const isClaimNsfw = (claim: Claim): boolean => { return false; }; -export function createNormalizedClaimSearchKey(options: { page?: number, release_time?: string }) { +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; @@ -31,20 +31,23 @@ export function createNormalizedClaimSearchKey(options: { page?: number, release return query; } -export function concatClaims(claimList: Array = [], concatClaimList: Array = []): Array { +export function concatClaims( + claimList: Array = [], + concatClaimList: Array = [] +): Array { if (!claimList || claimList.length === 0) { if (!concatClaimList) { return []; } return concatClaimList.slice(); } - + const claims = claimList.slice(); concatClaimList.forEach(claim => { if (!claims.some(item => item.claim_id === claim.claim_id)) { claims.push(claim); } }); - + return claims; } -- 2.45.2 From d5ffdeaec42470bcdb46d41c2ba7d8f8c5f0e37d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 4 Nov 2019 13:43:33 -0500 Subject: [PATCH 193/371] keep selectRecentTransactions --- dist/bundle.es.js | 13 +++++++++++++ src/index.js | 1 + src/redux/selectors/wallet.js | 15 +++++++++++++++ 3 files changed, 29 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3cc1426..d863ca5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1667,6 +1667,18 @@ const selectTransactionItems = reselect.createSelector(selectTransactionsById, b }); }); +const selectRecentTransactions = reselect.createSelector(selectTransactionItems, transactions => { + const threshold = new Date(); + threshold.setDate(threshold.getDate() - 7); + return transactions.filter(transaction => { + if (!transaction.date) { + return true; // pending transaction + } + + return transaction.date > threshold; + }); +}); + const selectHasTransactions = reselect.createSelector(selectTransactionItems, transactions => transactions && transactions.length > 0); const selectIsFetchingTransactions = reselect.createSelector(selectState$1, state => state.fetchingTransactions); @@ -5536,6 +5548,7 @@ exports.selectPublishFormValues = selectPublishFormValues; exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; +exports.selectRecentTransactions = selectRecentTransactions; exports.selectReservedBalance = selectReservedBalance; exports.selectResolvingUris = selectResolvingUris; exports.selectSearchBarFocused = selectSearchBarFocused; diff --git a/src/index.js b/src/index.js index f197c20..f44c3c6 100644 --- a/src/index.js +++ b/src/index.js @@ -277,6 +277,7 @@ export { selectSupportsByOutpoint, selectTotalSupports, selectTransactionItems, + selectRecentTransactions, selectHasTransactions, selectIsFetchingTransactions, selectIsSendingSupport, diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index a2c1c0f..950b092 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -215,6 +215,21 @@ export const selectTransactionItems = createSelector( } ); +export const selectRecentTransactions = createSelector( + selectTransactionItems, + transactions => { + const threshold = new Date(); + threshold.setDate(threshold.getDate() - 7); + return transactions.filter(transaction => { + if (!transaction.date) { + return true; // pending transaction + } + + return transaction.date > threshold; + }); + } +); + export const selectHasTransactions = createSelector( selectTransactionItems, transactions => transactions && transactions.length > 0 -- 2.45.2 From 06951e90b55db5f9415289f292aaaa8f0650db5d Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Mon, 4 Nov 2019 14:28:01 -0500 Subject: [PATCH 194/371] Bump js-yaml from 3.11.0 to 3.13.1 Bumps [js-yaml](https://github.com/nodeca/js-yaml) from 3.11.0 to 3.13.1. - [Release notes](https://github.com/nodeca/js-yaml/releases) - [Changelog](https://github.com/nodeca/js-yaml/blob/master/CHANGELOG.md) - [Commits](https://github.com/nodeca/js-yaml/compare/3.11.0...3.13.1) Signed-off-by: dependabot[bot] Bump extend from 3.0.1 to 3.0.2 Bumps [extend](https://github.com/justmoon/node-extend) from 3.0.1 to 3.0.2. - [Release notes](https://github.com/justmoon/node-extend/releases) - [Changelog](https://github.com/justmoon/node-extend/blob/master/CHANGELOG.md) - [Commits](https://github.com/justmoon/node-extend/compare/v3.0.1...v3.0.2) Signed-off-by: dependabot[bot] Bump fstream from 1.0.11 to 1.0.12 Bumps [fstream](https://github.com/npm/fstream) from 1.0.11 to 1.0.12. - [Release notes](https://github.com/npm/fstream/releases) - [Commits](https://github.com/npm/fstream/compare/v1.0.11...v1.0.12) Signed-off-by: dependabot[bot] Bump stringstream from 0.0.5 to 0.0.6 Bumps [stringstream](https://github.com/mhart/StringStream) from 0.0.5 to 0.0.6. - [Release notes](https://github.com/mhart/StringStream/releases) - [Commits](https://github.com/mhart/StringStream/compare/v0.0.5...v0.0.6) Signed-off-by: dependabot[bot] Bump lodash from 4.17.10 to 4.17.15 Bumps [lodash](https://github.com/lodash/lodash) from 4.17.10 to 4.17.15. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.10...4.17.15) Signed-off-by: dependabot[bot] Bump mixin-deep from 1.3.1 to 1.3.2 Bumps [mixin-deep](https://github.com/jonschlinkert/mixin-deep) from 1.3.1 to 1.3.2. - [Release notes](https://github.com/jonschlinkert/mixin-deep/releases) - [Commits](https://github.com/jonschlinkert/mixin-deep/compare/1.3.1...1.3.2) Signed-off-by: dependabot[bot] Bump eslint-utils from 1.3.1 to 1.4.3 Bumps [eslint-utils](https://github.com/mysticatea/eslint-utils) from 1.3.1 to 1.4.3. - [Release notes](https://github.com/mysticatea/eslint-utils/releases) - [Commits](https://github.com/mysticatea/eslint-utils/compare/v1.3.1...v1.4.3) Signed-off-by: dependabot[bot] --- yarn.lock | 99 +++++++++++++++++++++++++------------------------------ 1 file changed, 44 insertions(+), 55 deletions(-) diff --git a/yarn.lock b/yarn.lock index eed6546..230a0ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1820,14 +1820,16 @@ eslint-scope@~3.7.1: estraverse "^4.1.1" eslint-utils@^1.3.0, eslint-utils@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.3.1.tgz#9a851ba89ee7c460346f97cf8939c7298827e512" - integrity sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q== + version "1.4.3" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-1.4.3.tgz#74fec7c54d0776b6f67e0251040b5806564e981f" + integrity sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q== + dependencies: + eslint-visitor-keys "^1.1.0" -eslint-visitor-keys@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#3f3180fb2e291017716acb4c9d6d5b5c34a6a81d" - integrity sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ== +eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2" + integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A== eslint@^5.1.0, eslint@^5.16.0: version "5.16.0" @@ -1886,9 +1888,9 @@ esprima@^3.1.3: integrity sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM= esprima@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" - integrity sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw== + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.0.1: version "1.0.1" @@ -2002,9 +2004,9 @@ extend-shallow@^3.0.0, extend-shallow@^3.0.2: is-extendable "^1.0.1" extend@~3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" - integrity sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ= + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== external-editor@^3.0.3: version "3.0.3" @@ -2256,9 +2258,9 @@ fs.realpath@^1.0.0: integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= fstream@~1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" - integrity sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE= + version "1.0.12" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" + integrity sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg== dependencies: graceful-fs "^4.1.2" inherits "~2.0.0" @@ -2317,7 +2319,7 @@ glob-parent@^2.0.0: dependencies: is-glob "^2.0.0" -glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: +glob@^7.1.1, glob@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" integrity sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ== @@ -2330,9 +2332,9 @@ glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: path-is-absolute "^1.0.0" glob@^7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.3.tgz#3960832d3f1574108342dafd3a67b332c0969df1" - integrity sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ== + version "7.1.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.5.tgz#6714c69bee20f3c3e64c4dd905553e532b40cdc0" + integrity sha512-J9dlskqUXK1OeTOYBEn5s8aMukWMwWfs+rPTn/jn50Ux4MNXVhubL1wu/j2t+H4NVI+cXEcCaYellqaPVGXNqQ== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" @@ -2377,9 +2379,9 @@ got@^7.1.0: url-to-options "^1.0.1" graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: - version "4.1.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" - integrity sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg= + version "4.2.3" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" + integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== har-schema@^2.0.0: version "2.0.0" @@ -2593,9 +2595,9 @@ inflight@^1.0.4: wrappy "1" inherits@2, inherits@~2.0.0, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== inquirer@^6.2.2: version "6.3.1" @@ -3084,7 +3086,7 @@ js-tokens@^3.0.0, js-tokens@^3.0.2: resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== -js-yaml@^3.13.0: +js-yaml@^3.13.0, js-yaml@^3.9.0: version "3.13.1" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== @@ -3092,14 +3094,6 @@ js-yaml@^3.13.0: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@^3.9.0: - version "3.11.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" - integrity sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - jsbn@~0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" @@ -3394,15 +3388,10 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0: - version "4.17.10" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" - integrity sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg== - -lodash@^4.17.11: - version "4.17.11" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d" - integrity sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg== +lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== log-symbols@^1.0.2: version "1.0.2" @@ -3566,9 +3555,9 @@ minimist@0.0.8: integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0= mixin-deep@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" - integrity sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ== + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== dependencies: for-in "^1.0.2" is-extendable "^1.0.1" @@ -3748,7 +3737,7 @@ once@^1.3.0: onetime@^1.0.0: version "1.1.0" - resolved "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + resolved "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" integrity sha1-ofeDj4MUxRbwXs78vEzP4EtO14k= onetime@^2.0.0: @@ -4349,11 +4338,11 @@ ret@~0.1.10: integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== rimraf@2, rimraf@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" - integrity sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w== + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== dependencies: - glob "^7.0.5" + glob "^7.1.3" rimraf@2.6.3: version "2.6.3" @@ -4789,9 +4778,9 @@ stringify-object@^3.2.2: is-regexp "^1.0.0" stringstream@~0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" - integrity sha1-TkhM1N5aC7vuGORjB3EKioFiGHg= + version "0.0.6" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.6.tgz#7880225b0d4ad10e30927d167a1d6f2fd3b33a72" + integrity sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA== strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" -- 2.45.2 From 03d53fb4ddadc8dc469670cf75a624d0bca354f2 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 5 Nov 2019 13:24:41 -0500 Subject: [PATCH 195/371] maint: support 0.44 SDK maint: support 0.44 SDK --- dist/bundle.es.js | 48 +++++++++++++++------------ dist/flow-typed/File.js | 1 + dist/flow-typed/Lbry.js | 59 +++++++++++++++++++++++++++++----- dist/flow-typed/Transaction.js | 1 + flow-typed/File.js | 1 + flow-typed/Lbry.js | 59 +++++++++++++++++++++++++++++----- flow-typed/Transaction.js | 1 + src/lbry.js | 1 + src/redux/actions/claims.js | 12 +++---- src/redux/actions/comments.js | 9 ++++-- src/redux/actions/file_info.js | 14 +++++--- src/redux/actions/wallet.js | 8 ++--- src/redux/reducers/comments.js | 4 +-- 13 files changed, 162 insertions(+), 56 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d863ca5..39a32fb 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -775,6 +775,7 @@ const Lbry = { stream_list: params => daemonCallWithResult('stream_list', params), channel_abandon: params => daemonCallWithResult('channel_abandon', params), support_create: params => daemonCallWithResult('support_create', params), + support_list: params => daemonCallWithResult('support_list', params), // File fetching and manipulation file_list: (params = {}) => daemonCallWithResult('file_list', params), @@ -2193,7 +2194,7 @@ function doUpdateBalance() { } = getState(); if (walletBalancePromise === null) { - walletBalancePromise = lbryProxy.wallet_balance({ reserved_subtotals: true }).then(response => { + walletBalancePromise = lbryProxy.wallet_balance().then(response => { walletBalancePromise = null; const { available, reserved, reserved_subtotals, total } = response; @@ -2245,17 +2246,17 @@ function doFetchTransactions(page = 1, pageSize = 99999) { }; } -function doFetchSupports() { +function doFetchSupports(page = 1, pageSize = 99999) { return dispatch => { dispatch({ type: FETCH_SUPPORTS_STARTED }); - lbryProxy.support_list().then(results => { + lbryProxy.support_list({ page, page_size: pageSize }).then(result => { dispatch({ type: FETCH_SUPPORTS_COMPLETED, data: { - supports: results + supports: result.items } }); }); @@ -2614,13 +2615,13 @@ function doResolveUri(uri) { return doResolveUris([uri]); } -function doFetchClaimListMine(page = 1, pageSize = 9999) { +function doFetchClaimListMine(page = 1, pageSize = 99999) { return dispatch => { dispatch({ type: FETCH_CLAIM_LIST_MINE_STARTED }); - lbryProxy.claim_list({ page, page_size: pageSize }).then(result => { + lbryProxy.stream_list({ page, page_size: pageSize }).then(result => { const claims = result.items; dispatch({ @@ -2874,7 +2875,7 @@ function doImportChannel(certificate) { }; } -function doFetchChannelListMine() { +function doFetchChannelListMine(page = 1, pageSize = 99999) { return dispatch => { dispatch({ type: FETCH_CHANNEL_LIST_STARTED @@ -2883,11 +2884,11 @@ function doFetchChannelListMine() { const callback = channels => { dispatch({ type: FETCH_CHANNEL_LIST_COMPLETED, - data: { claims: channels } + data: { claims: channels.items } }); }; - lbryProxy.channel_list().then(callback); + lbryProxy.channel_list({ page, page_size: pageSize }).then(callback); }; } @@ -3210,12 +3211,15 @@ function doFetchFileInfo(uri) { } }); - lbryProxy.file_list({ outpoint, full_status: true }).then(fileInfos => { + lbryProxy.file_list({ outpoint, full_status: true, page: 1, page_size: 1 }).then(result => { + const { items: fileInfos } = result; + const fileInfo = fileInfos[0]; + dispatch({ type: FETCH_FILE_INFO_COMPLETED, data: { outpoint, - fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null + fileInfo: fileInfo || null } }); }); @@ -3223,7 +3227,7 @@ function doFetchFileInfo(uri) { }; } -function doFileList() { +function doFileList(page = 1, pageSize = 99999) { return (dispatch, getState) => { const state = getState(); const isFetching = selectIsFetchingFileList(state); @@ -3233,11 +3237,12 @@ function doFileList() { type: FILE_LIST_STARTED }); - lbryProxy.file_list().then(fileInfos => { + lbryProxy.file_list({ page, page_size: pageSize }).then(result => { + const { items: fileInfos } = result; dispatch({ type: FILE_LIST_SUCCEEDED, data: { - fileInfos + fileInfos: fileInfos.reverse() } }); }); @@ -3889,7 +3894,7 @@ const doDeleteTag = name => ({ // -function doCommentList(uri) { +function doCommentList(uri, page = 1, pageSize = 99999) { return (dispatch, getState) => { const state = getState(); const claim = selectClaimsByUri(state)[uri]; @@ -3899,12 +3904,15 @@ function doCommentList(uri) { type: COMMENT_LIST_STARTED }); lbryProxy.comment_list({ - claim_id: claimId - }).then(results => { + claim_id: claimId, + page, + page_size: pageSize + }).then(result => { + const { items: comments } = result; dispatch({ type: COMMENT_LIST_COMPLETED, data: { - comments: results, + comments, claimId: claimId, uri: uri } @@ -4387,8 +4395,8 @@ const commentReducer = handleActions({ const byId = Object.assign({}, state.byId); const commentsByUri = Object.assign({}, state.commentsByUri); - if (comments['items']) { - byId[claimId] = comments['items']; + if (comments) { + byId[claimId] = comments; commentsByUri[uri] = claimId; } return _extends$7({}, state, { diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index c4c151c..71a2523 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -2,6 +2,7 @@ declare type FileListItem = { metadata: StreamMetadata, + added_on: number, blobs_completed: number, blobs_in_stream: number, blobs_remaining: number, diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index e967a97..047f9a0 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -108,6 +108,10 @@ declare type ClaimSearchResponse = { declare type ClaimListResponse = { items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, }; declare type ChannelCreateResponse = GenericTxResponse & { @@ -119,15 +123,47 @@ declare type ChannelUpdateResponse = GenericTxResponse & { }; declare type CommentCreateResponse = Comment; -declare type CommentListResponse = Array; +declare type CommentListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; -declare type ChannelListResponse = Array; +declare type ChannelListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; -declare type FileListResponse = Array; +declare type FileListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; -declare type TxListResponse = { items: Array }; +declare type TxListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; -declare type BlobListResponse = Array; +declare type SupportListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; + +declare type BlobListResponse = { items: Array }; declare type WalletListResponse = Array<{ id: string, @@ -146,7 +182,13 @@ declare type SyncApplyResponse = { declare type SupportAbandonResponse = GenericTxResponse; -declare type StreamListResponse = { items: Array }; +declare type StreamListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; // // Types used in the generic Lbry object that is exported @@ -177,11 +219,13 @@ declare type LbryTypes = { channel_create: (params: {}) => Promise, channel_update: (params: {}) => Promise, channel_import: (params: {}) => Promise, - channel_list: () => Promise, + channel_list: (params?: {}) => Promise, stream_abandon: (params: {}) => Promise, stream_list: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, support_create: (params: {}) => Promise, + support_list: (params: {}) => Promise, + support_abandon: (params: {}) => Promise, // File fetching and manipulation file_list: (params: {}) => Promise, @@ -208,7 +252,6 @@ declare type LbryTypes = { address_unused: (params: {}) => Promise, // New address address_list: (params: {}) => Promise, transaction_list: (params: {}) => Promise, - support_abandon: (params: {}) => Promise, // Sync sync_hash: (params: {}) => Promise, diff --git a/dist/flow-typed/Transaction.js b/dist/flow-typed/Transaction.js index 0042576..db9e592 100644 --- a/dist/flow-typed/Transaction.js +++ b/dist/flow-typed/Transaction.js @@ -19,6 +19,7 @@ declare type Support = { is_change: string, is_mine: string, name: string, + normalized_name: string, nout: string, permanent_url: string, timestamp: number, diff --git a/flow-typed/File.js b/flow-typed/File.js index c4c151c..71a2523 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -2,6 +2,7 @@ declare type FileListItem = { metadata: StreamMetadata, + added_on: number, blobs_completed: number, blobs_in_stream: number, blobs_remaining: number, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index e967a97..047f9a0 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -108,6 +108,10 @@ declare type ClaimSearchResponse = { declare type ClaimListResponse = { items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, }; declare type ChannelCreateResponse = GenericTxResponse & { @@ -119,15 +123,47 @@ declare type ChannelUpdateResponse = GenericTxResponse & { }; declare type CommentCreateResponse = Comment; -declare type CommentListResponse = Array; +declare type CommentListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; -declare type ChannelListResponse = Array; +declare type ChannelListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; -declare type FileListResponse = Array; +declare type FileListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; -declare type TxListResponse = { items: Array }; +declare type TxListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; -declare type BlobListResponse = Array; +declare type SupportListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; + +declare type BlobListResponse = { items: Array }; declare type WalletListResponse = Array<{ id: string, @@ -146,7 +182,13 @@ declare type SyncApplyResponse = { declare type SupportAbandonResponse = GenericTxResponse; -declare type StreamListResponse = { items: Array }; +declare type StreamListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; // // Types used in the generic Lbry object that is exported @@ -177,11 +219,13 @@ declare type LbryTypes = { channel_create: (params: {}) => Promise, channel_update: (params: {}) => Promise, channel_import: (params: {}) => Promise, - channel_list: () => Promise, + channel_list: (params?: {}) => Promise, stream_abandon: (params: {}) => Promise, stream_list: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, support_create: (params: {}) => Promise, + support_list: (params: {}) => Promise, + support_abandon: (params: {}) => Promise, // File fetching and manipulation file_list: (params: {}) => Promise, @@ -208,7 +252,6 @@ declare type LbryTypes = { address_unused: (params: {}) => Promise, // New address address_list: (params: {}) => Promise, transaction_list: (params: {}) => Promise, - support_abandon: (params: {}) => Promise, // Sync sync_hash: (params: {}) => Promise, diff --git a/flow-typed/Transaction.js b/flow-typed/Transaction.js index 0042576..db9e592 100644 --- a/flow-typed/Transaction.js +++ b/flow-typed/Transaction.js @@ -19,6 +19,7 @@ declare type Support = { is_change: string, is_mine: string, name: string, + normalized_name: string, nout: string, permanent_url: string, timestamp: number, diff --git a/src/lbry.js b/src/lbry.js index ed7ad7d..66a58e0 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -85,6 +85,7 @@ const Lbry: LbryTypes = { stream_list: params => daemonCallWithResult('stream_list', params), channel_abandon: params => daemonCallWithResult('channel_abandon', params), support_create: params => daemonCallWithResult('support_create', params), + support_list: params => daemonCallWithResult('support_list', params), // File fetching and manipulation file_list: (params = {}) => daemonCallWithResult('file_list', params), diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 5c296a1..b61313b 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -94,13 +94,13 @@ export function doResolveUri(uri: string) { return doResolveUris([uri]); } -export function doFetchClaimListMine(page: number = 1, pageSize: number = 9999) { +export function doFetchClaimListMine(page: number = 1, pageSize: number = 99999) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED, }); - Lbry.claim_list({ page, page_size: pageSize }).then((result: ClaimListResponse) => { + Lbry.stream_list({ page, page_size: pageSize }).then((result: StreamListResponse) => { const claims = result.items; dispatch({ @@ -382,20 +382,20 @@ export function doImportChannel(certificate: string) { }; } -export function doFetchChannelListMine() { +export function doFetchChannelListMine(page: number = 1, pageSize: number = 99999) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_CHANNEL_LIST_STARTED, }); - const callback = (channels: Array) => { + const callback = (channels: ChannelListResponse) => { dispatch({ type: ACTIONS.FETCH_CHANNEL_LIST_COMPLETED, - data: { claims: channels }, + data: { claims: channels.items }, }); }; - Lbry.channel_list().then(callback); + Lbry.channel_list({ page, page_size: pageSize }).then(callback); }; } diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 61e9f6b..dbf1d94 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -4,7 +4,7 @@ import Lbry from 'lbry'; import { selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims'; import { doToast } from 'redux/actions/notifications'; -export function doCommentList(uri: string) { +export function doCommentList(uri: string, page: number = 1, pageSize: number = 99999) { return (dispatch: Dispatch, getState: GetState) => { const state = getState(); const claim = selectClaimsByUri(state)[uri]; @@ -15,12 +15,15 @@ export function doCommentList(uri: string) { }); Lbry.comment_list({ claim_id: claimId, + page, + page_size: pageSize, }) - .then((results: CommentListResponse) => { + .then((result: CommentListResponse) => { + const { items: comments } = result; dispatch({ type: ACTIONS.COMMENT_LIST_COMPLETED, data: { - comments: results, + comments, claimId: claimId, uri: uri, }, diff --git a/src/redux/actions/file_info.js b/src/redux/actions/file_info.js index 7177183..00c735a 100644 --- a/src/redux/actions/file_info.js +++ b/src/redux/actions/file_info.js @@ -19,12 +19,15 @@ export function doFetchFileInfo(uri) { }, }); - Lbry.file_list({ outpoint, full_status: true }).then(fileInfos => { + Lbry.file_list({ outpoint, full_status: true, page: 1, page_size: 1 }).then(result => { + const { items: fileInfos } = result; + const fileInfo = fileInfos[0]; + dispatch({ type: ACTIONS.FETCH_FILE_INFO_COMPLETED, data: { outpoint, - fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null, + fileInfo: fileInfo || null, }, }); }); @@ -32,7 +35,7 @@ export function doFetchFileInfo(uri) { }; } -export function doFileList() { +export function doFileList(page: number = 1, pageSize: number = 99999) { return (dispatch, getState) => { const state = getState(); const isFetching = selectIsFetchingFileList(state); @@ -42,11 +45,12 @@ export function doFileList() { type: ACTIONS.FILE_LIST_STARTED, }); - Lbry.file_list().then(fileInfos => { + Lbry.file_list({ page, page_size: pageSize }).then(result => { + const { items: fileInfos } = result; dispatch({ type: ACTIONS.FILE_LIST_SUCCEEDED, data: { - fileInfos, + fileInfos: fileInfos.reverse(), }, }); }); diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 047c306..6164a31 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -13,7 +13,7 @@ export function doUpdateBalance() { } = getState(); if (walletBalancePromise === null) { - walletBalancePromise = Lbry.wallet_balance({ reserved_subtotals: true }).then(response => { + walletBalancePromise = Lbry.wallet_balance().then(response => { walletBalancePromise = null; const { available, reserved, reserved_subtotals, total } = response; @@ -67,17 +67,17 @@ export function doFetchTransactions(page = 1, pageSize = 99999) { }; } -export function doFetchSupports() { +export function doFetchSupports(page = 1, pageSize = 99999) { return dispatch => { dispatch({ type: ACTIONS.FETCH_SUPPORTS_STARTED, }); - Lbry.support_list().then(results => { + Lbry.support_list({ page, page_size: pageSize }).then(result => { dispatch({ type: ACTIONS.FETCH_SUPPORTS_COMPLETED, data: { - supports: results, + supports: result.items, }, }); }); diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js index 1f99467..3d1738b 100644 --- a/src/redux/reducers/comments.js +++ b/src/redux/reducers/comments.js @@ -42,8 +42,8 @@ export const commentReducer = handleActions( const byId = Object.assign({}, state.byId); const commentsByUri = Object.assign({}, state.commentsByUri); - if (comments['items']) { - byId[claimId] = comments['items']; + if (comments) { + byId[claimId] = comments; commentsByUri[uri] = claimId; } return { -- 2.45.2 From e3d1e8754499f983b2c9aa6bd0fef1812daf3e32 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 5 Nov 2019 13:52:17 -0500 Subject: [PATCH 196/371] cleanup --- dist/bundle.es.js | 12 ++++++++---- dist/flow-typed/Lbry.js | 4 ++-- flow-typed/Lbry.js | 4 ++-- src/redux/actions/claims.js | 4 ++-- src/redux/selectors/file_info.js | 31 ++++++++++++++++--------------- 5 files changed, 30 insertions(+), 25 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 39a32fb..b39425c 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2881,10 +2881,10 @@ function doFetchChannelListMine(page = 1, pageSize = 99999) { type: FETCH_CHANNEL_LIST_STARTED }); - const callback = channels => { + const callback = response => { dispatch({ type: FETCH_CHANNEL_LIST_COMPLETED, - data: { claims: channels.items } + data: { claims: response.items } }); }; @@ -3017,7 +3017,7 @@ const selectFileListDownloadedSort = reselect.createSelector(selectState$3, stat const selectDownloadedUris = reselect.createSelector(selectFileInfosDownloaded, // We should use permament_url but it doesn't exist in file_list -info => info.slice().reverse().map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)); +info => info.slice().map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)); const makeSelectMediaTypeForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), makeSelectContentTypeForUri(uri), (fileInfo, contentType) => { if (!fileInfo && !contentType) { @@ -3068,7 +3068,11 @@ const makeSelectSearchDownloadUrlsForPage = (query, page = 1) => reselect.create const start = (Number(page) - 1) * Number(PAGE_SIZE); const end = Number(page) * Number(PAGE_SIZE); - return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos.slice(start, end).map(fileInfo => buildURI({ streamName: fileInfo.claim_name, channelName: fileInfo.channel_name, channelClaimId: fileInfo.channel_claim_id })) : []; + return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos.slice(start, end).map(fileInfo => buildURI({ + streamName: fileInfo.claim_name, + channelName: fileInfo.channel_name, + channelClaimId: fileInfo.channel_claim_id + })) : []; }); const makeSelectSearchDownloadUrlsCount = query => reselect.createSelector(selectFileInfosDownloaded, fileInfos => { diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 047f9a0..006e170 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -215,11 +215,11 @@ declare type LbryTypes = { publish: (params: {}) => Promise, claim_search: (params: {}) => Promise, - claim_list: (params?: {}) => Promise, + claim_list: (params: {}) => Promise, channel_create: (params: {}) => Promise, channel_update: (params: {}) => Promise, channel_import: (params: {}) => Promise, - channel_list: (params?: {}) => Promise, + channel_list: (params: {}) => Promise, stream_abandon: (params: {}) => Promise, stream_list: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 047f9a0..006e170 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -215,11 +215,11 @@ declare type LbryTypes = { publish: (params: {}) => Promise, claim_search: (params: {}) => Promise, - claim_list: (params?: {}) => Promise, + claim_list: (params: {}) => Promise, channel_create: (params: {}) => Promise, channel_update: (params: {}) => Promise, channel_import: (params: {}) => Promise, - channel_list: (params?: {}) => Promise, + channel_list: (params: {}) => Promise, stream_abandon: (params: {}) => Promise, stream_list: (params: {}) => Promise, channel_abandon: (params: {}) => Promise, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index b61313b..1cacf65 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -388,10 +388,10 @@ export function doFetchChannelListMine(page: number = 1, pageSize: number = 9999 type: ACTIONS.FETCH_CHANNEL_LIST_STARTED, }); - const callback = (channels: ChannelListResponse) => { + const callback = (response: ChannelListResponse) => { dispatch({ type: ACTIONS.FETCH_CHANNEL_LIST_COMPLETED, - data: { claims: channels.items }, + data: { claims: response.items }, }); }; diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 1431004..84374e8 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -146,11 +146,7 @@ export const selectFileListDownloadedSort = createSelector( export const selectDownloadedUris = createSelector( selectFileInfosDownloaded, // We should use permament_url but it doesn't exist in file_list - info => - info - .slice() - .reverse() - .map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) + info => info.slice().map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) ); export const makeSelectMediaTypeForUri = uri => @@ -214,9 +210,11 @@ function filterFileInfos(fileInfos, query) { const queryMatchRegExp = new RegExp(query, 'i'); return fileInfos.filter(fileInfo => { const { metadata } = fileInfo; - return (metadata.title && metadata.title.match(queryMatchRegExp)) || + return ( + (metadata.title && metadata.title.match(queryMatchRegExp)) || (fileInfo.channel_name && fileInfo.channel_name.match(queryMatchRegExp)) || - (fileInfo.claim_name && fileInfo.claim_name.match(queryMatchRegExp)); + (fileInfo.claim_name && fileInfo.claim_name.match(queryMatchRegExp)) + ); }); } @@ -228,22 +226,25 @@ export const makeSelectSearchDownloadUrlsForPage = (query, page = 1) => selectFileInfosDownloaded, fileInfos => { const matchingFileInfos = filterFileInfos(fileInfos, query); - const start = ((Number(page) - 1) * Number(PAGE_SIZE)); - const end = (Number(page) * Number(PAGE_SIZE)); + const start = (Number(page) - 1) * Number(PAGE_SIZE); + const end = Number(page) * Number(PAGE_SIZE); - return (matchingFileInfos && matchingFileInfos.length) + return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos.slice(start, end).map(fileInfo => - buildURI({ streamName: fileInfo.claim_name, channelName: fileInfo.channel_name, channelClaimId: fileInfo.channel_claim_id })) + buildURI({ + streamName: fileInfo.claim_name, + channelName: fileInfo.channel_name, + channelClaimId: fileInfo.channel_claim_id, + }) + ) : []; } ); -export const makeSelectSearchDownloadUrlsCount = (query) => +export const makeSelectSearchDownloadUrlsCount = query => createSelector( selectFileInfosDownloaded, fileInfos => { - return fileInfos && fileInfos.length - ? filterFileInfos(fileInfos, query).length - : 0; + return fileInfos && fileInfos.length ? filterFileInfos(fileInfos, query).length : 0; } ); -- 2.45.2 From 32875c3ba75d20dbaa0d032a6827597ebdf460ef Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 14 Nov 2019 12:59:37 -0500 Subject: [PATCH 197/371] fix: download list in correct order --- dist/bundle.es.js | 4 ++-- src/redux/actions/file_info.js | 4 ++-- src/redux/selectors/file_info.js | 18 ++++++++++-------- 3 files changed, 14 insertions(+), 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index a0028d0..3213ff2 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2970,7 +2970,7 @@ const makeSelectLoadingForUri = uri => reselect.createSelector(selectUrisLoading return isFetching; }); -const selectFileInfosDownloaded = reselect.createSelector(selectFileInfosByOutpoint, selectMyClaims, (byOutpoint, myClaims) => Object.values(byOutpoint).filter(fileInfo => { +const selectFileInfosDownloaded = reselect.createSelector(selectFileInfosByOutpoint, selectMyClaims, (byOutpoint, myClaims) => Object.values(byOutpoint).reverse().filter(fileInfo => { const myClaimIds = myClaims.map(claim => claim.claim_id); return fileInfo && myClaimIds.indexOf(fileInfo.claim_id) === -1 && (fileInfo.completed || fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0); @@ -3246,7 +3246,7 @@ function doFileList(page = 1, pageSize = 99999) { dispatch({ type: FILE_LIST_SUCCEEDED, data: { - fileInfos: fileInfos.reverse() + fileInfos: fileInfos } }); }); diff --git a/src/redux/actions/file_info.js b/src/redux/actions/file_info.js index 00c735a..b218053 100644 --- a/src/redux/actions/file_info.js +++ b/src/redux/actions/file_info.js @@ -35,7 +35,7 @@ export function doFetchFileInfo(uri) { }; } -export function doFileList(page: number = 1, pageSize: number = 99999) { +export function doFileList(page = 1, pageSize = 99999) { return (dispatch, getState) => { const state = getState(); const isFetching = selectIsFetchingFileList(state); @@ -50,7 +50,7 @@ export function doFileList(page: number = 1, pageSize: number = 99999) { dispatch({ type: ACTIONS.FILE_LIST_SUCCEEDED, data: { - fileInfos: fileInfos.reverse(), + fileInfos: fileInfos, }, }); }); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 84374e8..f29f3b1 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -80,15 +80,17 @@ export const selectFileInfosDownloaded = createSelector( selectFileInfosByOutpoint, selectMyClaims, (byOutpoint, myClaims) => - Object.values(byOutpoint).filter(fileInfo => { - const myClaimIds = myClaims.map(claim => claim.claim_id); + Object.values(byOutpoint) + .reverse() + .filter(fileInfo => { + const myClaimIds = myClaims.map(claim => claim.claim_id); - return ( - fileInfo && - myClaimIds.indexOf(fileInfo.claim_id) === -1 && - (fileInfo.completed || fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0) - ); - }) + return ( + fileInfo && + myClaimIds.indexOf(fileInfo.claim_id) === -1 && + (fileInfo.completed || fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0) + ); + }) ); // export const selectFileInfoForUri = (state, props) => { -- 2.45.2 From 84fb36841a030447e08ef2d583684cd0a573b4b2 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 18 Nov 2019 14:00:03 -0500 Subject: [PATCH 198/371] add channel item count for canonical url as well as vanity url --- dist/bundle.es.js | 1 + src/redux/reducers/claims.js | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3213ff2..4c1dfa7 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4016,6 +4016,7 @@ function handleClaimAction(state, action) { const { claimsInChannel, stream, channel } = resolveResponse; if (claimsInChannel) { channelClaimCounts[url] = claimsInChannel; + channelClaimCounts[channel.canonical_url] = claimsInChannel; } if (stream) { diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index f828645..5663657 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -85,6 +85,7 @@ function handleClaimAction(state: State, action: any): State { const { claimsInChannel, stream, channel } = resolveResponse; if (claimsInChannel) { channelClaimCounts[url] = claimsInChannel; + channelClaimCounts[channel.canonical_url] = claimsInChannel; } if (stream) { -- 2.45.2 From f5a62363cf6d3ff33a42a4446e6df3024a7780d8 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 18 Nov 2019 14:15:00 -0500 Subject: [PATCH 199/371] same fix for streams --- dist/bundle.es.js | 4 ++++ src/redux/reducers/claims.js | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4c1dfa7..5f3fa68 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4022,6 +4022,10 @@ function handleClaimAction(state, action) { if (stream) { byId[stream.claim_id] = stream; byUri[url] = stream.claim_id; + + // If url isn't a canonical_url, make sure that is added too + byUri[stream.canonical_url] = stream.claim_id; + // Also add the permanent_url here until lighthouse returns canonical_url for search results byUri[stream.permanent_url] = stream.claim_id; newResolvingUrls.delete(stream.canonical_url); diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 5663657..103abe0 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -91,6 +91,10 @@ function handleClaimAction(state: State, action: any): State { if (stream) { byId[stream.claim_id] = stream; byUri[url] = stream.claim_id; + + // If url isn't a canonical_url, make sure that is added too + byUri[stream.canonical_url] = stream.claim_id; + // Also add the permanent_url here until lighthouse returns canonical_url for search results byUri[stream.permanent_url] = stream.claim_id; newResolvingUrls.delete(stream.canonical_url); -- 2.45.2 From c30889d3392b89ffffdb5beea8534f2aa0f76b19 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 19 Nov 2019 15:29:32 -0500 Subject: [PATCH 200/371] handle claimsInChannels for channel fetch so pagination always works --- dist/bundle.es.js | 13 ++++++++++--- src/redux/actions/claims.js | 5 +++-- src/redux/reducers/claims.js | 15 +++++++++++++-- 3 files changed, 26 insertions(+), 7 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 5f3fa68..bbb0504 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2732,13 +2732,14 @@ function doFetchClaimsByChannel(uri, page = 1) { page: page || 1, order_by: ['release_time'] }).then(result => { - const { items: claimsInChannel, page: returnedPage } = result; + const { items: claims, total_items: claimsInChannel, page: returnedPage } = result; dispatch({ type: FETCH_CHANNEL_CLAIMS_COMPLETED, data: { uri, - claims: claimsInChannel || [], + claimsInChannel, + claims: claims || [], page: returnedPage || undefined } }); @@ -4172,9 +4173,10 @@ reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { const { uri, claims, + claimsInChannel, page } = action.data; - + const channelClaimCounts = Object.assign({}, state.channelClaimCounts); const claimsByChannel = Object.assign({}, state.claimsByChannel); const byChannel = Object.assign({}, claimsByChannel[uri]); const allClaimIds = new Set(byChannel.all); @@ -4192,6 +4194,10 @@ reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { }); } + if (claimsInChannel) { + channelClaimCounts[uri] = claimsInChannel; + } + byChannel.all = allClaimIds; byChannel[page] = currentPageClaimIds; claimsByChannel[uri] = byChannel; @@ -4202,6 +4208,7 @@ reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { byId, fetchingChannelClaims, claimsByUri, + channelClaimCounts, currentChannelPage: page }); }; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 1cacf65..cd21153 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -221,13 +221,14 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { page: page || 1, order_by: ['release_time'], }).then((result: ClaimSearchResponse) => { - const { items: claimsInChannel, page: returnedPage } = result; + const { items: claims, total_items: claimsInChannel, page: returnedPage } = result; dispatch({ type: ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED, data: { uri, - claims: claimsInChannel || [], + claimsInChannel, + claims: claims || [], page: returnedPage || undefined, }, }); diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 103abe0..d5154a4 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -246,9 +246,15 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): const { uri, claims, + claimsInChannel, page, - }: { uri: string, claims: Array, page: number } = action.data; - + }: { + uri: string, + claims: Array, + claimsInChannel?: number, + page: number, + } = action.data; + const channelClaimCounts = Object.assign({}, state.channelClaimCounts); const claimsByChannel = Object.assign({}, state.claimsByChannel); const byChannel = Object.assign({}, claimsByChannel[uri]); const allClaimIds = new Set(byChannel.all); @@ -266,6 +272,10 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): }); } + if (claimsInChannel) { + channelClaimCounts[uri] = claimsInChannel; + } + byChannel.all = allClaimIds; byChannel[page] = currentPageClaimIds; claimsByChannel[uri] = byChannel; @@ -276,6 +286,7 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): byId, fetchingChannelClaims, claimsByUri, + channelClaimCounts, currentChannelPage: page, }); }; -- 2.45.2 From d96aeb7e71a41fc849c1a3fbc3cede2f78469d8f Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 21 Nov 2019 18:52:37 -0500 Subject: [PATCH 201/371] stores item and page counts from claim search with paginated claims --- dist/bundle.es.js | 26 +++++++++++++++++++++++--- src/index.js | 2 ++ src/redux/reducers/claims.js | 13 ++++++++++++- src/redux/selectors/claims.js | 23 ++++++++++++++++++++++- 4 files changed, 59 insertions(+), 5 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index bbb0504..2a8303f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1881,7 +1881,7 @@ const makeSelectClaimIsMine = rawUri => { const selectAllFetchingChannelClaims = reselect.createSelector(selectState$2, state => state.fetchingChannelClaims || {}); const makeSelectFetchingChannelClaims = uri => reselect.createSelector(selectAllFetchingChannelClaims, fetching => fetching && fetching[uri]); - +// this is actually the result of claim search const makeSelectClaimsInChannelForPage = (uri, page) => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { const byChannel = allClaims[uri] || {}; const claimIds = byChannel[page || 1]; @@ -1891,6 +1891,16 @@ const makeSelectClaimsInChannelForPage = (uri, page) => reselect.createSelector( return claimIds.map(claimId => byId[claimId]); }); +const makeSelectTotalMatchingClaimsInChannel = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { + const byChannel = allClaims[uri] || {}; + return byChannel['itemCount']; +}); + +const makeSelectTotalMatchingPaginatedPagesInChannel = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { + const byChannel = allClaims[uri] || {}; + return byChannel['pageCount']; +}); + const makeSelectClaimsInChannelForCurrentPageState = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, selectCurrentChannelPage, (byId, allClaims, page) => { const byChannel = allClaims[uri] || {}; const claimIds = byChannel[page || 1]; @@ -4174,11 +4184,17 @@ reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { uri, claims, claimsInChannel, - page + page, + totalPages } = action.data; + + // byChannel keeps claim_search relevant results by page. If the total changes, erase it. const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + const claimsByChannel = Object.assign({}, state.claimsByChannel); - const byChannel = Object.assign({}, claimsByChannel[uri]); + // check if count has changed - that means cached pagination will be wrong, so clear it + const previousCount = claimsByChannel[uri] && claimsByChannel[uri]['itemCount']; + const byChannel = claimsInChannel === previousCount ? Object.assign({}, claimsByChannel[uri]) : {}; const allClaimIds = new Set(byChannel.all); const currentPageClaimIds = []; const byId = Object.assign({}, state.byId); @@ -4199,6 +4215,8 @@ reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { } byChannel.all = allClaimIds; + byChannel.pageCount = totalPages; + byChannel.itemCount = claimsInChannel; byChannel[page] = currentPageClaimIds; claimsByChannel[uri] = byChannel; delete fetchingChannelClaims[uri]; @@ -5496,6 +5514,8 @@ exports.makeSelectTagsForUri = makeSelectTagsForUri; exports.makeSelectThumbnailForUri = makeSelectThumbnailForUri; exports.makeSelectTitleForUri = makeSelectTitleForUri; exports.makeSelectTotalItemsForChannel = makeSelectTotalItemsForChannel; +exports.makeSelectTotalMatchingClaimsInChannel = makeSelectTotalMatchingClaimsInChannel; +exports.makeSelectTotalMatchingPaginatedPagesInChannel = makeSelectTotalMatchingPaginatedPagesInChannel; exports.makeSelectTotalPagesForChannel = makeSelectTotalPagesForChannel; exports.makeSelectUriIsStreamable = makeSelectUriIsStreamable; exports.normalizeURI = normalizeURI; diff --git a/src/index.js b/src/index.js index 7812297..2cf47bb 100644 --- a/src/index.js +++ b/src/index.js @@ -159,6 +159,8 @@ export { makeSelectClaimIsMine, makeSelectFetchingChannelClaims, makeSelectClaimsInChannelForPage, + makeSelectTotalMatchingPaginatedPagesInChannel, + makeSelectTotalMatchingClaimsInChannel, makeSelectMetadataForUri, makeSelectMetadataItemForUri, makeSelectThumbnailForUri, diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index d5154a4..cd3a7f1 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -31,6 +31,8 @@ type State = { claimsByChannel: { [string]: { all: Array, + pageCount: number, + itemCount: number, [number]: Array, }, }, @@ -248,15 +250,22 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): claims, claimsInChannel, page, + totalPages, }: { uri: string, claims: Array, claimsInChannel?: number, page: number, + totalPages: number, } = action.data; + + // byChannel keeps claim_search relevant results by page. If the total changes, erase it. const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + const claimsByChannel = Object.assign({}, state.claimsByChannel); - const byChannel = Object.assign({}, claimsByChannel[uri]); + // check if count has changed - that means cached pagination will be wrong, so clear it + const previousCount = claimsByChannel[uri] && claimsByChannel[uri]['itemCount']; + const byChannel = (claimsInChannel === previousCount) ? Object.assign({}, claimsByChannel[uri]) : {}; const allClaimIds = new Set(byChannel.all); const currentPageClaimIds = []; const byId = Object.assign({}, state.byId); @@ -277,6 +286,8 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): } byChannel.all = allClaimIds; + byChannel.pageCount = totalPages; + byChannel.itemCount = claimsInChannel; byChannel[page] = currentPageClaimIds; claimsByChannel[uri] = byChannel; delete fetchingChannelClaims[uri]; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index d90936e..f953d8f 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -177,7 +177,7 @@ export const makeSelectFetchingChannelClaims = (uri: string) => selectAllFetchingChannelClaims, fetching => fetching && fetching[uri] ); - +// this is actually the result of claim search export const makeSelectClaimsInChannelForPage = (uri: string, page?: number) => createSelector( selectClaimsById, @@ -192,6 +192,27 @@ export const makeSelectClaimsInChannelForPage = (uri: string, page?: number) => } ); +export const makeSelectTotalMatchingClaimsInChannel = (uri: string) => + createSelector( + selectClaimsById, + selectAllClaimsByChannel, + (byId, allClaims) => { + const byChannel = allClaims[uri] || {}; + return byChannel['itemCount']; + } + ); + +export const makeSelectTotalMatchingPaginatedPagesInChannel = (uri: string) => + createSelector( + selectClaimsById, + selectAllClaimsByChannel, + (byId, allClaims) => { + const byChannel = allClaims[uri] || {}; + return byChannel['pageCount']; + } + ); + + export const makeSelectClaimsInChannelForCurrentPageState = (uri: string) => createSelector( selectClaimsById, -- 2.45.2 From 15934866e1d55871129c61f99511582d1fb655d1 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 21 Nov 2019 20:36:06 -0500 Subject: [PATCH 202/371] rename claimsByChannel to paginated... --- dist/bundle.es.js | 28 ++++++++++++---------------- src/index.js | 4 ++-- src/redux/reducers/claims.js | 18 +++++++----------- src/redux/selectors/claims.js | 8 ++++---- 4 files changed, 25 insertions(+), 33 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2a8303f..7566ec3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1805,7 +1805,7 @@ const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsByI return claims; }); -const selectAllClaimsByChannel = reselect.createSelector(selectState$2, state => state.claimsByChannel || {}); +const selectAllClaimsByChannel = reselect.createSelector(selectState$2, state => state.paginatedClaimsByChannel || {}); const selectPendingById = reselect.createSelector(selectState$2, state => state.pendingById || {}); @@ -1881,7 +1881,7 @@ const makeSelectClaimIsMine = rawUri => { const selectAllFetchingChannelClaims = reselect.createSelector(selectState$2, state => state.fetchingChannelClaims || {}); const makeSelectFetchingChannelClaims = uri => reselect.createSelector(selectAllFetchingChannelClaims, fetching => fetching && fetching[uri]); -// this is actually the result of claim search + const makeSelectClaimsInChannelForPage = (uri, page) => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { const byChannel = allClaims[uri] || {}; const claimIds = byChannel[page || 1]; @@ -1891,12 +1891,12 @@ const makeSelectClaimsInChannelForPage = (uri, page) => reselect.createSelector( return claimIds.map(claimId => byId[claimId]); }); -const makeSelectTotalMatchingClaimsInChannel = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { +const makeSelectTotalClaimsInChannelSearch = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { const byChannel = allClaims[uri] || {}; return byChannel['itemCount']; }); -const makeSelectTotalMatchingPaginatedPagesInChannel = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { +const makeSelectTotalPagesInChannelSearch = uri => reselect.createSelector(selectClaimsById, selectAllClaimsByChannel, (byId, allClaims) => { const byChannel = allClaims[uri] || {}; return byChannel['pageCount']; }); @@ -3991,7 +3991,7 @@ const reducers = {}; const defaultState = { byId: {}, claimsByUri: {}, - claimsByChannel: {}, + paginatedClaimsByChannel: {}, channelClaimCounts: {}, fetchingChannelClaims: {}, resolvingUris: [], @@ -4191,10 +4191,10 @@ reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { // byChannel keeps claim_search relevant results by page. If the total changes, erase it. const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - const claimsByChannel = Object.assign({}, state.claimsByChannel); + const paginatedClaimsByChannel = Object.assign({}, state.paginatedClaimsByChannel); // check if count has changed - that means cached pagination will be wrong, so clear it - const previousCount = claimsByChannel[uri] && claimsByChannel[uri]['itemCount']; - const byChannel = claimsInChannel === previousCount ? Object.assign({}, claimsByChannel[uri]) : {}; + const previousCount = paginatedClaimsByChannel[uri] && paginatedClaimsByChannel[uri]['itemCount']; + const byChannel = claimsInChannel === previousCount ? Object.assign({}, paginatedClaimsByChannel[uri]) : {}; const allClaimIds = new Set(byChannel.all); const currentPageClaimIds = []; const byId = Object.assign({}, state.byId); @@ -4210,19 +4210,15 @@ reducers[FETCH_CHANNEL_CLAIMS_COMPLETED] = (state, action) => { }); } - if (claimsInChannel) { - channelClaimCounts[uri] = claimsInChannel; - } - byChannel.all = allClaimIds; byChannel.pageCount = totalPages; byChannel.itemCount = claimsInChannel; byChannel[page] = currentPageClaimIds; - claimsByChannel[uri] = byChannel; + paginatedClaimsByChannel[uri] = byChannel; delete fetchingChannelClaims[uri]; return Object.assign({}, state, { - claimsByChannel, + paginatedClaimsByChannel, byId, fetchingChannelClaims, claimsByUri, @@ -5513,10 +5509,10 @@ exports.makeSelectSupportsForUri = makeSelectSupportsForUri; exports.makeSelectTagsForUri = makeSelectTagsForUri; exports.makeSelectThumbnailForUri = makeSelectThumbnailForUri; exports.makeSelectTitleForUri = makeSelectTitleForUri; +exports.makeSelectTotalClaimsInChannelSearch = makeSelectTotalClaimsInChannelSearch; exports.makeSelectTotalItemsForChannel = makeSelectTotalItemsForChannel; -exports.makeSelectTotalMatchingClaimsInChannel = makeSelectTotalMatchingClaimsInChannel; -exports.makeSelectTotalMatchingPaginatedPagesInChannel = makeSelectTotalMatchingPaginatedPagesInChannel; exports.makeSelectTotalPagesForChannel = makeSelectTotalPagesForChannel; +exports.makeSelectTotalPagesInChannelSearch = makeSelectTotalPagesInChannelSearch; exports.makeSelectUriIsStreamable = makeSelectUriIsStreamable; exports.normalizeURI = normalizeURI; exports.notificationsReducer = notificationsReducer; diff --git a/src/index.js b/src/index.js index 2cf47bb..41d1196 100644 --- a/src/index.js +++ b/src/index.js @@ -159,8 +159,8 @@ export { makeSelectClaimIsMine, makeSelectFetchingChannelClaims, makeSelectClaimsInChannelForPage, - makeSelectTotalMatchingPaginatedPagesInChannel, - makeSelectTotalMatchingClaimsInChannel, + makeSelectTotalPagesInChannelSearch, + makeSelectTotalClaimsInChannelSearch, makeSelectMetadataForUri, makeSelectMetadataItemForUri, makeSelectThumbnailForUri, diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index cd3a7f1..8e6b121 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -28,7 +28,7 @@ type State = { claimSearchByQuery: { [string]: Array }, claimSearchByQueryLastPageReached: { [string]: Array }, creatingChannel: boolean, - claimsByChannel: { + paginatedClaimsByChannel: { [string]: { all: Array, pageCount: number, @@ -45,7 +45,7 @@ const reducers = {}; const defaultState = { byId: {}, claimsByUri: {}, - claimsByChannel: {}, + paginatedClaimsByChannel: {}, channelClaimCounts: {}, fetchingChannelClaims: {}, resolvingUris: [], @@ -262,10 +262,10 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): // byChannel keeps claim_search relevant results by page. If the total changes, erase it. const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - const claimsByChannel = Object.assign({}, state.claimsByChannel); + const paginatedClaimsByChannel = Object.assign({}, state.paginatedClaimsByChannel); // check if count has changed - that means cached pagination will be wrong, so clear it - const previousCount = claimsByChannel[uri] && claimsByChannel[uri]['itemCount']; - const byChannel = (claimsInChannel === previousCount) ? Object.assign({}, claimsByChannel[uri]) : {}; + const previousCount = paginatedClaimsByChannel[uri] && paginatedClaimsByChannel[uri]['itemCount']; + const byChannel = (claimsInChannel === previousCount) ? Object.assign({}, paginatedClaimsByChannel[uri]) : {}; const allClaimIds = new Set(byChannel.all); const currentPageClaimIds = []; const byId = Object.assign({}, state.byId); @@ -281,19 +281,15 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): }); } - if (claimsInChannel) { - channelClaimCounts[uri] = claimsInChannel; - } - byChannel.all = allClaimIds; byChannel.pageCount = totalPages; byChannel.itemCount = claimsInChannel; byChannel[page] = currentPageClaimIds; - claimsByChannel[uri] = byChannel; + paginatedClaimsByChannel[uri] = byChannel; delete fetchingChannelClaims[uri]; return Object.assign({}, state, { - claimsByChannel, + paginatedClaimsByChannel, byId, fetchingChannelClaims, claimsByUri, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index f953d8f..2d920a5 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -54,7 +54,7 @@ export const selectClaimsByUri = createSelector( export const selectAllClaimsByChannel = createSelector( selectState, - state => state.claimsByChannel || {} + state => state.paginatedClaimsByChannel || {} ); export const selectPendingById = createSelector( @@ -177,7 +177,7 @@ export const makeSelectFetchingChannelClaims = (uri: string) => selectAllFetchingChannelClaims, fetching => fetching && fetching[uri] ); -// this is actually the result of claim search + export const makeSelectClaimsInChannelForPage = (uri: string, page?: number) => createSelector( selectClaimsById, @@ -192,7 +192,7 @@ export const makeSelectClaimsInChannelForPage = (uri: string, page?: number) => } ); -export const makeSelectTotalMatchingClaimsInChannel = (uri: string) => +export const makeSelectTotalClaimsInChannelSearch = (uri: string) => createSelector( selectClaimsById, selectAllClaimsByChannel, @@ -202,7 +202,7 @@ export const makeSelectTotalMatchingClaimsInChannel = (uri: string) => } ); -export const makeSelectTotalMatchingPaginatedPagesInChannel = (uri: string) => +export const makeSelectTotalPagesInChannelSearch = (uri: string) => createSelector( selectClaimsById, selectAllClaimsByChannel, -- 2.45.2 From b09b7745b7b30db940ed402d954f5fc040840e68 Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 25 Nov 2019 15:11:32 -0500 Subject: [PATCH 203/371] fixes hidden claims notification --- dist/bundle.es.js | 7 +++++++ src/index.js | 1 + src/redux/selectors/claims.js | 12 ++++++++++++ 3 files changed, 20 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 7566ec3..6c3b9df 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2041,6 +2041,12 @@ const makeSelectNsfwCountForChannel = uri => reselect.createSelector(selectClaim }, 0); }); +const makeSelectOmittedCountForChannel = uri => reselect.createSelector(makeSelectTotalItemsForChannel(uri), makeSelectTotalClaimsInChannelSearch(uri), (claimsInChannel, claimsInSearch) => { + if (claimsInChannel && claimsInSearch) { + return claimsInChannel - claimsInSearch; + } else return 0; +}); + const makeSelectClaimIsNsfw = uri => reselect.createSelector(makeSelectClaimForUri(uri), // Eventually these will come from some list of tags that are considered adult // Or possibly come from users settings of what tags they want to hide @@ -5495,6 +5501,7 @@ exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri; exports.makeSelectMyStreamUrlsForPage = makeSelectMyStreamUrlsForPage; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; +exports.makeSelectOmittedCountForChannel = makeSelectOmittedCountForChannel; exports.makeSelectPendingByUri = makeSelectPendingByUri; exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; diff --git a/src/index.js b/src/index.js index 41d1196..9b9f572 100644 --- a/src/index.js +++ b/src/index.js @@ -175,6 +175,7 @@ export { makeSelectTotalPagesForChannel, makeSelectNsfwCountFromUris, makeSelectNsfwCountForChannel, + makeSelectOmittedCountForChannel, makeSelectClaimIsNsfw, makeSelectRecommendedContentForUri, makeSelectFirstRecommendedFileForUri, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 2d920a5..b6cb93c 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -466,6 +466,18 @@ export const makeSelectNsfwCountForChannel = (uri: string) => } ); +export const makeSelectOmittedCountForChannel = (uri: string) => + createSelector( + makeSelectTotalItemsForChannel(uri), + makeSelectTotalClaimsInChannelSearch(uri), + (claimsInChannel, claimsInSearch) => { + if (claimsInChannel && claimsInSearch) { + return claimsInChannel - claimsInSearch; + } + else return 0; + } + ); + export const makeSelectClaimIsNsfw = (uri: string): boolean => createSelector( makeSelectClaimForUri(uri), -- 2.45.2 From 93c7da0c2786ee4086b7be1cce2269a76f058018 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 11 Dec 2019 09:45:18 -0500 Subject: [PATCH 204/371] supports wallet servers and daemonSettings preferences --- dist/bundle.es.js | 117 +++++++++++++++++++++++++++++-- src/constants/action_types.js | 3 + src/constants/daemon_settings.js | 39 +++++++++++ src/constants/shared_prefs.js | 3 + src/index.js | 5 ++ src/redux/actions/sync.js | 10 +-- src/redux/actions/wallet.js | 10 +++ 7 files changed, 178 insertions(+), 9 deletions(-) create mode 100644 src/constants/daemon_settings.js create mode 100644 src/constants/shared_prefs.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 6c3b9df..b321f5c 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -85,6 +85,7 @@ const WALLET_LOCK_COMPLETED = 'WALLET_LOCK_COMPLETED'; const WALLET_LOCK_FAILED = 'WALLET_LOCK_FAILED'; const WALLET_STATUS_START = 'WALLET_STATUS_START'; const WALLET_STATUS_COMPLETED = 'WALLET_STATUS_COMPLETED'; +const WALLET_RESTART = 'WALLET_RESTART'; const SET_TRANSACTION_LIST_FILTER = 'SET_TRANSACTION_LIST_FILTER'; const UPDATE_CURRENT_HEIGHT = 'UPDATE_CURRENT_HEIGHT'; const SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; @@ -168,6 +169,8 @@ const SEARCH_BLUR = 'SEARCH_BLUR'; // Settings const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; +const SHARED_PREFERENCE_SET = 'SHARED_PREFERENCE_SET'; +const WALLET_SERVERS_CACHED = 'WALLET_SERVERS_CACHED'; const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; const UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT'; @@ -327,6 +330,7 @@ var action_types = /*#__PURE__*/Object.freeze({ WALLET_LOCK_FAILED: WALLET_LOCK_FAILED, WALLET_STATUS_START: WALLET_STATUS_START, WALLET_STATUS_COMPLETED: WALLET_STATUS_COMPLETED, + WALLET_RESTART: WALLET_RESTART, SET_TRANSACTION_LIST_FILTER: SET_TRANSACTION_LIST_FILTER, UPDATE_CURRENT_HEIGHT: UPDATE_CURRENT_HEIGHT, SET_DRAFT_TRANSACTION_AMOUNT: SET_DRAFT_TRANSACTION_AMOUNT, @@ -400,6 +404,8 @@ var action_types = /*#__PURE__*/Object.freeze({ SEARCH_FOCUS: SEARCH_FOCUS, SEARCH_BLUR: SEARCH_BLUR, DAEMON_SETTINGS_RECEIVED: DAEMON_SETTINGS_RECEIVED, + SHARED_PREFERENCE_SET: SHARED_PREFERENCE_SET, + WALLET_SERVERS_CACHED: WALLET_SERVERS_CACHED, CLIENT_SETTING_CHANGED: CLIENT_SETTING_CHANGED, UPDATE_IS_NIGHT: UPDATE_IS_NIGHT, AUTHENTICATION_STARTED: AUTHENTICATION_STARTED, @@ -672,6 +678,94 @@ var speech_urls = /*#__PURE__*/Object.freeze({ SPEECH_PUBLISH: SPEECH_PUBLISH }); +const ANNOUNCE_HEAD_AND_SD_ONLY = 'announce_head_and_sd_only'; +const API = 'api'; +const BLOB_DOWNLOAD_TIMEOUT = 'blob_download_timeout'; +const BLOB_LRU_CACHE_SIZE = 'blob_lru_cache_size'; +const BLOCKCHAIN_NAME = 'blockchain_name'; +const CACHE_TIME = 'cache_time'; +const COIN_SELECTION_STRATEGY = 'coin_selection_strategy'; +const COMMENT_SERVER = 'comment_server'; +const COMPONENTS_TO_SKIP = 'components_to_skip'; +const CONCURRENT_BLOB_ANNOUNCERS = 'concurrent_blob_announcers'; +const CONCURRENT_REFLECTOR_UPLOADS = 'concurrent_reflector_uploads'; +const CONFIG = 'config'; +const DATA_DIR = 'data_dir'; +const DOWNLOAD_DIR = 'download_dir'; +const DOWNLOAD_TIMEOUT = 'download_timeout'; +const FIXED_PEER_DELAY = 'fixed_peer_delay'; +const KNOWN_DHT_NODES = 'known_dht_nodes'; +const LBRYUM_SERVERS = 'lbryum_servers'; +const MAX_CONNECTIONS_PER_DOWNLOAD = 'max_connections_per_download'; +const MAX_KEY_FEE = 'max_key_fee'; +const DEFAULT_WALLET = 'default_wallet'; +const NETWORK_INTERFACE = 'network_interface'; +const NODE_RPC_TIMEOUT = 'node_rpc_timeout'; +const PEER_CONNECT_TIMEOUT = 'peer_connect_timeout'; +const REFLECT_STREAMS = 'reflect_streams'; +const REFLECTOR_SERVERS = 'reflector_servers'; +const S3_HEADERS_DEPTH = 's3_headers_depth'; +const SAVE_BLOBS = 'save_blobs'; +const SAVE_FILES = 'save_files'; +const SHARE_USAGE_DATA = 'share_usage_data'; +const SPLIT_BUCKETS_UNDER_INDEX = 'split_buckets_under_index'; +const STREAMING_GET = 'streaming_get'; +const STREAMING_SERVER = 'streaming_server'; +const TCP_PORT = 'tcp_port'; +const TRACK_BANDWIDTH = 'track_bandwidth'; +const UDP_PORT = 'udp_port'; +const USE_UPNP = 'use_upnp'; +const WALLET_DIR = 'wallet_dir'; +const WALLETS = 'wallets'; + +var daemon_settings = /*#__PURE__*/Object.freeze({ + ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, + API: API, + BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, + BLOB_LRU_CACHE_SIZE: BLOB_LRU_CACHE_SIZE, + BLOCKCHAIN_NAME: BLOCKCHAIN_NAME, + CACHE_TIME: CACHE_TIME, + COIN_SELECTION_STRATEGY: COIN_SELECTION_STRATEGY, + COMMENT_SERVER: COMMENT_SERVER, + COMPONENTS_TO_SKIP: COMPONENTS_TO_SKIP, + CONCURRENT_BLOB_ANNOUNCERS: CONCURRENT_BLOB_ANNOUNCERS, + CONCURRENT_REFLECTOR_UPLOADS: CONCURRENT_REFLECTOR_UPLOADS, + CONFIG: CONFIG, + DATA_DIR: DATA_DIR, + DOWNLOAD_DIR: DOWNLOAD_DIR, + DOWNLOAD_TIMEOUT: DOWNLOAD_TIMEOUT, + FIXED_PEER_DELAY: FIXED_PEER_DELAY, + KNOWN_DHT_NODES: KNOWN_DHT_NODES, + LBRYUM_SERVERS: LBRYUM_SERVERS, + MAX_CONNECTIONS_PER_DOWNLOAD: MAX_CONNECTIONS_PER_DOWNLOAD, + MAX_KEY_FEE: MAX_KEY_FEE, + DEFAULT_WALLET: DEFAULT_WALLET, + NETWORK_INTERFACE: NETWORK_INTERFACE, + NODE_RPC_TIMEOUT: NODE_RPC_TIMEOUT, + PEER_CONNECT_TIMEOUT: PEER_CONNECT_TIMEOUT, + REFLECT_STREAMS: REFLECT_STREAMS, + REFLECTOR_SERVERS: REFLECTOR_SERVERS, + S3_HEADERS_DEPTH: S3_HEADERS_DEPTH, + SAVE_BLOBS: SAVE_BLOBS, + SAVE_FILES: SAVE_FILES, + SHARE_USAGE_DATA: SHARE_USAGE_DATA, + SPLIT_BUCKETS_UNDER_INDEX: SPLIT_BUCKETS_UNDER_INDEX, + STREAMING_GET: STREAMING_GET, + STREAMING_SERVER: STREAMING_SERVER, + TCP_PORT: TCP_PORT, + TRACK_BANDWIDTH: TRACK_BANDWIDTH, + UDP_PORT: UDP_PORT, + USE_UPNP: USE_UPNP, + WALLET_DIR: WALLET_DIR, + WALLETS: WALLETS +}); + +const WALLET_SERVERS = LBRYUM_SERVERS; + +var shared_prefs = /*#__PURE__*/Object.freeze({ + WALLET_SERVERS: WALLET_SERVERS +}); + const SEARCH_TYPES = { FILE: 'file', CHANNEL: 'channel', @@ -1410,18 +1504,18 @@ var _extends$2 = Object.assign || function (target) { for (var i = 1; i < argume function extractUserState(rawObj) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blockedChannels } = rawObj.value; + const { subscriptions, tags, blockedChannels, settings } = rawObj.value; - return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blockedChannels ? { blockedChannels } : {}); + return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blockedChannels ? { blockedChannels } : {}, settings ? { settings } : {}); } return {}; } -function doPopulateSharedUserState(settings) { +function doPopulateSharedUserState(sharedSettings) { return dispatch => { - const { subscriptions, tags } = extractUserState(settings); - dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags } }); + const { subscriptions, tags, blockedChannels, settings } = extractUserState(sharedSettings); + dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags, blockedChannels, settings } }); // clientSettings ? hideSplash ? }; } @@ -2494,6 +2588,16 @@ function doWalletUnlock(password) { }; } +function doWalletRestart() { + return dispatch => { + dispatch({ + type: WALLET_RESTART + }); + // this basically returns null when it's done. :( + // might be good to dispatch ACTIONS.WALLET_RESTARTED + lbryProxy.wallet_reconnect(); + }; +} function doWalletDecrypt() { return dispatch => { dispatch({ @@ -5378,6 +5482,7 @@ const selectChannelIsBlocked = uri => reselect.createSelector(selectBlockedChann exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; +exports.DAEMON_SETTINGS = daemon_settings; exports.DEFAULT_FOLLOWED_TAGS = DEFAULT_FOLLOWED_TAGS; exports.DEFAULT_KNOWN_TAGS = DEFAULT_KNOWN_TAGS; exports.LICENSES = licenses; @@ -5387,6 +5492,7 @@ exports.PAGES = pages; exports.SEARCH_OPTIONS = SEARCH_OPTIONS; exports.SEARCH_TYPES = SEARCH_TYPES; exports.SETTINGS = settings; +exports.SHARED_PREFS = shared_prefs; exports.SORT_OPTIONS = sort_options; exports.SPEECH_URLS = speech_urls; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; @@ -5459,6 +5565,7 @@ exports.doUpdateSearchQuery = doUpdateSearchQuery; exports.doUploadThumbnail = doUploadThumbnail; exports.doWalletDecrypt = doWalletDecrypt; exports.doWalletEncrypt = doWalletEncrypt; +exports.doWalletRestart = doWalletRestart; exports.doWalletStatus = doWalletStatus; exports.doWalletUnlock = doWalletUnlock; exports.fileInfoReducer = fileInfoReducer; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 4e0e334..2b92990 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -62,6 +62,7 @@ export const WALLET_LOCK_COMPLETED = 'WALLET_LOCK_COMPLETED'; export const WALLET_LOCK_FAILED = 'WALLET_LOCK_FAILED'; export const WALLET_STATUS_START = 'WALLET_STATUS_START'; export const WALLET_STATUS_COMPLETED = 'WALLET_STATUS_COMPLETED'; +export const WALLET_RESTART = 'WALLET_RESTART'; export const SET_TRANSACTION_LIST_FILTER = 'SET_TRANSACTION_LIST_FILTER'; export const UPDATE_CURRENT_HEIGHT = 'UPDATE_CURRENT_HEIGHT'; export const SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; @@ -145,6 +146,8 @@ export const SEARCH_BLUR = 'SEARCH_BLUR'; // Settings export const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; +export const SHARED_PREFERENCE_SET = 'SHARED_PREFERENCE_SET'; +export const WALLET_SERVERS_CACHED = 'WALLET_SERVERS_CACHED'; export const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; export const UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT'; diff --git a/src/constants/daemon_settings.js b/src/constants/daemon_settings.js new file mode 100644 index 0000000..04e4fd2 --- /dev/null +++ b/src/constants/daemon_settings.js @@ -0,0 +1,39 @@ +export const ANNOUNCE_HEAD_AND_SD_ONLY = 'announce_head_and_sd_only'; +export const API = 'api'; +export const BLOB_DOWNLOAD_TIMEOUT = 'blob_download_timeout'; +export const BLOB_LRU_CACHE_SIZE = 'blob_lru_cache_size'; +export const BLOCKCHAIN_NAME = 'blockchain_name'; +export const CACHE_TIME = 'cache_time'; +export const COIN_SELECTION_STRATEGY = 'coin_selection_strategy'; +export const COMMENT_SERVER = 'comment_server'; +export const COMPONENTS_TO_SKIP = 'components_to_skip'; +export const CONCURRENT_BLOB_ANNOUNCERS = 'concurrent_blob_announcers'; +export const CONCURRENT_REFLECTOR_UPLOADS = 'concurrent_reflector_uploads'; +export const CONFIG = 'config'; +export const DATA_DIR = 'data_dir'; +export const DOWNLOAD_DIR = 'download_dir'; +export const DOWNLOAD_TIMEOUT = 'download_timeout'; +export const FIXED_PEER_DELAY = 'fixed_peer_delay'; +export const KNOWN_DHT_NODES = 'known_dht_nodes'; +export const LBRYUM_SERVERS = 'lbryum_servers'; +export const MAX_CONNECTIONS_PER_DOWNLOAD = 'max_connections_per_download'; +export const MAX_KEY_FEE = 'max_key_fee'; +export const DEFAULT_WALLET = 'default_wallet'; +export const NETWORK_INTERFACE = 'network_interface'; +export const NODE_RPC_TIMEOUT = 'node_rpc_timeout'; +export const PEER_CONNECT_TIMEOUT = 'peer_connect_timeout'; +export const REFLECT_STREAMS = 'reflect_streams'; +export const REFLECTOR_SERVERS = 'reflector_servers'; +export const S3_HEADERS_DEPTH = 's3_headers_depth'; +export const SAVE_BLOBS = 'save_blobs'; +export const SAVE_FILES = 'save_files'; +export const SHARE_USAGE_DATA = 'share_usage_data'; +export const SPLIT_BUCKETS_UNDER_INDEX = 'split_buckets_under_index'; +export const STREAMING_GET = 'streaming_get'; +export const STREAMING_SERVER = 'streaming_server'; +export const TCP_PORT = 'tcp_port'; +export const TRACK_BANDWIDTH = 'track_bandwidth'; +export const UDP_PORT = 'udp_port'; +export const USE_UPNP = 'use_upnp'; +export const WALLET_DIR = 'wallet_dir'; +export const WALLETS = 'wallets'; diff --git a/src/constants/shared_prefs.js b/src/constants/shared_prefs.js new file mode 100644 index 0000000..4fe51c4 --- /dev/null +++ b/src/constants/shared_prefs.js @@ -0,0 +1,3 @@ +import * as DAEMON_SETTINGS from './daemon_settings'; + +export const WALLET_SERVERS = DAEMON_SETTINGS.LBRYUM_SERVERS; diff --git a/src/index.js b/src/index.js index 9b9f572..22d877f 100644 --- a/src/index.js +++ b/src/index.js @@ -8,6 +8,8 @@ import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as TRANSACTIONS from 'constants/transaction_types'; import * as TX_LIST from 'constants/transaction_list'; import * as SPEECH_URLS from 'constants/speech_urls'; +import * as DAEMON_SETTINGS from 'constants/daemon_settings'; +import * as SHARED_PREFS from 'constants/shared_prefs'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS } from 'constants/tags'; import Lbry, { apiCall } from 'lbry'; @@ -22,6 +24,7 @@ export { SEARCH_TYPES, SEARCH_OPTIONS, SETTINGS, + DAEMON_SETTINGS, TRANSACTIONS, TX_LIST, SORT_OPTIONS, @@ -30,6 +33,7 @@ export { DEFAULT_FOLLOWED_TAGS, MATURE_TAGS, SPEECH_URLS, + SHARED_PREFS, }; // common @@ -109,6 +113,7 @@ export { doWalletDecrypt, doWalletUnlock, doWalletStatus, + doWalletRestart, doSetTransactionListFilter, doUpdateBlockHeight, doClearSupport, diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 7adf1d9..727d2ba 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -8,27 +8,29 @@ type SharedData = { subscriptions?: Array, tags?: Array, blockedChannels?: Array, + settings?: any, }, }; function extractUserState(rawObj: SharedData) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blockedChannels } = rawObj.value; + const { subscriptions, tags, blockedChannels, settings} = rawObj.value; return { ...(subscriptions ? { subscriptions } : {}), ...(tags ? { tags } : {}), ...(blockedChannels ? { blockedChannels } : {}), + ...(settings ? { settings } : {}), }; } return {}; } -export function doPopulateSharedUserState(settings: any) { +export function doPopulateSharedUserState(sharedSettings: any) { return (dispatch: Dispatch) => { - const { subscriptions, tags } = extractUserState(settings); - dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags } }); + const { subscriptions, tags, blockedChannels, settings } = extractUserState(sharedSettings); + dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags, blockedChannels, settings } }); // clientSettings ? hideSplash ? }; } diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 6164a31..5a6a026 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -338,6 +338,16 @@ export function doWalletLock() { }; } +export function doWalletRestart() { + return dispatch => { + dispatch({ + type: ACTIONS.WALLET_RESTART, + }); + // this basically returns null when it's done. :( + // might be good to dispatch ACTIONS.WALLET_RESTARTED + Lbry.wallet_reconnect(); + }; +} export function doWalletDecrypt() { return dispatch => { dispatch({ -- 2.45.2 From 7d2e8ba1707100393975897a70a28a63b288bc47 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 11 Dec 2019 14:27:52 -0500 Subject: [PATCH 205/371] more --- dist/bundle.es.js | 10 +++++++--- src/constants/action_types.js | 1 + src/index.js | 2 +- src/redux/actions/wallet.js | 8 ++++++-- 4 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b321f5c..14c51ba 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -86,6 +86,7 @@ const WALLET_LOCK_FAILED = 'WALLET_LOCK_FAILED'; const WALLET_STATUS_START = 'WALLET_STATUS_START'; const WALLET_STATUS_COMPLETED = 'WALLET_STATUS_COMPLETED'; const WALLET_RESTART = 'WALLET_RESTART'; +const WALLET_RESTART_COMPLETED = 'WALLET_RESTART_COMPLETED'; const SET_TRANSACTION_LIST_FILTER = 'SET_TRANSACTION_LIST_FILTER'; const UPDATE_CURRENT_HEIGHT = 'UPDATE_CURRENT_HEIGHT'; const SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; @@ -331,6 +332,7 @@ var action_types = /*#__PURE__*/Object.freeze({ WALLET_STATUS_START: WALLET_STATUS_START, WALLET_STATUS_COMPLETED: WALLET_STATUS_COMPLETED, WALLET_RESTART: WALLET_RESTART, + WALLET_RESTART_COMPLETED: WALLET_RESTART_COMPLETED, SET_TRANSACTION_LIST_FILTER: SET_TRANSACTION_LIST_FILTER, UPDATE_CURRENT_HEIGHT: UPDATE_CURRENT_HEIGHT, SET_DRAFT_TRANSACTION_AMOUNT: SET_DRAFT_TRANSACTION_AMOUNT, @@ -2588,14 +2590,16 @@ function doWalletUnlock(password) { }; } -function doWalletRestart() { +function doWalletReconnect() { return dispatch => { dispatch({ type: WALLET_RESTART }); // this basically returns null when it's done. :( // might be good to dispatch ACTIONS.WALLET_RESTARTED - lbryProxy.wallet_reconnect(); + lbryProxy.wallet_reconnect().then(dispatch({ + type: WALLET_RESTART_COMPLETED + })); }; } function doWalletDecrypt() { @@ -5565,7 +5569,7 @@ exports.doUpdateSearchQuery = doUpdateSearchQuery; exports.doUploadThumbnail = doUploadThumbnail; exports.doWalletDecrypt = doWalletDecrypt; exports.doWalletEncrypt = doWalletEncrypt; -exports.doWalletRestart = doWalletRestart; +exports.doWalletReconnect = doWalletReconnect; exports.doWalletStatus = doWalletStatus; exports.doWalletUnlock = doWalletUnlock; exports.fileInfoReducer = fileInfoReducer; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 2b92990..80f041a 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -63,6 +63,7 @@ export const WALLET_LOCK_FAILED = 'WALLET_LOCK_FAILED'; export const WALLET_STATUS_START = 'WALLET_STATUS_START'; export const WALLET_STATUS_COMPLETED = 'WALLET_STATUS_COMPLETED'; export const WALLET_RESTART = 'WALLET_RESTART'; +export const WALLET_RESTART_COMPLETED = 'WALLET_RESTART_COMPLETED'; export const SET_TRANSACTION_LIST_FILTER = 'SET_TRANSACTION_LIST_FILTER'; export const UPDATE_CURRENT_HEIGHT = 'UPDATE_CURRENT_HEIGHT'; export const SET_DRAFT_TRANSACTION_AMOUNT = 'SET_DRAFT_TRANSACTION_AMOUNT'; diff --git a/src/index.js b/src/index.js index 22d877f..7b794aa 100644 --- a/src/index.js +++ b/src/index.js @@ -113,7 +113,7 @@ export { doWalletDecrypt, doWalletUnlock, doWalletStatus, - doWalletRestart, + doWalletReconnect, doSetTransactionListFilter, doUpdateBlockHeight, doClearSupport, diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 5a6a026..a7dc8a8 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -338,14 +338,18 @@ export function doWalletLock() { }; } -export function doWalletRestart() { +export function doWalletReconnect() { return dispatch => { dispatch({ type: ACTIONS.WALLET_RESTART, }); // this basically returns null when it's done. :( // might be good to dispatch ACTIONS.WALLET_RESTARTED - Lbry.wallet_reconnect(); + Lbry.wallet_reconnect().then( + dispatch({ + type: ACTIONS.WALLET_RESTART_COMPLETED, + }) + ); }; } export function doWalletDecrypt() { -- 2.45.2 From ee6831c2a8f688113ca3977ed5601ffec5bc5932 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 12 Dec 2019 11:47:09 -0500 Subject: [PATCH 206/371] review changes --- dist/bundle.es.js | 17 +++++++++++++---- src/constants/action_types.js | 2 +- src/constants/shared_prefs.js | 9 +++++++++ src/redux/actions/sync.js | 2 +- src/redux/actions/wallet.js | 2 +- 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 14c51ba..cdb82b3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -171,7 +171,7 @@ const SEARCH_BLUR = 'SEARCH_BLUR'; // Settings const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; const SHARED_PREFERENCE_SET = 'SHARED_PREFERENCE_SET'; -const WALLET_SERVERS_CACHED = 'WALLET_SERVERS_CACHED'; +const SAVE_CUSTOM_WALLET_SERVERS = 'SAVE_CUSTOM_WALLET_SERVERS'; const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; const UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT'; @@ -407,7 +407,7 @@ var action_types = /*#__PURE__*/Object.freeze({ SEARCH_BLUR: SEARCH_BLUR, DAEMON_SETTINGS_RECEIVED: DAEMON_SETTINGS_RECEIVED, SHARED_PREFERENCE_SET: SHARED_PREFERENCE_SET, - WALLET_SERVERS_CACHED: WALLET_SERVERS_CACHED, + SAVE_CUSTOM_WALLET_SERVERS: SAVE_CUSTOM_WALLET_SERVERS, CLIENT_SETTING_CHANGED: CLIENT_SETTING_CHANGED, UPDATE_IS_NIGHT: UPDATE_IS_NIGHT, AUTHENTICATION_STARTED: AUTHENTICATION_STARTED, @@ -762,6 +762,15 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ WALLETS: WALLETS }); +/* +* How to use this file: +* Settings exported from here will trigger the setting to be +* sent to the preference middleware when set using the +* usual setDaemonSettings and clearDaemonSettings methods. +* +* See redux/settings/actions in the app for where this is used. + */ + const WALLET_SERVERS = LBRYUM_SERVERS; var shared_prefs = /*#__PURE__*/Object.freeze({ @@ -1517,7 +1526,7 @@ function extractUserState(rawObj) { function doPopulateSharedUserState(sharedSettings) { return dispatch => { const { subscriptions, tags, blockedChannels, settings } = extractUserState(sharedSettings); - dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags, blockedChannels, settings } }); // clientSettings ? hideSplash ? + dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags, blockedChannels, settings } }); }; } @@ -2597,7 +2606,7 @@ function doWalletReconnect() { }); // this basically returns null when it's done. :( // might be good to dispatch ACTIONS.WALLET_RESTARTED - lbryProxy.wallet_reconnect().then(dispatch({ + lbryProxy.wallet_reconnect().then(() => dispatch({ type: WALLET_RESTART_COMPLETED })); }; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 80f041a..1f56340 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -148,7 +148,7 @@ export const SEARCH_BLUR = 'SEARCH_BLUR'; // Settings export const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; export const SHARED_PREFERENCE_SET = 'SHARED_PREFERENCE_SET'; -export const WALLET_SERVERS_CACHED = 'WALLET_SERVERS_CACHED'; +export const SAVE_CUSTOM_WALLET_SERVERS = 'SAVE_CUSTOM_WALLET_SERVERS'; export const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; export const UPDATE_IS_NIGHT = 'UPDATE_IS_NIGHT'; diff --git a/src/constants/shared_prefs.js b/src/constants/shared_prefs.js index 4fe51c4..56faf8f 100644 --- a/src/constants/shared_prefs.js +++ b/src/constants/shared_prefs.js @@ -1,3 +1,12 @@ +/* +* How to use this file: +* Settings exported from here will trigger the setting to be +* sent to the preference middleware when set using the +* usual setDaemonSettings and clearDaemonSettings methods. +* +* See redux/settings/actions in the app for where this is used. + */ + import * as DAEMON_SETTINGS from './daemon_settings'; export const WALLET_SERVERS = DAEMON_SETTINGS.LBRYUM_SERVERS; diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 727d2ba..3957a33 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -30,7 +30,7 @@ function extractUserState(rawObj: SharedData) { export function doPopulateSharedUserState(sharedSettings: any) { return (dispatch: Dispatch) => { const { subscriptions, tags, blockedChannels, settings } = extractUserState(sharedSettings); - dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags, blockedChannels, settings } }); // clientSettings ? hideSplash ? + dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags, blockedChannels, settings } }); }; } diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index a7dc8a8..4fdfb15 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -345,7 +345,7 @@ export function doWalletReconnect() { }); // this basically returns null when it's done. :( // might be good to dispatch ACTIONS.WALLET_RESTARTED - Lbry.wallet_reconnect().then( + Lbry.wallet_reconnect().then(() => dispatch({ type: ACTIONS.WALLET_RESTART_COMPLETED, }) -- 2.45.2 From 341d60661468b654b9baf5b96ca4a08ee202f0f2 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 12 Dec 2019 14:51:07 -0500 Subject: [PATCH 207/371] review changes --- dist/bundle.es.js | 6 ++++-- src/constants/action_types.js | 1 + src/constants/{shared_prefs.js => shared_preferences.js} | 0 src/index.js | 4 ++-- 4 files changed, 7 insertions(+), 4 deletions(-) rename src/constants/{shared_prefs.js => shared_preferences.js} (100%) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index cdb82b3..73a6be8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -170,6 +170,7 @@ const SEARCH_BLUR = 'SEARCH_BLUR'; // Settings const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; +const DAEMON_STATUS_RECEIVED = 'DAEMON_STATUS_RECEIVED'; const SHARED_PREFERENCE_SET = 'SHARED_PREFERENCE_SET'; const SAVE_CUSTOM_WALLET_SERVERS = 'SAVE_CUSTOM_WALLET_SERVERS'; const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; @@ -406,6 +407,7 @@ var action_types = /*#__PURE__*/Object.freeze({ SEARCH_FOCUS: SEARCH_FOCUS, SEARCH_BLUR: SEARCH_BLUR, DAEMON_SETTINGS_RECEIVED: DAEMON_SETTINGS_RECEIVED, + DAEMON_STATUS_RECEIVED: DAEMON_STATUS_RECEIVED, SHARED_PREFERENCE_SET: SHARED_PREFERENCE_SET, SAVE_CUSTOM_WALLET_SERVERS: SAVE_CUSTOM_WALLET_SERVERS, CLIENT_SETTING_CHANGED: CLIENT_SETTING_CHANGED, @@ -773,7 +775,7 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; -var shared_prefs = /*#__PURE__*/Object.freeze({ +var shared_preferences = /*#__PURE__*/Object.freeze({ WALLET_SERVERS: WALLET_SERVERS }); @@ -5505,7 +5507,7 @@ exports.PAGES = pages; exports.SEARCH_OPTIONS = SEARCH_OPTIONS; exports.SEARCH_TYPES = SEARCH_TYPES; exports.SETTINGS = settings; -exports.SHARED_PREFS = shared_prefs; +exports.SHARED_PREFERENCES = shared_preferences; exports.SORT_OPTIONS = sort_options; exports.SPEECH_URLS = speech_urls; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 1f56340..ac23374 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -147,6 +147,7 @@ export const SEARCH_BLUR = 'SEARCH_BLUR'; // Settings export const DAEMON_SETTINGS_RECEIVED = 'DAEMON_SETTINGS_RECEIVED'; +export const DAEMON_STATUS_RECEIVED = 'DAEMON_STATUS_RECEIVED'; export const SHARED_PREFERENCE_SET = 'SHARED_PREFERENCE_SET'; export const SAVE_CUSTOM_WALLET_SERVERS = 'SAVE_CUSTOM_WALLET_SERVERS'; export const CLIENT_SETTING_CHANGED = 'CLIENT_SETTING_CHANGED'; diff --git a/src/constants/shared_prefs.js b/src/constants/shared_preferences.js similarity index 100% rename from src/constants/shared_prefs.js rename to src/constants/shared_preferences.js diff --git a/src/index.js b/src/index.js index 7b794aa..fc78d59 100644 --- a/src/index.js +++ b/src/index.js @@ -9,7 +9,7 @@ import * as TRANSACTIONS from 'constants/transaction_types'; import * as TX_LIST from 'constants/transaction_list'; import * as SPEECH_URLS from 'constants/speech_urls'; import * as DAEMON_SETTINGS from 'constants/daemon_settings'; -import * as SHARED_PREFS from 'constants/shared_prefs'; +import * as SHARED_PREFERENCES from 'constants/shared_preferences'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS } from 'constants/tags'; import Lbry, { apiCall } from 'lbry'; @@ -33,7 +33,7 @@ export { DEFAULT_FOLLOWED_TAGS, MATURE_TAGS, SPEECH_URLS, - SHARED_PREFS, + SHARED_PREFERENCES, }; // common -- 2.45.2 From 00d8a9e5c25bb08000c7fc7625f7f5730b64a5d4 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 12 Dec 2019 20:31:37 -0500 Subject: [PATCH 208/371] fixes bug of reporting 0 claims --- 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 6c3b9df..ff828fe 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2042,7 +2042,7 @@ const makeSelectNsfwCountForChannel = uri => reselect.createSelector(selectClaim }); const makeSelectOmittedCountForChannel = uri => reselect.createSelector(makeSelectTotalItemsForChannel(uri), makeSelectTotalClaimsInChannelSearch(uri), (claimsInChannel, claimsInSearch) => { - if (claimsInChannel && claimsInSearch) { + if (claimsInChannel && typeof claimsInSearch === 'number' && claimsInSearch >= 0) { return claimsInChannel - claimsInSearch; } else return 0; }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index b6cb93c..dafdd43 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -471,7 +471,7 @@ export const makeSelectOmittedCountForChannel = (uri: string) => makeSelectTotalItemsForChannel(uri), makeSelectTotalClaimsInChannelSearch(uri), (claimsInChannel, claimsInSearch) => { - if (claimsInChannel && claimsInSearch) { + if (claimsInChannel && typeof claimsInSearch === 'number' && claimsInSearch >= 0) { return claimsInChannel - claimsInSearch; } else return 0; -- 2.45.2 From 1f342558d6ec0fe1dfd595832aca58d5324debc5 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 13 Dec 2019 13:53:08 -0500 Subject: [PATCH 209/371] make sure we never store tags as something other than a string --- dist/bundle.es.js | 14 +++++++++++++- src/redux/selectors/tags.js | 2 +- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 73a6be8..62eeff4 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,6 +15,7 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ + __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -274,6 +275,7 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ + __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -516,6 +518,7 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ + __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -546,6 +549,7 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ + __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -595,6 +599,7 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ + __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -622,6 +627,7 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ + __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -635,6 +641,7 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ + __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -654,6 +661,7 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ + __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -670,6 +678,7 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ + __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -678,6 +687,7 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ + __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -723,6 +733,7 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ + __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -776,6 +787,7 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ + __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); @@ -5462,7 +5474,7 @@ const selectState$9 = state => state.tags || {}; const selectKnownTagsByName = reselect.createSelector(selectState$9, state => state.knownTags); -const selectFollowedTagsList = reselect.createSelector(selectState$9, state => state.followedTags); +const selectFollowedTagsList = reselect.createSelector(selectState$9, state => state.followedTags.filter(tag => typeof tag === 'string')); const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag.toLowerCase() })).sort((a, b) => a.name.localeCompare(b.name))); diff --git a/src/redux/selectors/tags.js b/src/redux/selectors/tags.js index f46151b..17f3fd8 100644 --- a/src/redux/selectors/tags.js +++ b/src/redux/selectors/tags.js @@ -10,7 +10,7 @@ export const selectKnownTagsByName = createSelector( export const selectFollowedTagsList = createSelector( selectState, - (state: TagState): Array => state.followedTags + (state: TagState): Array => state.followedTags.filter(tag => typeof tag === 'string') ); export const selectFollowedTags = createSelector( -- 2.45.2 From 8fd694e96279a0fb74ee72f2ec1f5b0f14d6b410 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 13 Dec 2019 14:47:16 -0500 Subject: [PATCH 210/371] update types --- dist/flow-typed/Lbry.js | 2 ++ flow-typed/Lbry.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 006e170..cc8a4ac 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -50,6 +50,8 @@ declare type StatusResponse = { blocks_behind: number, is_encrypted: boolean, is_locked: boolean, + headers_synchronization_progress: number, + available_servers: number, }, }; diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 006e170..cc8a4ac 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -50,6 +50,8 @@ declare type StatusResponse = { blocks_behind: number, is_encrypted: boolean, is_locked: boolean, + headers_synchronization_progress: number, + available_servers: number, }, }; -- 2.45.2 From 7a26e77e27f57562528a554a30ced0dd259691ef Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Sun, 15 Dec 2019 19:56:01 -0500 Subject: [PATCH 211/371] fix: hard error on space in URI The app would crash, and so would Android. Eventually users would need a way to abandon them - can do so via the CLI for now. Not many in this boat. --- dist/bundle.es.js | 20 ++++---------------- src/lbryURI.js | 8 ++++---- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8f827ba..9d5fc8a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,7 +15,6 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ - __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -275,7 +274,6 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ - __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -518,7 +516,6 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ - __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -549,7 +546,6 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ - __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -599,7 +595,6 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ - __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -627,7 +622,6 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -641,7 +635,6 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -661,7 +654,6 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ - __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -678,7 +670,6 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ - __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -687,7 +678,6 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ - __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -733,7 +723,6 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ - __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -787,7 +776,6 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ - __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); @@ -1182,7 +1170,7 @@ function parseURIModifier(modSeperator, modValue) { if (modSeperator) { if (!modValue) { - throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); + console.error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); } if (modSeperator === '#') { @@ -1195,15 +1183,15 @@ function parseURIModifier(modSeperator, modValue) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__(`Invalid claim ID %claimId%.`, { claimId })); + console.error(__(`Invalid claim ID %claimId%.`, { claimId })); } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Claim sequence must be a number.')); + console.error(__('Claim sequence must be a number.')); } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Bid position must be a number.')); + console.error(__('Bid position must be a number.')); } return [claimId, claimSequence, bidPosition]; diff --git a/src/lbryURI.js b/src/lbryURI.js index a019418..e6fce46 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -138,7 +138,7 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) { if (modSeperator) { if (!modValue) { - throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); + console.error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); } if (modSeperator === '#') { @@ -151,15 +151,15 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - throw new Error(__(`Invalid claim ID %claimId%.`, { claimId })); + console.error(__(`Invalid claim ID %claimId%.`, { claimId })); } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Claim sequence must be a number.')); + console.error(__('Claim sequence must be a number.')); } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - throw new Error(__('Bid position must be a number.')); + console.error(__('Bid position must be a number.')); } return [claimId, claimSequence, bidPosition]; -- 2.45.2 From 31c8ec5051420febdbee85379581e99e09d0a1b6 Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 16 Dec 2019 13:20:07 -0500 Subject: [PATCH 212/371] fixes blockedChannel sync --- dist/bundle.es.js | 12 ++++++------ src/redux/actions/sync.js | 10 +++++----- src/redux/reducers/blocked.js | 6 +++--- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9d5fc8a..08cf676 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1517,9 +1517,9 @@ var _extends$2 = Object.assign || function (target) { for (var i = 1; i < argume function extractUserState(rawObj) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blockedChannels, settings } = rawObj.value; + const { subscriptions, tags, blocked, settings } = rawObj.value; - return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blockedChannels ? { blockedChannels } : {}, settings ? { settings } : {}); + return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blocked ? { blocked } : {}, settings ? { settings } : {}); } return {}; @@ -1527,8 +1527,8 @@ function extractUserState(rawObj) { function doPopulateSharedUserState(sharedSettings) { return dispatch => { - const { subscriptions, tags, blockedChannels, settings } = extractUserState(sharedSettings); - dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags, blockedChannels, settings } }); + const { subscriptions, tags, blocked, settings } = extractUserState(sharedSettings); + dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags, blocked, settings } }); }; } @@ -5122,9 +5122,9 @@ const blockedReducer = handleActions({ }; }, [USER_STATE_POPULATE]: (state, action) => { - const { blockedChannels } = action.data; + const { blocked } = action.data; return _extends$e({}, state, { - blockedChannels: blockedChannels && blockedChannels.length ? blockedChannels : state.blockedChannels + blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } }, defaultState$9); diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 3957a33..41a25ea 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -7,19 +7,19 @@ type SharedData = { value: { subscriptions?: Array, tags?: Array, - blockedChannels?: Array, + blocked?: Array, settings?: any, }, }; function extractUserState(rawObj: SharedData) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blockedChannels, settings} = rawObj.value; + const { subscriptions, tags, blocked, settings} = rawObj.value; return { ...(subscriptions ? { subscriptions } : {}), ...(tags ? { tags } : {}), - ...(blockedChannels ? { blockedChannels } : {}), + ...(blocked ? { blocked } : {}), ...(settings ? { settings } : {}), }; } @@ -29,8 +29,8 @@ function extractUserState(rawObj: SharedData) { export function doPopulateSharedUserState(sharedSettings: any) { return (dispatch: Dispatch) => { - const { subscriptions, tags, blockedChannels, settings } = extractUserState(sharedSettings); - dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags, blockedChannels, settings } }); + const { subscriptions, tags, blocked, settings } = extractUserState(sharedSettings); + dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags, blocked, settings } }); }; } diff --git a/src/redux/reducers/blocked.js b/src/redux/reducers/blocked.js index 7a9fd85..b69d9c9 100644 --- a/src/redux/reducers/blocked.js +++ b/src/redux/reducers/blocked.js @@ -28,13 +28,13 @@ export const blockedReducer = handleActions( }, [ACTIONS.USER_STATE_POPULATE]: ( state: BlocklistState, - action: { data: { blockedChannels: ?Array } } + action: { data: { blocked: ?Array } } ) => { - const { blockedChannels } = action.data; + const { blocked } = action.data; return { ...state, blockedChannels: - blockedChannels && blockedChannels.length ? blockedChannels : state.blockedChannels, + blocked && blocked.length ? blocked : state.blockedChannels, }; }, }, -- 2.45.2 From 9081e377bd1283f182669ec77f077beaed5f65d2 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 18 Dec 2019 15:14:24 +0100 Subject: [PATCH 213/371] doSendTip i18n fix --- dist/bundle.es.js | 16 ++-------------- src/redux/actions/wallet.js | 6 +++--- 2 files changed, 5 insertions(+), 17 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8f827ba..36824ad 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,7 +15,6 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ - __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -275,7 +274,6 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ - __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -518,7 +516,6 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ - __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -549,7 +546,6 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ - __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -599,7 +595,6 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ - __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -627,7 +622,6 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -641,7 +635,6 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -661,7 +654,6 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ - __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -678,7 +670,6 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ - __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -687,7 +678,6 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ - __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -733,7 +723,6 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ - __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -787,7 +776,6 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ - __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); @@ -2510,7 +2498,7 @@ function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { if (balance - amount <= 0) { dispatch(doToast({ - message: 'Insufficient credits', + message: __('Insufficient credits'), isError: true })); return; @@ -2518,7 +2506,7 @@ function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { const success = () => { dispatch(doToast({ - message: shouldSupport ? __(`You deposited ${amount} LBC as a support!`) : __(`You sent ${amount} LBC as a tip, Mahalo!`), + message: shouldSupport ? __('You deposited %amount% LBC as a support!', { amount }) : __('You sent %amount% LBC as a tip, Mahalo!', { amount }), linkText: __('History'), linkTarget: __('/wallet') })); diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 4fdfb15..4ae4f02 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -206,7 +206,7 @@ export function doSendTip(amount, claimId, isSupport, successCallback, errorCall if (balance - amount <= 0) { dispatch( doToast({ - message: 'Insufficient credits', + message: __('Insufficient credits'), isError: true, }) ); @@ -217,8 +217,8 @@ export function doSendTip(amount, claimId, isSupport, successCallback, errorCall dispatch( doToast({ message: shouldSupport - ? __(`You deposited ${amount} LBC as a support!`) - : __(`You sent ${amount} LBC as a tip, Mahalo!`), + ? __('You deposited %amount% LBC as a support!', { amount }) + : __('You sent %amount% LBC as a tip, Mahalo!', { amount }), linkText: __('History'), linkTarget: __('/wallet'), }) -- 2.45.2 From 74eba1f297cd1fe458033323776a9c8d891a4fa1 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 18 Dec 2019 11:47:18 -0500 Subject: [PATCH 214/371] provide walletReconnecting state in wallet reducer --- dist/bundle.es.js | 13 ++++++++++++- src/index.js | 1 + src/redux/reducers/wallet.js | 11 +++++++++++ src/redux/selectors/wallet.js | 5 +++++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 08cf676..ec30e15 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1829,6 +1829,8 @@ const makeSelectLatestTransactions = reselect.createSelector(selectTransactionIt const selectFilteredTransactionCount = reselect.createSelector(selectFilteredTransactions, filteredTransactions => filteredTransactions.length); +const selectIsWalletReconnecting = reselect.createSelector(selectState$1, state => state.walletReconnecting); + 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 _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; } @@ -5169,7 +5171,8 @@ const defaultState$a = { walletLockPending: false, walletLockSucceded: null, walletLockResult: null, - transactionListFilter: 'all' + transactionListFilter: 'all', + walletReconnecting: false }; const walletReducer = handleActions({ @@ -5391,6 +5394,13 @@ const walletReducer = handleActions({ [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$f({}, state, { latestBlock: action.data + }), + [WALLET_RESTART]: state => _extends$f({}, state, { + walletReconnecting: true + }), + + [WALLET_RESTART_COMPLETED]: state => _extends$f({}, state, { + walletReconnecting: false }) }, defaultState$a); @@ -5701,6 +5711,7 @@ exports.selectIsResolvingPublishUris = selectIsResolvingPublishUris; exports.selectIsSearching = selectIsSearching; exports.selectIsSendingSupport = selectIsSendingSupport; exports.selectIsStillEditing = selectIsStillEditing; +exports.selectIsWalletReconnecting = selectIsWalletReconnecting; exports.selectLastPurchasedUri = selectLastPurchasedUri; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; diff --git a/src/index.js b/src/index.js index fc78d59..65f1db9 100644 --- a/src/index.js +++ b/src/index.js @@ -312,6 +312,7 @@ export { makeSelectLatestTransactions, makeSelectFilteredTransactionsForPage, selectFilteredTransactionCount, + selectIsWalletReconnecting, } from 'redux/selectors/wallet'; export { diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index ae7511d..26639a2 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -42,6 +42,7 @@ type WalletState = { walletLockPending: boolean, walletLockSucceded: ?boolean, walletLockResult: ?boolean, + walletReconnecting: boolean, }; const defaultState = { @@ -74,6 +75,7 @@ const defaultState = { walletLockSucceded: null, walletLockResult: null, transactionListFilter: 'all', + walletReconnecting: false, }; export const walletReducer = handleActions( @@ -326,6 +328,15 @@ export const walletReducer = handleActions( ...state, latestBlock: action.data, }), + [ACTIONS.WALLET_RESTART]: (state: WalletState) => ({ + ...state, + walletReconnecting: true, + }), + + [ACTIONS.WALLET_RESTART_COMPLETED]: (state: WalletState) => ({ + ...state, + walletReconnecting: false, + }), }, defaultState ); diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 950b092..77b1bb3 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -323,3 +323,8 @@ export const selectFilteredTransactionCount = createSelector( selectFilteredTransactions, filteredTransactions => filteredTransactions.length ); + +export const selectIsWalletReconnecting = createSelector( + selectState, + state => state.walletReconnecting +); -- 2.45.2 From 8086ccdc01f31a88a36e5d9e3404b308b2a70ee2 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 18 Dec 2019 17:20:08 -0500 Subject: [PATCH 215/371] pass related_to flag to search for recommended content --- dist/bundle.es.js | 30 +++++++++++++++++++++--------- src/redux/actions/search.js | 13 ++++++++++--- src/redux/selectors/claims.js | 24 +++++++++++++----------- src/redux/selectors/search.js | 8 ++++++-- src/util/query-params.js | 10 +++++++++- 5 files changed, 59 insertions(+), 26 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ec30e15..2ac93ed 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1042,7 +1042,7 @@ function toQueryString(params) { return parts.join('&'); } -const getSearchQueryString = (query, options = {}, includeUserOptions = false) => { +const getSearchQueryString = (query, options = {}, includeUserOptions = false, additionalOptions = {}) => { const encodedQuery = encodeURIComponent(query); const queryParams = [`s=${encodedQuery}`, `size=${options.size || DEFAULT_SEARCH_SIZE}`, `from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`]; @@ -1056,6 +1056,13 @@ const getSearchQueryString = (query, options = {}, includeUserOptions = false) = } } + if (additionalOptions) { + Object.keys(additionalOptions).forEach(key => { + const option = additionalOptions[key]; + queryParams.push(`${key}=${option}`); + }); + } + return queryParams.join('&'); }; @@ -1395,11 +1402,11 @@ const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selec // Creates a query string based on the state in the search reducer // Can be overrided by passing in custom sizes/from values for other areas pagination -const makeSelectQueryWithOptions = (customQuery, customSize, customFrom, isBackgroundSearch = false // If it's a background search, don't use the users settings -) => reselect.createSelector(selectSearchValue, selectSearchOptions, (query, options) => { +const makeSelectQueryWithOptions = (customQuery, customSize, customFrom, isBackgroundSearch = false, // If it's a background search, don't use the users settings +additionalOptions = {}) => reselect.createSelector(selectSearchValue, selectSearchOptions, (query, options) => { const size = customSize || options[SEARCH_OPTIONS.RESULT_COUNT]; - const queryString = getSearchQueryString(customQuery || query, _extends$1({}, options, { size, from: customFrom }), !isBackgroundSearch); + const queryString = getSearchQueryString(customQuery || query, _extends$1({}, options, { size, from: customFrom }), !isBackgroundSearch, additionalOptions); return queryString; }); @@ -2179,7 +2186,13 @@ const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSe const { title } = claim.value; - const searchQuery = getSearchQueryString(title ? title.replace(/\//, ' ') : ''); + if (!title) { + return; + } + + const searchQuery = getSearchQueryString(title, undefined, undefined, { + related_to: claim.claim_id + }); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { @@ -3908,9 +3921,8 @@ const doUpdateSearchQuery = (query, shouldSkipSuggestions) => dispatch => { } }; -const doSearch = (rawQuery, // pass in a query if you don't want to search for what's in the search bar -size, // only pass in if you don't want to use the users setting (ex: related content) -from, isBackgroundSearch = false) => (dispatch, getState) => { +const doSearch = (rawQuery, size, // only pass in if you don't want to use the users setting (ex: related content) +from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); if (!query) { @@ -3921,7 +3933,7 @@ from, isBackgroundSearch = false) => (dispatch, getState) => { } const state = getState(); - const queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch)(state); + let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)(state); // If we have already searched for something, we don't need to do anything const urisForQuery = makeSelectSearchUris(queryWithOptions)(state); diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index d5c6ce3..b1463f5 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -75,10 +75,13 @@ export const doUpdateSearchQuery = (query: string, shouldSkipSuggestions: ?boole }; export const doSearch = ( - rawQuery: string, // pass in a query if you don't want to search for what's in the search bar + rawQuery: string, size: ?number, // only pass in if you don't want to use the users setting (ex: related content) from: ?number, - isBackgroundSearch: boolean = false + isBackgroundSearch: boolean = false, + options: { + related_to?: string, + } = {} ) => (dispatch: Dispatch, getState: GetState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); @@ -90,7 +93,9 @@ export const doSearch = ( } const state = getState(); - const queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch)(state); + let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)( + state + ); // If we have already searched for something, we don't need to do anything const urisForQuery = makeSelectSearchUris(queryWithOptions)(state); @@ -151,6 +156,8 @@ export const doSearch = ( }); }; +export const doSearchForRelatedContent = (query: string) => {}; + export const doFocusSearchInput = () => (dispatch: Dispatch) => dispatch({ type: ACTIONS.SEARCH_FOCUS, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index dafdd43..b2c437b 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -212,7 +212,6 @@ export const makeSelectTotalPagesInChannelSearch = (uri: string) => } ); - export const makeSelectClaimsInChannelForCurrentPageState = (uri: string) => createSelector( selectClaimsById, @@ -261,8 +260,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -473,8 +472,7 @@ export const makeSelectOmittedCountForChannel = (uri: string) => (claimsInChannel, claimsInSearch) => { if (claimsInChannel && typeof claimsInSearch === 'number' && claimsInSearch >= 0) { return claimsInChannel - claimsInSearch; - } - else return 0; + } else return 0; } ); @@ -508,7 +506,13 @@ export const makeSelectRecommendedContentForUri = (uri: string) => const { title } = claim.value; - const searchQuery = getSearchQueryString(title ? title.replace(/\//, ' ') : ''); + if (!title) { + return; + } + + const searchQuery = getSearchQueryString(title, undefined, undefined, { + related_to: claim.claim_id, + }); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { @@ -625,11 +629,9 @@ export const makeSelectMyStreamUrlsForPage = (page: number = 1) => createSelector( selectMyClaimUrisWithoutChannels, urls => { - const start = ((Number(page) - 1) * Number(PAGE_SIZE)); - const end = (Number(page) * Number(PAGE_SIZE)); - return (urls && urls.length) - ? urls.slice(start, end) - : []; + const start = (Number(page) - 1) * Number(PAGE_SIZE); + const end = Number(page) * Number(PAGE_SIZE); + return urls && urls.length ? urls.slice(start, end) : []; } ); diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index aada012..d556602 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -137,7 +137,10 @@ export const makeSelectQueryWithOptions = ( customQuery: ?string, customSize: ?number, customFrom: ?number, - isBackgroundSearch: boolean = false // If it's a background search, don't use the users settings + isBackgroundSearch: boolean = false, // If it's a background search, don't use the users settings + additionalOptions: { + related_to?: string, + } = {} ) => createSelector( selectSearchValue, @@ -148,7 +151,8 @@ export const makeSelectQueryWithOptions = ( const queryString = getSearchQueryString( customQuery || query, { ...options, size, from: customFrom }, - !isBackgroundSearch + !isBackgroundSearch, + additionalOptions ); return queryString; diff --git a/src/util/query-params.js b/src/util/query-params.js index 9f6ae1f..7a3da29 100644 --- a/src/util/query-params.js +++ b/src/util/query-params.js @@ -36,7 +36,8 @@ export function toQueryString(params: { [string]: string | number }) { export const getSearchQueryString = ( query: string, options: any = {}, - includeUserOptions: boolean = false + includeUserOptions: boolean = false, + additionalOptions: {} = {} ) => { const encodedQuery = encodeURIComponent(query); const queryParams = [ @@ -67,5 +68,12 @@ export const getSearchQueryString = ( } } + if (additionalOptions) { + Object.keys(additionalOptions).forEach(key => { + const option = additionalOptions[key]; + queryParams.push(`${key}=${option}`); + }); + } + return queryParams.join('&'); }; -- 2.45.2 From 3779c058886fcadcb12e2bb432b39df81d9f6c21 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 20 Dec 2019 11:40:29 -0500 Subject: [PATCH 216/371] fix wallet balance subscribe when the api call fails --- dist/bundle.es.js | 14 +++++++++++++ src/redux/actions/wallet.js | 42 ++++++++++++++++++++----------------- 2 files changed, 37 insertions(+), 19 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2ac93ed..b6b97c1 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,6 +15,7 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ + __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -274,6 +275,7 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ + __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -516,6 +518,7 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ + __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -546,6 +549,7 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ + __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -595,6 +599,7 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ + __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -622,6 +627,7 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ + __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -635,6 +641,7 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ + __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -654,6 +661,7 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ + __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -670,6 +678,7 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ + __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -678,6 +687,7 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ + __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -723,6 +733,7 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ + __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -776,6 +787,7 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ + __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); @@ -2352,6 +2364,8 @@ function doUpdateBalance() { } }); } + }).catch(() => { + walletBalancePromise = null; }); } diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 4fdfb15..36ba375 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -13,27 +13,31 @@ export function doUpdateBalance() { } = getState(); if (walletBalancePromise === null) { - walletBalancePromise = Lbry.wallet_balance().then(response => { - walletBalancePromise = null; + walletBalancePromise = Lbry.wallet_balance() + .then(response => { + walletBalancePromise = null; - const { available, reserved, reserved_subtotals, total } = response; - const { claims, supports, tips } = reserved_subtotals; - const totalFloat = parseFloat(total); + const { available, reserved, reserved_subtotals, total } = response; + const { claims, supports, tips } = reserved_subtotals; + const totalFloat = parseFloat(total); - if (totalInStore !== totalFloat) { - dispatch({ - type: ACTIONS.UPDATE_BALANCE, - data: { - totalBalance: totalFloat, - balance: parseFloat(available), - reservedBalance: parseFloat(reserved), - claimsBalance: parseFloat(claims), - supportsBalance: parseFloat(supports), - tipsBalance: parseFloat(tips), - }, - }); - } - }); + if (totalInStore !== totalFloat) { + dispatch({ + type: ACTIONS.UPDATE_BALANCE, + data: { + totalBalance: totalFloat, + balance: parseFloat(available), + reservedBalance: parseFloat(reserved), + claimsBalance: parseFloat(claims), + supportsBalance: parseFloat(supports), + tipsBalance: parseFloat(tips), + }, + }); + } + }) + .catch(() => { + walletBalancePromise = null; + }); } return walletBalancePromise; -- 2.45.2 From 0db20834f9ff99d3ba7acd8e4e8ebb5a41f7e7b4 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 20 Dec 2019 12:05:35 -0500 Subject: [PATCH 217/371] remove forward slash from search query when selecting --- dist/bundle.es.js | 2 +- src/redux/actions/search.js | 2 -- src/redux/selectors/claims.js | 6 +++--- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b6b97c1..8834776 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2202,7 +2202,7 @@ const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSe return; } - const searchQuery = getSearchQueryString(title, undefined, undefined, { + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), undefined, undefined, { related_to: claim.claim_id }); diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index b1463f5..5dff3b2 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -156,8 +156,6 @@ export const doSearch = ( }); }; -export const doSearchForRelatedContent = (query: string) => {}; - export const doFocusSearchInput = () => (dispatch: Dispatch) => dispatch({ type: ACTIONS.SEARCH_FOCUS, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index b2c437b..8bf2d31 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -260,8 +260,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -510,7 +510,7 @@ export const makeSelectRecommendedContentForUri = (uri: string) => return; } - const searchQuery = getSearchQueryString(title, undefined, undefined, { + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), undefined, undefined, { related_to: claim.claim_id, }); -- 2.45.2 From 1a6156940547526f4942d9f108795f42ab204d17 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Sat, 21 Dec 2019 14:23:50 -0500 Subject: [PATCH 218/371] fix: hard errors on URL issues --- dist/bundle.es.js | 22 +++++----------------- src/lbryURI.js | 10 +++++----- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8834776..173bea1 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,7 +15,6 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ - __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -275,7 +274,6 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ - __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -518,7 +516,6 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ - __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -549,7 +546,6 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ - __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -599,7 +595,6 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ - __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -627,7 +622,6 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -641,7 +635,6 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -661,7 +654,6 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ - __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -678,7 +670,6 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ - __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -687,7 +678,6 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ - __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -733,7 +723,6 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ - __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -787,7 +776,6 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ - __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); @@ -1133,17 +1121,17 @@ function parseURI(URL, requireProto = false) { // Validate protocol if (requireProto && !proto) { - throw new Error(__('LBRY URLs must include a protocol prefix (lbry://).')); + console.error(__('LBRY URLs must include a protocol prefix (lbry://).')); } // Validate and process name if (!streamNameOrChannelName) { - throw new Error(__('URL does not include name.')); + console.error(__('URL does not include name.')); } rest.forEach(urlPiece => { if (urlPiece && urlPiece.includes(' ')) { - throw new Error('URL can not include a space'); + console.error('URL can not include a space'); } }); @@ -1153,11 +1141,11 @@ function parseURI(URL, requireProto = false) { if (includesChannel) { if (!channelName) { - throw new Error(__('No channel name after @.')); + console.error(__('No channel name after @.')); } if (channelName.length < channelNameMinLength) { - throw new Error(__(`Channel names must be at least %channelNameMinLength% characters.`, { + console.error(__(`Channel names must be at least %channelNameMinLength% characters.`, { channelNameMinLength })); } diff --git a/src/lbryURI.js b/src/lbryURI.js index e6fce46..2656b2d 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -63,17 +63,17 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj // Validate protocol if (requireProto && !proto) { - throw new Error(__('LBRY URLs must include a protocol prefix (lbry://).')); + console.error(__('LBRY URLs must include a protocol prefix (lbry://).')); } // Validate and process name if (!streamNameOrChannelName) { - throw new Error(__('URL does not include name.')); + console.error(__('URL does not include name.')); } rest.forEach(urlPiece => { if (urlPiece && urlPiece.includes(' ')) { - throw new Error('URL can not include a space'); + console.error('URL can not include a space'); } }); @@ -83,11 +83,11 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj if (includesChannel) { if (!channelName) { - throw new Error(__('No channel name after @.')); + console.error(__('No channel name after @.')); } if (channelName.length < channelNameMinLength) { - throw new Error( + console.error( __(`Channel names must be at least %channelNameMinLength% characters.`, { channelNameMinLength, }) -- 2.45.2 From a2be979986dc93be4c2c596846109f5394f64fa1 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Sat, 21 Dec 2019 15:32:55 -0500 Subject: [PATCH 219/371] fix: don't hard error on space only --- dist/bundle.es.js | 16 ++++++++-------- src/lbryURI.js | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 173bea1..668b173 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1121,12 +1121,12 @@ function parseURI(URL, requireProto = false) { // Validate protocol if (requireProto && !proto) { - console.error(__('LBRY URLs must include a protocol prefix (lbry://).')); + throw new Error(__('LBRY URLs must include a protocol prefix (lbry://).')); } // Validate and process name if (!streamNameOrChannelName) { - console.error(__('URL does not include name.')); + throw new Error(__('URL does not include name.')); } rest.forEach(urlPiece => { @@ -1141,11 +1141,11 @@ function parseURI(URL, requireProto = false) { if (includesChannel) { if (!channelName) { - console.error(__('No channel name after @.')); + throw new Error(__('No channel name after @.')); } if (channelName.length < channelNameMinLength) { - console.error(__(`Channel names must be at least %channelNameMinLength% characters.`, { + throw new Error(__(`Channel names must be at least %channelNameMinLength% characters.`, { channelNameMinLength })); } @@ -1177,7 +1177,7 @@ function parseURIModifier(modSeperator, modValue) { if (modSeperator) { if (!modValue) { - console.error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); + throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); } if (modSeperator === '#') { @@ -1190,15 +1190,15 @@ function parseURIModifier(modSeperator, modValue) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - console.error(__(`Invalid claim ID %claimId%.`, { claimId })); + throw new Error(__(`Invalid claim ID %claimId%.`, { claimId })); } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - console.error(__('Claim sequence must be a number.')); + throw new Error(__('Claim sequence must be a number.')); } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - console.error(__('Bid position must be a number.')); + throw new Error(__('Bid position must be a number.')); } return [claimId, claimSequence, bidPosition]; diff --git a/src/lbryURI.js b/src/lbryURI.js index 2656b2d..15ab4e6 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -63,12 +63,12 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj // Validate protocol if (requireProto && !proto) { - console.error(__('LBRY URLs must include a protocol prefix (lbry://).')); + throw new Error(__('LBRY URLs must include a protocol prefix (lbry://).')); } // Validate and process name if (!streamNameOrChannelName) { - console.error(__('URL does not include name.')); + throw new Error(__('URL does not include name.')); } rest.forEach(urlPiece => { @@ -83,11 +83,11 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj if (includesChannel) { if (!channelName) { - console.error(__('No channel name after @.')); + throw new Error(__('No channel name after @.')); } if (channelName.length < channelNameMinLength) { - console.error( + throw new Error( __(`Channel names must be at least %channelNameMinLength% characters.`, { channelNameMinLength, }) @@ -138,7 +138,7 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) { if (modSeperator) { if (!modValue) { - console.error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); + throw new Error(__(`No modifier provided after separator %modSeperator%.`, { modSeperator })); } if (modSeperator === '#') { @@ -151,15 +151,15 @@ function parseURIModifier(modSeperator: ?string, modValue: ?string) { } if (claimId && (claimId.length > claimIdMaxLength || !claimId.match(/^[0-9a-f]+$/))) { - console.error(__(`Invalid claim ID %claimId%.`, { claimId })); + throw new Error(__(`Invalid claim ID %claimId%.`, { claimId })); } if (claimSequence && !claimSequence.match(/^-?[1-9][0-9]*$/)) { - console.error(__('Claim sequence must be a number.')); + throw new Error(__('Claim sequence must be a number.')); } if (bidPosition && !bidPosition.match(/^-?[1-9][0-9]*$/)) { - console.error(__('Bid position must be a number.')); + throw new Error(__('Bid position must be a number.')); } return [claimId, claimSequence, bidPosition]; -- 2.45.2 From eb8fff0e5afd43be00822b3f476eea9e0eb7b075 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Sun, 5 Jan 2020 11:37:35 +0100 Subject: [PATCH 220/371] add optional resolveResults parameter to doSearch (#257) --- dist/bundle.es.js | 6 ++++-- src/redux/actions/search.js | 7 +++++-- src/redux/selectors/claims.js | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c6d4c90..035f91c 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3924,7 +3924,7 @@ const doUpdateSearchQuery = (query, shouldSkipSuggestions) => dispatch => { }; const doSearch = (rawQuery, size, // only pass in if you don't want to use the users setting (ex: related content) -from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => { +from, isBackgroundSearch = false, options = {}, resolveResults = true) => (dispatch, getState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); if (!query) { @@ -3973,7 +3973,9 @@ from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => { } const url = buildURI(urlObj); - actions.push(doResolveUri(url)); + if (resolveResults) { + actions.push(doResolveUri(url)); + } uris.push(url); } }); diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 5dff3b2..3cd3a47 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -81,7 +81,8 @@ export const doSearch = ( isBackgroundSearch: boolean = false, options: { related_to?: string, - } = {} + } = {}, + resolveResults: boolean = true ) => (dispatch: Dispatch, getState: GetState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); @@ -135,7 +136,9 @@ export const doSearch = ( } const url = buildURI(urlObj); - actions.push(doResolveUri(url)); + if (resolveResults) { + actions.push(doResolveUri(url)); + } uris.push(url); } }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 8bf2d31..e825188 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -260,8 +260,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } -- 2.45.2 From d45c160b10f9e6f9e56fe724105e7381fdb5375f Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 7 Jan 2020 00:21:13 -0500 Subject: [PATCH 221/371] Adds proper comment type --- flow-typed/Comment.js | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/flow-typed/Comment.js b/flow-typed/Comment.js index f2f35b7..4619430 100644 --- a/flow-typed/Comment.js +++ b/flow-typed/Comment.js @@ -1,19 +1,22 @@ declare type Comment = { - author?: string, - author_url?: string, - claim_index?: number, - comment_id?: number, - downvotes?: number, - message: string, - omitted?: number, - reply_count?: number, - time_posted?: number, - upvotes?: number, - parent_id?: number, + comment: string, // comment body + comment_id: string, // sha256 digest + timestamp: number, // integer representing unix-time + is_hidden: boolean, // claim owner may enable/disable this + channel_id?: string, // claimId of channel signing this comment + channel_name?: string, // name of channel claim + channel_url?: string, // full lbry url to signing channel + signature?: string, // signature of comment by originating channel + signing_ts?: string, // timestamp used when signing this comment + is_channel_signature_valid?: boolean, // whether or not the signature could be validated + parent_id?: number, // comment_id of comment this is in reply to + claim_id?: string, // id linking to the claim this comment }; +// todo: relate individual comments to their commentId declare type CommentsState = { - byId: {}, - isLoading: boolean, commentsByUri: { [string]: string }, -} + byId: { [string]: Array }, + isLoading: boolean, + myComments: ?Set, +}; -- 2.45.2 From 7c55a9e0f51b4efa2b01983b86d265e6282d2546 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 7 Jan 2020 00:22:57 -0500 Subject: [PATCH 222/371] Adds edit, hide, and abandon action types from new lbry sdk api --- dist/bundle.es.js | 9 +++++++++ src/constants/action_types.js | 9 +++++++++ src/redux/reducers/comments.js | 37 ++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 035f91c..da208a5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -377,6 +377,15 @@ var action_types = /*#__PURE__*/Object.freeze({ COMMENT_CREATE_STARTED: COMMENT_CREATE_STARTED, COMMENT_CREATE_COMPLETED: COMMENT_CREATE_COMPLETED, COMMENT_CREATE_FAILED: COMMENT_CREATE_FAILED, + COMMENT_ABANDON_STARTED: COMMENT_ABANDON_STARTED, + COMMENT_ABANDON_COMPLETED: COMMENT_ABANDON_COMPLETED, + COMMENT_ABANDON_FAILED: COMMENT_ABANDON_FAILED, + COMMENT_HIDE_STARTED: COMMENT_HIDE_STARTED, + COMMENT_HIDE_COMPLETED: COMMENT_HIDE_COMPLETED, + COMMENT_HIDE_FAILED: COMMENT_HIDE_FAILED, + COMMENT_EDIT_STARTED: COMMENT_EDIT_STARTED, + COMMENT_EDIT_COMPLETED: COMMENT_EDIT_COMPLETED, + COMMENT_EDIT_FAILED: COMMENT_EDIT_FAILED, FILE_LIST_STARTED: FILE_LIST_STARTED, FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index ac23374..097b2cd 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -111,6 +111,15 @@ export const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED'; export const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; export const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; export const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; +export const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; +export const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; +export const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; +export const COMMENT_EDIT_STARTED = 'COMMENT_EDIT_STARTED'; +export const COMMENT_EDIT_COMPLETED = 'COMMENT_EDIT_COMPLETED'; +export const COMMENT_EDIT_FAILED = 'COMMENT_EDIT_FAILED'; +export const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; +export const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; +export const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; // Files export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js index 3d1738b..c3b9bd4 100644 --- a/src/redux/reducers/comments.js +++ b/src/redux/reducers/comments.js @@ -6,6 +6,7 @@ const defaultState: CommentsState = { byId: {}, commentsByUri: {}, isLoading: false, + myComments: undefined, }; export const commentReducer = handleActions( @@ -58,6 +59,42 @@ export const commentReducer = handleActions( ...state, isLoading: false, }), + [ACTIONS.COMMENT_ABANDON_STARTED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: true, + }), + [ACTIONS.COMMENT_ABANDON_COMPLETED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + [ACTIONS.COMMENT_ABANDON_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + [ACTIONS.COMMENT_EDIT_STARTED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: true, + }), + [ACTIONS.COMMENT_EDIT_COMPLETED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + [ACTIONS.COMMENT_EDIT_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + [ACTIONS.COMMENT_HIDE_STARTED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: true, + }), + [ACTIONS.COMMENT_HIDE_COMPLETED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + [ACTIONS.COMMENT_HIDE_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), }, defaultState ); -- 2.45.2 From 4cbbee497519e68df0c621c72a86cf75eb199499 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Wed, 8 Jan 2020 17:27:36 -0500 Subject: [PATCH 223/371] add lbry as default tag --- src/constants/tags.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/constants/tags.js b/src/constants/tags.js index ef3fd9e..9456a81 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -510,4 +510,5 @@ export const DEFAULT_KNOWN_TAGS = [ 'portugal', 'dantdm', 'teaser', + 'lbry' ]; -- 2.45.2 From 78ec8c3c16cd350068151233c3780d980bba54a7 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Thu, 9 Jan 2020 17:09:37 -0500 Subject: [PATCH 224/371] Adds edit, hide, and abandon action types from new lbry sdk api --- flow-typed/Lbry.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index cc8a4ac..92ce9dd 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -125,6 +125,8 @@ declare type ChannelUpdateResponse = GenericTxResponse & { }; declare type CommentCreateResponse = Comment; +declare type CommentEditResponse = Comment; + declare type CommentListResponse = { items: Array, page: number, @@ -133,6 +135,16 @@ declare type CommentListResponse = { total_pages: number, }; +declare type CommentHideResponse = { + // keyed by the CommentIds entered + [string]: { hidden: boolean }, +}; + +declare type CommentAbandonResponse = { + // keyed by the CommentId given + [string]: { abandoned: boolean }, +}; + declare type ChannelListResponse = { items: Array, page: number, -- 2.45.2 From ba9e68b1da73b067c38fa7693e569aeba45f9c1a Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Thu, 9 Jan 2020 17:10:54 -0500 Subject: [PATCH 225/371] claim_id is now guaranteed --- flow-typed/Comment.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/flow-typed/Comment.js b/flow-typed/Comment.js index 4619430..368164c 100644 --- a/flow-typed/Comment.js +++ b/flow-typed/Comment.js @@ -1,6 +1,7 @@ declare type Comment = { comment: string, // comment body comment_id: string, // sha256 digest + claim_id: string, // id linking to the claim this comment timestamp: number, // integer representing unix-time is_hidden: boolean, // claim owner may enable/disable this channel_id?: string, // claimId of channel signing this comment @@ -10,7 +11,6 @@ declare type Comment = { signing_ts?: string, // timestamp used when signing this comment is_channel_signature_valid?: boolean, // whether or not the signature could be validated parent_id?: number, // comment_id of comment this is in reply to - claim_id?: string, // id linking to the claim this comment }; // todo: relate individual comments to their commentId -- 2.45.2 From 586b07a2431c75f4fb30c370f270fad8a5c79ac5 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Thu, 9 Jan 2020 17:11:37 -0500 Subject: [PATCH 226/371] adds edit, hide, and abandon methods to call the API with --- src/lbry.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/lbry.js b/src/lbry.js index ceb96f3..9fdd033 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -119,6 +119,11 @@ const Lbry: LbryTypes = { // Comments comment_list: (params = {}) => daemonCallWithResult('comment_list', params), comment_create: (params = {}) => daemonCallWithResult('comment_create', params), + // todo: implement these in reducers + comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), + comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), + comment_edit: (params = {}) => daemonCallWithResult('comment_hide', params), + // Connect to the sdk connect: () => { if (Lbry.connectPromise === null) { -- 2.45.2 From 28440873346a21d4a5daf2524ff70104844b3c8c Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Thu, 9 Jan 2020 21:27:23 -0500 Subject: [PATCH 227/371] Schema change for `CommentsState` --- flow-typed/Comment.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/flow-typed/Comment.js b/flow-typed/Comment.js index 368164c..64ea974 100644 --- a/flow-typed/Comment.js +++ b/flow-typed/Comment.js @@ -16,7 +16,8 @@ declare type Comment = { // todo: relate individual comments to their commentId declare type CommentsState = { commentsByUri: { [string]: string }, - byId: { [string]: Array }, + byId: { [string]: Array }, + commentById: { [string]: Comment }, isLoading: boolean, - myComments: ?Set, + myComments: ?Set, }; -- 2.45.2 From c171a38067ec9d3e806df9afb4d08e51065d307d Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Thu, 9 Jan 2020 21:27:59 -0500 Subject: [PATCH 228/371] Adds parent_id param to `comment_create` to allow replies --- src/redux/actions/comments.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index dbf1d94..64b5344 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -55,9 +55,10 @@ export function doCommentCreate( myChannels && myChannels.find(myChannel => myChannel.name === channel); const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null; return Lbry.comment_create({ - comment, - claim_id, - channel_id, + comment: comment, + claim_id: claim_id, + channel_id: channel_id, + parent_id: parent_id, }) .then((result: Comment) => { dispatch({ -- 2.45.2 From b65149fe003e301505b8c6a9bc9b95428dad62a7 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Thu, 9 Jan 2020 21:28:35 -0500 Subject: [PATCH 229/371] Refactors old reducers to be compliant with new schema --- src/redux/reducers/comments.js | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js index c3b9bd4..0513625 100644 --- a/src/redux/reducers/comments.js +++ b/src/redux/reducers/comments.js @@ -3,8 +3,9 @@ import * as ACTIONS from 'constants/action_types'; import { handleActions } from 'util/redux-utils'; const defaultState: CommentsState = { - byId: {}, - commentsByUri: {}, + commentById: {}, // commentId -> Comment + byId: {}, // ClaimID -> list of comments + commentsByUri: {}, // URI -> claimId isLoading: false, myComments: undefined, }; @@ -23,16 +24,23 @@ export const commentReducer = handleActions( [ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => { const { comment, claimId }: any = action.data; + const commentById = Object.assign({}, state.commentById); const byId = Object.assign({}, state.byId); const comments = byId[claimId]; - const newComments = comments.slice(); + const newCommentIds = comments.slice(); - newComments.unshift(comment); - byId[claimId] = newComments; + // add the comment by its ID + commentById[comment.comment_id] = comment; + + // push the comment_id to the top of ID list + newCommentIds.unshift(comment.comment_id); + byId[claimId] = newCommentIds; return { ...state, + commentById, byId, + isLoading: false, }; }, @@ -40,16 +48,26 @@ export const commentReducer = handleActions( [ACTIONS.COMMENT_LIST_COMPLETED]: (state: CommentsState, action: any) => { const { comments, claimId, uri } = action.data; + + const commentById = Object.assign({}, state.commentById); const byId = Object.assign({}, state.byId); const commentsByUri = Object.assign({}, state.commentsByUri); if (comments) { - byId[claimId] = comments; + const commentIds = Array(comments.length); + // map the comment_ids to the new comments + for (let i = 0; i < comments.length; i++) { + commentIds[i] = comments[i].comment_id; + commentById[commentIds[i]] = comments[i]; + } + + byId[claimId] = commentIds; commentsByUri[uri] = claimId; } return { ...state, byId, + commentById, commentsByUri, isLoading: false, }; -- 2.45.2 From 1038ff16c87d69b192b914773a5d07dbee8eb1e6 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Thu, 9 Jan 2020 21:29:16 -0500 Subject: [PATCH 230/371] Creates new selectors that are more consistent with the rest of the redux selectors for claims --- src/redux/selectors/comments.js | 37 +++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/src/redux/selectors/comments.js b/src/redux/selectors/comments.js index c391a5c..048e7f2 100644 --- a/src/redux/selectors/comments.js +++ b/src/redux/selectors/comments.js @@ -5,9 +5,37 @@ const selectState = state => state.comments || {}; export const selectCommentsById = createSelector( selectState, - state => state.byId || {} + state => state.commentById || {} ); +export const selectCommentsByClaimId = createSelector( + selectState, + selectCommentsById, + (state, byId) => { + const byClaimId = state.byId || {}; + const comments = {}; + + // for every claimId -> commentId, put comments in the object + Object.keys(byClaimId).forEach(claimId => { + // get all the commentIds that commented on this ClaimId + const commentIds = byClaimId[claimId]; + + // map a new array of comments by the claimId + comments[claimId] = Array(commentIds === null ? 0 : commentIds.length); + for (let i = 0; i < commentIds.length; i++) { + comments[claimId][i] = byId[commentIds[i]]; + } + }); + + return comments; + } +); + +// previously this used a mapping from claimId -> Array +/* export const selectCommentsById = createSelector( + selectState, + state => state.byId || {} +); */ export const selectCommentsByUri = createSelector( selectState, state => { @@ -21,16 +49,17 @@ export const selectCommentsByUri = createSelector( comments[uri] = claimId; } }); + return comments; } ); export const makeSelectCommentsForUri = (uri: string) => createSelector( - selectCommentsById, + selectCommentsByClaimId, selectCommentsByUri, - (byId, byUri) => { + (byClaimId, byUri) => { const claimId = byUri[uri]; - return byId && byId[claimId]; + return byClaimId && byClaimId[claimId]; } ); -- 2.45.2 From ff9493f33494ddd9b69a7f95a04ac14919990dc8 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Thu, 9 Jan 2020 21:29:54 -0500 Subject: [PATCH 231/371] Reflect changes in dist code --- dist/bundle.es.js | 132 ++++++++++++++++++++++++++++++++----- dist/flow-typed/Comment.js | 32 +++++---- dist/flow-typed/Lbry.js | 12 ++++ 3 files changed, 145 insertions(+), 31 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index da208a5..e8b420a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -134,6 +134,15 @@ const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED'; const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; +const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; +const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; +const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; +const COMMENT_EDIT_STARTED = 'COMMENT_EDIT_STARTED'; +const COMMENT_EDIT_COMPLETED = 'COMMENT_EDIT_COMPLETED'; +const COMMENT_EDIT_FAILED = 'COMMENT_EDIT_FAILED'; +const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; +const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; +const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; // Files const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; @@ -380,12 +389,12 @@ var action_types = /*#__PURE__*/Object.freeze({ COMMENT_ABANDON_STARTED: COMMENT_ABANDON_STARTED, COMMENT_ABANDON_COMPLETED: COMMENT_ABANDON_COMPLETED, COMMENT_ABANDON_FAILED: COMMENT_ABANDON_FAILED, - COMMENT_HIDE_STARTED: COMMENT_HIDE_STARTED, - COMMENT_HIDE_COMPLETED: COMMENT_HIDE_COMPLETED, - COMMENT_HIDE_FAILED: COMMENT_HIDE_FAILED, COMMENT_EDIT_STARTED: COMMENT_EDIT_STARTED, COMMENT_EDIT_COMPLETED: COMMENT_EDIT_COMPLETED, COMMENT_EDIT_FAILED: COMMENT_EDIT_FAILED, + COMMENT_HIDE_STARTED: COMMENT_HIDE_STARTED, + COMMENT_HIDE_COMPLETED: COMMENT_HIDE_COMPLETED, + COMMENT_HIDE_FAILED: COMMENT_HIDE_FAILED, FILE_LIST_STARTED: FILE_LIST_STARTED, FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, @@ -925,6 +934,11 @@ const Lbry = { // Comments comment_list: (params = {}) => daemonCallWithResult('comment_list', params), comment_create: (params = {}) => daemonCallWithResult('comment_create', params), + // todo: implement these in reducers + comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), + comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), + comment_edit: (params = {}) => daemonCallWithResult('comment_hide', params), + // Connect to the sdk connect: () => { if (Lbry.connectPromise === null) { @@ -1232,6 +1246,18 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; + { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } + } + if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -4104,9 +4130,10 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { const namedChannelClaim = myChannels && myChannels.find(myChannel => myChannel.name === channel); const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null; return lbryProxy.comment_create({ - comment, - claim_id, - channel_id + comment: comment, + claim_id: claim_id, + channel_id: channel_id, + parent_id: parent_id }).then(result => { dispatch({ type: COMMENT_CREATE_COMPLETED, @@ -4542,9 +4569,11 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action var _extends$7 = 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; }; const defaultState$1 = { - byId: {}, - commentsByUri: {}, - isLoading: false + commentById: {}, // commentId -> Comment + byId: {}, // ClaimID -> list of comments + commentsByUri: {}, // URI -> claimId + isLoading: false, + myComments: undefined }; const commentReducer = handleActions({ @@ -4558,15 +4587,22 @@ const commentReducer = handleActions({ [COMMENT_CREATE_COMPLETED]: (state, action) => { const { comment, claimId } = action.data; + const commentById = Object.assign({}, state.commentById); const byId = Object.assign({}, state.byId); const comments = byId[claimId]; - const newComments = comments.slice(); + const newCommentIds = comments.slice(); - newComments.unshift(comment); - byId[claimId] = newComments; + // add the comment by its ID + commentById[comment.comment_id] = comment; + + // push the comment_id to the top of ID list + newCommentIds.unshift(comment.comment_id); + byId[claimId] = newCommentIds; return _extends$7({}, state, { - byId + commentById, + byId, + isLoading: false }); }, @@ -4574,15 +4610,25 @@ const commentReducer = handleActions({ [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; + + const commentById = Object.assign({}, state.commentById); const byId = Object.assign({}, state.byId); const commentsByUri = Object.assign({}, state.commentsByUri); if (comments) { - byId[claimId] = comments; + const commentIds = Array(comments.length); + // map the comment_ids to the new comments + for (let i = 0; i < comments.length; i++) { + commentIds[i] = comments[i].comment_id; + commentById[commentIds[i]] = comments[i]; + } + + byId[claimId] = commentIds; commentsByUri[uri] = claimId; } return _extends$7({}, state, { byId, + commentById, commentsByUri, isLoading: false }); @@ -4590,6 +4636,33 @@ const commentReducer = handleActions({ [COMMENT_LIST_FAILED]: (state, action) => _extends$7({}, state, { isLoading: false + }), + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$7({}, state, { + isLoading: true + }), + [COMMENT_ABANDON_COMPLETED]: (state, action) => _extends$7({}, state, { + isLoading: false + }), + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$7({}, state, { + isLoading: false + }), + [COMMENT_EDIT_STARTED]: (state, action) => _extends$7({}, state, { + isLoading: true + }), + [COMMENT_EDIT_COMPLETED]: (state, action) => _extends$7({}, state, { + isLoading: false + }), + [COMMENT_EDIT_FAILED]: (state, action) => _extends$7({}, state, { + isLoading: false + }), + [COMMENT_HIDE_STARTED]: (state, action) => _extends$7({}, state, { + isLoading: true + }), + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$7({}, state, { + isLoading: false + }), + [COMMENT_HIDE_FAILED]: (state, action) => _extends$7({}, state, { + isLoading: false }) }, defaultState$1); @@ -5470,8 +5543,32 @@ const selectError = reselect.createSelector(selectState$7, state => { const selectState$8 = state => state.comments || {}; -const selectCommentsById = reselect.createSelector(selectState$8, state => state.byId || {}); +const selectCommentsById = reselect.createSelector(selectState$8, state => state.commentById || {}); +const selectCommentsByClaimId = reselect.createSelector(selectState$8, selectCommentsById, (state, byId) => { + const byClaimId = state.byId || {}; + const comments = {}; + + // for every claimId -> commentId, put comments in the object + Object.keys(byClaimId).forEach(claimId => { + // get all the commentIds that commented on this ClaimId + const commentIds = byClaimId[claimId]; + + // map a new array of comments by the claimId + comments[claimId] = Array(commentIds === null ? 0 : commentIds.length); + for (let i = 0; i < commentIds.length; i++) { + comments[claimId][i] = byId[commentIds[i]]; + } + }); + + return comments; +}); + +// previously this used a mapping from claimId -> Array +/* export const selectCommentsById = createSelector( + selectState, + state => state.byId || {} +); */ const selectCommentsByUri = reselect.createSelector(selectState$8, state => { const byUri = state.commentsByUri || {}; const comments = {}; @@ -5483,12 +5580,13 @@ const selectCommentsByUri = reselect.createSelector(selectState$8, state => { comments[uri] = claimId; } }); + return comments; }); -const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsById, selectCommentsByUri, (byId, byUri) => { +const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsByClaimId, selectCommentsByUri, (byClaimId, byUri) => { const claimId = byUri[uri]; - return byId && byId[claimId]; + return byClaimId && byClaimId[claimId]; }); // diff --git a/dist/flow-typed/Comment.js b/dist/flow-typed/Comment.js index f2f35b7..64ea974 100644 --- a/dist/flow-typed/Comment.js +++ b/dist/flow-typed/Comment.js @@ -1,19 +1,23 @@ declare type Comment = { - author?: string, - author_url?: string, - claim_index?: number, - comment_id?: number, - downvotes?: number, - message: string, - omitted?: number, - reply_count?: number, - time_posted?: number, - upvotes?: number, - parent_id?: number, + comment: string, // comment body + comment_id: string, // sha256 digest + claim_id: string, // id linking to the claim this comment + timestamp: number, // integer representing unix-time + is_hidden: boolean, // claim owner may enable/disable this + channel_id?: string, // claimId of channel signing this comment + channel_name?: string, // name of channel claim + channel_url?: string, // full lbry url to signing channel + signature?: string, // signature of comment by originating channel + signing_ts?: string, // timestamp used when signing this comment + is_channel_signature_valid?: boolean, // whether or not the signature could be validated + parent_id?: number, // comment_id of comment this is in reply to }; +// todo: relate individual comments to their commentId declare type CommentsState = { - byId: {}, - isLoading: boolean, commentsByUri: { [string]: string }, -} + byId: { [string]: Array }, + commentById: { [string]: Comment }, + isLoading: boolean, + myComments: ?Set, +}; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index cc8a4ac..92ce9dd 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -125,6 +125,8 @@ declare type ChannelUpdateResponse = GenericTxResponse & { }; declare type CommentCreateResponse = Comment; +declare type CommentEditResponse = Comment; + declare type CommentListResponse = { items: Array, page: number, @@ -133,6 +135,16 @@ declare type CommentListResponse = { total_pages: number, }; +declare type CommentHideResponse = { + // keyed by the CommentIds entered + [string]: { hidden: boolean }, +}; + +declare type CommentAbandonResponse = { + // keyed by the CommentId given + [string]: { abandoned: boolean }, +}; + declare type ChannelListResponse = { items: Array, page: number, -- 2.45.2 From 24707eea5b8c5095edf0ba981c3220fedb5bcb41 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Mon, 13 Jan 2020 11:53:35 -0500 Subject: [PATCH 232/371] fix type on parent_id param --- src/redux/actions/comments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 64b5344..a56b5a1 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -43,7 +43,7 @@ export function doCommentCreate( comment: string = '', claim_id: string = '', channel: ?string, - parent_id?: number + parent_id?: string, ) { return (dispatch: Dispatch, getState: GetState) => { const state = getState(); -- 2.45.2 From 13cd56dabccfb359913786687a2d79f4cdf88fec Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Mon, 13 Jan 2020 16:52:23 -0500 Subject: [PATCH 233/371] "comment edit" -> "comment update" --- flow-typed/Lbry.js | 2 +- src/constants/action_types.js | 6 ++-- src/lbry.js | 4 +-- src/redux/reducers/comments.js | 65 +++++++++++++++++++++++++++------- 4 files changed, 59 insertions(+), 18 deletions(-) diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 92ce9dd..8afe66f 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -125,7 +125,7 @@ declare type ChannelUpdateResponse = GenericTxResponse & { }; declare type CommentCreateResponse = Comment; -declare type CommentEditResponse = Comment; +declare type CommentUpdateResponse = Comment; declare type CommentListResponse = { items: Array, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 097b2cd..0c31338 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -114,9 +114,9 @@ export const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; export const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; export const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; export const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; -export const COMMENT_EDIT_STARTED = 'COMMENT_EDIT_STARTED'; -export const COMMENT_EDIT_COMPLETED = 'COMMENT_EDIT_COMPLETED'; -export const COMMENT_EDIT_FAILED = 'COMMENT_EDIT_FAILED'; +export const COMMENT_UPDATE_STARTED = 'COMMENT_UPDATE_STARTED'; +export const COMMENT_UPDATE_COMPLETED = 'COMMENT_UPDATE_COMPLETED'; +export const COMMENT_UPDATE_FAILED = 'COMMENT_UPDATE_FAILED'; export const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; export const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; export const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; diff --git a/src/lbry.js b/src/lbry.js index 9fdd033..f6cc88c 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -119,10 +119,10 @@ const Lbry: LbryTypes = { // Comments comment_list: (params = {}) => daemonCallWithResult('comment_list', params), comment_create: (params = {}) => daemonCallWithResult('comment_create', params), - // todo: implement these in reducers comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), - comment_edit: (params = {}) => daemonCallWithResult('comment_hide', params), + // requires SDK ver. 0.53.0 + comment_update: (params = {}) => daemonCallWithResult('comment_update', params), // Connect to the sdk connect: () => { diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js index 0513625..8876b0e 100644 --- a/src/redux/reducers/comments.js +++ b/src/redux/reducers/comments.js @@ -23,7 +23,7 @@ export const commentReducer = handleActions( }), [ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => { - const { comment, claimId }: any = action.data; + const { comment, claimId }: { comment: Comment, claimId: string } = action.data; const commentById = Object.assign({}, state.commentById); const byId = Object.assign({}, state.byId); const comments = byId[claimId]; @@ -54,7 +54,11 @@ export const commentReducer = handleActions( const commentsByUri = Object.assign({}, state.commentsByUri); if (comments) { + // we use an Array to preserve order of listing + // in reality this doesn't matter and we can just + // sort comments by their timestamp const commentIds = Array(comments.length); + // map the comment_ids to the new comments for (let i = 0; i < comments.length; i++) { commentIds[i] = comments[i].comment_id; @@ -81,34 +85,71 @@ export const commentReducer = handleActions( ...state, isLoading: true, }), - [ACTIONS.COMMENT_ABANDON_COMPLETED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: false, - }), + // remove the existing comment from the id -> comment list and claim -> commentIds + [ACTIONS.COMMENT_ABANDON_COMPLETED]: (state: CommentsState, action: any) => { + const { comment_id, abandoned } = action.data; + const commentById = Object.assign({}, state.commentById); + const byId = Object.assign({}, state.byId); + + if (abandoned && comment_id in abandoned) { + // messy but necessary for the time being + const comment: Comment = commentById[comment_id]; + const commentIds = byId[comment.claim_id]; + byId[comment.claim_id] = commentIds.filter(commentId => commentId !== comment_id); + + Object.keys(commentById).forEach(commentId => { + if (commentId === comment_id) { + delete commentById[commentId]; + } + }); + } + return { + ...state, + commentById, + byId, + isLoading: false, + }; + }, + // do nothing [ACTIONS.COMMENT_ABANDON_FAILED]: (state: CommentsState, action: any) => ({ ...state, isLoading: false, }), - [ACTIONS.COMMENT_EDIT_STARTED]: (state: CommentsState, action: any) => ({ + // do nothing + [ACTIONS.COMMENT_UPDATE_STARTED]: (state: CommentsState, action: any) => ({ ...state, isLoading: true, }), - [ACTIONS.COMMENT_EDIT_COMPLETED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: false, - }), - [ACTIONS.COMMENT_EDIT_FAILED]: (state: CommentsState, action: any) => ({ + // replace existing comment with comment returned here under its comment_id + [ACTIONS.COMMENT_UPDATE_COMPLETED]: (state: CommentsState, action: any) => { + const { comment } = action.data; + const commentById = Object.assign({}, state.commentById); + + if (comment) { + commentById[comment.comment_id] = comment; + } + + return { + ...state, + commentById, + isLoading: false, + }; + }, + // nothing can be done here + [ACTIONS.COMMENT_UPDATE_FAILED]: (state: CommentsState, action: any) => ({ ...state, isLoading: false, }), + // nothing can really be done here [ACTIONS.COMMENT_HIDE_STARTED]: (state: CommentsState, action: any) => ({ ...state, isLoading: true, }), [ACTIONS.COMMENT_HIDE_COMPLETED]: (state: CommentsState, action: any) => ({ - ...state, + ...state, // todo: add HiddenComments state & create selectors isLoading: false, }), + // nothing can be done here [ACTIONS.COMMENT_HIDE_FAILED]: (state: CommentsState, action: any) => ({ ...state, isLoading: false, -- 2.45.2 From c0db949a53dee4b06acfcc96d7f2a874d3f6e468 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Mon, 13 Jan 2020 16:55:28 -0500 Subject: [PATCH 234/371] lint --- src/constants/shared_preferences.js | 12 ++++---- src/redux/actions/content.js | 3 +- src/redux/actions/sync.js | 7 +++-- src/redux/reducers/blocked.js | 3 +- src/redux/reducers/claims.js | 3 +- src/redux/selectors/content.js | 19 +++++++----- src/redux/selectors/notifications.js | 44 ++++++++++++++++------------ 7 files changed, 53 insertions(+), 38 deletions(-) diff --git a/src/constants/shared_preferences.js b/src/constants/shared_preferences.js index 56faf8f..e508e83 100644 --- a/src/constants/shared_preferences.js +++ b/src/constants/shared_preferences.js @@ -1,10 +1,10 @@ /* -* How to use this file: -* Settings exported from here will trigger the setting to be -* sent to the preference middleware when set using the -* usual setDaemonSettings and clearDaemonSettings methods. -* -* See redux/settings/actions in the app for where this is used. + * How to use this file: + * Settings exported from here will trigger the setting to be + * sent to the preference middleware when set using the + * usual setDaemonSettings and clearDaemonSettings methods. + * + * See redux/settings/actions in the app for where this is used. */ import * as DAEMON_SETTINGS from './daemon_settings'; diff --git a/src/redux/actions/content.js b/src/redux/actions/content.js index fff0f11..2654f74 100644 --- a/src/redux/actions/content.js +++ b/src/redux/actions/content.js @@ -1,7 +1,8 @@ +// @flow import * as ACTIONS from 'constants/action_types'; export function savePosition(claimId: string, outpoint: string, position: number) { - return dispatch => { + return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.SET_CONTENT_POSITION, data: { claimId, outpoint, position }, diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 41a25ea..7f80d33 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -14,7 +14,7 @@ type SharedData = { function extractUserState(rawObj: SharedData) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blocked, settings} = rawObj.value; + const { subscriptions, tags, blocked, settings } = rawObj.value; return { ...(subscriptions ? { subscriptions } : {}), @@ -30,7 +30,10 @@ function extractUserState(rawObj: SharedData) { export function doPopulateSharedUserState(sharedSettings: any) { return (dispatch: Dispatch) => { const { subscriptions, tags, blocked, settings } = extractUserState(sharedSettings); - dispatch({ type: ACTIONS.USER_STATE_POPULATE, data: { subscriptions, tags, blocked, settings } }); + dispatch({ + type: ACTIONS.USER_STATE_POPULATE, + data: { subscriptions, tags, blocked, settings }, + }); }; } diff --git a/src/redux/reducers/blocked.js b/src/redux/reducers/blocked.js index b69d9c9..c688936 100644 --- a/src/redux/reducers/blocked.js +++ b/src/redux/reducers/blocked.js @@ -33,8 +33,7 @@ export const blockedReducer = handleActions( const { blocked } = action.data; return { ...state, - blockedChannels: - blocked && blocked.length ? blocked : state.blockedChannels, + blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels, }; }, }, diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 8e6b121..56a4383 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -265,7 +265,8 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): const paginatedClaimsByChannel = Object.assign({}, state.paginatedClaimsByChannel); // check if count has changed - that means cached pagination will be wrong, so clear it const previousCount = paginatedClaimsByChannel[uri] && paginatedClaimsByChannel[uri]['itemCount']; - const byChannel = (claimsInChannel === previousCount) ? Object.assign({}, paginatedClaimsByChannel[uri]) : {}; + const byChannel = + claimsInChannel === previousCount ? Object.assign({}, paginatedClaimsByChannel[uri]) : {}; const allClaimIds = new Set(byChannel.all); const currentPageClaimIds = []; const byId = Object.assign({}, state.byId); diff --git a/src/redux/selectors/content.js b/src/redux/selectors/content.js index f494fab..2daac6e 100644 --- a/src/redux/selectors/content.js +++ b/src/redux/selectors/content.js @@ -1,14 +1,19 @@ +// @flow import { createSelector } from 'reselect'; import { makeSelectClaimForUri } from 'redux/selectors/claims'; export const selectState = (state: any) => state.content || {}; export const makeSelectContentPositionForUri = (uri: string) => - createSelector(selectState, makeSelectClaimForUri(uri), (state, claim) => { - if (!claim) { - return null; + createSelector( + selectState, + makeSelectClaimForUri(uri), + (state, claim) => { + if (!claim) { + return null; + } + const outpoint = `${claim.txid}:${claim.nout}`; + const id = claim.claim_id; + return state.positions[id] ? state.positions[id][outpoint] : null; } - const outpoint = `${claim.txid}:${claim.nout}`; - const id = claim.claim_id; - return state.positions[id] ? state.positions[id][outpoint] : null; - }); + ); diff --git a/src/redux/selectors/notifications.js b/src/redux/selectors/notifications.js index 00844be..8894442 100644 --- a/src/redux/selectors/notifications.js +++ b/src/redux/selectors/notifications.js @@ -1,26 +1,32 @@ import { createSelector } from 'reselect'; -export const selectState = (state) => state.notifications || {}; +export const selectState = state => state.notifications || {}; -export const selectToast = createSelector(selectState, (state) => { - if (state.toasts.length) { - const { id, params } = state.toasts[0]; - return { - id, - ...params, - }; +export const selectToast = createSelector( + selectState, + state => { + if (state.toasts.length) { + const { id, params } = state.toasts[0]; + return { + id, + ...params, + }; + } + + return null; } +); - return null; -}); +export const selectError = createSelector( + selectState, + state => { + if (state.errors.length) { + const { error } = state.errors[0]; + return { + error, + }; + } -export const selectError = createSelector(selectState, (state) => { - if (state.errors.length) { - const { error } = state.errors[0]; - return { - error, - }; + return null; } - - return null; -}); +); -- 2.45.2 From 2bdbf3d645baabaf59fdaf08c7cf735118cead24 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Mon, 13 Jan 2020 17:00:04 -0500 Subject: [PATCH 235/371] Implements reducers for COMMENT_UPDATE, COMMENT_HIDE, and COMMENT_ABANDON --- dist/bundle.es.js | 194 +++++++++++++++++++++++++++------- dist/flow-typed/Lbry.js | 6 +- flow-typed/Lbry.js | 4 + src/index.js | 8 +- src/redux/actions/comments.js | 99 ++++++++++++++++- 5 files changed, 271 insertions(+), 40 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e8b420a..9e3c5e6 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -137,9 +137,9 @@ const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; -const COMMENT_EDIT_STARTED = 'COMMENT_EDIT_STARTED'; -const COMMENT_EDIT_COMPLETED = 'COMMENT_EDIT_COMPLETED'; -const COMMENT_EDIT_FAILED = 'COMMENT_EDIT_FAILED'; +const COMMENT_UPDATE_STARTED = 'COMMENT_UPDATE_STARTED'; +const COMMENT_UPDATE_COMPLETED = 'COMMENT_UPDATE_COMPLETED'; +const COMMENT_UPDATE_FAILED = 'COMMENT_UPDATE_FAILED'; const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; @@ -389,9 +389,9 @@ var action_types = /*#__PURE__*/Object.freeze({ COMMENT_ABANDON_STARTED: COMMENT_ABANDON_STARTED, COMMENT_ABANDON_COMPLETED: COMMENT_ABANDON_COMPLETED, COMMENT_ABANDON_FAILED: COMMENT_ABANDON_FAILED, - COMMENT_EDIT_STARTED: COMMENT_EDIT_STARTED, - COMMENT_EDIT_COMPLETED: COMMENT_EDIT_COMPLETED, - COMMENT_EDIT_FAILED: COMMENT_EDIT_FAILED, + COMMENT_UPDATE_STARTED: COMMENT_UPDATE_STARTED, + COMMENT_UPDATE_COMPLETED: COMMENT_UPDATE_COMPLETED, + COMMENT_UPDATE_FAILED: COMMENT_UPDATE_FAILED, COMMENT_HIDE_STARTED: COMMENT_HIDE_STARTED, COMMENT_HIDE_COMPLETED: COMMENT_HIDE_COMPLETED, COMMENT_HIDE_FAILED: COMMENT_HIDE_FAILED, @@ -783,12 +783,12 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ }); /* -* How to use this file: -* Settings exported from here will trigger the setting to be -* sent to the preference middleware when set using the -* usual setDaemonSettings and clearDaemonSettings methods. -* -* See redux/settings/actions in the app for where this is used. + * How to use this file: + * Settings exported from here will trigger the setting to be + * sent to the preference middleware when set using the + * usual setDaemonSettings and clearDaemonSettings methods. + * + * See redux/settings/actions in the app for where this is used. */ const WALLET_SERVERS = LBRYUM_SERVERS; @@ -934,10 +934,10 @@ const Lbry = { // Comments comment_list: (params = {}) => daemonCallWithResult('comment_list', params), comment_create: (params = {}) => daemonCallWithResult('comment_create', params), - // todo: implement these in reducers comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), - comment_edit: (params = {}) => daemonCallWithResult('comment_hide', params), + // requires SDK ver. 0.53.0 + comment_update: (params = {}) => daemonCallWithResult('comment_update', params), // Connect to the sdk connect: () => { @@ -1246,18 +1246,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -1570,7 +1558,10 @@ function extractUserState(rawObj) { function doPopulateSharedUserState(sharedSettings) { return dispatch => { const { subscriptions, tags, blocked, settings } = extractUserState(sharedSettings); - dispatch({ type: USER_STATE_POPULATE, data: { subscriptions, tags, blocked, settings } }); + dispatch({ + type: USER_STATE_POPULATE, + data: { subscriptions, tags, blocked, settings } + }); }; } @@ -4053,6 +4044,8 @@ const doUpdateSearchOptions = newOptions => (dispatch, getState) => { } }; +// + function savePosition(claimId, outpoint, position) { return dispatch => { dispatch({ @@ -4155,6 +4148,89 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { }; } +function doCommentHide(comment_id) { + return dispatch => { + dispatch({ + type: COMMENT_HIDE_STARTED + }); + return lbryProxy.comment_hide({ + comment_ids: [comment_id] + }).then(result => { + dispatch({ + type: COMMENT_HIDE_COMPLETED, + data: result + }); + }).catch(error => { + dispatch({ + type: COMMENT_HIDE_FAILED, + data: error + }); + dispatch(doToast({ + message: `SDK Errored when trying to hide Comment with comment_id: "${comment_id}"`, + isError: true + })); + }); + }; +} + +function doCommentAbandon(comment_id) { + return dispatch => { + dispatch({ + type: COMMENT_ABANDON_STARTED + }); + return lbryProxy.comment_abandon({ + comment_id: comment_id + }).then(result => { + dispatch({ + type: COMMENT_ABANDON_COMPLETED, + data: { + comment_id: comment_id, + abandoned: result + } + }); + }).catch(error => { + dispatch({ + type: COMMENT_ABANDON_FAILED, + data: error + }); + dispatch(doToast({ + message: `SDK Errored during abandon on Comment w/ ID = "${comment_id}"`, + isError: true + })); + }); + }; +} + +function doCommentUpdate(comment_id, comment) { + // if they provided an empty string, they must have wanted to abandon + if (comment === '') { + return doCommentAbandon(comment_id); + } else { + return dispatch => { + dispatch({ + type: COMMENT_UPDATE_STARTED + }); + return lbryProxy.comment_update({ + comment_id: comment_id, + comment: comment + }).then(result => { + dispatch({ + type: COMMENT_UPDATE_COMPLETED, + data: { + comment: result + } + }); + }).catch(error => { + dispatch({ type: COMMENT_UPDATE_FAILED, data: error }); + dispatch(doToast({ + message: `SDK Errored during update on Comment w/ ID = ${comment_id}`, + isError: true + })); + }); + }; + } +} + // const doToggleBlockChannel = uri => ({ @@ -4616,7 +4692,11 @@ const commentReducer = handleActions({ const commentsByUri = Object.assign({}, state.commentsByUri); if (comments) { + // we use an Array to preserve order of listing + // in reality this doesn't matter and we can just + // sort comments by their timestamp const commentIds = Array(comments.length); + // map the comment_ids to the new comments for (let i = 0; i < comments.length; i++) { commentIds[i] = comments[i].comment_id; @@ -4640,27 +4720,64 @@ const commentReducer = handleActions({ [COMMENT_ABANDON_STARTED]: (state, action) => _extends$7({}, state, { isLoading: true }), - [COMMENT_ABANDON_COMPLETED]: (state, action) => _extends$7({}, state, { - isLoading: false - }), + // remove the existing comment from the id -> comment list and claim -> commentIds + [COMMENT_ABANDON_COMPLETED]: (state, action) => { + const { comment_id, abandoned } = action.data; + const commentById = Object.assign({}, state.commentById); + const byId = Object.assign({}, state.byId); + + if (abandoned && comment_id in abandoned) { + // messy but necessary for the time being + const comment = commentById[comment_id]; + const commentIds = byId[comment.claim_id]; + byId[comment.claim_id] = commentIds.filter(commentId => commentId !== comment_id); + + Object.keys(commentById).forEach(commentId => { + if (commentId === comment_id) { + delete commentById[commentId]; + } + }); + } + return _extends$7({}, state, { + commentById, + byId, + isLoading: false + }); + }, + // do nothing [COMMENT_ABANDON_FAILED]: (state, action) => _extends$7({}, state, { isLoading: false }), - [COMMENT_EDIT_STARTED]: (state, action) => _extends$7({}, state, { + // do nothing + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$7({}, state, { isLoading: true }), - [COMMENT_EDIT_COMPLETED]: (state, action) => _extends$7({}, state, { - isLoading: false - }), - [COMMENT_EDIT_FAILED]: (state, action) => _extends$7({}, state, { + // replace existing comment with comment returned here under its comment_id + [COMMENT_UPDATE_COMPLETED]: (state, action) => { + const { comment } = action.data; + const commentById = Object.assign({}, state.commentById); + + if (comment) { + commentById[comment.comment_id] = comment; + } + + return _extends$7({}, state, { + commentById, + isLoading: false + }); + }, + // nothing can be done here + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$7({}, state, { isLoading: false }), + // nothing can really be done here [COMMENT_HIDE_STARTED]: (state, action) => _extends$7({}, state, { isLoading: true }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$7({}, state, { + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$7({}, state, { // todo: add HiddenComments state & create selectors isLoading: false }), + // nothing can be done here [COMMENT_HIDE_FAILED]: (state, action) => _extends$7({}, state, { isLoading: false }) @@ -5502,6 +5619,8 @@ const walletReducer = handleActions({ }) }, defaultState$a); +// + const selectState$6 = state => state.content || {}; const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$6, makeSelectClaimForUri(uri), (state, claim) => { @@ -5666,8 +5785,11 @@ exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doClaimSearch = doClaimSearch; exports.doClearPublish = doClearPublish; exports.doClearSupport = doClearSupport; +exports.doCommentAbandon = doCommentAbandon; exports.doCommentCreate = doCommentCreate; +exports.doCommentHide = doCommentHide; exports.doCommentList = doCommentList; +exports.doCommentUpdate = doCommentUpdate; exports.doCreateChannel = doCreateChannel; exports.doDeletePurchasedUri = doDeletePurchasedUri; exports.doDeleteTag = doDeleteTag; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 92ce9dd..408beb0 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -125,7 +125,7 @@ declare type ChannelUpdateResponse = GenericTxResponse & { }; declare type CommentCreateResponse = Comment; -declare type CommentEditResponse = Comment; +declare type CommentUpdateResponse = Comment; declare type CommentListResponse = { items: Array, @@ -254,6 +254,10 @@ declare type LbryTypes = { // Commenting comment_list: (params: {}) => Promise, comment_create: (params: {}) => Promise, + comment_update: (params: {}) => Promise, + comment_hide: (params: {}) => Promise, + comment_abandon: (params: {}) => Promise, + // Wallet utilities wallet_balance: (params: {}) => Promise, wallet_decrypt: (prams: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 8afe66f..408beb0 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -254,6 +254,10 @@ declare type LbryTypes = { // Commenting comment_list: (params: {}) => Promise, comment_create: (params: {}) => Promise, + comment_update: (params: {}) => Promise, + comment_hide: (params: {}) => Promise, + comment_abandon: (params: {}) => Promise, + // Wallet utilities wallet_balance: (params: {}) => Promise, wallet_decrypt: (prams: {}) => Promise, diff --git a/src/index.js b/src/index.js index 65f1db9..98c6e8a 100644 --- a/src/index.js +++ b/src/index.js @@ -121,7 +121,13 @@ export { export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; -export { doCommentList, doCommentCreate } from 'redux/actions/comments'; +export { + doCommentList, + doCommentCreate, + doCommentAbandon, + doCommentHide, + doCommentUpdate, +} from 'redux/actions/comments'; export { doToggleBlockChannel } from 'redux/actions/blocked'; diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index a56b5a1..48f4bad 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -43,7 +43,7 @@ export function doCommentCreate( comment: string = '', claim_id: string = '', channel: ?string, - parent_id?: string, + parent_id?: string ) { return (dispatch: Dispatch, getState: GetState) => { const state = getState(); @@ -60,7 +60,7 @@ export function doCommentCreate( channel_id: channel_id, parent_id: parent_id, }) - .then((result: Comment) => { + .then((result: CommentCreateResponse) => { dispatch({ type: ACTIONS.COMMENT_CREATE_COMPLETED, data: { @@ -83,3 +83,98 @@ export function doCommentCreate( }); }; } + +export function doCommentHide(comment_id: string) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.COMMENT_HIDE_STARTED, + }); + return Lbry.comment_hide({ + comment_ids: [comment_id], + }) + .then((result: CommentHideResponse) => { + dispatch({ + type: ACTIONS.COMMENT_HIDE_COMPLETED, + data: result, + }); + }) + .catch(error => { + dispatch({ + type: ACTIONS.COMMENT_HIDE_FAILED, + data: error, + }); + dispatch( + doToast({ + message: `SDK Errored when trying to hide Comment with comment_id: "${comment_id}"`, + isError: true, + }) + ); + }); + }; +} + +export function doCommentAbandon(comment_id: string) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_STARTED, + }); + return Lbry.comment_abandon({ + comment_id: comment_id, + }) + .then((result: CommentAbandonResponse) => { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_COMPLETED, + data: { + comment_id: comment_id, + abandoned: result, + }, + }); + }) + .catch(error => { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_FAILED, + data: error, + }); + dispatch( + doToast({ + message: `SDK Errored during abandon on Comment w/ ID = "${comment_id}"`, + isError: true, + }) + ); + }); + }; +} + +export function doCommentUpdate(comment_id: string, comment: string) { + // if they provided an empty string, they must have wanted to abandon + if (comment === '') { + return doCommentAbandon(comment_id); + } else { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.COMMENT_UPDATE_STARTED, + }); + return Lbry.comment_update({ + comment_id: comment_id, + comment: comment, + }) + .then((result: CommentUpdateResponse) => { + dispatch({ + type: ACTIONS.COMMENT_UPDATE_COMPLETED, + data: { + comment: result, + }, + }); + }) + .catch(error => { + dispatch({ type: ACTIONS.COMMENT_UPDATE_FAILED, data: error }); + dispatch( + doToast({ + message: `SDK Errored during update on Comment w/ ID = ${comment_id}`, + isError: true, + }) + ); + }); + }; + } +} -- 2.45.2 From c30a8ec66c0d5692cc93ef8adeb95ba830c857f8 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Mon, 13 Jan 2020 17:04:41 -0500 Subject: [PATCH 236/371] Add todos --- src/redux/selectors/comments.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/redux/selectors/comments.js b/src/redux/selectors/comments.js index 048e7f2..86286ea 100644 --- a/src/redux/selectors/comments.js +++ b/src/redux/selectors/comments.js @@ -63,3 +63,6 @@ export const makeSelectCommentsForUri = (uri: string) => return byClaimId && byClaimId[claimId]; } ); + +// todo: allow SDK to retrieve user comments through comment_list +// todo: implement selectors for selecting comments owned by user -- 2.45.2 From d79b8ce2269951fdbc6d0040ae24f17bf9edf17d Mon Sep 17 00:00:00 2001 From: Yamboy1 Date: Wed, 15 Jan 2020 13:17:25 +1300 Subject: [PATCH 237/371] Fix wrong language when editing claim --- dist/bundle.es.js | 245 ++++++++++++++++++--------------- src/redux/reducers/publish.js | 2 +- src/redux/selectors/publish.js | 48 ++++--- 3 files changed, 164 insertions(+), 131 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 035f91c..4091541 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -803,7 +803,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['gaming', 'pop culture', 'Entertainment', 'technology', 'music', 'funny', 'Education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'sony interactive entertainment', 'film & animation', 'game', 'weapons', "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', 'ps4live', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'ps4share', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'xbox', 'autos & vehicles', 'Travel & Events', 'food', 'science', 'xbox one', 'liberal', 'democrat', 'progressive', 'survival', 'Nonprofits & Activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', "let's", 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox 360', 'animation', 'unboxing', 'money', 'how', 'travel', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'sony computer entertainment', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets & animals', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'grand theft auto v', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'gta 5', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'crypto news', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'fortnite battle royale', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'xbox360', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'Juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'action role-playing game', 'playthrough part', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing video game', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'Humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser']; +const DEFAULT_KNOWN_TAGS = ['gaming', 'pop culture', 'Entertainment', 'technology', 'music', 'funny', 'Education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'sony interactive entertainment', 'film & animation', 'game', 'weapons', "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', 'ps4live', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'ps4share', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'xbox', 'autos & vehicles', 'Travel & Events', 'food', 'science', 'xbox one', 'liberal', 'democrat', 'progressive', 'survival', 'Nonprofits & Activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', "let's", 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox 360', 'animation', 'unboxing', 'money', 'how', 'travel', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'sony computer entertainment', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets & animals', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'grand theft auto v', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'gta 5', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'crypto news', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'fortnite battle royale', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'xbox360', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'Juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'action role-playing game', 'playthrough part', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing video game', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'Humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry']; // @@ -1223,6 +1223,18 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; + { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } + } + if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -3425,18 +3437,14 @@ function doSetFileListSort(page, value) { }; } +var _extends$5 = 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$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 selectState$5 = state => state.publish || {}; -const selectPublishFormValues = reselect.createSelector(selectState$5, state => { - const formValues = _objectWithoutProperties$2(state, ['pendingPublish']); - return formValues; -}); -const makeSelectPublishFormValue = item => reselect.createSelector(selectState$5, state => state[item]); - // Is the current uri the same as the uri they clicked "edit" on -const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, publishState => { +const selectIsStillEditing = reselect.createSelector(selectState$5, publishState => { const { editingURI, uri } = publishState; if (!editingURI || !uri) { @@ -3461,6 +3469,21 @@ const selectIsStillEditing = reselect.createSelector(selectPublishFormValues, pu return currentName === editName; }); +const selectPublishFormValues = reselect.createSelector(selectState$5, selectIsStillEditing, (state, isStillEditing) => { + const { language, languages } = state; + const formValues = _objectWithoutProperties$2(state, ['pendingPublish']); + + let actualLanguage; + // Sets default if editing a claim with a set language + if (!language && isStillEditing && languages[0]) { + actualLanguage = languages[0]; + } else { + actualLanguage = language || 'en'; + } + return _extends$5({}, formValues, { language: actualLanguage }); +}); +const makeSelectPublishFormValue = item => reselect.createSelector(selectState$5, state => state[item]); + const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, selectIsStillEditing, selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => { const { channelName: contentName, streamName: claimName } = parseURI(uri); const { streamClaimId: editClaimId } = parseURI(editingURI); @@ -3512,7 +3535,7 @@ const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClai return null; }); -var _extends$5 = 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; }; +var _extends$6 = 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; }; const doResetThumbnailStatus = () => dispatch => { dispatch({ @@ -3550,7 +3573,7 @@ const doClearPublish = () => dispatch => { const doUpdatePublishForm = publishFormValue => dispatch => dispatch({ type: UPDATE_PUBLISH_FORM, - data: _extends$5({}, publishFormValue) + data: _extends$6({}, publishFormValue) }); const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => dispatch => { @@ -4128,7 +4151,7 @@ const doToggleBlockChannel = uri => ({ } }); -var _extends$6 = 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; }; +var _extends$7 = 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; }; const reducers = {}; const defaultState = { @@ -4231,7 +4254,7 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$6({}, handleClaimAction(state, action)); + return _extends$7({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -4402,7 +4425,7 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; -reducers[CREATE_CHANNEL_STARTED] = state => _extends$6({}, state, { +reducers[CREATE_CHANNEL_STARTED] = state => _extends$7({}, state, { creatingChannel: true, createChannelError: null }); @@ -4490,7 +4513,7 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { delete fetchingClaimSearchByQuery[query]; - return Object.assign({}, state, _extends$6({}, handleClaimAction(state, action), { + return Object.assign({}, state, _extends$7({}, handleClaimAction(state, action), { claimSearchByQuery, claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery @@ -4530,7 +4553,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -var _extends$7 = 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; }; +var _extends$8 = 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; }; const defaultState$1 = { byId: {}, @@ -4539,11 +4562,11 @@ const defaultState$1 = { }; const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$7({}, state, { + [COMMENT_CREATE_STARTED]: (state, action) => _extends$8({}, state, { isLoading: true }), - [COMMENT_CREATE_FAILED]: (state, action) => _extends$7({}, state, { + [COMMENT_CREATE_FAILED]: (state, action) => _extends$8({}, state, { isLoading: false }), @@ -4556,12 +4579,12 @@ const commentReducer = handleActions({ newComments.unshift(comment); byId[claimId] = newComments; - return _extends$7({}, state, { + return _extends$8({}, state, { byId }); }, - [COMMENT_LIST_STARTED]: state => _extends$7({}, state, { isLoading: true }), + [COMMENT_LIST_STARTED]: state => _extends$8({}, state, { isLoading: true }), [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; @@ -4572,19 +4595,19 @@ const commentReducer = handleActions({ byId[claimId] = comments; commentsByUri[uri] = claimId; } - return _extends$7({}, state, { + return _extends$8({}, state, { byId, commentsByUri, isLoading: false }); }, - [COMMENT_LIST_FAILED]: (state, action) => _extends$7({}, state, { + [COMMENT_LIST_FAILED]: (state, action) => _extends$8({}, state, { isLoading: false }) }, defaultState$1); -var _extends$8 = 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; }; +var _extends$9 = 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; }; const reducers$1 = {}; const defaultState$2 = { @@ -4593,9 +4616,9 @@ const defaultState$2 = { reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$8({}, state, { - positions: _extends$8({}, state.positions, { - [claimId]: _extends$8({}, state.positions[claimId], { + return _extends$9({}, state, { + positions: _extends$9({}, state.positions, { + [claimId]: _extends$9({}, state.positions[claimId], { [outpoint]: position }) }) @@ -4762,7 +4785,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -var _extends$9 = 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; }; +var _extends$a = 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; }; const reducers$3 = {}; const defaultState$4 = { @@ -4778,7 +4801,7 @@ reducers$3[PURCHASE_URI_STARTED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$9({}, state, { + return _extends$a({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: '' }); @@ -4796,7 +4819,7 @@ reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$9({}, state, { + return _extends$a({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, purchaseUriErrorMessage: '' @@ -4811,7 +4834,7 @@ reducers$3[PURCHASE_URI_FAILED] = (state, action) => { newFailedPurchaseUris.push(uri); } - return _extends$9({}, state, { + return _extends$a({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: error }); @@ -4824,7 +4847,7 @@ reducers$3[DELETE_PURCHASED_URI] = (state, action) => { newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); } - return _extends$9({}, state, { + return _extends$a({}, state, { purchasedUris: newPurchasedUris }); }; @@ -4835,7 +4858,7 @@ function fileReducer(state = defaultState$4, action) { return state; } -var _extends$a = 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; }; +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; }; const defaultState$5 = { notifications: [], @@ -4850,7 +4873,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$a({}, state, { + return _extends$b({}, state, { toasts: newToasts }); }, @@ -4858,7 +4881,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$a({}, state, { + return _extends$b({}, state, { toasts: newToasts }); }, @@ -4869,7 +4892,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$a({}, state, { + return _extends$b({}, state, { notifications: newNotifications }); }, @@ -4880,7 +4903,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$a({}, state, { + return _extends$b({}, state, { notifications }); }, @@ -4889,7 +4912,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$a({}, state, { + return _extends$b({}, state, { notifications: newNotifications }); }, @@ -4900,7 +4923,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$a({}, state, { + return _extends$b({}, state, { errors: newErrors }); }, @@ -4908,13 +4931,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$a({}, state, { + return _extends$b({}, state, { errors: newErrors }); } }, defaultState$5); -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; }; +var _extends$c = 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$3(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; } @@ -4931,7 +4954,7 @@ const defaultState$6 = { thumbnailPath: '', uploadThumbnailStatus: API_DOWN, description: '', - language: 'en', + language: '', nsfw: false, channel: CHANNEL_ANONYMOUS, channelId: '', @@ -4951,17 +4974,17 @@ const defaultState$6 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$b({}, state, data); + return _extends$c({}, state, data); }, - [CLEAR_PUBLISH]: () => _extends$b({}, defaultState$6), - [PUBLISH_START]: state => _extends$b({}, state, { + [CLEAR_PUBLISH]: () => _extends$c({}, defaultState$6), + [PUBLISH_START]: state => _extends$c({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$b({}, state, { + [PUBLISH_FAIL]: state => _extends$c({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$b({}, state, { + [PUBLISH_SUCCESS]: state => _extends$c({}, state, { publishing: false, publishSuccess: true }), @@ -4976,14 +4999,14 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$b({}, defaultState$6, publishData, { + return _extends$c({}, defaultState$6, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$6); -var _extends$c = 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; }; +var _extends$d = 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; }; const defaultState$7 = { isActive: false, // does the user have any typed text in the search input @@ -5003,29 +5026,29 @@ const defaultState$7 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$c({}, state, { + [SEARCH_START]: state => _extends$d({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$c({}, state, { + return _extends$d({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$c({}, state, { + [SEARCH_FAIL]: state => _extends$d({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$c({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$d({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$c({}, state, { - suggestions: _extends$c({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$d({}, state, { + suggestions: _extends$d({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -5033,30 +5056,30 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$c({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$d({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$c({}, state, { + [SEARCH_FOCUS]: state => _extends$d({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$c({}, state, { + [SEARCH_BLUR]: state => _extends$d({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$c({}, oldOptions, newOptions); - return _extends$c({}, state, { + const options = _extends$d({}, oldOptions, newOptions); + return _extends$d({}, state, { options }); } }, defaultState$7); -var _extends$d = 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; }; +var _extends$e = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$d({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$e({}, tagsMap, { [tag]: { name: tag } }), {}); } @@ -5079,7 +5102,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$d({}, state, { + return _extends$e({}, state, { followedTags: newFollowedTags }); }, @@ -5088,10 +5111,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$d({}, knownTags); + let newKnownTags = _extends$e({}, knownTags); newKnownTags[name] = { name }; - return _extends$d({}, state, { + return _extends$e({}, state, { knownTags: newKnownTags }); }, @@ -5100,24 +5123,24 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$d({}, knownTags); + let newKnownTags = _extends$e({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$d({}, state, { + return _extends$e({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); }, [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; - return _extends$d({}, state, { + return _extends$e({}, state, { followedTags: tags && tags.length ? tags : DEFAULT_FOLLOWED_TAGS }); } }, defaultState$8); -var _extends$e = 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; }; +var _extends$f = 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; }; const defaultState$9 = { blockedChannels: [] @@ -5141,13 +5164,13 @@ const blockedReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { blocked } = action.data; - return _extends$e({}, state, { + return _extends$f({}, state, { blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } }, defaultState$9); -var _extends$f = 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; }; +var _extends$g = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -5192,25 +5215,25 @@ const defaultState$a = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$f({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$g({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$f({}, state.transactions); + const byId = _extends$g({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$f({}, state, { + return _extends$g({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$f({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$g({}, state, { fetchingSupports: true }), @@ -5223,7 +5246,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$f({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$g({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -5232,7 +5255,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$f({}, state, { + return _extends$g({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -5245,23 +5268,23 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$f({}, state, { + return _extends$g({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$f({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$g({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$f({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$g({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$f({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$g({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -5270,32 +5293,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$f({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$g({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$f({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$g({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$f({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$g({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$f({}, state, { draftTransaction: newDraft }); + return _extends$g({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$f({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$g({}, oldDraft, { address: action.data.address }); - return _extends$f({}, state, { draftTransaction: newDraft }); + return _extends$g({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$f({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$g({}, state.draftTransaction, { sending: true }); - return _extends$f({}, state, { draftTransaction: newDraftTransaction }); + return _extends$g({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -5308,114 +5331,114 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$f({}, state, { draftTransaction: newDraftTransaction }); + return _extends$g({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$f({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$g({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$f({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$g({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$f({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$g({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$f({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$g({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$f({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$g({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$f({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$g({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$f({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$g({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$f({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$g({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$f({}, state, { + [WALLET_DECRYPT_START]: state => _extends$g({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$f({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$g({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$f({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$g({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$f({}, state, { + [WALLET_UNLOCK_START]: state => _extends$g({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$f({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$g({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$f({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$g({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$f({}, state, { + [WALLET_LOCK_START]: state => _extends$g({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$f({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$g({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$f({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$g({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$f({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$g({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$f({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$g({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$f({}, state, { + [WALLET_RESTART]: state => _extends$g({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$f({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$g({}, state, { walletReconnecting: false }) }, defaultState$a); @@ -5431,14 +5454,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$g = 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; }; +var _extends$h = 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; }; const selectState$7 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$7, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$g({ + return _extends$h({ id }, params); } diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js index 93ae3e5..19c5d7a 100644 --- a/src/redux/reducers/publish.js +++ b/src/redux/reducers/publish.js @@ -43,7 +43,7 @@ const defaultState: PublishState = { thumbnailPath: '', uploadThumbnailStatus: THUMBNAIL_STATUSES.API_DOWN, description: '', - language: 'en', + language: '', nsfw: false, channel: CHANNEL_ANONYMOUS, channelId: '', diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index ce0a20c..a4c6dd7 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -9,23 +9,9 @@ import { const selectState = state => state.publish || {}; -export const selectPublishFormValues = createSelector( - selectState, - state => { - const { pendingPublish, ...formValues } = state; - return formValues; - } -); - -export const makeSelectPublishFormValue = item => - createSelector( - selectState, - state => state[item] - ); - // Is the current uri the same as the uri they clicked "edit" on export const selectIsStillEditing = createSelector( - selectPublishFormValues, + selectState, publishState => { const { editingURI, uri } = publishState; @@ -52,6 +38,30 @@ export const selectIsStillEditing = createSelector( } ); +export const selectPublishFormValues = createSelector( + selectState, + selectIsStillEditing, + (state, isStillEditing) => { + const { language, languages } = state; + const { pendingPublish, ...formValues } = state; + + let actualLanguage; + // Sets default if editing a claim with a set language + if (!language && isStillEditing && languages[0]) { + actualLanguage = languages[0]; + } else { + actualLanguage = language || 'en'; + } + return { ...formValues, language: actualLanguage }; + } +); + +export const makeSelectPublishFormValue = item => + createSelector( + selectState, + state => state[item] + ); + export const selectMyClaimForUri = createSelector( selectPublishFormValues, selectIsStillEditing, @@ -68,10 +78,10 @@ export const selectMyClaimForUri = createSelector( return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => - !contentName - ? claim.name === claimName - : claim.name === contentName || claim.name === claimName - ); + !contentName + ? claim.name === claimName + : claim.name === contentName || claim.name === claimName + ); } ); -- 2.45.2 From 648fff0c6aca7035984dee33e0d71d43346bbbe9 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 16 Jan 2020 10:59:35 -0500 Subject: [PATCH 238/371] cleanup --- dist/bundle.es.js | 16 ++-------------- src/redux/selectors/publish.js | 3 +-- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4091541..6eb0bef 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1223,18 +1223,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -3470,8 +3458,8 @@ const selectIsStillEditing = reselect.createSelector(selectState$5, publishState }); const selectPublishFormValues = reselect.createSelector(selectState$5, selectIsStillEditing, (state, isStillEditing) => { - const { language, languages } = state; - const formValues = _objectWithoutProperties$2(state, ['pendingPublish']); + const { pendingPublish, language, languages } = state, + formValues = _objectWithoutProperties$2(state, ['pendingPublish', 'language', 'languages']); let actualLanguage; // Sets default if editing a claim with a set language diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index a4c6dd7..463bef3 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -42,8 +42,7 @@ export const selectPublishFormValues = createSelector( selectState, selectIsStillEditing, (state, isStillEditing) => { - const { language, languages } = state; - const { pendingPublish, ...formValues } = state; + const { pendingPublish, language, languages, ...formValues } = state; let actualLanguage; // Sets default if editing a claim with a set language -- 2.45.2 From 1a12e73c2cbc2d478d8ad0c0102dfef7b2154655 Mon Sep 17 00:00:00 2001 From: Yamboy1 Date: Sun, 19 Jan 2020 16:21:17 +1300 Subject: [PATCH 239/371] Remove assumption that a publish has a language --- src/redux/selectors/publish.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index 463bef3..10ed95b 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -46,7 +46,7 @@ export const selectPublishFormValues = createSelector( let actualLanguage; // Sets default if editing a claim with a set language - if (!language && isStillEditing && languages[0]) { + if (!language && isStillEditing && languages && languages[0]) { actualLanguage = languages[0]; } else { actualLanguage = language || 'en'; -- 2.45.2 From fd0d097c91fb6132ba614114ad5ee268c9f05951 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Sun, 19 Jan 2020 21:27:36 -0500 Subject: [PATCH 240/371] Cleanup --- dist/bundle.es.js | 31 ++++++++++++++++++++----------- src/redux/actions/comments.js | 6 +++--- src/redux/reducers/comments.js | 6 +----- src/redux/selectors/comments.js | 4 +--- 4 files changed, 25 insertions(+), 22 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9e3c5e6..c80a7e8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1246,6 +1246,18 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; + { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } + } + if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -4166,7 +4178,7 @@ function doCommentHide(comment_id) { data: error }); dispatch(doToast({ - message: `SDK Errored when trying to hide Comment with comment_id: "${comment_id}"`, + message: 'There was an error hiding this comment. Please try again later.', isError: true })); }); @@ -4194,7 +4206,7 @@ function doCommentAbandon(comment_id) { data: error }); dispatch(doToast({ - message: `SDK Errored during abandon on Comment w/ ID = "${comment_id}"`, + message: 'There was an error hiding this comment. Please try again later.', isError: true })); }); @@ -4223,7 +4235,7 @@ function doCommentUpdate(comment_id, comment) { }).catch(error => { dispatch({ type: COMMENT_UPDATE_FAILED, data: error }); dispatch(doToast({ - message: `SDK Errored during update on Comment w/ ID = ${comment_id}`, + message: 'There was an error hiding this comment. Please try again later.', isError: true })); }); @@ -4732,11 +4744,7 @@ const commentReducer = handleActions({ const commentIds = byId[comment.claim_id]; byId[comment.claim_id] = commentIds.filter(commentId => commentId !== comment_id); - Object.keys(commentById).forEach(commentId => { - if (commentId === comment_id) { - delete commentById[commentId]; - } - }); + delete commentById[comment_id]; } return _extends$7({}, state, { commentById, @@ -5668,12 +5676,10 @@ const selectCommentsByClaimId = reselect.createSelector(selectState$8, selectCom const byClaimId = state.byId || {}; const comments = {}; - // for every claimId -> commentId, put comments in the object + // replace every comment_id in the list with the actual comment object Object.keys(byClaimId).forEach(claimId => { - // get all the commentIds that commented on this ClaimId const commentIds = byClaimId[claimId]; - // map a new array of comments by the claimId comments[claimId] = Array(commentIds === null ? 0 : commentIds.length); for (let i = 0; i < commentIds.length; i++) { comments[claimId][i] = byId[commentIds[i]]; @@ -5708,6 +5714,9 @@ const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsBy return byClaimId && byClaimId[claimId]; }); +// todo: allow SDK to retrieve user comments through comment_list +// todo: implement selectors for selecting comments owned by user + // const selectState$9 = state => state.tags || {}; diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 48f4bad..01c79b2 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -105,7 +105,7 @@ export function doCommentHide(comment_id: string) { }); dispatch( doToast({ - message: `SDK Errored when trying to hide Comment with comment_id: "${comment_id}"`, + message: 'There was an error hiding this comment. Please try again later.', isError: true, }) ); @@ -137,7 +137,7 @@ export function doCommentAbandon(comment_id: string) { }); dispatch( doToast({ - message: `SDK Errored during abandon on Comment w/ ID = "${comment_id}"`, + message: 'There was an error hiding this comment. Please try again later.', isError: true, }) ); @@ -170,7 +170,7 @@ export function doCommentUpdate(comment_id: string, comment: string) { dispatch({ type: ACTIONS.COMMENT_UPDATE_FAILED, data: error }); dispatch( doToast({ - message: `SDK Errored during update on Comment w/ ID = ${comment_id}`, + message: 'There was an error hiding this comment. Please try again later.', isError: true, }) ); diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js index 8876b0e..c45edd0 100644 --- a/src/redux/reducers/comments.js +++ b/src/redux/reducers/comments.js @@ -97,11 +97,7 @@ export const commentReducer = handleActions( const commentIds = byId[comment.claim_id]; byId[comment.claim_id] = commentIds.filter(commentId => commentId !== comment_id); - Object.keys(commentById).forEach(commentId => { - if (commentId === comment_id) { - delete commentById[commentId]; - } - }); + delete commentById[comment_id]; } return { ...state, diff --git a/src/redux/selectors/comments.js b/src/redux/selectors/comments.js index 86286ea..c3a2f2d 100644 --- a/src/redux/selectors/comments.js +++ b/src/redux/selectors/comments.js @@ -15,12 +15,10 @@ export const selectCommentsByClaimId = createSelector( const byClaimId = state.byId || {}; const comments = {}; - // for every claimId -> commentId, put comments in the object + // replace every comment_id in the list with the actual comment object Object.keys(byClaimId).forEach(claimId => { - // get all the commentIds that commented on this ClaimId const commentIds = byClaimId[claimId]; - // map a new array of comments by the claimId comments[claimId] = Array(commentIds === null ? 0 : commentIds.length); for (let i = 0; i < commentIds.length; i++) { comments[claimId][i] = byId[commentIds[i]]; -- 2.45.2 From bc2436dce28eec09a268afb4b896421ec718443f Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 21 Jan 2020 00:46:14 -0500 Subject: [PATCH 241/371] Corrects abandon return type & fixes issue where redux wasn't being changed --- dist/bundle.es.js | 62 +++++++++++++++++++--------------- dist/flow-typed/Lbry.js | 2 +- flow-typed/Lbry.js | 2 +- src/redux/actions/comments.js | 21 ++++++++---- src/redux/reducers/comments.js | 19 ++++++----- 5 files changed, 61 insertions(+), 45 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c915b8b..16deb2d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4067,7 +4067,7 @@ const doUpdateSearchOptions = newOptions => (dispatch, getState) => { } }; -// +// function savePosition(claimId, outpoint, position) { return dispatch => { @@ -4204,13 +4204,20 @@ function doCommentAbandon(comment_id) { return lbryProxy.comment_abandon({ comment_id: comment_id }).then(result => { - dispatch({ - type: COMMENT_ABANDON_COMPLETED, - data: { - comment_id: comment_id, - abandoned: result - } - }); + // Comment may not be deleted if the signing channel can't be signed. + // This will happen if the channel was recently created or abandoned. + if (result.abandoned) { + dispatch({ + type: COMMENT_ABANDON_COMPLETED, + data: { + comment_id: comment_id + } + }); + } else { + dispatch({ + type: COMMENT_ABANDON_FAILED + }); + } }).catch(error => { dispatch({ type: COMMENT_ABANDON_FAILED, @@ -4740,35 +4747,36 @@ const commentReducer = handleActions({ [COMMENT_LIST_FAILED]: (state, action) => _extends$8({}, state, { isLoading: false }), - [COMMENT_ABANDON_STARTED]: (state, action) => _extends$7({}, state, { + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$8({}, state, { isLoading: true }), - // remove the existing comment from the id -> comment list and claim -> commentIds [COMMENT_ABANDON_COMPLETED]: (state, action) => { - const { comment_id, abandoned } = action.data; + const { comment_id } = action.data; const commentById = Object.assign({}, state.commentById); const byId = Object.assign({}, state.byId); - if (abandoned && comment_id in abandoned) { - // messy but necessary for the time being - const comment = commentById[comment_id]; - const commentIds = byId[comment.claim_id]; - byId[comment.claim_id] = commentIds.filter(commentId => commentId !== comment_id); - - delete commentById[comment_id]; + // to remove the comment and its references + const claimId = commentById[comment_id].claim_id; + for (let i = 0; i < byId[claimId].length; i++) { + if (byId[claimId][i] === comment_id) { + byId[claimId].splice(i, 1); + break; + } } - return _extends$7({}, state, { + delete commentById[comment_id]; + + return _extends$8({}, state, { commentById, byId, isLoading: false }); }, // do nothing - [COMMENT_ABANDON_FAILED]: (state, action) => _extends$7({}, state, { + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$8({}, state, { isLoading: false }), // do nothing - [COMMENT_UPDATE_STARTED]: (state, action) => _extends$7({}, state, { + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$8({}, state, { isLoading: true }), // replace existing comment with comment returned here under its comment_id @@ -4780,24 +4788,24 @@ const commentReducer = handleActions({ commentById[comment.comment_id] = comment; } - return _extends$7({}, state, { + return _extends$8({}, state, { commentById, isLoading: false }); }, // nothing can be done here - [COMMENT_UPDATE_FAILED]: (state, action) => _extends$7({}, state, { + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$8({}, state, { isLoading: false }), // nothing can really be done here - [COMMENT_HIDE_STARTED]: (state, action) => _extends$7({}, state, { + [COMMENT_HIDE_STARTED]: (state, action) => _extends$8({}, state, { isLoading: true }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$7({}, state, { // todo: add HiddenComments state & create selectors + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$8({}, state, { // todo: add HiddenComments state & create selectors isLoading: false }), // nothing can be done here - [COMMENT_HIDE_FAILED]: (state, action) => _extends$7({}, state, { + [COMMENT_HIDE_FAILED]: (state, action) => _extends$8({}, state, { isLoading: false }) }, defaultState$1); @@ -5638,7 +5646,7 @@ const walletReducer = handleActions({ }) }, defaultState$a); -// +// const selectState$6 = state => state.content || {}; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 408beb0..d2657cb 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -142,7 +142,7 @@ declare type CommentHideResponse = { declare type CommentAbandonResponse = { // keyed by the CommentId given - [string]: { abandoned: boolean }, + abandoned: boolean, }; declare type ChannelListResponse = { diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 408beb0..d2657cb 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -142,7 +142,7 @@ declare type CommentHideResponse = { declare type CommentAbandonResponse = { // keyed by the CommentId given - [string]: { abandoned: boolean }, + abandoned: boolean, }; declare type ChannelListResponse = { diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 01c79b2..4441651 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -122,13 +122,20 @@ export function doCommentAbandon(comment_id: string) { comment_id: comment_id, }) .then((result: CommentAbandonResponse) => { - dispatch({ - type: ACTIONS.COMMENT_ABANDON_COMPLETED, - data: { - comment_id: comment_id, - abandoned: result, - }, - }); + // Comment may not be deleted if the signing channel can't be signed. + // This will happen if the channel was recently created or abandoned. + if (result.abandoned) { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_COMPLETED, + data: { + comment_id: comment_id, + }, + }); + } else { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_FAILED, + }); + } }) .catch(error => { dispatch({ diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js index c45edd0..493d225 100644 --- a/src/redux/reducers/comments.js +++ b/src/redux/reducers/comments.js @@ -85,20 +85,21 @@ export const commentReducer = handleActions( ...state, isLoading: true, }), - // remove the existing comment from the id -> comment list and claim -> commentIds [ACTIONS.COMMENT_ABANDON_COMPLETED]: (state: CommentsState, action: any) => { - const { comment_id, abandoned } = action.data; + const { comment_id } = action.data; const commentById = Object.assign({}, state.commentById); const byId = Object.assign({}, state.byId); - if (abandoned && comment_id in abandoned) { - // messy but necessary for the time being - const comment: Comment = commentById[comment_id]; - const commentIds = byId[comment.claim_id]; - byId[comment.claim_id] = commentIds.filter(commentId => commentId !== comment_id); - - delete commentById[comment_id]; + // to remove the comment and its references + const claimId = commentById[comment_id].claim_id; + for (let i = 0; i < byId[claimId].length; i++) { + if (byId[claimId][i] === comment_id) { + byId[claimId].splice(i, 1); + break; + } } + delete commentById[comment_id]; + return { ...state, commentById, -- 2.45.2 From 3495066d35791720f4ede3586d5579635e8c432f Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 21 Jan 2020 11:46:22 -0500 Subject: [PATCH 242/371] update build --- dist/bundle.es.js | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 6eb0bef..7335a1a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,6 +15,7 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ + __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -274,6 +275,7 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ + __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -516,6 +518,7 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ + __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -546,6 +549,7 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ + __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -595,6 +599,7 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ + __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -622,6 +627,7 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ + __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -635,6 +641,7 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ + __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -654,6 +661,7 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ + __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -670,6 +678,7 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ + __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -678,6 +687,7 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ + __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -723,6 +733,7 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ + __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -776,6 +787,7 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ + __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); @@ -3463,7 +3475,7 @@ const selectPublishFormValues = reselect.createSelector(selectState$5, selectIsS let actualLanguage; // Sets default if editing a claim with a set language - if (!language && isStillEditing && languages[0]) { + if (!language && isStillEditing && languages && languages[0]) { actualLanguage = languages[0]; } else { actualLanguage = language || 'en'; -- 2.45.2 From abe72c1a82c281438b94ca757088b3670aa8905d Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 21 Jan 2020 12:00:18 -0500 Subject: [PATCH 243/371] fix: publish bug with same uri + channel --- dist/bundle.es.js | 12 +++++++----- src/redux/actions/publish.js | 12 +++++++----- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 7335a1a..1c6a34a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3748,6 +3748,8 @@ const doPublish = (success, fail) => (dispatch, getState) => { tags, locations } = publishData; + // Handle scenario where we have a claim that has the same name as a channel we are publishing with. + const myClaimForUriEditing = myClaimForUri.name === name ? myClaimForUri : null; let publishingLicense; switch (licenseType) { @@ -3791,10 +3793,10 @@ const doPublish = (success, fail) => (dispatch, getState) => { } // Set release time to curret date. On edits, keep original release/transaction time as release_time - if (myClaimForUri && myClaimForUri.value.release_time) { + if (myClaimForUriEditing && myClaimForUriEditing.value.release_time) { publishPayload.release_time = Number(myClaimForUri.value.release_time); - } else if (myClaimForUri && myClaimForUri.timestamp) { - publishPayload.release_time = Number(myClaimForUri.timestamp); + } else if (myClaimForUriEditing && myClaimForUriEditing.timestamp) { + publishPayload.release_time = Number(myClaimForUriEditing.timestamp); } else { publishPayload.release_time = Number(Math.round(Date.now() / 1000)); } @@ -3803,8 +3805,8 @@ const doPublish = (success, fail) => (dispatch, getState) => { publishPayload.channel_id = channelId; } - if (myClaimForUri && myClaimForUri.value && myClaimForUri.value.locations) { - publishPayload.locations = myClaimForUri.value.locations; + if (myClaimForUriEditing && myClaimForUriEditing.value && myClaimForUriEditing.value.locations) { + publishPayload.locations = myClaimForUriEditing.value.locations; } if (!contentIsFree && fee && fee.currency && Number(fee.amount) > 0) { diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 214174b..5a770d9 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -265,6 +265,8 @@ export const doPublish = (success: Function, fail: Function) => ( tags, locations, } = publishData; + // Handle scenario where we have a claim that has the same name as a channel we are publishing with. + const myClaimForUriEditing = myClaimForUri.name === name ? myClaimForUri : null; let publishingLicense; switch (licenseType) { @@ -327,10 +329,10 @@ export const doPublish = (success: Function, fail: Function) => ( } // Set release time to curret date. On edits, keep original release/transaction time as release_time - if (myClaimForUri && myClaimForUri.value.release_time) { + if (myClaimForUriEditing && myClaimForUriEditing.value.release_time) { publishPayload.release_time = Number(myClaimForUri.value.release_time); - } else if (myClaimForUri && myClaimForUri.timestamp) { - publishPayload.release_time = Number(myClaimForUri.timestamp); + } else if (myClaimForUriEditing && myClaimForUriEditing.timestamp) { + publishPayload.release_time = Number(myClaimForUriEditing.timestamp); } else { publishPayload.release_time = Number(Math.round(Date.now() / 1000)); } @@ -339,8 +341,8 @@ export const doPublish = (success: Function, fail: Function) => ( publishPayload.channel_id = channelId; } - if (myClaimForUri && myClaimForUri.value && myClaimForUri.value.locations) { - publishPayload.locations = myClaimForUri.value.locations; + if (myClaimForUriEditing && myClaimForUriEditing.value && myClaimForUriEditing.value.locations) { + publishPayload.locations = myClaimForUriEditing.value.locations; } if (!contentIsFree && fee && (fee.currency && Number(fee.amount) > 0)) { -- 2.45.2 From f0891dd298b1f311a37c4713d2db009f62088b09 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 21 Jan 2020 13:33:24 -0500 Subject: [PATCH 244/371] fix publishing --- dist/bundle.es.js | 2 +- src/redux/actions/publish.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1c6a34a..4163f5b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3749,7 +3749,7 @@ const doPublish = (success, fail) => (dispatch, getState) => { locations } = publishData; // Handle scenario where we have a claim that has the same name as a channel we are publishing with. - const myClaimForUriEditing = myClaimForUri.name === name ? myClaimForUri : null; + const myClaimForUriEditing = myClaimForUri && myClaimForUri.name === name ? myClaimForUri : null; let publishingLicense; switch (licenseType) { diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 5a770d9..fb00179 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -266,7 +266,7 @@ export const doPublish = (success: Function, fail: Function) => ( locations, } = publishData; // Handle scenario where we have a claim that has the same name as a channel we are publishing with. - const myClaimForUriEditing = myClaimForUri.name === name ? myClaimForUri : null; + const myClaimForUriEditing = myClaimForUri && myClaimForUri.name === name ? myClaimForUri : null; let publishingLicense; switch (licenseType) { -- 2.45.2 From 11840e01b64515a015a8dcd495ea84e70ee9e21c Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 9 Jan 2020 21:36:18 -0500 Subject: [PATCH 245/371] channel list will no longer overwrite resolved claims byId --- dist/bundle.es.js | 4 +++- src/redux/reducers/claims.js | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4163f5b..9ae6b9d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4319,7 +4319,9 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { claims.forEach(claim => { // $FlowFixMe myChannelClaims.add(claim.claim_id); - byId[claim.claim_id] = claim; + if (!byId[claim.claim_id]) { + byId[claim.claim_id] = claim; + } if (pendingById[claim.claim_id] && claim.confirmations > 0) { delete pendingById[claim.claim_id]; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 8e6b121..f60cdca 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -216,7 +216,9 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St claims.forEach(claim => { // $FlowFixMe myChannelClaims.add(claim.claim_id); - byId[claim.claim_id] = claim; + if (!byId[claim.claim_id]) { + byId[claim.claim_id] = claim; + } if (pendingById[claim.claim_id] && claim.confirmations > 0) { delete pendingById[claim.claim_id]; @@ -265,7 +267,8 @@ reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_COMPLETED] = (state: State, action: any): const paginatedClaimsByChannel = Object.assign({}, state.paginatedClaimsByChannel); // check if count has changed - that means cached pagination will be wrong, so clear it const previousCount = paginatedClaimsByChannel[uri] && paginatedClaimsByChannel[uri]['itemCount']; - const byChannel = (claimsInChannel === previousCount) ? Object.assign({}, paginatedClaimsByChannel[uri]) : {}; + const byChannel = + claimsInChannel === previousCount ? Object.assign({}, paginatedClaimsByChannel[uri]) : {}; const allClaimIds = new Set(byChannel.all); const currentPageClaimIds = []; const byId = Object.assign({}, state.byId); -- 2.45.2 From 17a5260c3fb23e74dd7ac8fd8a2e7beaf60afac8 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 22 Jan 2020 02:04:50 +0100 Subject: [PATCH 246/371] add doResolvedSearch actions which returns resolved search results (#258) * add doResolvedSearch actions which returns resolved search results * add recommended content selector * update ResolvedSearchResult type * support for multiple pages of resolved search results --- dist/bundle.es.js | 154 +++++++++++++++++++++++++++++++--- dist/flow-typed/Search.js | 25 ++++++ flow-typed/Search.js | 25 ++++++ src/constants/action_types.js | 3 + src/constants/tags.js | 2 +- src/index.js | 6 ++ src/redux/actions/search.js | 72 ++++++++++++++++ src/redux/reducers/search.js | 43 ++++++++++ src/redux/selectors/claims.js | 41 ++++++++- src/redux/selectors/search.js | 32 +++++++ 10 files changed, 388 insertions(+), 15 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4163f5b..0549d59 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,7 +15,6 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ - __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -163,6 +162,9 @@ const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; const SEARCH_START = 'SEARCH_START'; const SEARCH_SUCCESS = 'SEARCH_SUCCESS'; const SEARCH_FAIL = 'SEARCH_FAIL'; +const RESOLVED_SEARCH_START = 'RESOLVED_SEARCH_START'; +const RESOLVED_SEARCH_SUCCESS = 'RESOLVED_SEARCH_SUCCESS'; +const RESOLVED_SEARCH_FAIL = 'RESOLVED_SEARCH_FAIL'; const UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY'; const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS'; const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS'; @@ -275,7 +277,6 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ - __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -403,6 +404,9 @@ var action_types = /*#__PURE__*/Object.freeze({ SEARCH_START: SEARCH_START, SEARCH_SUCCESS: SEARCH_SUCCESS, SEARCH_FAIL: SEARCH_FAIL, + RESOLVED_SEARCH_START: RESOLVED_SEARCH_START, + RESOLVED_SEARCH_SUCCESS: RESOLVED_SEARCH_SUCCESS, + RESOLVED_SEARCH_FAIL: RESOLVED_SEARCH_FAIL, UPDATE_SEARCH_QUERY: UPDATE_SEARCH_QUERY, UPDATE_SEARCH_OPTIONS: UPDATE_SEARCH_OPTIONS, UPDATE_SEARCH_SUGGESTIONS: UPDATE_SEARCH_SUGGESTIONS, @@ -518,7 +522,6 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ - __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -549,7 +552,6 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ - __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -599,7 +601,6 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ - __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -627,7 +628,6 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -641,7 +641,6 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -661,7 +660,6 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ - __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -678,7 +676,6 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ - __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -687,7 +684,6 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ - __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -733,7 +729,6 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ - __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -787,7 +782,6 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ - __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); @@ -1342,6 +1336,18 @@ const makeSelectSearchUris = query => // replace statement below is kind of ugly, and repeated in doSearch action reselect.createSelector(selectSearchUrisByQuery, byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]); +const selectResolvedSearchResultsByQuery = reselect.createSelector(selectState, state => state.resolvedResultsByQuery); + +const selectResolvedSearchResultsByQueryLastPageReached = reselect.createSelector(selectState, state => state.resolvedResultsByQueryLastPageReached); + +const makeSelectResolvedSearchResults = query => +// replace statement below is kind of ugly, and repeated in doSearch action +reselect.createSelector(selectResolvedSearchResultsByQuery, byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]); + +const makeSelectResolvedSearchResultsLastPageReached = query => +// replace statement below is kind of ugly, and repeated in doSearch action +reselect.createSelector(selectResolvedSearchResultsByQueryLastPageReached, byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query]); + const selectSearchBarFocused = reselect.createSelector(selectState, state => state.focused); const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selectSuggestions, (query, suggestions) => { @@ -2277,6 +2283,34 @@ const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(sele const selectMyStreamUrlsCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); +const makeSelectResolvedRecommendedContentForUri = (uri, size) => reselect.createSelector(makeSelectClaimForUri(uri), selectResolvedSearchResultsByQuery, (claim, resolvedResultsByQuery) => { + const atVanityURI = !uri.includes('#'); + + let recommendedContent; + if (claim) { + // always grab full URL - this can change once search returns canonical + const currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); + + const { title } = claim.value; + + if (!title) { + return; + } + + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), { size }, undefined, { + related_to: claim.claim_id + }); + + let results = resolvedResultsByQuery[searchQuery]; + if (results) { + results = results.filter(result => buildURI({ streamClaimId: result.claimId, streamName: result.name }) !== currentUri); + recommendedContent = results; + } + } + + return recommendedContent; +}); + function numberWithCommas(x) { var parts = x.toString().split('.'); parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ','); @@ -4020,6 +4054,63 @@ from, isBackgroundSearch = false, options = {}, resolveResults = true) => (dispa }); }; +const doResolvedSearch = (rawQuery, size, // only pass in if you don't want to use the users setting (ex: related content) +from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => { + const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); + + if (!query) { + dispatch({ + type: RESOLVED_SEARCH_FAIL + }); + return; + } + + const state = getState(); + let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)(state); + + // make from null so that we can maintain a reference to the same query for multiple pages and simply append the found results + let queryWithoutFrom = makeSelectQueryWithOptions(query, size, null, isBackgroundSearch, options)(state); + + // If we have already searched for something, we don't need to do anything + // TODO: Tweak this check for multiple page results + /* const resultsForQuery = makeSelectResolvedSearchResults(queryWithOptions)(state); + if (resultsForQuery && resultsForQuery.length && resultsForQuery.length > (from * size)) { + return; + } */ + + dispatch({ + type: RESOLVED_SEARCH_START + }); + + if (!state.search.searchQuery && !isBackgroundSearch) { + dispatch(doUpdateSearchQuery(query)); + } + + fetch(`${CONNECTION_STRING}search?resolve=true&${queryWithOptions}`).then(handleFetchResponse).then(data => { + const results = []; + + data.forEach(result => { + if (result) { + results.push(result); + } + }); + + dispatch({ + type: RESOLVED_SEARCH_SUCCESS, + data: { + query: queryWithoutFrom, + results, + pageSize: size, + append: parseInt(from, 10) > parseInt(size, 10) - 1 + } + }); + }).catch(e => { + dispatch({ + type: RESOLVED_SEARCH_FAIL + }); + }); +}; + const doFocusSearchInput = () => dispatch => dispatch({ type: SEARCH_FOCUS }); @@ -5024,7 +5115,9 @@ const defaultState$7 = { [SEARCH_OPTIONS.MEDIA_APPLICATION]: true }, suggestions: {}, - urisByQuery: {} + urisByQuery: {}, + resolvedResultsByQuery: {}, + resolvedResultsByQueryLastPageReached: {} }; const searchReducer = handleActions({ @@ -5044,6 +5137,35 @@ const searchReducer = handleActions({ searching: false }), + [RESOLVED_SEARCH_START]: state => _extends$d({}, state, { + searching: true + }), + [RESOLVED_SEARCH_SUCCESS]: (state, action) => { + const resolvedResultsByQuery = Object.assign({}, state.resolvedResultsByQuery); + const resolvedResultsByQueryLastPageReached = Object.assign({}, state.resolvedResultsByQueryLastPageReached); + const { append, query, results, pageSize } = action.data; + + if (append) { + // todo: check for duplicates when concatenating? + resolvedResultsByQuery[query] = resolvedResultsByQuery[query] && resolvedResultsByQuery[query].length ? resolvedResultsByQuery[query].concat(results) : results; + } else { + resolvedResultsByQuery[query] = results; + } + + // the returned number of urls is less than the page size, so we're on the last page + resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; + + return _extends$d({}, state, { + searching: false, + resolvedResultsByQuery, + resolvedResultsByQueryLastPageReached + }); + }, + + [RESOLVED_SEARCH_FAIL]: state => _extends$d({}, state, { + searching: false + }), + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$d({}, state, { searchQuery: action.data.query, isActive: true @@ -5612,6 +5734,7 @@ exports.doPurchaseUri = doPurchaseUri; exports.doResetThumbnailStatus = doResetThumbnailStatus; exports.doResolveUri = doResolveUri; exports.doResolveUris = doResolveUris; +exports.doResolvedSearch = doResolvedSearch; exports.doSearch = doSearch; exports.doSendDraftTransaction = doSendDraftTransaction; exports.doSendTip = doSendTip; @@ -5680,6 +5803,9 @@ exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; +exports.makeSelectResolvedRecommendedContentForUri = makeSelectResolvedRecommendedContentForUri; +exports.makeSelectResolvedSearchResults = makeSelectResolvedSearchResults; +exports.makeSelectResolvedSearchResultsLastPageReached = makeSelectResolvedSearchResultsLastPageReached; exports.makeSelectSearchDownloadUrlsCount = makeSelectSearchDownloadUrlsCount; exports.makeSelectSearchDownloadUrlsForPage = makeSelectSearchDownloadUrlsForPage; exports.makeSelectSearchUris = makeSelectSearchUris; @@ -5772,6 +5898,8 @@ exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; exports.selectReservedBalance = selectReservedBalance; +exports.selectResolvedSearchResultsByQuery = selectResolvedSearchResultsByQuery; +exports.selectResolvedSearchResultsByQueryLastPageReached = selectResolvedSearchResultsByQueryLastPageReached; exports.selectResolvingUris = selectResolvingUris; exports.selectSearchBarFocused = selectSearchBarFocused; exports.selectSearchOptions = selectSearchOptions; diff --git a/dist/flow-typed/Search.js b/dist/flow-typed/Search.js index 5fad710..2a2152e 100644 --- a/dist/flow-typed/Search.js +++ b/dist/flow-typed/Search.js @@ -28,6 +28,8 @@ declare type SearchState = { options: SearchOptions, suggestions: { [string]: Array }, urisByQuery: {}, + resolvedResultsByQuery: {}, + resolvedResultsByQueryLastPageReached: {}, }; declare type SearchSuccess = { @@ -57,3 +59,26 @@ declare type UpdateSearchOptions = { type: ACTIONS.UPDATE_SEARCH_OPTIONS, data: SearchOptions, }; + +declare type ResolvedSearchResult = { + channel: string, + channel_claim_id: string, + claimId: string, + duration: number, + fee: number, + name: string, + nsfw: boolean, + release_time: string, + thumbnail_url: string, + title: string, +}; + +declare type ResolvedSearchSuccess = { + type: ACTIONS.RESOLVED_SEARCH_SUCCESS, + data: { + append: boolean, + pageSize: number, + results: Array, + query: string, + }, +}; diff --git a/flow-typed/Search.js b/flow-typed/Search.js index 5fad710..2a2152e 100644 --- a/flow-typed/Search.js +++ b/flow-typed/Search.js @@ -28,6 +28,8 @@ declare type SearchState = { options: SearchOptions, suggestions: { [string]: Array }, urisByQuery: {}, + resolvedResultsByQuery: {}, + resolvedResultsByQueryLastPageReached: {}, }; declare type SearchSuccess = { @@ -57,3 +59,26 @@ declare type UpdateSearchOptions = { type: ACTIONS.UPDATE_SEARCH_OPTIONS, data: SearchOptions, }; + +declare type ResolvedSearchResult = { + channel: string, + channel_claim_id: string, + claimId: string, + duration: number, + fee: number, + name: string, + nsfw: boolean, + release_time: string, + thumbnail_url: string, + title: string, +}; + +declare type ResolvedSearchSuccess = { + type: ACTIONS.RESOLVED_SEARCH_SUCCESS, + data: { + append: boolean, + pageSize: number, + results: Array, + query: string, + }, +}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index ac23374..42cf987 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -139,6 +139,9 @@ export const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; export const SEARCH_START = 'SEARCH_START'; export const SEARCH_SUCCESS = 'SEARCH_SUCCESS'; export const SEARCH_FAIL = 'SEARCH_FAIL'; +export const RESOLVED_SEARCH_START = 'RESOLVED_SEARCH_START'; +export const RESOLVED_SEARCH_SUCCESS = 'RESOLVED_SEARCH_SUCCESS'; +export const RESOLVED_SEARCH_FAIL = 'RESOLVED_SEARCH_FAIL'; export const UPDATE_SEARCH_QUERY = 'UPDATE_SEARCH_QUERY'; export const UPDATE_SEARCH_OPTIONS = 'UPDATE_SEARCH_OPTIONS'; export const UPDATE_SEARCH_SUGGESTIONS = 'UPDATE_SEARCH_SUGGESTIONS'; diff --git a/src/constants/tags.js b/src/constants/tags.js index 9456a81..e44fe37 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -510,5 +510,5 @@ export const DEFAULT_KNOWN_TAGS = [ 'portugal', 'dantdm', 'teaser', - 'lbry' + 'lbry', ]; diff --git a/src/index.js b/src/index.js index 65f1db9..b9d554f 100644 --- a/src/index.js +++ b/src/index.js @@ -90,6 +90,7 @@ export { export { doSearch, + doResolvedSearch, doUpdateSearchQuery, doFocusSearchInput, doBlurSearchInput, @@ -183,6 +184,7 @@ export { makeSelectOmittedCountForChannel, makeSelectClaimIsNsfw, makeSelectRecommendedContentForUri, + makeSelectResolvedRecommendedContentForUri, makeSelectFirstRecommendedFileForUri, makeSelectChannelForClaimUri, makeSelectClaimIsPending, @@ -265,9 +267,13 @@ export { export { selectSearchState }; export { makeSelectSearchUris, + makeSelectResolvedSearchResults, + makeSelectResolvedSearchResultsLastPageReached, selectSearchValue, selectSearchOptions, selectIsSearching, + selectResolvedSearchResultsByQuery, + selectResolvedSearchResultsByQueryLastPageReached, selectSearchUrisByQuery, selectSearchBarFocused, selectSearchSuggestions, diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 3cd3a47..e00d7ba 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -4,6 +4,7 @@ import { buildURI } from 'lbryURI'; import { doResolveUri } from 'redux/actions/claims'; import { makeSelectSearchUris, + makeSelectResolvedSearchResults, selectSuggestions, makeSelectQueryWithOptions, selectSearchValue, @@ -159,6 +160,77 @@ export const doSearch = ( }); }; +export const doResolvedSearch = ( + rawQuery: string, + size: ?number, // only pass in if you don't want to use the users setting (ex: related content) + from: ?number, + isBackgroundSearch: boolean = false, + options: { + related_to?: string, + } = {} +) => (dispatch: Dispatch, getState: GetState) => { + const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); + + if (!query) { + dispatch({ + type: ACTIONS.RESOLVED_SEARCH_FAIL, + }); + return; + } + + const state = getState(); + let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)( + state + ); + + // make from null so that we can maintain a reference to the same query for multiple pages and simply append the found results + let queryWithoutFrom = makeSelectQueryWithOptions(query, size, null, isBackgroundSearch, options)( + state + ); + + // If we have already searched for something, we don't need to do anything + // TODO: Tweak this check for multiple page results + /* const resultsForQuery = makeSelectResolvedSearchResults(queryWithOptions)(state); + if (resultsForQuery && resultsForQuery.length && resultsForQuery.length > (from * size)) { + return; + } */ + + dispatch({ + type: ACTIONS.RESOLVED_SEARCH_START, + }); + + if (!state.search.searchQuery && !isBackgroundSearch) { + dispatch(doUpdateSearchQuery(query)); + } + + fetch(`${CONNECTION_STRING}search?resolve=true&${queryWithOptions}`) + .then(handleFetchResponse) + .then((data: Array) => { + const results = []; + + data.forEach(result => { + if (result) { + results.push(result); + } + }); + + dispatch({ + type: ACTIONS.RESOLVED_SEARCH_SUCCESS, + data: { + query: queryWithoutFrom, + results, + pageSize: size, + append: parseInt(from, 10) > parseInt(size, 10) - 1, + }, + }); + }) + .catch(e => { + dispatch({ + type: ACTIONS.RESOLVED_SEARCH_FAIL, + }); + }); +}; + export const doFocusSearchInput = () => (dispatch: Dispatch) => dispatch({ type: ACTIONS.SEARCH_FOCUS, diff --git a/src/redux/reducers/search.js b/src/redux/reducers/search.js index ee0bd8b..27e1013 100644 --- a/src/redux/reducers/search.js +++ b/src/redux/reducers/search.js @@ -18,6 +18,8 @@ const defaultState = { }, suggestions: {}, urisByQuery: {}, + resolvedResultsByQuery: {}, + resolvedResultsByQueryLastPageReached: {}, }; export const searchReducer = handleActions( @@ -41,6 +43,47 @@ export const searchReducer = handleActions( searching: false, }), + [ACTIONS.RESOLVED_SEARCH_START]: (state: SearchState): SearchState => ({ + ...state, + searching: true, + }), + [ACTIONS.RESOLVED_SEARCH_SUCCESS]: ( + state: SearchState, + action: ResolvedSearchSuccess + ): SearchState => { + const resolvedResultsByQuery = Object.assign({}, state.resolvedResultsByQuery); + const resolvedResultsByQueryLastPageReached = Object.assign( + {}, + state.resolvedResultsByQueryLastPageReached + ); + const { append, query, results, pageSize } = action.data; + + if (append) { + // todo: check for duplicates when concatenating? + resolvedResultsByQuery[query] = + resolvedResultsByQuery[query] && resolvedResultsByQuery[query].length + ? resolvedResultsByQuery[query].concat(results) + : results; + } else { + resolvedResultsByQuery[query] = results; + } + + // the returned number of urls is less than the page size, so we're on the last page + resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; + + return { + ...state, + searching: false, + resolvedResultsByQuery, + resolvedResultsByQueryLastPageReached, + }; + }, + + [ACTIONS.RESOLVED_SEARCH_FAIL]: (state: SearchState): SearchState => ({ + ...state, + searching: false, + }), + [ACTIONS.UPDATE_SEARCH_QUERY]: ( state: SearchState, action: UpdateSearchQuery diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index e825188..6adf368 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -1,6 +1,9 @@ // @flow import { normalizeURI, buildURI, parseURI } from 'lbryURI'; -import { selectSearchUrisByQuery } from 'redux/selectors/search'; +import { + selectResolvedSearchResultsByQuery, + selectSearchUrisByQuery, +} from 'redux/selectors/search'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { createSelector } from 'reselect'; import { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; @@ -639,3 +642,39 @@ export const selectMyStreamUrlsCount = createSelector( selectMyClaimUrisWithoutChannels, channels => channels.length ); + +export const makeSelectResolvedRecommendedContentForUri = (uri: string, size: number) => + createSelector( + makeSelectClaimForUri(uri), + selectResolvedSearchResultsByQuery, + (claim, resolvedResultsByQuery) => { + const atVanityURI = !uri.includes('#'); + + let recommendedContent; + if (claim) { + // always grab full URL - this can change once search returns canonical + const currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); + + const { title } = claim.value; + + if (!title) { + return; + } + + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), { size }, undefined, { + related_to: claim.claim_id, + }); + + let results = resolvedResultsByQuery[searchQuery]; + if (results) { + results = results.filter( + result => + buildURI({ streamClaimId: result.claimId, streamName: result.name }) !== currentUri + ); + recommendedContent = results; + } + } + + return recommendedContent; + } + ); diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index d556602..48dca04 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -44,6 +44,38 @@ export const makeSelectSearchUris = (query: string): ((state: State) => Array byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query] ); +export const selectResolvedSearchResultsByQuery: ( + state: State +) => { [string]: Array } = createSelector( + selectState, + state => state.resolvedResultsByQuery +); + +export const selectResolvedSearchResultsByQueryLastPageReached: ( + state: State +) => { [string]: Array } = createSelector( + selectState, + state => state.resolvedResultsByQueryLastPageReached +); + +export const makeSelectResolvedSearchResults = ( + query: string +): ((state: State) => Array) => + // replace statement below is kind of ugly, and repeated in doSearch action + createSelector( + selectResolvedSearchResultsByQuery, + byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query] + ); + +export const makeSelectResolvedSearchResultsLastPageReached = ( + query: string +): ((state: State) => boolean) => + // replace statement below is kind of ugly, and repeated in doSearch action + createSelector( + selectResolvedSearchResultsByQueryLastPageReached, + byQuery => byQuery[query ? query.replace(/^lbry:\/\//i, '').replace(/\//, ' ') : query] + ); + export const selectSearchBarFocused: boolean = createSelector( selectState, state => state.focused -- 2.45.2 From cda1f431b7463aaa74edff5ee9565ca8e935d607 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 22 Jan 2020 09:28:47 -0500 Subject: [PATCH 247/371] update build --- dist/bundle.es.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index a865e0c..3f58baa 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,6 +15,7 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ + __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -277,6 +278,7 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ + __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -522,6 +524,7 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ + __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -552,6 +555,7 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ + __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -601,6 +605,7 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ + __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -628,6 +633,7 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ + __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -641,6 +647,7 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ + __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -660,6 +667,7 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ + __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -676,6 +684,7 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ + __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -684,6 +693,7 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ + __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -729,6 +739,7 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ + __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -782,6 +793,7 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ + __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); -- 2.45.2 From 968686be689fbaf5ba2033ad0a106907320570b9 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 23 Jan 2020 16:01:27 -0500 Subject: [PATCH 248/371] update build --- dist/bundle.es.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8d472d8..23581cf 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1264,18 +1264,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } -- 2.45.2 From 0a4e0ca33f2df3e51c570ba1c637d459a5bbe0a0 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 28 Jan 2020 16:45:05 -0500 Subject: [PATCH 249/371] Corrects error messages --- src/redux/actions/comments.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 4441651..c31dfd3 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -76,7 +76,7 @@ export function doCommentCreate( }); dispatch( doToast({ - message: 'Oops, someone broke comments.', + message: 'Unable to create comment, please try again later.', isError: true, }) ); @@ -105,7 +105,7 @@ export function doCommentHide(comment_id: string) { }); dispatch( doToast({ - message: 'There was an error hiding this comment. Please try again later.', + message: 'Unable to hide this comment, please try again later.', isError: true, }) ); @@ -144,7 +144,7 @@ export function doCommentAbandon(comment_id: string) { }); dispatch( doToast({ - message: 'There was an error hiding this comment. Please try again later.', + message: 'Unable to delete this comment, please try again later.', isError: true, }) ); @@ -177,7 +177,7 @@ export function doCommentUpdate(comment_id: string, comment: string) { dispatch({ type: ACTIONS.COMMENT_UPDATE_FAILED, data: error }); dispatch( doToast({ - message: 'There was an error hiding this comment. Please try again later.', + message: 'Unable to edit this comment, please try again later.', isError: true, }) ); -- 2.45.2 From 50528607e79ce327db3a3868f347a366f27aaaaa Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 28 Jan 2020 17:20:23 -0500 Subject: [PATCH 250/371] Fixes bug where comments would be incorrectly marked as updated & adds user-friendly messages --- dist/bundle.es.js | 69 ++++++++++++++++++++-------------- src/redux/actions/comments.js | 30 +++++++++++---- src/redux/reducers/comments.js | 5 +-- 3 files changed, 64 insertions(+), 40 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 23581cf..5aeafb0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,7 +15,6 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ - __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -286,8 +285,7 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; // Sync const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; -var action_types = /*#__PURE__*/Object.freeze({ - __proto__: null, +var ACTIONS = /*#__PURE__*/Object.freeze({ WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -542,7 +540,6 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ - __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -573,7 +570,6 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ - __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -623,7 +619,6 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ - __proto__: null, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, @@ -651,7 +646,6 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -665,7 +659,6 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -685,7 +678,6 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ - __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -702,7 +694,6 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ - __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -711,7 +702,6 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ - __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -757,7 +747,6 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ - __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -811,7 +800,6 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ const WALLET_SERVERS = LBRYUM_SERVERS; var shared_preferences = /*#__PURE__*/Object.freeze({ - __proto__: null, WALLET_SERVERS: WALLET_SERVERS }); @@ -1264,6 +1252,18 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; + { + if (claimId) { + console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); + } + if (claimName) { + console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); + } + if (contentName) { + console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); + } + } + if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } @@ -4269,7 +4269,7 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { data: error }); dispatch(doToast({ - message: 'Oops, someone broke comments.', + message: 'Unable to create comment, please try again later.', isError: true })); }); @@ -4294,7 +4294,7 @@ function doCommentHide(comment_id) { data: error }); dispatch(doToast({ - message: 'There was an error hiding this comment. Please try again later.', + message: 'Unable to hide this comment, please try again later.', isError: true })); }); @@ -4329,7 +4329,7 @@ function doCommentAbandon(comment_id) { data: error }); dispatch(doToast({ - message: 'There was an error hiding this comment. Please try again later.', + message: 'Unable to delete this comment, please try again later.', isError: true })); }); @@ -4349,16 +4349,30 @@ function doCommentUpdate(comment_id, comment) { comment_id: comment_id, comment: comment }).then(result => { - dispatch({ - type: COMMENT_UPDATE_COMPLETED, - data: { - comment: result - } - }); + if (result != null) { + dispatch({ + type: COMMENT_UPDATE_COMPLETED, + data: { + comment: result + } + }); + } else { + // the result will return null + dispatch({ + type: undefined + }); + dispatch(doToast({ + message: 'Your channel is still being setup, try again in a few moments.', + isError: true + })); + } }).catch(error => { - dispatch({ type: COMMENT_UPDATE_FAILED, data: error }); + dispatch({ + type: COMMENT_UPDATE_FAILED, + data: error + }); dispatch(doToast({ - message: 'There was an error hiding this comment. Please try again later.', + message: 'Unable to edit this comment, please try again later.', isError: true })); }); @@ -4890,10 +4904,7 @@ const commentReducer = handleActions({ [COMMENT_UPDATE_COMPLETED]: (state, action) => { const { comment } = action.data; const commentById = Object.assign({}, state.commentById); - - if (comment) { - commentById[comment.comment_id] = comment; - } + commentById[comment.comment_id] = comment; return _extends$8({}, state, { commentById, @@ -5913,7 +5924,7 @@ const selectChannelIsBlocked = uri => reselect.createSelector(selectBlockedChann return state.includes(uri); }); -exports.ACTIONS = action_types; +exports.ACTIONS = ACTIONS; exports.CLAIM_VALUES = claim; exports.DAEMON_SETTINGS = daemon_settings; exports.DEFAULT_FOLLOWED_TAGS = DEFAULT_FOLLOWED_TAGS; diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index c31dfd3..4c6f876 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -166,15 +166,31 @@ export function doCommentUpdate(comment_id: string, comment: string) { comment: comment, }) .then((result: CommentUpdateResponse) => { - dispatch({ - type: ACTIONS.COMMENT_UPDATE_COMPLETED, - data: { - comment: result, - }, - }); + if (result != null) { + dispatch({ + type: ACTIONS.COMMENT_UPDATE_COMPLETED, + data: { + comment: result, + }, + }); + } else { + // the result will return null + dispatch({ + type: ACTIONS.COMENT_UPDATE_FAILED, + }); + dispatch( + doToast({ + message: 'Your channel is still being setup, try again in a few moments.', + isError: true, + }) + ); + } }) .catch(error => { - dispatch({ type: ACTIONS.COMMENT_UPDATE_FAILED, data: error }); + dispatch({ + type: ACTIONS.COMMENT_UPDATE_FAILED, + data: error, + }); dispatch( doToast({ message: 'Unable to edit this comment, please try again later.', diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js index 493d225..46d08d8 100644 --- a/src/redux/reducers/comments.js +++ b/src/redux/reducers/comments.js @@ -121,10 +121,7 @@ export const commentReducer = handleActions( [ACTIONS.COMMENT_UPDATE_COMPLETED]: (state: CommentsState, action: any) => { const { comment } = action.data; const commentById = Object.assign({}, state.commentById); - - if (comment) { - commentById[comment.comment_id] = comment; - } + commentById[comment.comment_id] = comment; return { ...state, -- 2.45.2 From 4b4217879cc548bef0765e0ab205c19657f23322 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 28 Jan 2020 17:34:28 -0500 Subject: [PATCH 251/371] Error for abandon operations as well --- dist/bundle.es.js | 4 ++++ src/redux/actions/comments.js | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 5aeafb0..af58953 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4322,6 +4322,10 @@ function doCommentAbandon(comment_id) { dispatch({ type: COMMENT_ABANDON_FAILED }); + dispatch(doToast({ + message: 'Your channel is still being setup, try again in a few moments.', + isError: true + })); } }).catch(error => { dispatch({ diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 4c6f876..5ddd34b 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -135,6 +135,12 @@ export function doCommentAbandon(comment_id: string) { dispatch({ type: ACTIONS.COMMENT_ABANDON_FAILED, }); + dispatch( + doToast({ + message: 'Your channel is still being setup, try again in a few moments.', + isError: true, + }) + ); } }) .catch(error => { -- 2.45.2 From e8602bdf5ef03ca909c11420bc8a10d8eaa4ee9f Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 29 Jan 2020 14:07:43 -0500 Subject: [PATCH 252/371] yarn build --- dist/bundle.es.js | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index af58953..116bb55 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1252,18 +1252,6 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); const { claimId, claimName, contentName } = deprecatedParts; - { - if (claimId) { - console.error(__("'claimId' should no longer be used. Use 'streamClaimId' or 'channelClaimId' instead")); - } - if (claimName) { - console.error(__("'claimName' should no longer be used. Use 'streamClaimName' or 'channelClaimName' instead")); - } - if (contentName) { - console.error(__("'contentName' should no longer be used. Use 'streamName' instead")); - } - } - if (!claimName && !channelName && !streamName) { console.error(__("'claimName', 'channelName', and 'streamName' are all empty. One must be present to build a url.")); } -- 2.45.2 From b5bbece10db5433cab922a773ae42310f6470a66 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 29 Jan 2020 14:18:15 -0500 Subject: [PATCH 253/371] fix typo --- dist/bundle.es.js | 6 +++--- src/redux/actions/comments.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 116bb55..29c130f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -285,7 +285,7 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; // Sync const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; -var ACTIONS = /*#__PURE__*/Object.freeze({ +var action_types = /*#__PURE__*/Object.freeze({ WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -4351,7 +4351,7 @@ function doCommentUpdate(comment_id, comment) { } else { // the result will return null dispatch({ - type: undefined + type: COMMENT_UPDATE_FAILED }); dispatch(doToast({ message: 'Your channel is still being setup, try again in a few moments.', @@ -5916,7 +5916,7 @@ const selectChannelIsBlocked = uri => reselect.createSelector(selectBlockedChann return state.includes(uri); }); -exports.ACTIONS = ACTIONS; +exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; exports.DAEMON_SETTINGS = daemon_settings; exports.DEFAULT_FOLLOWED_TAGS = DEFAULT_FOLLOWED_TAGS; diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 5ddd34b..0bcb8cb 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -182,7 +182,7 @@ export function doCommentUpdate(comment_id: string, comment: string) { } else { // the result will return null dispatch({ - type: ACTIONS.COMENT_UPDATE_FAILED, + type: ACTIONS.COMMENT_UPDATE_FAILED, }); dispatch( doToast({ -- 2.45.2 From d8c65c5bd3e9de579e28c4570edc61ac7f8b3282 Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 28 Jan 2020 16:33:35 -0500 Subject: [PATCH 254/371] support blocking mature recommended results if uri is not mature --- src/redux/selectors/claims.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 6adf368..8a93eb0 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -499,7 +499,8 @@ export const makeSelectRecommendedContentForUri = (uri: string) => createSelector( makeSelectClaimForUri(uri), selectSearchUrisByQuery, - (claim, searchUrisByQuery) => { + makeSelectClaimIsNsfw(uri), + (claim, searchUrisByQuery, isMature) => { const atVanityURI = !uri.includes('#'); let recommendedContent; @@ -513,9 +514,11 @@ export const makeSelectRecommendedContentForUri = (uri: string) => return; } - const searchQuery = getSearchQueryString(title.replace(/\//, ' '), undefined, undefined, { - related_to: claim.claim_id, - }); + const options = { related_to: claim.claim_id } + if (!isMature) { + options['nsfw'] = false; + } + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), undefined, undefined, options); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { -- 2.45.2 From 71e85536dbe397df98a47a3c4b4311760b2e7419 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 29 Jan 2020 14:20:59 -0500 Subject: [PATCH 255/371] rebase --- dist/bundle.es.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 29c130f..7df3d24 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2220,7 +2220,7 @@ claim => { return isClaimNsfw(claim); }); -const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), selectSearchUrisByQuery, (claim, searchUrisByQuery) => { +const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), selectSearchUrisByQuery, makeSelectClaimIsNsfw(uri), (claim, searchUrisByQuery, isMature) => { const atVanityURI = !uri.includes('#'); let recommendedContent; @@ -2234,9 +2234,11 @@ const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSe return; } - const searchQuery = getSearchQueryString(title.replace(/\//, ' '), undefined, undefined, { - related_to: claim.claim_id - }); + const options = { related_to: claim.claim_id }; + if (!isMature) { + options['nsfw'] = false; + } + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), undefined, undefined, options); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { -- 2.45.2 From f77bee9cf1456f84128fdb74aaf756ec7fd1b8c8 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 30 Jan 2020 17:13:40 -0500 Subject: [PATCH 256/371] handle repost claims --- dist/bundle.es.js | 255 ++++++++++++++++++---------------- dist/flow-typed/Claim.js | 1 + flow-typed/Claim.js | 1 + src/redux/selectors/claims.js | 18 ++- 4 files changed, 152 insertions(+), 123 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 29c130f..de556f7 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1934,7 +1934,7 @@ function concatClaims(claimList = [], concatClaimList = []) { return claims; } -// +var _extends$4 = 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; }; const selectState$2 = state => state.claims || {}; const selectClaimsById = reselect.createSelector(selectState$2, state => state.byId || {}); @@ -2003,7 +2003,7 @@ const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, valid = true; } catch (e) {} - if (valid) { + if (valid && byUri) { const claimId = isChannel ? channelClaimId : streamClaimId; const pendingClaim = pendingById[claimId]; @@ -2011,7 +2011,20 @@ const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, return pendingClaim; } - return byUri && byUri[normalizeURI(uri)]; + const claim = byUri[normalizeURI(uri)]; + if (claim === undefined || claim === null) { + // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) + return claim; + } + + const repostedClaim = claim.reposted_claim; + if (repostedClaim) { + return _extends$4({}, repostedClaim, { + repost_channel_url: claim.canonical_url + }); + } else { + return claim; + } } }); @@ -2767,7 +2780,7 @@ function batchActions(...actions) { }; } -var _extends$4 = 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; }; +var _extends$5 = 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) { return (dispatch, getState) => { @@ -2807,7 +2820,7 @@ function doResolveUris(uris, returnCachedClaims = false) { // https://github.com/facebook/flow/issues/2221 if (uriResolveInfo) { if (uriResolveInfo.error) { - resolveInfo[uri] = _extends$4({}, fallbackResolveInfo); + resolveInfo[uri] = _extends$5({}, fallbackResolveInfo); } else { let result = {}; if (uriResolveInfo.value_type === 'channel') { @@ -3497,7 +3510,7 @@ function doSetFileListSort(page, value) { }; } -var _extends$5 = 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; }; +var _extends$6 = 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$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; } @@ -3540,7 +3553,7 @@ const selectPublishFormValues = reselect.createSelector(selectState$5, selectIsS } else { actualLanguage = language || 'en'; } - return _extends$5({}, formValues, { language: actualLanguage }); + return _extends$6({}, formValues, { language: actualLanguage }); }); const makeSelectPublishFormValue = item => reselect.createSelector(selectState$5, state => state[item]); @@ -3595,7 +3608,7 @@ const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClai return null; }); -var _extends$6 = 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; }; +var _extends$7 = 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; }; const doResetThumbnailStatus = () => dispatch => { dispatch({ @@ -3633,7 +3646,7 @@ const doClearPublish = () => dispatch => { const doUpdatePublishForm = publishFormValue => dispatch => dispatch({ type: UPDATE_PUBLISH_FORM, - data: _extends$6({}, publishFormValue) + data: _extends$7({}, publishFormValue) }); const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => dispatch => { @@ -4381,7 +4394,7 @@ const doToggleBlockChannel = uri => ({ } }); -var _extends$7 = 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; }; +var _extends$8 = 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; }; const reducers = {}; const defaultState = { @@ -4484,7 +4497,7 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$7({}, handleClaimAction(state, action)); + return _extends$8({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -4657,7 +4670,7 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; -reducers[CREATE_CHANNEL_STARTED] = state => _extends$7({}, state, { +reducers[CREATE_CHANNEL_STARTED] = state => _extends$8({}, state, { creatingChannel: true, createChannelError: null }); @@ -4745,7 +4758,7 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { delete fetchingClaimSearchByQuery[query]; - return Object.assign({}, state, _extends$7({}, handleClaimAction(state, action), { + return Object.assign({}, state, _extends$8({}, handleClaimAction(state, action), { claimSearchByQuery, claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery @@ -4785,7 +4798,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -var _extends$8 = 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; }; +var _extends$9 = 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; }; const defaultState$1 = { commentById: {}, // commentId -> Comment @@ -4796,11 +4809,11 @@ const defaultState$1 = { }; const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$8({}, state, { + [COMMENT_CREATE_STARTED]: (state, action) => _extends$9({}, state, { isLoading: true }), - [COMMENT_CREATE_FAILED]: (state, action) => _extends$8({}, state, { + [COMMENT_CREATE_FAILED]: (state, action) => _extends$9({}, state, { isLoading: false }), @@ -4818,14 +4831,14 @@ const commentReducer = handleActions({ newCommentIds.unshift(comment.comment_id); byId[claimId] = newCommentIds; - return _extends$8({}, state, { + return _extends$9({}, state, { commentById, byId, isLoading: false }); }, - [COMMENT_LIST_STARTED]: state => _extends$8({}, state, { isLoading: true }), + [COMMENT_LIST_STARTED]: state => _extends$9({}, state, { isLoading: true }), [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; @@ -4849,7 +4862,7 @@ const commentReducer = handleActions({ byId[claimId] = commentIds; commentsByUri[uri] = claimId; } - return _extends$8({}, state, { + return _extends$9({}, state, { byId, commentById, commentsByUri, @@ -4857,10 +4870,10 @@ const commentReducer = handleActions({ }); }, - [COMMENT_LIST_FAILED]: (state, action) => _extends$8({}, state, { + [COMMENT_LIST_FAILED]: (state, action) => _extends$9({}, state, { isLoading: false }), - [COMMENT_ABANDON_STARTED]: (state, action) => _extends$8({}, state, { + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$9({}, state, { isLoading: true }), [COMMENT_ABANDON_COMPLETED]: (state, action) => { @@ -4878,18 +4891,18 @@ const commentReducer = handleActions({ } delete commentById[comment_id]; - return _extends$8({}, state, { + return _extends$9({}, state, { commentById, byId, isLoading: false }); }, // do nothing - [COMMENT_ABANDON_FAILED]: (state, action) => _extends$8({}, state, { + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$9({}, state, { isLoading: false }), // do nothing - [COMMENT_UPDATE_STARTED]: (state, action) => _extends$8({}, state, { + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$9({}, state, { isLoading: true }), // replace existing comment with comment returned here under its comment_id @@ -4898,29 +4911,29 @@ const commentReducer = handleActions({ const commentById = Object.assign({}, state.commentById); commentById[comment.comment_id] = comment; - return _extends$8({}, state, { + return _extends$9({}, state, { commentById, isLoading: false }); }, // nothing can be done here - [COMMENT_UPDATE_FAILED]: (state, action) => _extends$8({}, state, { + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$9({}, state, { isLoading: false }), // nothing can really be done here - [COMMENT_HIDE_STARTED]: (state, action) => _extends$8({}, state, { + [COMMENT_HIDE_STARTED]: (state, action) => _extends$9({}, state, { isLoading: true }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$8({}, state, { // todo: add HiddenComments state & create selectors + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$9({}, state, { // todo: add HiddenComments state & create selectors isLoading: false }), // nothing can be done here - [COMMENT_HIDE_FAILED]: (state, action) => _extends$8({}, state, { + [COMMENT_HIDE_FAILED]: (state, action) => _extends$9({}, state, { isLoading: false }) }, defaultState$1); -var _extends$9 = 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; }; +var _extends$a = 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; }; const reducers$1 = {}; const defaultState$2 = { @@ -4929,9 +4942,9 @@ const defaultState$2 = { reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$9({}, state, { - positions: _extends$9({}, state.positions, { - [claimId]: _extends$9({}, state.positions[claimId], { + return _extends$a({}, state, { + positions: _extends$a({}, state.positions, { + [claimId]: _extends$a({}, state.positions[claimId], { [outpoint]: position }) }) @@ -5098,7 +5111,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -var _extends$a = 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; }; +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; }; const reducers$3 = {}; const defaultState$4 = { @@ -5114,7 +5127,7 @@ reducers$3[PURCHASE_URI_STARTED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$a({}, state, { + return _extends$b({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: '' }); @@ -5132,7 +5145,7 @@ reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$a({}, state, { + return _extends$b({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, purchaseUriErrorMessage: '' @@ -5147,7 +5160,7 @@ reducers$3[PURCHASE_URI_FAILED] = (state, action) => { newFailedPurchaseUris.push(uri); } - return _extends$a({}, state, { + return _extends$b({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: error }); @@ -5160,7 +5173,7 @@ reducers$3[DELETE_PURCHASED_URI] = (state, action) => { newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); } - return _extends$a({}, state, { + return _extends$b({}, state, { purchasedUris: newPurchasedUris }); }; @@ -5171,7 +5184,7 @@ function fileReducer(state = defaultState$4, action) { return state; } -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; }; +var _extends$c = 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; }; const defaultState$5 = { notifications: [], @@ -5186,7 +5199,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$b({}, state, { + return _extends$c({}, state, { toasts: newToasts }); }, @@ -5194,7 +5207,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$b({}, state, { + return _extends$c({}, state, { toasts: newToasts }); }, @@ -5205,7 +5218,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$b({}, state, { + return _extends$c({}, state, { notifications: newNotifications }); }, @@ -5216,7 +5229,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$b({}, state, { + return _extends$c({}, state, { notifications }); }, @@ -5225,7 +5238,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$b({}, state, { + return _extends$c({}, state, { notifications: newNotifications }); }, @@ -5236,7 +5249,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$b({}, state, { + return _extends$c({}, state, { errors: newErrors }); }, @@ -5244,13 +5257,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$b({}, state, { + return _extends$c({}, state, { errors: newErrors }); } }, defaultState$5); -var _extends$c = 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; }; +var _extends$d = 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$3(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; } @@ -5287,17 +5300,17 @@ const defaultState$6 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$c({}, state, data); + return _extends$d({}, state, data); }, - [CLEAR_PUBLISH]: () => _extends$c({}, defaultState$6), - [PUBLISH_START]: state => _extends$c({}, state, { + [CLEAR_PUBLISH]: () => _extends$d({}, defaultState$6), + [PUBLISH_START]: state => _extends$d({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$c({}, state, { + [PUBLISH_FAIL]: state => _extends$d({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$c({}, state, { + [PUBLISH_SUCCESS]: state => _extends$d({}, state, { publishing: false, publishSuccess: true }), @@ -5312,14 +5325,14 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$c({}, defaultState$6, publishData, { + return _extends$d({}, defaultState$6, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$6); -var _extends$d = 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; }; +var _extends$e = 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; }; const defaultState$7 = { isActive: false, // does the user have any typed text in the search input @@ -5341,23 +5354,23 @@ const defaultState$7 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$d({}, state, { + [SEARCH_START]: state => _extends$e({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$d({}, state, { + return _extends$e({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$d({}, state, { + [SEARCH_FAIL]: state => _extends$e({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$d({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$e({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -5375,24 +5388,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$d({}, state, { + return _extends$e({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$d({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$e({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$d({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$e({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$d({}, state, { - suggestions: _extends$d({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$e({}, state, { + suggestions: _extends$e({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -5400,30 +5413,30 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$d({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$e({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$d({}, state, { + [SEARCH_FOCUS]: state => _extends$e({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$d({}, state, { + [SEARCH_BLUR]: state => _extends$e({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$d({}, oldOptions, newOptions); - return _extends$d({}, state, { + const options = _extends$e({}, oldOptions, newOptions); + return _extends$e({}, state, { options }); } }, defaultState$7); -var _extends$e = 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; }; +var _extends$f = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$e({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$f({}, tagsMap, { [tag]: { name: tag } }), {}); } @@ -5446,7 +5459,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$e({}, state, { + return _extends$f({}, state, { followedTags: newFollowedTags }); }, @@ -5455,10 +5468,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$e({}, knownTags); + let newKnownTags = _extends$f({}, knownTags); newKnownTags[name] = { name }; - return _extends$e({}, state, { + return _extends$f({}, state, { knownTags: newKnownTags }); }, @@ -5467,24 +5480,24 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$e({}, knownTags); + let newKnownTags = _extends$f({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$e({}, state, { + return _extends$f({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); }, [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; - return _extends$e({}, state, { + return _extends$f({}, state, { followedTags: tags && tags.length ? tags : DEFAULT_FOLLOWED_TAGS }); } }, defaultState$8); -var _extends$f = 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; }; +var _extends$g = 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; }; const defaultState$9 = { blockedChannels: [] @@ -5508,13 +5521,13 @@ const blockedReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { blocked } = action.data; - return _extends$f({}, state, { + return _extends$g({}, state, { blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } }, defaultState$9); -var _extends$g = 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; }; +var _extends$h = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -5559,25 +5572,25 @@ const defaultState$a = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$g({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$h({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$g({}, state.transactions); + const byId = _extends$h({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$g({}, state, { + return _extends$h({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$g({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$h({}, state, { fetchingSupports: true }), @@ -5590,7 +5603,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$g({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$h({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -5599,7 +5612,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$g({}, state, { + return _extends$h({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -5612,23 +5625,23 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$g({}, state, { + return _extends$h({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$g({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$h({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$g({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$h({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$g({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$h({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -5637,32 +5650,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$g({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$h({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$g({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$h({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$g({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$h({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$g({}, state, { draftTransaction: newDraft }); + return _extends$h({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$g({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$h({}, oldDraft, { address: action.data.address }); - return _extends$g({}, state, { draftTransaction: newDraft }); + return _extends$h({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$g({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$h({}, state.draftTransaction, { sending: true }); - return _extends$g({}, state, { draftTransaction: newDraftTransaction }); + return _extends$h({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -5675,114 +5688,114 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$g({}, state, { draftTransaction: newDraftTransaction }); + return _extends$h({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$g({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$h({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$g({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$h({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$g({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$h({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$g({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$h({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$g({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$h({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$g({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$h({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$g({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$g({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$h({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$g({}, state, { + [WALLET_DECRYPT_START]: state => _extends$h({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$g({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$g({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$h({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$g({}, state, { + [WALLET_UNLOCK_START]: state => _extends$h({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$g({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$h({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$g({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$h({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$g({}, state, { + [WALLET_LOCK_START]: state => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$g({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$g({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$g({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$h({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$g({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$h({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$g({}, state, { + [WALLET_RESTART]: state => _extends$h({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$g({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$h({}, state, { walletReconnecting: false }) }, defaultState$a); @@ -5800,14 +5813,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$h = 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; }; +var _extends$i = 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; }; const selectState$7 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$7, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$h({ + return _extends$i({ id }, params); } diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 54e414f..5ebe5e9 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -33,6 +33,7 @@ declare type GenericClaim = { type: 'claim' | 'update' | 'support', value_type: 'stream' | 'channel', signing_channel?: ChannelClaim, + repost_channel_url?: string, meta: { activation_height: number, claims_in_channel?: number, diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 54e414f..5ebe5e9 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -33,6 +33,7 @@ declare type GenericClaim = { type: 'claim' | 'update' | 'support', value_type: 'stream' | 'channel', signing_channel?: ChannelClaim, + repost_channel_url?: string, meta: { activation_height: number, claims_in_channel?: number, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 6adf368..900f8d7 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -114,7 +114,7 @@ export const makeSelectClaimForUri = (uri: string) => valid = true; } catch (e) {} - if (valid) { + if (valid && byUri) { const claimId = isChannel ? channelClaimId : streamClaimId; const pendingClaim = pendingById[claimId]; @@ -122,7 +122,21 @@ export const makeSelectClaimForUri = (uri: string) => return pendingClaim; } - return byUri && byUri[normalizeURI(uri)]; + const claim = byUri[normalizeURI(uri)]; + if (claim === undefined || claim === null) { + // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) + return claim; + } + + const repostedClaim = claim.reposted_claim; + if (repostedClaim) { + return { + ...repostedClaim, + repost_channel_url: claim.canonical_url, + }; + } else { + return claim; + } } } ); -- 2.45.2 From bfbaa0dbdd2c1b2b340c0760d0d97c99f3cefb02 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 30 Jan 2020 17:44:08 -0500 Subject: [PATCH 257/371] fix typo --- dist/bundle.es.js | 4 +++- src/redux/selectors/claims.js | 17 ++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 523d972..f029ce8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2019,8 +2019,10 @@ const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, const repostedClaim = claim.reposted_claim; if (repostedClaim) { + const channelUrl = claim.signing_channel && claim.signing_channel.canonical_url; + return _extends$4({}, repostedClaim, { - repost_channel_url: claim.canonical_url + repost_channel_url: channelUrl }); } else { return claim; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 51e5e33..cc8aff6 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -130,9 +130,11 @@ export const makeSelectClaimForUri = (uri: string) => const repostedClaim = claim.reposted_claim; if (repostedClaim) { + const channelUrl = claim.signing_channel && claim.signing_channel.canonical_url; + return { ...repostedClaim, - repost_channel_url: claim.canonical_url, + repost_channel_url: channelUrl, }; } else { return claim; @@ -277,8 +279,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -528,11 +530,16 @@ export const makeSelectRecommendedContentForUri = (uri: string) => return; } - const options = { related_to: claim.claim_id } + const options = { related_to: claim.claim_id }; if (!isMature) { options['nsfw'] = false; } - const searchQuery = getSearchQueryString(title.replace(/\//, ' '), undefined, undefined, options); + const searchQuery = getSearchQueryString( + title.replace(/\//, ' '), + undefined, + undefined, + options + ); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { -- 2.45.2 From 635381a616da9da31bba33637ca0dcaaf9692053 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 30 Jan 2020 01:30:27 -0500 Subject: [PATCH 258/371] convert search options to expandable object wip bundle --- dist/bundle.es.js | 63 ++++++++++++++++++++++++----------- src/redux/actions/search.js | 51 +++++++++++++++++++++------- src/redux/selectors/claims.js | 21 ++++++------ src/redux/selectors/search.js | 25 +++++++------- src/util/query-params.js | 10 ++++-- 5 files changed, 114 insertions(+), 56 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f029ce8..d619f34 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1071,9 +1071,11 @@ function toQueryString(params) { return parts.join('&'); } -const getSearchQueryString = (query, options = {}, includeUserOptions = false, additionalOptions = {}) => { +const getSearchQueryString = (query, options = {}) => { const encodedQuery = encodeURIComponent(query); const queryParams = [`s=${encodedQuery}`, `size=${options.size || DEFAULT_SEARCH_SIZE}`, `from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`]; + const { isBackgroundSearch } = options; + const includeUserOptions = typeof isBackgroundSearch === 'undefined' ? false : !isBackgroundSearch; if (includeUserOptions) { const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; @@ -1085,6 +1087,12 @@ const getSearchQueryString = (query, options = {}, includeUserOptions = false, a } } + const additionalOptions = {}; + const { related_to } = options; + const { nsfw } = options; + if (related_to) additionalOptions['related_to'] = related_to; + if (typeof nsfw !== 'undefined') additionalOptions['nsfw'] = nsfw; + if (additionalOptions) { Object.keys(additionalOptions).forEach(key => { const option = additionalOptions[key]; @@ -1443,11 +1451,11 @@ const selectSearchSuggestions = reselect.createSelector(selectSearchValue, selec // Creates a query string based on the state in the search reducer // Can be overrided by passing in custom sizes/from values for other areas pagination -const makeSelectQueryWithOptions = (customQuery, customSize, customFrom, isBackgroundSearch = false, // If it's a background search, don't use the users settings -additionalOptions = {}) => reselect.createSelector(selectSearchValue, selectSearchOptions, (query, options) => { - const size = customSize || options[SEARCH_OPTIONS.RESULT_COUNT]; - const queryString = getSearchQueryString(customQuery || query, _extends$1({}, options, { size, from: customFrom }), !isBackgroundSearch, additionalOptions); + +const makeSelectQueryWithOptions = (customQuery, options) => reselect.createSelector(selectSearchValue, selectSearchOptions, (query, defaultOptions) => { + const searchOptions = _extends$1({}, defaultOptions, options); + const queryString = getSearchQueryString(customQuery || query, searchOptions); return queryString; }); @@ -2249,11 +2257,11 @@ const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSe return; } - const options = { related_to: claim.claim_id }; + const options = { related_to: claim.claim_id, isBackgroundSearch: true }; if (!isMature) { options['nsfw'] = false; } - const searchQuery = getSearchQueryString(title.replace(/\//, ' '), undefined, undefined, options); + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { @@ -2326,7 +2334,7 @@ const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(sele const selectMyStreamUrlsCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); -const makeSelectResolvedRecommendedContentForUri = (uri, size) => reselect.createSelector(makeSelectClaimForUri(uri), selectResolvedSearchResultsByQuery, (claim, resolvedResultsByQuery) => { +const makeSelectResolvedRecommendedContentForUri = (uri, size) => reselect.createSelector(makeSelectClaimForUri(uri), selectResolvedSearchResultsByQuery, makeSelectClaimIsNsfw(uri), (claim, resolvedResultsByQuery, isMature) => { const atVanityURI = !uri.includes('#'); let recommendedContent; @@ -2340,9 +2348,12 @@ const makeSelectResolvedRecommendedContentForUri = (uri, size) => reselect.creat return; } - const searchQuery = getSearchQueryString(title.replace(/\//, ' '), { size }, undefined, { - related_to: claim.claim_id - }); + const options = { related_to: claim.claim_id, isBackgroundSearch: true }; + if (!isMature) { + options['nsfw'] = false; + } + + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); let results = resolvedResultsByQuery[searchQuery]; if (results) { @@ -3968,7 +3979,7 @@ function handleFetchResponse(response) { return response.status === 200 ? Promise.resolve(response.json()) : Promise.reject(new Error(response.statusText)); } -// +var _extends$7 = 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; }; const DEBOUNCED_SEARCH_SUGGESTION_MS = 300; @@ -4025,9 +4036,10 @@ const doUpdateSearchQuery = (query, shouldSkipSuggestions) => dispatch => { } }; -const doSearch = (rawQuery, size, // only pass in if you don't want to use the users setting (ex: related content) -from, isBackgroundSearch = false, options = {}, resolveResults = true) => (dispatch, getState) => { +const doSearch = (rawQuery, searchOptions) => (dispatch, getState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); + const resolveResults = searchOptions && searchOptions.resolveResults; + const isBackgroundSearch = searchOptions && searchOptions.isBackgroundSearch || false; if (!query) { dispatch({ @@ -4037,7 +4049,8 @@ from, isBackgroundSearch = false, options = {}, resolveResults = true) => (dispa } const state = getState(); - let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)(state); + + let queryWithOptions = makeSelectQueryWithOptions(query, searchOptions)(state); // If we have already searched for something, we don't need to do anything const urisForQuery = makeSelectSearchUris(queryWithOptions)(state); @@ -4108,11 +4121,23 @@ from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => { return; } + const optionsWithFrom = _extends$7({ + size, + from, + isBackgroundSearch + }, options); + + const optionsWithoutFrom = _extends$7({ + size, + isBackgroundSearch + }, options); + const state = getState(); - let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)(state); + + let queryWithOptions = makeSelectQueryWithOptions(query, optionsWithFrom)(state); // make from null so that we can maintain a reference to the same query for multiple pages and simply append the found results - let queryWithoutFrom = makeSelectQueryWithOptions(query, size, null, isBackgroundSearch, options)(state); + let queryWithoutFrom = makeSelectQueryWithOptions(query, optionsWithoutFrom)(state); // If we have already searched for something, we don't need to do anything // TODO: Tweak this check for multiple page results @@ -4162,7 +4187,7 @@ const doBlurSearchInput = () => dispatch => dispatch({ type: SEARCH_BLUR }); -const doUpdateSearchOptions = newOptions => (dispatch, getState) => { +const doUpdateSearchOptions = (newOptions, additionalOptions) => (dispatch, getState) => { const state = getState(); const searchValue = selectSearchValue(state); @@ -4173,7 +4198,7 @@ const doUpdateSearchOptions = newOptions => (dispatch, getState) => { if (searchValue) { // After updating, perform a search with the new options - dispatch(doSearch(searchValue)); + dispatch(doSearch(searchValue, additionalOptions)); } }; diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index e00d7ba..9701929 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -17,6 +17,20 @@ const DEBOUNCED_SEARCH_SUGGESTION_MS = 300; type Dispatch = (action: any) => any; type GetState = () => { search: SearchState }; +type SearchOptions = { + size?: number, + from?: number, + related_to?: string, + nsfw?: boolean, + isBackgroundSearch?: boolean, + resolveResults?: boolean, +} + +type AdditionalOptions = { + isBackgroundSearch: boolean, + nsfw?: boolean, +} + // We can't use env's because they aren't passed into node_modules let CONNECTION_STRING = 'https://lighthouse.lbry.com/'; @@ -75,17 +89,14 @@ export const doUpdateSearchQuery = (query: string, shouldSkipSuggestions: ?boole } }; + export const doSearch = ( rawQuery: string, - size: ?number, // only pass in if you don't want to use the users setting (ex: related content) - from: ?number, - isBackgroundSearch: boolean = false, - options: { - related_to?: string, - } = {}, - resolveResults: boolean = true + searchOptions: SearchOptions, ) => (dispatch: Dispatch, getState: GetState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); + const resolveResults = searchOptions && searchOptions.resolveResults; + const isBackgroundSearch = (searchOptions && searchOptions.isBackgroundSearch) || false; if (!query) { dispatch({ @@ -95,7 +106,8 @@ export const doSearch = ( } const state = getState(); - let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)( + + let queryWithOptions = makeSelectQueryWithOptions(query, searchOptions)( state ); @@ -167,6 +179,7 @@ export const doResolvedSearch = ( isBackgroundSearch: boolean = false, options: { related_to?: string, + // nsfw here } = {} ) => (dispatch: Dispatch, getState: GetState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); @@ -178,13 +191,27 @@ export const doResolvedSearch = ( return; } + const optionsWithFrom: SearchOptions = { + size, + from, + isBackgroundSearch, + ...options, + } + + const optionsWithoutFrom: SearchOptions = { + size, + isBackgroundSearch, + ...options, + } + const state = getState(); - let queryWithOptions = makeSelectQueryWithOptions(query, size, from, isBackgroundSearch, options)( + + let queryWithOptions = makeSelectQueryWithOptions(query, optionsWithFrom)( state ); // make from null so that we can maintain a reference to the same query for multiple pages and simply append the found results - let queryWithoutFrom = makeSelectQueryWithOptions(query, size, null, isBackgroundSearch, options)( + let queryWithoutFrom = makeSelectQueryWithOptions(query, optionsWithoutFrom)( state ); @@ -241,7 +268,7 @@ export const doBlurSearchInput = () => (dispatch: Dispatch) => type: ACTIONS.SEARCH_BLUR, }); -export const doUpdateSearchOptions = (newOptions: SearchOptions) => ( +export const doUpdateSearchOptions = (newOptions: SearchOptions, additionalOptions: AdditionalOptions) => ( dispatch: Dispatch, getState: GetState ) => { @@ -255,6 +282,6 @@ export const doUpdateSearchOptions = (newOptions: SearchOptions) => ( if (searchValue) { // After updating, perform a search with the new options - dispatch(doSearch(searchValue)); + dispatch(doSearch(searchValue, additionalOptions)); } }; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index cc8aff6..c7f489b 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -530,16 +530,11 @@ export const makeSelectRecommendedContentForUri = (uri: string) => return; } - const options = { related_to: claim.claim_id }; + const options = { related_to: claim.claim_id, isBackgroundSearch: true }; if (!isMature) { options['nsfw'] = false; } - const searchQuery = getSearchQueryString( - title.replace(/\//, ' '), - undefined, - undefined, - options - ); + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); let searchUris = searchUrisByQuery[searchQuery]; if (searchUris) { @@ -671,7 +666,8 @@ export const makeSelectResolvedRecommendedContentForUri = (uri: string, size: nu createSelector( makeSelectClaimForUri(uri), selectResolvedSearchResultsByQuery, - (claim, resolvedResultsByQuery) => { + makeSelectClaimIsNsfw(uri), + (claim, resolvedResultsByQuery, isMature) => { const atVanityURI = !uri.includes('#'); let recommendedContent; @@ -685,9 +681,12 @@ export const makeSelectResolvedRecommendedContentForUri = (uri: string, size: nu return; } - const searchQuery = getSearchQueryString(title.replace(/\//, ' '), { size }, undefined, { - related_to: claim.claim_id, - }); + const options = { related_to: claim.claim_id, isBackgroundSearch: true } + if (!isMature) { + options['nsfw'] = false; + } + + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); let results = resolvedResultsByQuery[searchQuery]; if (results) { diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index 48dca04..e3efd11 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -165,26 +165,27 @@ export const selectSearchSuggestions: Array = createSelector( // Creates a query string based on the state in the search reducer // Can be overrided by passing in custom sizes/from values for other areas pagination + +type CustomOptions = { + isBackgroundSearch?: boolean, + size?: number, + from?: number, + related_to?: string, + nsfw?: boolean, +} + export const makeSelectQueryWithOptions = ( customQuery: ?string, - customSize: ?number, - customFrom: ?number, - isBackgroundSearch: boolean = false, // If it's a background search, don't use the users settings - additionalOptions: { - related_to?: string, - } = {} + options: CustomOptions, ) => createSelector( selectSearchValue, selectSearchOptions, - (query, options) => { - const size = customSize || options[SEARCH_OPTIONS.RESULT_COUNT]; - + (query, defaultOptions) => { + const searchOptions = { ...defaultOptions, ...options }; const queryString = getSearchQueryString( customQuery || query, - { ...options, size, from: customFrom }, - !isBackgroundSearch, - additionalOptions + searchOptions, ); return queryString; diff --git a/src/util/query-params.js b/src/util/query-params.js index 7a3da29..80a1d54 100644 --- a/src/util/query-params.js +++ b/src/util/query-params.js @@ -36,8 +36,6 @@ export function toQueryString(params: { [string]: string | number }) { export const getSearchQueryString = ( query: string, options: any = {}, - includeUserOptions: boolean = false, - additionalOptions: {} = {} ) => { const encodedQuery = encodeURIComponent(query); const queryParams = [ @@ -45,6 +43,8 @@ export const getSearchQueryString = ( `size=${options.size || DEFAULT_SEARCH_SIZE}`, `from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`, ]; + const { isBackgroundSearch } = options; + const includeUserOptions = typeof isBackgroundSearch === 'undefined' ? false : !isBackgroundSearch; if (includeUserOptions) { const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; @@ -68,6 +68,12 @@ export const getSearchQueryString = ( } } + const additionalOptions = {} + const { related_to } = options; + const { nsfw } = options; + if (related_to) additionalOptions['related_to'] = related_to; + if (typeof nsfw !== 'undefined') additionalOptions['nsfw'] = nsfw; + if (additionalOptions) { Object.keys(additionalOptions).forEach(key => { const option = additionalOptions[key]; -- 2.45.2 From 2b01ce4e79be9e2de11223a4065994567cfc6324 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 30 Jan 2020 18:01:27 -0500 Subject: [PATCH 259/371] fix flow errors --- dist/bundle.es.js | 231 +++++++++++++++++----------------- src/redux/actions/search.js | 46 +++---- src/redux/selectors/claims.js | 17 ++- 3 files changed, 146 insertions(+), 148 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d619f34..07d9eea 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2258,6 +2258,7 @@ const makeSelectRecommendedContentForUri = uri => reselect.createSelector(makeSe } const options = { related_to: claim.claim_id, isBackgroundSearch: true }; + if (!isMature) { options['nsfw'] = false; } @@ -3979,7 +3980,7 @@ function handleFetchResponse(response) { return response.status === 200 ? Promise.resolve(response.json()) : Promise.reject(new Error(response.statusText)); } -var _extends$7 = 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; }; +var _extends$8 = 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; }; const DEBOUNCED_SEARCH_SUGGESTION_MS = 300; @@ -4121,13 +4122,13 @@ from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => { return; } - const optionsWithFrom = _extends$7({ + const optionsWithFrom = _extends$8({ size, from, isBackgroundSearch }, options); - const optionsWithoutFrom = _extends$7({ + const optionsWithoutFrom = _extends$8({ size, isBackgroundSearch }, options); @@ -4423,7 +4424,7 @@ const doToggleBlockChannel = uri => ({ } }); -var _extends$8 = 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; }; +var _extends$9 = 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; }; const reducers = {}; const defaultState = { @@ -4526,7 +4527,7 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$8({}, handleClaimAction(state, action)); + return _extends$9({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -4699,7 +4700,7 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; -reducers[CREATE_CHANNEL_STARTED] = state => _extends$8({}, state, { +reducers[CREATE_CHANNEL_STARTED] = state => _extends$9({}, state, { creatingChannel: true, createChannelError: null }); @@ -4787,7 +4788,7 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { delete fetchingClaimSearchByQuery[query]; - return Object.assign({}, state, _extends$8({}, handleClaimAction(state, action), { + return Object.assign({}, state, _extends$9({}, handleClaimAction(state, action), { claimSearchByQuery, claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery @@ -4827,7 +4828,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -var _extends$9 = 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; }; +var _extends$a = 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; }; const defaultState$1 = { commentById: {}, // commentId -> Comment @@ -4838,11 +4839,11 @@ const defaultState$1 = { }; const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$9({}, state, { + [COMMENT_CREATE_STARTED]: (state, action) => _extends$a({}, state, { isLoading: true }), - [COMMENT_CREATE_FAILED]: (state, action) => _extends$9({}, state, { + [COMMENT_CREATE_FAILED]: (state, action) => _extends$a({}, state, { isLoading: false }), @@ -4860,14 +4861,14 @@ const commentReducer = handleActions({ newCommentIds.unshift(comment.comment_id); byId[claimId] = newCommentIds; - return _extends$9({}, state, { + return _extends$a({}, state, { commentById, byId, isLoading: false }); }, - [COMMENT_LIST_STARTED]: state => _extends$9({}, state, { isLoading: true }), + [COMMENT_LIST_STARTED]: state => _extends$a({}, state, { isLoading: true }), [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; @@ -4891,7 +4892,7 @@ const commentReducer = handleActions({ byId[claimId] = commentIds; commentsByUri[uri] = claimId; } - return _extends$9({}, state, { + return _extends$a({}, state, { byId, commentById, commentsByUri, @@ -4899,10 +4900,10 @@ const commentReducer = handleActions({ }); }, - [COMMENT_LIST_FAILED]: (state, action) => _extends$9({}, state, { + [COMMENT_LIST_FAILED]: (state, action) => _extends$a({}, state, { isLoading: false }), - [COMMENT_ABANDON_STARTED]: (state, action) => _extends$9({}, state, { + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$a({}, state, { isLoading: true }), [COMMENT_ABANDON_COMPLETED]: (state, action) => { @@ -4920,18 +4921,18 @@ const commentReducer = handleActions({ } delete commentById[comment_id]; - return _extends$9({}, state, { + return _extends$a({}, state, { commentById, byId, isLoading: false }); }, // do nothing - [COMMENT_ABANDON_FAILED]: (state, action) => _extends$9({}, state, { + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$a({}, state, { isLoading: false }), // do nothing - [COMMENT_UPDATE_STARTED]: (state, action) => _extends$9({}, state, { + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$a({}, state, { isLoading: true }), // replace existing comment with comment returned here under its comment_id @@ -4940,29 +4941,29 @@ const commentReducer = handleActions({ const commentById = Object.assign({}, state.commentById); commentById[comment.comment_id] = comment; - return _extends$9({}, state, { + return _extends$a({}, state, { commentById, isLoading: false }); }, // nothing can be done here - [COMMENT_UPDATE_FAILED]: (state, action) => _extends$9({}, state, { + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$a({}, state, { isLoading: false }), // nothing can really be done here - [COMMENT_HIDE_STARTED]: (state, action) => _extends$9({}, state, { + [COMMENT_HIDE_STARTED]: (state, action) => _extends$a({}, state, { isLoading: true }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$9({}, state, { // todo: add HiddenComments state & create selectors + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$a({}, state, { // todo: add HiddenComments state & create selectors isLoading: false }), // nothing can be done here - [COMMENT_HIDE_FAILED]: (state, action) => _extends$9({}, state, { + [COMMENT_HIDE_FAILED]: (state, action) => _extends$a({}, state, { isLoading: false }) }, defaultState$1); -var _extends$a = 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; }; +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; }; const reducers$1 = {}; const defaultState$2 = { @@ -4971,9 +4972,9 @@ const defaultState$2 = { reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$a({}, state, { - positions: _extends$a({}, state.positions, { - [claimId]: _extends$a({}, state.positions[claimId], { + return _extends$b({}, state, { + positions: _extends$b({}, state.positions, { + [claimId]: _extends$b({}, state.positions[claimId], { [outpoint]: position }) }) @@ -5140,7 +5141,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -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; }; +var _extends$c = 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; }; const reducers$3 = {}; const defaultState$4 = { @@ -5156,7 +5157,7 @@ reducers$3[PURCHASE_URI_STARTED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$b({}, state, { + return _extends$c({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: '' }); @@ -5174,7 +5175,7 @@ reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); } - return _extends$b({}, state, { + return _extends$c({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchasedUris: newPurchasedUris, purchaseUriErrorMessage: '' @@ -5189,7 +5190,7 @@ reducers$3[PURCHASE_URI_FAILED] = (state, action) => { newFailedPurchaseUris.push(uri); } - return _extends$b({}, state, { + return _extends$c({}, state, { failedPurchaseUris: newFailedPurchaseUris, purchaseUriErrorMessage: error }); @@ -5202,7 +5203,7 @@ reducers$3[DELETE_PURCHASED_URI] = (state, action) => { newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); } - return _extends$b({}, state, { + return _extends$c({}, state, { purchasedUris: newPurchasedUris }); }; @@ -5213,7 +5214,7 @@ function fileReducer(state = defaultState$4, action) { return state; } -var _extends$c = 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; }; +var _extends$d = 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; }; const defaultState$5 = { notifications: [], @@ -5228,7 +5229,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$c({}, state, { + return _extends$d({}, state, { toasts: newToasts }); }, @@ -5236,7 +5237,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$c({}, state, { + return _extends$d({}, state, { toasts: newToasts }); }, @@ -5247,7 +5248,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$c({}, state, { + return _extends$d({}, state, { notifications: newNotifications }); }, @@ -5258,7 +5259,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$c({}, state, { + return _extends$d({}, state, { notifications }); }, @@ -5267,7 +5268,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$c({}, state, { + return _extends$d({}, state, { notifications: newNotifications }); }, @@ -5278,7 +5279,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$c({}, state, { + return _extends$d({}, state, { errors: newErrors }); }, @@ -5286,13 +5287,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$c({}, state, { + return _extends$d({}, state, { errors: newErrors }); } }, defaultState$5); -var _extends$d = 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; }; +var _extends$e = 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$3(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; } @@ -5329,17 +5330,17 @@ const defaultState$6 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$d({}, state, data); + return _extends$e({}, state, data); }, - [CLEAR_PUBLISH]: () => _extends$d({}, defaultState$6), - [PUBLISH_START]: state => _extends$d({}, state, { + [CLEAR_PUBLISH]: () => _extends$e({}, defaultState$6), + [PUBLISH_START]: state => _extends$e({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$d({}, state, { + [PUBLISH_FAIL]: state => _extends$e({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$d({}, state, { + [PUBLISH_SUCCESS]: state => _extends$e({}, state, { publishing: false, publishSuccess: true }), @@ -5354,14 +5355,14 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$d({}, defaultState$6, publishData, { + return _extends$e({}, defaultState$6, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$6); -var _extends$e = 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; }; +var _extends$f = 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; }; const defaultState$7 = { isActive: false, // does the user have any typed text in the search input @@ -5383,23 +5384,23 @@ const defaultState$7 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$e({}, state, { + [SEARCH_START]: state => _extends$f({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$e({}, state, { + return _extends$f({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$e({}, state, { + [SEARCH_FAIL]: state => _extends$f({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$e({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$f({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -5417,24 +5418,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$e({}, state, { + return _extends$f({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$e({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$f({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$e({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$f({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$e({}, state, { - suggestions: _extends$e({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$f({}, state, { + suggestions: _extends$f({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -5442,30 +5443,30 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$e({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$f({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$e({}, state, { + [SEARCH_FOCUS]: state => _extends$f({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$e({}, state, { + [SEARCH_BLUR]: state => _extends$f({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$e({}, oldOptions, newOptions); - return _extends$e({}, state, { + const options = _extends$f({}, oldOptions, newOptions); + return _extends$f({}, state, { options }); } }, defaultState$7); -var _extends$f = 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; }; +var _extends$g = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$f({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$g({}, tagsMap, { [tag]: { name: tag } }), {}); } @@ -5488,7 +5489,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$f({}, state, { + return _extends$g({}, state, { followedTags: newFollowedTags }); }, @@ -5497,10 +5498,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$f({}, knownTags); + let newKnownTags = _extends$g({}, knownTags); newKnownTags[name] = { name }; - return _extends$f({}, state, { + return _extends$g({}, state, { knownTags: newKnownTags }); }, @@ -5509,24 +5510,24 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$f({}, knownTags); + let newKnownTags = _extends$g({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$f({}, state, { + return _extends$g({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); }, [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; - return _extends$f({}, state, { + return _extends$g({}, state, { followedTags: tags && tags.length ? tags : DEFAULT_FOLLOWED_TAGS }); } }, defaultState$8); -var _extends$g = 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; }; +var _extends$h = 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; }; const defaultState$9 = { blockedChannels: [] @@ -5550,13 +5551,13 @@ const blockedReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { blocked } = action.data; - return _extends$g({}, state, { + return _extends$h({}, state, { blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } }, defaultState$9); -var _extends$h = 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; }; +var _extends$i = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -5601,25 +5602,25 @@ const defaultState$a = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$h({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$i({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$h({}, state.transactions); + const byId = _extends$i({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$h({}, state, { + return _extends$i({}, state, { transactions: byId, fetchingTransactions: false }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$h({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$i({}, state, { fetchingSupports: true }), @@ -5632,7 +5633,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$h({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$i({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -5641,7 +5642,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$h({}, state, { + return _extends$i({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -5654,23 +5655,23 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$h({}, state, { + return _extends$i({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$h({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$h({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$i({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$h({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$i({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -5679,32 +5680,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$h({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$i({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$h({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$i({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$h({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$i({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$h({}, state, { draftTransaction: newDraft }); + return _extends$i({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$h({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$i({}, oldDraft, { address: action.data.address }); - return _extends$h({}, state, { draftTransaction: newDraft }); + return _extends$i({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$h({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$i({}, state.draftTransaction, { sending: true }); - return _extends$h({}, state, { draftTransaction: newDraftTransaction }); + return _extends$i({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -5717,114 +5718,114 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$h({}, state, { draftTransaction: newDraftTransaction }); + return _extends$i({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$h({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$i({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$h({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$i({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$h({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$i({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$h({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$i({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$i({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$h({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$i({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$i({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$h({}, state, { + [WALLET_DECRYPT_START]: state => _extends$i({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$i({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$h({}, state, { + [WALLET_UNLOCK_START]: state => _extends$i({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$i({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$i({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$h({}, state, { + [WALLET_LOCK_START]: state => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$h({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$i({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$h({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$i({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$h({}, state, { + [WALLET_RESTART]: state => _extends$i({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$h({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$i({}, state, { walletReconnecting: false }) }, defaultState$a); @@ -5842,14 +5843,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$i = 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; }; +var _extends$j = 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; }; const selectState$7 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$7, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$i({ + return _extends$j({ id }, params); } diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 9701929..bee1350 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -24,12 +24,7 @@ type SearchOptions = { nsfw?: boolean, isBackgroundSearch?: boolean, resolveResults?: boolean, -} - -type AdditionalOptions = { - isBackgroundSearch: boolean, - nsfw?: boolean, -} +}; // We can't use env's because they aren't passed into node_modules let CONNECTION_STRING = 'https://lighthouse.lbry.com/'; @@ -89,11 +84,10 @@ export const doUpdateSearchQuery = (query: string, shouldSkipSuggestions: ?boole } }; - -export const doSearch = ( - rawQuery: string, - searchOptions: SearchOptions, -) => (dispatch: Dispatch, getState: GetState) => { +export const doSearch = (rawQuery: string, searchOptions: SearchOptions) => ( + dispatch: Dispatch, + getState: GetState +) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); const resolveResults = searchOptions && searchOptions.resolveResults; const isBackgroundSearch = (searchOptions && searchOptions.isBackgroundSearch) || false; @@ -107,9 +101,7 @@ export const doSearch = ( const state = getState(); - let queryWithOptions = makeSelectQueryWithOptions(query, searchOptions)( - state - ); + let queryWithOptions = makeSelectQueryWithOptions(query, searchOptions)(state); // If we have already searched for something, we don't need to do anything const urisForQuery = makeSelectSearchUris(queryWithOptions)(state); @@ -174,9 +166,9 @@ export const doSearch = ( export const doResolvedSearch = ( rawQuery: string, - size: ?number, // only pass in if you don't want to use the users setting (ex: related content) - from: ?number, - isBackgroundSearch: boolean = false, + size?: number, // only pass in if you don't want to use the users setting (ex: related content) + from?: number, + isBackgroundSearch?: boolean = false, options: { related_to?: string, // nsfw here @@ -196,24 +188,20 @@ export const doResolvedSearch = ( from, isBackgroundSearch, ...options, - } + }; const optionsWithoutFrom: SearchOptions = { size, isBackgroundSearch, ...options, - } + }; const state = getState(); - let queryWithOptions = makeSelectQueryWithOptions(query, optionsWithFrom)( - state - ); + let queryWithOptions = makeSelectQueryWithOptions(query, optionsWithFrom)(state); // make from null so that we can maintain a reference to the same query for multiple pages and simply append the found results - let queryWithoutFrom = makeSelectQueryWithOptions(query, optionsWithoutFrom)( - state - ); + let queryWithoutFrom = makeSelectQueryWithOptions(query, optionsWithoutFrom)(state); // If we have already searched for something, we don't need to do anything // TODO: Tweak this check for multiple page results @@ -268,10 +256,10 @@ export const doBlurSearchInput = () => (dispatch: Dispatch) => type: ACTIONS.SEARCH_BLUR, }); -export const doUpdateSearchOptions = (newOptions: SearchOptions, additionalOptions: AdditionalOptions) => ( - dispatch: Dispatch, - getState: GetState -) => { +export const doUpdateSearchOptions = ( + newOptions: SearchOptions, + additionalOptions: SearchOptions +) => (dispatch: Dispatch, getState: GetState) => { const state = getState(); const searchValue = selectSearchValue(state); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index c7f489b..73a3018 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -279,8 +279,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -530,7 +530,12 @@ export const makeSelectRecommendedContentForUri = (uri: string) => return; } - const options = { related_to: claim.claim_id, isBackgroundSearch: true }; + const options: { + related_to?: string, + nsfw?: boolean, + isBackgroundSearch?: boolean, + } = { related_to: claim.claim_id, isBackgroundSearch: true }; + if (!isMature) { options['nsfw'] = false; } @@ -681,7 +686,11 @@ export const makeSelectResolvedRecommendedContentForUri = (uri: string, size: nu return; } - const options = { related_to: claim.claim_id, isBackgroundSearch: true } + const options: { + related_to?: string, + nsfw?: boolean, + isBackgroundSearch?: boolean, + } = { related_to: claim.claim_id, isBackgroundSearch: true }; if (!isMature) { options['nsfw'] = false; } -- 2.45.2 From f0a0a59c4c4cedbbe4c50ec423c5b2e202cbe800 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Sat, 1 Feb 2020 13:33:04 -0500 Subject: [PATCH 260/371] add known tags --- dist/bundle.es.js | 2 +- src/constants/tags.js | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 07d9eea..9153398 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -827,7 +827,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['gaming', 'pop culture', 'Entertainment', 'technology', 'music', 'funny', 'Education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'sony interactive entertainment', 'film & animation', 'game', 'weapons', "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', 'ps4live', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'ps4share', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'xbox', 'autos & vehicles', 'Travel & Events', 'food', 'science', 'xbox one', 'liberal', 'democrat', 'progressive', 'survival', 'Nonprofits & Activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', "let's", 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox 360', 'animation', 'unboxing', 'money', 'how', 'travel', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'sony computer entertainment', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets & animals', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'grand theft auto v', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'gta 5', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'crypto news', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'fortnite battle royale', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'xbox360', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'Juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'action role-playing game', 'playthrough part', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing video game', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'Humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'Entertainment', 'technology', 'music', 'funny', 'Education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'sony interactive entertainment', 'film & animation', 'game', 'weapons', "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', 'ps4live', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'ps4share', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'xbox', 'autos & vehicles', 'Travel & Events', 'food', 'science', 'xbox one', 'liberal', 'democrat', 'progressive', 'survival', 'Nonprofits & Activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', "let's", 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox 360', 'animation', 'unboxing', 'money', 'how', 'travel', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'sony computer entertainment', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets & animals', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'grand theft auto v', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'gta 5', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'crypto news', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'fortnite battle royale', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'xbox360', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'Juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'action role-playing game', 'playthrough part', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing video game', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'Humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry']; // diff --git a/src/constants/tags.js b/src/constants/tags.js index e44fe37..3a1e26d 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -16,6 +16,8 @@ export const DEFAULT_FOLLOWED_TAGS = [ export const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; export const DEFAULT_KNOWN_TAGS = [ + 'free speech', + 'censorship', 'gaming', 'pop culture', 'Entertainment', -- 2.45.2 From afc76b08d705e961f91cc319f06d1c8c40333659 Mon Sep 17 00:00:00 2001 From: YULIUS KURNIAWAN KRISTIANTO Date: Mon, 3 Feb 2020 05:55:34 +0700 Subject: [PATCH 261/371] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 200acb5..e8be4ab 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2017-2019 LBRY Inc +Copyright (c) 2017-2020 LBRY Inc Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, -- 2.45.2 From c262a68f8ff03462e4aea7bef5656d745b1e4c59 Mon Sep 17 00:00:00 2001 From: Yamboy1 Date: Sat, 8 Feb 2020 09:59:10 +1300 Subject: [PATCH 262/371] Add html to the list of "documents" Must have done this locally and forgot about it --- src/lbry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lbry.js b/src/lbry.js index f6cc88c..0332011 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -40,7 +40,7 @@ const Lbry: LbryTypes = { [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], - [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], + [/\.(html|json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], -- 2.45.2 From b2ef2617607d4086b390c5ecc8074f894c6a5248 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 10 Feb 2020 12:04:34 +0100 Subject: [PATCH 263/371] Resolved search updates (#273) * add doResolvedSearch actions which returns resolved search results * add recommended content selector * update ResolvedSearchResult type * support for multiple pages of resolved search results * add nsfw flag --- dist/bundle.es.js | 5 +++-- src/redux/actions/search.js | 15 +++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9153398..c83f84b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4112,7 +4112,7 @@ const doSearch = (rawQuery, searchOptions) => (dispatch, getState) => { }; const doResolvedSearch = (rawQuery, size, // only pass in if you don't want to use the users setting (ex: related content) -from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => { +from, isBackgroundSearch = false, options = {}, nsfw) => (dispatch, getState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); if (!query) { @@ -4155,7 +4155,8 @@ from, isBackgroundSearch = false, options = {}) => (dispatch, getState) => { dispatch(doUpdateSearchQuery(query)); } - fetch(`${CONNECTION_STRING}search?resolve=true&${queryWithOptions}`).then(handleFetchResponse).then(data => { + const fetchUrl = nsfw ? `${CONNECTION_STRING}search?resolve=true&${queryWithOptions}` : `${CONNECTION_STRING}search?resolve=true&nsfw=false&${queryWithOptions}`; + fetch(fetchUrl).then(handleFetchResponse).then(data => { const results = []; data.forEach(result => { diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index bee1350..6094277 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -166,13 +166,13 @@ export const doSearch = (rawQuery: string, searchOptions: SearchOptions) => ( export const doResolvedSearch = ( rawQuery: string, - size?: number, // only pass in if you don't want to use the users setting (ex: related content) - from?: number, - isBackgroundSearch?: boolean = false, + size: ?number, // only pass in if you don't want to use the users setting (ex: related content) + from: ?number, + isBackgroundSearch: boolean = false, options: { related_to?: string, - // nsfw here - } = {} + } = {}, + nsfw: boolean ) => (dispatch: Dispatch, getState: GetState) => { const query = rawQuery.replace(/^lbry:\/\//i, '').replace(/\//, ' '); @@ -218,7 +218,10 @@ export const doResolvedSearch = ( dispatch(doUpdateSearchQuery(query)); } - fetch(`${CONNECTION_STRING}search?resolve=true&${queryWithOptions}`) + const fetchUrl = nsfw + ? `${CONNECTION_STRING}search?resolve=true&${queryWithOptions}` + : `${CONNECTION_STRING}search?resolve=true&nsfw=false&${queryWithOptions}`; + fetch(fetchUrl) .then(handleFetchResponse) .then((data: Array) => { const results = []; -- 2.45.2 From 1de1d534c982db913f145a6171f39d7b8ebd61af Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Mon, 10 Feb 2020 12:20:48 +0100 Subject: [PATCH 264/371] add resolve parameter to channel_list --- dist/bundle.es.js | 4 ++-- src/redux/actions/claims.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c83f84b..28fa1d4 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3129,7 +3129,7 @@ function doImportChannel(certificate) { }; } -function doFetchChannelListMine(page = 1, pageSize = 99999) { +function doFetchChannelListMine(page = 1, pageSize = 99999, resolve = false) { return dispatch => { dispatch({ type: FETCH_CHANNEL_LIST_STARTED @@ -3142,7 +3142,7 @@ function doFetchChannelListMine(page = 1, pageSize = 99999) { }); }; - lbryProxy.channel_list({ page, page_size: pageSize }).then(callback); + lbryProxy.channel_list({ page, page_size: pageSize, resolve }).then(callback); }; } diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index cd21153..5975dec 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -383,7 +383,7 @@ export function doImportChannel(certificate: string) { }; } -export function doFetchChannelListMine(page: number = 1, pageSize: number = 99999) { +export function doFetchChannelListMine(page: number = 1, pageSize: number = 99999, resolve: boolean = false) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_CHANNEL_LIST_STARTED, @@ -396,7 +396,7 @@ export function doFetchChannelListMine(page: number = 1, pageSize: number = 9999 }); }; - Lbry.channel_list({ page, page_size: pageSize }).then(callback); + Lbry.channel_list({ page, page_size: pageSize, resolve }).then(callback); }; } -- 2.45.2 From bd07919a72daa841a4b377beb18a3fda73a6113f Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 10 Feb 2020 10:49:45 -0500 Subject: [PATCH 265/371] redux for reposts --- dist/bundle.es.js | 104 ++++++++++++++++++++++++++++++++-- dist/flow-typed/Lbry.js | 10 ++++ flow-typed/Lbry.js | 10 ++++ src/constants/action_types.js | 4 ++ src/index.js | 4 ++ src/lbry.js | 2 +- src/redux/actions/claims.js | 61 +++++++++++++++++--- src/redux/reducers/claims.js | 45 +++++++++++++++ src/redux/selectors/claims.js | 14 ++++- 9 files changed, 238 insertions(+), 16 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c83f84b..93e2949 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -126,6 +126,10 @@ const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; const CLAIM_SEARCH_BY_TAGS_STARTED = 'CLAIM_SEARCH_BY_TAGS_STARTED'; const CLAIM_SEARCH_BY_TAGS_COMPLETED = 'CLAIM_SEARCH_BY_TAGS_COMPLETED'; const CLAIM_SEARCH_BY_TAGS_FAILED = 'CLAIM_SEARCH_BY_TAGS_FAILED'; +const CLAIM_REPOST_STARTED = 'CLAIM_REPOST_STARTED'; +const CLAIM_REPOST_COMPLETED = 'CLAIM_REPOST_COMPLETED'; +const CLAIM_REPOST_FAILED = 'CLAIM_REPOST_FAILED'; +const CLEAR_REPOST_ERROR = 'CLEAR_REPOST_ERROR'; // Comments const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; @@ -383,6 +387,10 @@ var action_types = /*#__PURE__*/Object.freeze({ CLAIM_SEARCH_BY_TAGS_STARTED: CLAIM_SEARCH_BY_TAGS_STARTED, CLAIM_SEARCH_BY_TAGS_COMPLETED: CLAIM_SEARCH_BY_TAGS_COMPLETED, CLAIM_SEARCH_BY_TAGS_FAILED: CLAIM_SEARCH_BY_TAGS_FAILED, + CLAIM_REPOST_STARTED: CLAIM_REPOST_STARTED, + CLAIM_REPOST_COMPLETED: CLAIM_REPOST_COMPLETED, + CLAIM_REPOST_FAILED: CLAIM_REPOST_FAILED, + CLEAR_REPOST_ERROR: CLEAR_REPOST_ERROR, COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, @@ -865,7 +873,7 @@ const Lbry = { // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType, fileName) => { if (fileName) { - const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; + const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(html|json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; const res = formats.reduce((ret, testpair) => { switch (testpair[0].test(ret)) { @@ -907,6 +915,7 @@ const Lbry = { channel_abandon: params => daemonCallWithResult('channel_abandon', params), support_create: params => daemonCallWithResult('support_create', params), support_list: params => daemonCallWithResult('support_list', params), + stream_repost: params => daemonCallWithResult('stream_repost', params), // File fetching and manipulation file_list: (params = {}) => daemonCallWithResult('file_list', params), @@ -942,7 +951,6 @@ const Lbry = { comment_create: (params = {}) => daemonCallWithResult('comment_create', params), comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), - // requires SDK ver. 0.53.0 comment_update: (params = {}) => daemonCallWithResult('comment_update', params), // Connect to the sdk @@ -1953,6 +1961,10 @@ const selectCreatingChannel = reselect.createSelector(selectState$2, state => st const selectCreateChannelError = reselect.createSelector(selectState$2, state => state.createChannelError); +const selectRepostLoading = reselect.createSelector(selectState$2, state => state.repostLoading); + +const selectRepostError = reselect.createSelector(selectState$2, state => state.repostError); + const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { const byUri = state.claimsByUri || {}; const claims = {}; @@ -2874,7 +2886,7 @@ function doFetchClaimListMine(page = 1, pageSize = 99999) { type: FETCH_CLAIM_LIST_MINE_STARTED }); - lbryProxy.stream_list({ page, page_size: pageSize }).then(result => { + lbryProxy.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'] }).then(result => { const claims = result.items; dispatch({ @@ -3190,6 +3202,47 @@ function doClaimSearch(options = { }; } +function doRepost(options) { + return dispatch => { + // $FlowFixMe + return new Promise(resolve => { + dispatch({ + type: CLAIM_REPOST_STARTED + }); + + function success(response) { + const repostClaim = response.outputs[0]; + dispatch({ + type: CLAIM_REPOST_COMPLETED, + data: { + originalClaimId: options.claim_id, + repostClaim + } + }); + + resolve(); + } + + function failure(error) { + dispatch({ + type: CLAIM_REPOST_FAILED, + data: { + error: error.message + } + }); + } + + lbryProxy.stream_repost(options).then(success, failure); + }); + }; +} + +function doClearRepostError() { + return { + type: CLEAR_REPOST_ERROR + }; +} + const selectState$3 = state => state.fileInfo || {}; const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); @@ -4450,7 +4503,9 @@ const defaultState = { updatingChannel: false, creatingChannel: false, createChannelError: undefined, - pendingChannelImport: false + pendingChannelImport: false, + repostLoading: false, + repostError: undefined }; function handleClaimAction(state, action) { @@ -4805,6 +4860,43 @@ reducers[CLAIM_SEARCH_FAILED] = (state, action) => { }); }; +reducers[CLAIM_REPOST_STARTED] = state => { + return _extends$9({}, state, { + repostLoading: true, + repostError: null + }); +}; +reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { + const { originalClaimId, repostClaim } = action.data; + const byId = _extends$9({}, state.byId); + const claimsByUri = _extends$9({}, state.claimsByUri); + const claimThatWasReposted = byId[originalClaimId]; + + const repostStub = _extends$9({}, repostClaim, { reposted_claim: claimThatWasReposted }); + byId[repostStub.claim_id] = repostStub; + claimsByUri[repostStub.permanent_url] = repostStub.claim_id; + + return _extends$9({}, state, { + byId, + claimsByUri, + repostLoading: false, + repostError: null + }); +}; +reducers[CLAIM_REPOST_FAILED] = (state, action) => { + const { error } = action.data; + + return _extends$9({}, state, { + repostLoading: false, + repostError: error + }); +}; +reducers[CLEAR_REPOST_ERROR] = state => { + return _extends$9({}, state, { + repostError: null + }); +}; + function claimsReducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); @@ -5997,6 +6089,7 @@ exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doClaimSearch = doClaimSearch; exports.doClearPublish = doClearPublish; +exports.doClearRepostError = doClearRepostError; exports.doClearSupport = doClearSupport; exports.doCommentAbandon = doCommentAbandon; exports.doCommentCreate = doCommentCreate; @@ -6026,6 +6119,7 @@ exports.doPreferenceSet = doPreferenceSet; exports.doPrepareEdit = doPrepareEdit; exports.doPublish = doPublish; exports.doPurchaseUri = doPurchaseUri; +exports.doRepost = doRepost; exports.doResetThumbnailStatus = doResetThumbnailStatus; exports.doResolveUri = doResolveUri; exports.doResolveUris = doResolveUris; @@ -6192,6 +6286,8 @@ exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; +exports.selectRepostError = selectRepostError; +exports.selectRepostLoading = selectRepostLoading; exports.selectReservedBalance = selectReservedBalance; exports.selectResolvedSearchResultsByQuery = selectResolvedSearchResultsByQuery; exports.selectResolvedSearchResultsByQueryLastPageReached = selectResolvedSearchResultsByQueryLastPageReached; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index d2657cb..ba88d27 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -204,6 +204,15 @@ declare type StreamListResponse = { total_pages: number, }; +declare type StreamRepostOptions = { + name: string, + bid: string, + claim_id: string, + channel_id: string, +}; + +declare type StreamRepostResponse = GenericTxResponse; + // // Types used in the generic Lbry object that is exported // @@ -240,6 +249,7 @@ declare type LbryTypes = { support_create: (params: {}) => Promise, support_list: (params: {}) => Promise, support_abandon: (params: {}) => Promise, + stream_repost: (params: StreamRepostOptions) => Promise, // File fetching and manipulation file_list: (params: {}) => Promise, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index d2657cb..ba88d27 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -204,6 +204,15 @@ declare type StreamListResponse = { total_pages: number, }; +declare type StreamRepostOptions = { + name: string, + bid: string, + claim_id: string, + channel_id: string, +}; + +declare type StreamRepostResponse = GenericTxResponse; + // // Types used in the generic Lbry object that is exported // @@ -240,6 +249,7 @@ declare type LbryTypes = { support_create: (params: {}) => Promise, support_list: (params: {}) => Promise, support_abandon: (params: {}) => Promise, + stream_repost: (params: StreamRepostOptions) => Promise, // File fetching and manipulation file_list: (params: {}) => Promise, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 1f8b841..ae74a0d 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -103,6 +103,10 @@ export const CLAIM_SEARCH_FAILED = 'CLAIM_SEARCH_FAILED'; export const CLAIM_SEARCH_BY_TAGS_STARTED = 'CLAIM_SEARCH_BY_TAGS_STARTED'; export const CLAIM_SEARCH_BY_TAGS_COMPLETED = 'CLAIM_SEARCH_BY_TAGS_COMPLETED'; export const CLAIM_SEARCH_BY_TAGS_FAILED = 'CLAIM_SEARCH_BY_TAGS_FAILED'; +export const CLAIM_REPOST_STARTED = 'CLAIM_REPOST_STARTED'; +export const CLAIM_REPOST_COMPLETED = 'CLAIM_REPOST_COMPLETED'; +export const CLAIM_REPOST_FAILED = 'CLAIM_REPOST_FAILED'; +export const CLEAR_REPOST_ERROR = 'CLEAR_REPOST_ERROR'; // Comments export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; diff --git a/src/index.js b/src/index.js index 3650efd..7dd8200 100644 --- a/src/index.js +++ b/src/index.js @@ -67,6 +67,8 @@ export { doUpdateChannel, doClaimSearch, doImportChannel, + doRepost, + doClearRepostError, } from 'redux/actions/claims'; export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -232,6 +234,8 @@ export { selectChannelImportPending, makeSelectMyStreamUrlsForPage, selectMyStreamUrlsCount, + selectRepostError, + selectRepostLoading, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/lbry.js b/src/lbry.js index 0332011..ea72713 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -86,6 +86,7 @@ const Lbry: LbryTypes = { channel_abandon: params => daemonCallWithResult('channel_abandon', params), support_create: params => daemonCallWithResult('support_create', params), support_list: params => daemonCallWithResult('support_list', params), + stream_repost: params => daemonCallWithResult('stream_repost', params), // File fetching and manipulation file_list: (params = {}) => daemonCallWithResult('file_list', params), @@ -121,7 +122,6 @@ const Lbry: LbryTypes = { comment_create: (params = {}) => daemonCallWithResult('comment_create', params), comment_hide: (params = {}) => daemonCallWithResult('comment_hide', params), comment_abandon: (params = {}) => daemonCallWithResult('comment_abandon', params), - // requires SDK ver. 0.53.0 comment_update: (params = {}) => daemonCallWithResult('comment_update', params), // Connect to the sdk diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index cd21153..2857097 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -100,16 +100,18 @@ export function doFetchClaimListMine(page: number = 1, pageSize: number = 99999) type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED, }); - Lbry.stream_list({ page, page_size: pageSize }).then((result: StreamListResponse) => { - const claims = result.items; + Lbry.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'] }).then( + (result: StreamListResponse) => { + const claims = result.items; - dispatch({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims, - }, - }); - }); + dispatch({ + type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + claims, + }, + }); + } + ); }; } @@ -455,3 +457,44 @@ export function doClaimSearch( Lbry.claim_search(options).then(success, failure); }; } + +export function doRepost(options: StreamRepostOptions) { + return (dispatch: Dispatch) => { + // $FlowFixMe + return new Promise(resolve => { + dispatch({ + type: ACTIONS.CLAIM_REPOST_STARTED, + }); + + function success(response) { + const repostClaim = response.outputs[0]; + dispatch({ + type: ACTIONS.CLAIM_REPOST_COMPLETED, + data: { + originalClaimId: options.claim_id, + repostClaim, + }, + }); + + resolve(); + } + + function failure(error) { + dispatch({ + type: ACTIONS.CLAIM_REPOST_FAILED, + data: { + error: error.message, + }, + }); + } + + Lbry.stream_repost(options).then(success, failure); + }); + }; +} + +export function doClearRepostError() { + return { + type: ACTIONS.CLEAR_REPOST_ERROR, + }; +} diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index f60cdca..2935cc4 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -39,6 +39,8 @@ type State = { updateChannelError: string, updatingChannel: boolean, pendingChannelImport: string | boolean, + repostLoading: boolean, + repostError: ?string, }; const reducers = {}; @@ -65,6 +67,8 @@ const defaultState = { creatingChannel: false, createChannelError: undefined, pendingChannelImport: false, + repostLoading: false, + repostError: undefined, }; function handleClaimAction(state: State, action: any): State { @@ -447,6 +451,47 @@ reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State, action: any): State => { }); }; +reducers[ACTIONS.CLAIM_REPOST_STARTED] = (state: State): State => { + return { + ...state, + repostLoading: true, + repostError: null, + }; +}; +reducers[ACTIONS.CLAIM_REPOST_COMPLETED] = (state: State, action: any): State => { + const { originalClaimId, repostClaim } = action.data; + const byId = { ...state.byId }; + const claimsByUri = { ...state.claimsByUri }; + const claimThatWasReposted = byId[originalClaimId]; + + const repostStub = { ...repostClaim, reposted_claim: claimThatWasReposted }; + byId[repostStub.claim_id] = repostStub; + claimsByUri[repostStub.permanent_url] = repostStub.claim_id; + + return { + ...state, + byId, + claimsByUri, + repostLoading: false, + repostError: null, + }; +}; +reducers[ACTIONS.CLAIM_REPOST_FAILED] = (state: State, action: any): State => { + const { error } = action.data; + + return { + ...state, + repostLoading: false, + repostError: error, + }; +}; +reducers[ACTIONS.CLEAR_REPOST_ERROR] = (state: State): State => { + return { + ...state, + repostError: null, + }; +}; + export function claimsReducer(state: State = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 73a3018..47b6a49 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -31,6 +31,16 @@ export const selectCreateChannelError = createSelector( state => state.createChannelError ); +export const selectRepostLoading = createSelector( + selectState, + state => state.repostLoading +); + +export const selectRepostError = createSelector( + selectState, + state => state.repostError +); + export const selectClaimsByUri = createSelector( selectState, selectClaimsById, @@ -279,8 +289,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } -- 2.45.2 From e7c42df2ada63a19000fe185ae3bde05db1f3951 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 12 Feb 2020 09:43:41 -0500 Subject: [PATCH 266/371] add repost_url and also add a way to return the original claim instead of the reposted claim --- dist/bundle.es.js | 5 +++-- src/redux/selectors/claims.js | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 93e2949..2c5709e 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2010,7 +2010,7 @@ const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, return pendingById[claimId]; }); -const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => { +const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => { // Check if a claim is pending first // It won't be in claimsByUri because resolving it will return nothing @@ -2038,10 +2038,11 @@ const makeSelectClaimForUri = uri => reselect.createSelector(selectClaimsByUri, } const repostedClaim = claim.reposted_claim; - if (repostedClaim) { + if (repostedClaim && returnRepost) { const channelUrl = claim.signing_channel && claim.signing_channel.canonical_url; return _extends$4({}, repostedClaim, { + repost_url: uri, repost_channel_url: channelUrl }); } else { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 47b6a49..6f67721 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -107,7 +107,7 @@ export const makeSelectPendingByUri = (uri: string) => } ); -export const makeSelectClaimForUri = (uri: string) => +export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) => createSelector( selectClaimsByUri, selectPendingById, @@ -139,11 +139,12 @@ export const makeSelectClaimForUri = (uri: string) => } const repostedClaim = claim.reposted_claim; - if (repostedClaim) { + if (repostedClaim && returnRepost) { const channelUrl = claim.signing_channel && claim.signing_channel.canonical_url; return { ...repostedClaim, + repost_url: uri, repost_channel_url: channelUrl, }; } else { -- 2.45.2 From 46e5196f7c9c95708242277e50dc0544c6133181 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 12 Feb 2020 12:17:50 -0500 Subject: [PATCH 267/371] list resolve defaults to true --- src/redux/actions/claims.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index e9a7a5b..cb429fe 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -94,13 +94,13 @@ export function doResolveUri(uri: string) { return doResolveUris([uri]); } -export function doFetchClaimListMine(page: number = 1, pageSize: number = 99999) { +export function doFetchClaimListMine(page: number = 1, pageSize: number = 99999, resolve: boolean = true) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED, }); - Lbry.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'] }).then( + Lbry.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'], resolve }).then( (result: StreamListResponse) => { const claims = result.items; @@ -385,7 +385,7 @@ export function doImportChannel(certificate: string) { }; } -export function doFetchChannelListMine(page: number = 1, pageSize: number = 99999, resolve: boolean = false) { +export function doFetchChannelListMine(page: number = 1, pageSize: number = 99999, resolve: boolean = true) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_CHANNEL_LIST_STARTED, -- 2.45.2 From 50aa80d139c7863503b8dfc77947e3cdf3ee801d Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 12 Feb 2020 16:45:30 -0500 Subject: [PATCH 268/371] channel list results applied as resolved --- dist/bundle.es.js | 35 +++++++++++++++++++++++++---------- src/redux/actions/claims.js | 1 + src/redux/reducers/claims.js | 26 ++++++++++++++++++++------ 3 files changed, 46 insertions(+), 16 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3217494..7b0dce3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2881,13 +2881,13 @@ function doResolveUri(uri) { return doResolveUris([uri]); } -function doFetchClaimListMine(page = 1, pageSize = 99999) { +function doFetchClaimListMine(page = 1, pageSize = 99999, resolve = true) { return dispatch => { dispatch({ type: FETCH_CLAIM_LIST_MINE_STARTED }); - lbryProxy.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'] }).then(result => { + lbryProxy.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'], resolve }).then(result => { const claims = result.items; dispatch({ @@ -3142,16 +3142,18 @@ function doImportChannel(certificate) { }; } -function doFetchChannelListMine(page = 1, pageSize = 99999, resolve = false) { +function doFetchChannelListMine(page = 1, pageSize = 99999, resolve = true) { return dispatch => { dispatch({ type: FETCH_CHANNEL_LIST_STARTED }); const callback = response => { + const { items } = response; + dispatch({ type: FETCH_CHANNEL_LIST_COMPLETED, - data: { claims: response.items } + data: { claims: items } }); }; @@ -4638,27 +4640,40 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { const pendingById = Object.assign(state.pendingById); let myChannelClaims; - let byId = Object.assign({}, state.byId); + const byId = Object.assign({}, state.byId); + const byUri = Object.assign({}, state.claimsByUri); + const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + if (!claims.length) { // $FlowFixMe myChannelClaims = null; } else { myChannelClaims = new Set(state.myChannelClaims); claims.forEach(claim => { + const { claims_in_channel: claimsInChannel } = claim.meta; + const { canonical_url: canonicalUrl, permanent_url: permanentUrl, claim_id: claimId } = claim; + + byUri[canonicalUrl] = claimId; + byUri[permanentUrl] = claimId; + channelClaimCounts[canonicalUrl] = claimsInChannel; + channelClaimCounts[permanentUrl] = claimsInChannel; + // $FlowFixMe - myChannelClaims.add(claim.claim_id); - if (!byId[claim.claim_id]) { - byId[claim.claim_id] = claim; + myChannelClaims.add(claimId); + if (!byId[claimId]) { + byId[claimId] = claim; } - if (pendingById[claim.claim_id] && claim.confirmations > 0) { - delete pendingById[claim.claim_id]; + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; } }); } return Object.assign({}, state, { byId, + claimsByUri: byUri, + channelClaimCounts, fetchingMyChannels: false, myChannelClaims, myClaims: concatClaims(myClaims, claims) diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index cb429fe..1ccd2a6 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -392,6 +392,7 @@ export function doFetchChannelListMine(page: number = 1, pageSize: number = 9999 }); const callback = (response: ChannelListResponse) => { + dispatch({ type: ACTIONS.FETCH_CHANNEL_LIST_COMPLETED, data: { claims: response.items }, diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 2935cc4..7ca9745 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -211,27 +211,41 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St const pendingById = Object.assign(state.pendingById); let myChannelClaims; - let byId = Object.assign({}, state.byId); + const byId = Object.assign({}, state.byId); + const byUri = Object.assign({}, state.claimsByUri); + const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + if (!claims.length) { // $FlowFixMe myChannelClaims = null; } else { myChannelClaims = new Set(state.myChannelClaims); claims.forEach(claim => { + const { meta } = claim; + const { claims_in_channel: claimsInChannel } = claim.meta; + const { canonical_url: canonicalUrl, permanent_url: permanentUrl, claim_id: claimId } = claim; + + byUri[canonicalUrl] = claimId; + byUri[permanentUrl] = claimId; + channelClaimCounts[canonicalUrl] = claimsInChannel; + channelClaimCounts[permanentUrl] = claimsInChannel; + // $FlowFixMe - myChannelClaims.add(claim.claim_id); - if (!byId[claim.claim_id]) { - byId[claim.claim_id] = claim; + myChannelClaims.add(claimId); + if (!byId[claimId]) { + byId[claimId] = claim; } - if (pendingById[claim.claim_id] && claim.confirmations > 0) { - delete pendingById[claim.claim_id]; + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; } }); } return Object.assign({}, state, { byId, + claimsByUri: byUri, + channelClaimCounts, fetchingMyChannels: false, myChannelClaims, myClaims: concatClaims(myClaims, claims), -- 2.45.2 From 3d64f8acc6c2ce37252f59feff89e1fc58cb74c1 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 13 Feb 2020 11:37:36 -0500 Subject: [PATCH 269/371] call claim_list after publishing to ensure repost is listed in my claims --- dist/bundle.es.js | 5 ++--- src/redux/actions/claims.js | 14 +++++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 7b0dce3..c3ce9d3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3149,11 +3149,9 @@ function doFetchChannelListMine(page = 1, pageSize = 99999, resolve = true) { }); const callback = response => { - const { items } = response; - dispatch({ type: FETCH_CHANNEL_LIST_COMPLETED, - data: { claims: items } + data: { claims: response.items } }); }; @@ -3223,6 +3221,7 @@ function doRepost(options) { } }); + dispatch(doFetchClaimListMine(1, 10)); resolve(); } diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 1ccd2a6..4e12c8d 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -94,7 +94,11 @@ export function doResolveUri(uri: string) { return doResolveUris([uri]); } -export function doFetchClaimListMine(page: number = 1, pageSize: number = 99999, resolve: boolean = true) { +export function doFetchClaimListMine( + page: number = 1, + pageSize: number = 99999, + resolve: boolean = true +) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED, @@ -385,14 +389,17 @@ export function doImportChannel(certificate: string) { }; } -export function doFetchChannelListMine(page: number = 1, pageSize: number = 99999, resolve: boolean = true) { +export function doFetchChannelListMine( + page: number = 1, + pageSize: number = 99999, + resolve: boolean = true +) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.FETCH_CHANNEL_LIST_STARTED, }); const callback = (response: ChannelListResponse) => { - dispatch({ type: ACTIONS.FETCH_CHANNEL_LIST_COMPLETED, data: { claims: response.items }, @@ -477,6 +484,7 @@ export function doRepost(options: StreamRepostOptions) { }, }); + dispatch(doFetchClaimListMine(1, 10)); resolve(); } -- 2.45.2 From 67a5654ffe657cbe5c4e739907adf1e04389305c Mon Sep 17 00:00:00 2001 From: jessop Date: Sun, 16 Feb 2020 14:52:58 -0500 Subject: [PATCH 270/371] migrates settings to redux --- dist/bundle.es.js | 39 +++++++++++++++++++++++++++++++++------ src/constants/settings.js | 24 +++++++++++++++++++----- 2 files changed, 52 insertions(+), 11 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c3ce9d3..c549c41 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -604,17 +604,31 @@ var pages = /*#__PURE__*/Object.freeze({ /* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ /* Many SETTINGS are stored in the localStorage by their name - be careful about changing the value of a SETTINGS constant, as doing so can invalidate existing SETTINGS */ + +const SHOW_NSFW = 'showNsfw'; const CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged'; const NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged'; const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; +const INVITE_ACKNOWLEDGED = 'invite_acknowledged'; const LANGUAGE = 'language'; -const SHOW_NSFW = 'showNsfw'; -const SHOW_UNAVAILABLE = 'showUnavailable'; -const INSTANT_PURCHASE_ENABLED = 'instantPurchaseEnabled'; -const INSTANT_PURCHASE_MAX = 'instantPurchaseMax'; +const SHOW_MATURE = 'show_mature'; +const SHOW_ANONYMOUS = 'show_anonymous'; +const SHOW_UNAVAILABLE = 'show_unavailable'; +const INSTANT_PURCHASE_ENABLED = 'instant_purchase_enabled'; +const INSTANT_PURCHASE_MAX = 'instant_purchase_max'; const THEME = 'theme'; const THEMES = 'themes'; -const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; +const AUTOMATIC_DARK_MODE_ENABLED = 'automatic_dark_mode_enabled'; +const AUTOPLAY = 'autoplay'; +const OS_NOTIFICATIONS_ENABLED = 'os_notifications_enabled'; +const AUTO_DOWNLOAD = 'auto_download'; +const AUTO_LAUNCH = 'auto_launch'; +const SUPPORT_OPTION = 'support_option'; +const HIDE_BALANCE = 'hide_balance'; +const HIDE_SPLASH_ANIMATION = 'hide_splash_animation'; +const FLOATING_PLAYER = 'floating_player'; +const DARK_MODE_TIMES = 'dark_mode_times'; +const ENABLE_SYNC = 'enable_sync'; // mobile settings const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; @@ -627,17 +641,30 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ + SHOW_NSFW: SHOW_NSFW, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, EMAIL_COLLECTION_ACKNOWLEDGED: EMAIL_COLLECTION_ACKNOWLEDGED, + INVITE_ACKNOWLEDGED: INVITE_ACKNOWLEDGED, LANGUAGE: LANGUAGE, - SHOW_NSFW: SHOW_NSFW, + SHOW_MATURE: SHOW_MATURE, + SHOW_ANONYMOUS: SHOW_ANONYMOUS, SHOW_UNAVAILABLE: SHOW_UNAVAILABLE, INSTANT_PURCHASE_ENABLED: INSTANT_PURCHASE_ENABLED, INSTANT_PURCHASE_MAX: INSTANT_PURCHASE_MAX, THEME: THEME, THEMES: THEMES, AUTOMATIC_DARK_MODE_ENABLED: AUTOMATIC_DARK_MODE_ENABLED, + AUTOPLAY: AUTOPLAY, + OS_NOTIFICATIONS_ENABLED: OS_NOTIFICATIONS_ENABLED, + AUTO_DOWNLOAD: AUTO_DOWNLOAD, + AUTO_LAUNCH: AUTO_LAUNCH, + SUPPORT_OPTION: SUPPORT_OPTION, + HIDE_BALANCE: HIDE_BALANCE, + HIDE_SPLASH_ANIMATION: HIDE_SPLASH_ANIMATION, + FLOATING_PLAYER: FLOATING_PLAYER, + DARK_MODE_TIMES: DARK_MODE_TIMES, + ENABLE_SYNC: ENABLE_SYNC, BACKGROUND_PLAY_ENABLED: BACKGROUND_PLAY_ENABLED, FOREGROUND_NOTIFICATION_ENABLED: FOREGROUND_NOTIFICATION_ENABLED, KEEP_DAEMON_RUNNING: KEEP_DAEMON_RUNNING, diff --git a/src/constants/settings.js b/src/constants/settings.js index f0edbe5..5d15850 100644 --- a/src/constants/settings.js +++ b/src/constants/settings.js @@ -1,17 +1,31 @@ /* hardcoded names still exist for these in reducers/settings.js - only discovered when debugging */ /* Many SETTINGS are stored in the localStorage by their name - be careful about changing the value of a SETTINGS constant, as doing so can invalidate existing SETTINGS */ + +export const SHOW_NSFW = 'showNsfw'; export const CREDIT_REQUIRED_ACKNOWLEDGED = 'credit_required_acknowledged'; export const NEW_USER_ACKNOWLEDGED = 'welcome_acknowledged'; export const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; +export const INVITE_ACKNOWLEDGED = 'invite_acknowledged'; export const LANGUAGE = 'language'; -export const SHOW_NSFW = 'showNsfw'; -export const SHOW_UNAVAILABLE = 'showUnavailable'; -export const INSTANT_PURCHASE_ENABLED = 'instantPurchaseEnabled'; -export const INSTANT_PURCHASE_MAX = 'instantPurchaseMax'; +export const SHOW_MATURE = 'show_mature'; +export const SHOW_ANONYMOUS = 'show_anonymous'; +export const SHOW_UNAVAILABLE = 'show_unavailable'; +export const INSTANT_PURCHASE_ENABLED = 'instant_purchase_enabled'; +export const INSTANT_PURCHASE_MAX = 'instant_purchase_max'; export const THEME = 'theme'; export const THEMES = 'themes'; -export const AUTOMATIC_DARK_MODE_ENABLED = 'automaticDarkModeEnabled'; +export const AUTOMATIC_DARK_MODE_ENABLED = 'automatic_dark_mode_enabled'; +export const AUTOPLAY = 'autoplay'; +export const OS_NOTIFICATIONS_ENABLED = 'os_notifications_enabled'; +export const AUTO_DOWNLOAD = 'auto_download'; +export const AUTO_LAUNCH = 'auto_launch'; +export const SUPPORT_OPTION = 'support_option'; +export const HIDE_BALANCE = 'hide_balance'; +export const HIDE_SPLASH_ANIMATION = 'hide_splash_animation'; +export const FLOATING_PLAYER = 'floating_player'; +export const DARK_MODE_TIMES = 'dark_mode_times'; +export const ENABLE_SYNC = 'enable_sync'; // mobile settings export const BACKGROUND_PLAY_ENABLED = 'backgroundPlayEnabled'; -- 2.45.2 From 04774dfe2204d5a9f2c567241fd1c57f62084263 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 20 Feb 2020 00:57:55 -0500 Subject: [PATCH 271/371] sync welcome and 3p analytics pref --- dist/bundle.es.js | 16 +++++++++++----- src/constants/action_types.js | 2 ++ src/constants/shared_preferences.js | 1 + src/redux/actions/sync.js | 12 +++++++++--- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c549c41..4f63f2d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -26,6 +26,8 @@ const DAEMON_READY = 'DAEMON_READY'; const DAEMON_VERSION_MATCH = 'DAEMON_VERSION_MATCH'; const DAEMON_VERSION_MISMATCH = 'DAEMON_VERSION_MISMATCH'; const VOLUME_CHANGED = 'VOLUME_CHANGED'; +const SET_WELCOME_VERSION = 'SET_WELCOME_VERSION'; +const SET_ALLOW_ANALYTICS = 'SET_ALLOW_ANALYTICS'; // Navigation const CHANGE_AFTER_AUTH_PATH = 'CHANGE_AFTER_AUTH_PATH'; @@ -295,6 +297,8 @@ var action_types = /*#__PURE__*/Object.freeze({ DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, DAEMON_VERSION_MISMATCH: DAEMON_VERSION_MISMATCH, VOLUME_CHANGED: VOLUME_CHANGED, + SET_WELCOME_VERSION: SET_WELCOME_VERSION, + SET_ALLOW_ANALYTICS: SET_ALLOW_ANALYTICS, CHANGE_AFTER_AUTH_PATH: CHANGE_AFTER_AUTH_PATH, WINDOW_SCROLLED: WINDOW_SCROLLED, HISTORY_NAVIGATE: HISTORY_NAVIGATE, @@ -833,9 +837,11 @@ var daemon_settings = /*#__PURE__*/Object.freeze({ */ const WALLET_SERVERS = LBRYUM_SERVERS; +const SHARE_USAGE_DATA$1 = SHARE_USAGE_DATA; var shared_preferences = /*#__PURE__*/Object.freeze({ - WALLET_SERVERS: WALLET_SERVERS + WALLET_SERVERS: WALLET_SERVERS, + SHARE_USAGE_DATA: SHARE_USAGE_DATA$1 }); const SEARCH_TYPES = { @@ -1608,9 +1614,9 @@ var _extends$2 = Object.assign || function (target) { for (var i = 1; i < argume function extractUserState(rawObj) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blocked, settings } = rawObj.value; + const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = rawObj.value; - return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blocked ? { blocked } : {}, settings ? { settings } : {}); + return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blocked ? { blocked } : {}, settings ? { settings } : {}, app_welcome_version ? { app_welcome_version } : {}, tv_welcome_version ? { tv_welcome_version } : {}, sharing_3P ? { sharing_3P } : {}); } return {}; @@ -1618,10 +1624,10 @@ function extractUserState(rawObj) { function doPopulateSharedUserState(sharedSettings) { return dispatch => { - const { subscriptions, tags, blocked, settings } = extractUserState(sharedSettings); + const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = extractUserState(sharedSettings); dispatch({ type: USER_STATE_POPULATE, - data: { subscriptions, tags, blocked, settings } + data: { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } }); }; } diff --git a/src/constants/action_types.js b/src/constants/action_types.js index ae74a0d..b66893b 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -3,6 +3,8 @@ export const DAEMON_READY = 'DAEMON_READY'; export const DAEMON_VERSION_MATCH = 'DAEMON_VERSION_MATCH'; export const DAEMON_VERSION_MISMATCH = 'DAEMON_VERSION_MISMATCH'; export const VOLUME_CHANGED = 'VOLUME_CHANGED'; +export const SET_WELCOME_VERSION = 'SET_WELCOME_VERSION'; +export const SET_ALLOW_ANALYTICS = 'SET_ALLOW_ANALYTICS'; // Navigation export const CHANGE_AFTER_AUTH_PATH = 'CHANGE_AFTER_AUTH_PATH'; diff --git a/src/constants/shared_preferences.js b/src/constants/shared_preferences.js index e508e83..58bee93 100644 --- a/src/constants/shared_preferences.js +++ b/src/constants/shared_preferences.js @@ -10,3 +10,4 @@ import * as DAEMON_SETTINGS from './daemon_settings'; export const WALLET_SERVERS = DAEMON_SETTINGS.LBRYUM_SERVERS; +export const SHARE_USAGE_DATA = DAEMON_SETTINGS.SHARE_USAGE_DATA; diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 7f80d33..9a1854e 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -9,18 +9,24 @@ type SharedData = { tags?: Array, blocked?: Array, settings?: any, + app_welcome_version?: number, + tv_welcome_version?: number, + sharing_3P?: boolean, }, }; function extractUserState(rawObj: SharedData) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blocked, settings } = rawObj.value; + const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = rawObj.value; return { ...(subscriptions ? { subscriptions } : {}), ...(tags ? { tags } : {}), ...(blocked ? { blocked } : {}), ...(settings ? { settings } : {}), + ...(app_welcome_version ? { app_welcome_version } : {}), + ...(tv_welcome_version ? { tv_welcome_version } : {}), + ...(sharing_3P ? { sharing_3P} : {}), }; } @@ -29,10 +35,10 @@ function extractUserState(rawObj: SharedData) { export function doPopulateSharedUserState(sharedSettings: any) { return (dispatch: Dispatch) => { - const { subscriptions, tags, blocked, settings } = extractUserState(sharedSettings); + const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = extractUserState(sharedSettings); dispatch({ type: ACTIONS.USER_STATE_POPULATE, - data: { subscriptions, tags, blocked, settings }, + data: { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P }, }); }; } -- 2.45.2 From 5c874e921769093428966fa7ecdf723719cb9067 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Fri, 21 Feb 2020 17:12:45 +0100 Subject: [PATCH 272/371] fix selector for resolved related content --- dist/bundle.es.js | 16 +++++++--------- src/redux/selectors/claims.js | 6 +----- src/util/query-params.js | 34 ++++++++++++++++++---------------- 3 files changed, 26 insertions(+), 30 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4f63f2d..81c0c99 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1120,11 +1120,13 @@ const getSearchQueryString = (query, options = {}) => { if (includeUserOptions) { const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; - queryParams.push(`claimType=${claimType}`); + if (claimType) { + queryParams.push(`claimType=${claimType}`); - // If they are only searching for channels, strip out the media info - if (!claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS)) { - queryParams.push(`mediaType=${[SEARCH_OPTIONS.MEDIA_FILE, SEARCH_OPTIONS.MEDIA_AUDIO, SEARCH_OPTIONS.MEDIA_VIDEO, SEARCH_OPTIONS.MEDIA_TEXT, SEARCH_OPTIONS.MEDIA_IMAGE, SEARCH_OPTIONS.MEDIA_APPLICATION].reduce((acc, currentOption) => options[currentOption] ? `${acc}${currentOption},` : acc, '')}`); + // If they are only searching for channels, strip out the media info + if (!claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS)) { + queryParams.push(`mediaType=${[SEARCH_OPTIONS.MEDIA_FILE, SEARCH_OPTIONS.MEDIA_AUDIO, SEARCH_OPTIONS.MEDIA_VIDEO, SEARCH_OPTIONS.MEDIA_TEXT, SEARCH_OPTIONS.MEDIA_IMAGE, SEARCH_OPTIONS.MEDIA_APPLICATION].reduce((acc, currentOption) => options[currentOption] ? `${acc}${currentOption},` : acc, '')}`); + } } } @@ -2395,13 +2397,9 @@ const makeSelectResolvedRecommendedContentForUri = (uri, size) => reselect.creat return; } - const options = { related_to: claim.claim_id, isBackgroundSearch: true }; - if (!isMature) { - options['nsfw'] = false; - } + const options = { related_to: claim.claim_id, size, isBackgroundSearch: false }; const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); - let results = resolvedResultsByQuery[searchQuery]; if (results) { results = results.filter(result => buildURI({ streamClaimId: result.claimId, streamName: result.name }) !== currentUri); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 6f67721..4db130a 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -701,13 +701,9 @@ export const makeSelectResolvedRecommendedContentForUri = (uri: string, size: nu related_to?: string, nsfw?: boolean, isBackgroundSearch?: boolean, - } = { related_to: claim.claim_id, isBackgroundSearch: true }; - if (!isMature) { - options['nsfw'] = false; - } + } = { related_to: claim.claim_id, size, isBackgroundSearch: false }; const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); - let results = resolvedResultsByQuery[searchQuery]; if (results) { results = results.filter( diff --git a/src/util/query-params.js b/src/util/query-params.js index 80a1d54..bb1d5ec 100644 --- a/src/util/query-params.js +++ b/src/util/query-params.js @@ -48,23 +48,25 @@ export const getSearchQueryString = ( if (includeUserOptions) { const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; - queryParams.push(`claimType=${claimType}`); + if (claimType) { + queryParams.push(`claimType=${claimType}`); - // If they are only searching for channels, strip out the media info - if (!claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS)) { - queryParams.push( - `mediaType=${[ - SEARCH_OPTIONS.MEDIA_FILE, - SEARCH_OPTIONS.MEDIA_AUDIO, - SEARCH_OPTIONS.MEDIA_VIDEO, - SEARCH_OPTIONS.MEDIA_TEXT, - SEARCH_OPTIONS.MEDIA_IMAGE, - SEARCH_OPTIONS.MEDIA_APPLICATION, - ].reduce( - (acc, currentOption) => (options[currentOption] ? `${acc}${currentOption},` : acc), - '' - )}` - ); + // If they are only searching for channels, strip out the media info + if (!claimType.includes(SEARCH_OPTIONS.INCLUDE_CHANNELS)) { + queryParams.push( + `mediaType=${[ + SEARCH_OPTIONS.MEDIA_FILE, + SEARCH_OPTIONS.MEDIA_AUDIO, + SEARCH_OPTIONS.MEDIA_VIDEO, + SEARCH_OPTIONS.MEDIA_TEXT, + SEARCH_OPTIONS.MEDIA_IMAGE, + SEARCH_OPTIONS.MEDIA_APPLICATION, + ].reduce( + (acc, currentOption) => (options[currentOption] ? `${acc}${currentOption},` : acc), + '' + )}` + ); + } } } -- 2.45.2 From 0bbebb186ed3d65edffba306869ba511d961bf95 Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 21 Feb 2020 12:05:49 -0500 Subject: [PATCH 273/371] fix bug in sync --- dist/bundle.es.js | 2 +- src/redux/actions/sync.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4f63f2d..451bd49 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1627,7 +1627,7 @@ function doPopulateSharedUserState(sharedSettings) { const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = extractUserState(sharedSettings); dispatch({ type: USER_STATE_POPULATE, - data: { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } + data: { subscriptions, tags, blocked, settings, welcomeVersion: app_welcome_version, tvWelcomeVersion: tv_welcome_version, allowAnalytics: sharing_3P } }); }; } diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 9a1854e..704e0dd 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -38,7 +38,7 @@ export function doPopulateSharedUserState(sharedSettings: any) { const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = extractUserState(sharedSettings); dispatch({ type: ACTIONS.USER_STATE_POPULATE, - data: { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P }, + data: { subscriptions, tags, blocked, settings, welcomeVersion: app_welcome_version, tvWelcomeVersion: tv_welcome_version, allowAnalytics: sharing_3P }, }); }; } -- 2.45.2 From b4fbc212ca6008ec05c31116182bf6dfa7a1cbcb Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 21 Feb 2020 12:20:18 -0500 Subject: [PATCH 274/371] remove tvWelcome --- dist/bundle.es.js | 10 +++++----- src/redux/actions/sync.js | 8 +++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 451bd49..dd87ebe 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1614,9 +1614,9 @@ var _extends$2 = Object.assign || function (target) { for (var i = 1; i < argume function extractUserState(rawObj) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = rawObj.value; + const { subscriptions, tags, blocked, settings, app_welcome_version, sharing_3P } = rawObj.value; - return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blocked ? { blocked } : {}, settings ? { settings } : {}, app_welcome_version ? { app_welcome_version } : {}, tv_welcome_version ? { tv_welcome_version } : {}, sharing_3P ? { sharing_3P } : {}); + return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blocked ? { blocked } : {}, settings ? { settings } : {}, app_welcome_version ? { app_welcome_version } : {}, sharing_3P ? { sharing_3P } : {}); } return {}; @@ -1624,10 +1624,10 @@ function extractUserState(rawObj) { function doPopulateSharedUserState(sharedSettings) { return dispatch => { - const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = extractUserState(sharedSettings); + const { subscriptions, tags, blocked, settings, app_welcome_version, sharing_3P } = extractUserState(sharedSettings); dispatch({ type: USER_STATE_POPULATE, - data: { subscriptions, tags, blocked, settings, welcomeVersion: app_welcome_version, tvWelcomeVersion: tv_welcome_version, allowAnalytics: sharing_3P } + data: { subscriptions, tags, blocked, settings, welcomeVersion: app_welcome_version, allowAnalytics: sharing_3P } }); }; } @@ -1687,7 +1687,7 @@ const buildSharedStateMiddleware = (actions, sharedStateFilters, sharedStateCb) } const actionResult = next(action); - // Call `getState` after calling `next` to ensure the state has updated in response to the action + // Call `getState` after calling `next` tqo ensure the state has updated in response to the action const nextState = getState(); const shared = {}; diff --git a/src/redux/actions/sync.js b/src/redux/actions/sync.js index 704e0dd..28b8d7a 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -10,14 +10,13 @@ type SharedData = { blocked?: Array, settings?: any, app_welcome_version?: number, - tv_welcome_version?: number, sharing_3P?: boolean, }, }; function extractUserState(rawObj: SharedData) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = rawObj.value; + const { subscriptions, tags, blocked, settings, app_welcome_version, sharing_3P } = rawObj.value; return { ...(subscriptions ? { subscriptions } : {}), @@ -25,7 +24,6 @@ function extractUserState(rawObj: SharedData) { ...(blocked ? { blocked } : {}), ...(settings ? { settings } : {}), ...(app_welcome_version ? { app_welcome_version } : {}), - ...(tv_welcome_version ? { tv_welcome_version } : {}), ...(sharing_3P ? { sharing_3P} : {}), }; } @@ -35,10 +33,10 @@ function extractUserState(rawObj: SharedData) { export function doPopulateSharedUserState(sharedSettings: any) { return (dispatch: Dispatch) => { - const { subscriptions, tags, blocked, settings, app_welcome_version, tv_welcome_version, sharing_3P } = extractUserState(sharedSettings); + const { subscriptions, tags, blocked, settings, app_welcome_version, sharing_3P } = extractUserState(sharedSettings); dispatch({ type: ACTIONS.USER_STATE_POPULATE, - data: { subscriptions, tags, blocked, settings, welcomeVersion: app_welcome_version, tvWelcomeVersion: tv_welcome_version, allowAnalytics: sharing_3P }, + data: { subscriptions, tags, blocked, settings, welcomeVersion: app_welcome_version, allowAnalytics: sharing_3P }, }); }; } -- 2.45.2 From 929c5de0e29e0e8fc0e11765cb20a90c0f984242 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Sun, 23 Feb 2020 20:19:01 -0500 Subject: [PATCH 275/371] return repost claim in doRepost --- dist/bundle.es.js | 2 +- src/redux/actions/claims.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4f63f2d..f25e82b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3255,7 +3255,7 @@ function doRepost(options) { }); dispatch(doFetchClaimListMine(1, 10)); - resolve(); + resolve(repostClaim); } function failure(error) { diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 4e12c8d..752e081 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -485,7 +485,7 @@ export function doRepost(options: StreamRepostOptions) { }); dispatch(doFetchClaimListMine(1, 10)); - resolve(); + resolve(repostClaim); } function failure(error) { -- 2.45.2 From 9c48cce570ee8e057068c86cb6507e1b441841ee Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 26 Feb 2020 19:11:36 +0100 Subject: [PATCH 276/371] escape curly braces in regexInvalidURI --- dist/bundle.es.js | 4 ++-- src/lbryURI.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e9e7b5e..966e82d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1153,7 +1153,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}]/u; +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}$/; const regexPartProtocol = '^((?:lbry://)?)'; const regexPartStreamOrChannelName = '([^:$#/]*)'; @@ -1689,7 +1689,7 @@ const buildSharedStateMiddleware = (actions, sharedStateFilters, sharedStateCb) } const actionResult = next(action); - // Call `getState` after calling `next` tqo ensure the state has updated in response to the action + // Call `getState` after calling `next` to ensure the state has updated in response to the action const nextState = getState(); const shared = {}; diff --git a/src/lbryURI.js b/src/lbryURI.js index 15ab4e6..b63c1f2 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -4,7 +4,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}]/u; +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}$/; const regexPartProtocol = '^((?:lbry://)?)'; const regexPartStreamOrChannelName = '([^:$#/]*)'; -- 2.45.2 From f36b91496b3852e3d032b6d360b14d5fafbc07a9 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 28 Feb 2020 12:00:53 -0500 Subject: [PATCH 277/371] add show_reposts to list of settings constants --- dist/bundle.es.js | 2 ++ src/constants/settings.js | 1 + 2 files changed, 3 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 966e82d..d9c16c3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -616,6 +616,7 @@ const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; const INVITE_ACKNOWLEDGED = 'invite_acknowledged'; const LANGUAGE = 'language'; const SHOW_MATURE = 'show_mature'; +const SHOW_REPOSTS = 'show_reposts'; const SHOW_ANONYMOUS = 'show_anonymous'; const SHOW_UNAVAILABLE = 'show_unavailable'; const INSTANT_PURCHASE_ENABLED = 'instant_purchase_enabled'; @@ -652,6 +653,7 @@ var settings = /*#__PURE__*/Object.freeze({ INVITE_ACKNOWLEDGED: INVITE_ACKNOWLEDGED, LANGUAGE: LANGUAGE, SHOW_MATURE: SHOW_MATURE, + SHOW_REPOSTS: SHOW_REPOSTS, SHOW_ANONYMOUS: SHOW_ANONYMOUS, SHOW_UNAVAILABLE: SHOW_UNAVAILABLE, INSTANT_PURCHASE_ENABLED: INSTANT_PURCHASE_ENABLED, diff --git a/src/constants/settings.js b/src/constants/settings.js index 5d15850..5dbbaf2 100644 --- a/src/constants/settings.js +++ b/src/constants/settings.js @@ -9,6 +9,7 @@ export const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; export const INVITE_ACKNOWLEDGED = 'invite_acknowledged'; export const LANGUAGE = 'language'; export const SHOW_MATURE = 'show_mature'; +export const SHOW_REPOSTS = 'show_reposts'; export const SHOW_ANONYMOUS = 'show_anonymous'; export const SHOW_UNAVAILABLE = 'show_unavailable'; export const INSTANT_PURCHASE_ENABLED = 'instant_purchase_enabled'; -- 2.45.2 From fd615dbb26fa5a6624a315e1a745a65d062cd295 Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 2 Mar 2020 01:28:36 -0500 Subject: [PATCH 278/371] enable transcoding flag --- dist/bundle.es.js | 13 ++++++++++--- src/redux/actions/publish.js | 6 ++++++ src/redux/reducers/publish.js | 6 ++++-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d9c16c3..730c2ac 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3923,7 +3923,8 @@ const doPublish = (success, fail) => (dispatch, getState) => { fee, uri, tags, - locations + locations, + optimize } = publishData; // Handle scenario where we have a claim that has the same name as a channel we are publishing with. const myClaimForUriEditing = myClaimForUri && myClaimForUri.name === name ? myClaimForUri : null; @@ -3991,6 +3992,10 @@ const doPublish = (success, fail) => (dispatch, getState) => { publishPayload.fee_amount = creditsToString(fee.amount); } + if (optimize) { + publishPayload.optimize_file = true; + } + // Only pass file on new uploads, not metadata only edits. // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; @@ -5465,7 +5470,8 @@ const defaultState$6 = { tags: [], publishing: false, publishSuccess: false, - publishError: undefined + publishError: undefined, + optimize: false }; const publishReducer = handleActions({ @@ -5473,7 +5479,8 @@ const publishReducer = handleActions({ const { data } = action; return _extends$e({}, state, data); }, - [CLEAR_PUBLISH]: () => _extends$e({}, defaultState$6), + [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$6, { bid: state.bid, optimize: state.optimize + }), [PUBLISH_START]: state => _extends$e({}, state, { publishing: true, publishSuccess: false diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index fb00179..a2fbdb0 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -264,6 +264,7 @@ export const doPublish = (success: Function, fail: Function) => ( uri, tags, locations, + optimize, } = publishData; // Handle scenario where we have a claim that has the same name as a channel we are publishing with. const myClaimForUriEditing = myClaimForUri && myClaimForUri.name === name ? myClaimForUri : null; @@ -301,6 +302,7 @@ export const doPublish = (success: Function, fail: Function) => ( tags: Array, locations?: Array, blocking: boolean, + optimize_file?: boolean, } = { name, title, @@ -350,6 +352,10 @@ export const doPublish = (success: Function, fail: Function) => ( publishPayload.fee_amount = creditsToString(fee.amount); } + if (optimize) { + publishPayload.optimize_file = true; + } + // Only pass file on new uploads, not metadata only edits. // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js index 19c5d7a..79e88f0 100644 --- a/src/redux/reducers/publish.js +++ b/src/redux/reducers/publish.js @@ -28,6 +28,7 @@ type PublishState = { otherLicenseDescription: string, licenseUrl: string, tags: Array, + optimize: boolean, }; const defaultState: PublishState = { @@ -58,6 +59,7 @@ const defaultState: PublishState = { publishing: false, publishSuccess: false, publishError: undefined, + optimize: false, }; export const publishReducer = handleActions( @@ -69,8 +71,8 @@ export const publishReducer = handleActions( ...data, }; }, - [ACTIONS.CLEAR_PUBLISH]: (): PublishState => ({ - ...defaultState, + [ACTIONS.CLEAR_PUBLISH]: (state: PublishState): PublishState => ({ + ...defaultState, bid: state.bid, optimize: state.optimize, }), [ACTIONS.PUBLISH_START]: (state: PublishState): PublishState => ({ ...state, -- 2.45.2 From 76207fb3c88868f4eb27d829fe2d3381b4de2f7a Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 9 Mar 2020 10:29:13 -0400 Subject: [PATCH 279/371] use canonical_url when returning own claim urls and fix lint --- dist/bundle.es.js | 10 ++++------ src/redux/actions/claims.js | 1 + src/redux/actions/search.js | 6 +++--- src/redux/selectors/claims.js | 6 +++--- 4 files changed, 11 insertions(+), 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d9c16c3..9202c35 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2206,7 +2206,7 @@ const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsW } else { return b.timestamp - a.timestamp; } -}).map(claim => `lbry://${claim.name}#${claim.claim_id}`)); +}).map(claim => claim.canonical_url)); const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); @@ -2920,6 +2920,7 @@ function doFetchClaimListMine(page = 1, pageSize = 99999, resolve = true) { type: FETCH_CLAIM_LIST_MINE_STARTED }); + // $FlowFixMe lbryProxy.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'], resolve }).then(result => { const claims = result.items; @@ -4210,14 +4211,11 @@ from, isBackgroundSearch = false, options = {}, nsfw) => (dispatch, getState) => return; } - const optionsWithFrom = _extends$8({ - size, - from, + const optionsWithFrom = _extends$8({}, size ? { size } : {}, from ? { from } : {}, { isBackgroundSearch }, options); - const optionsWithoutFrom = _extends$8({ - size, + const optionsWithoutFrom = _extends$8({}, size ? { size } : {}, { isBackgroundSearch }, options); diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 752e081..de18fd9 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -104,6 +104,7 @@ export function doFetchClaimListMine( type: ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED, }); + // $FlowFixMe Lbry.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'], resolve }).then( (result: StreamListResponse) => { const claims = result.items; diff --git a/src/redux/actions/search.js b/src/redux/actions/search.js index 6094277..37618eb 100644 --- a/src/redux/actions/search.js +++ b/src/redux/actions/search.js @@ -184,14 +184,14 @@ export const doResolvedSearch = ( } const optionsWithFrom: SearchOptions = { - size, - from, + ...(size ? { size } : {}), + ...(from ? { from } : {}), isBackgroundSearch, ...options, }; const optionsWithoutFrom: SearchOptions = { - size, + ...(size ? { size } : {}), isBackgroundSearch, ...options, }; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 4db130a..f359844 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -290,8 +290,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -377,7 +377,7 @@ export const selectMyClaimUrisWithoutChannels = createSelector( return b.timestamp - a.timestamp; } }) - .map(claim => `lbry://${claim.name}#${claim.claim_id}`) + .map(claim => claim.canonical_url) ); export const selectAllMyClaimsByOutpoint = createSelector( -- 2.45.2 From 09a6b6ce17834642acf11d76e4adb81e0785b614 Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 25 Feb 2020 08:51:18 -0500 Subject: [PATCH 280/371] Forces the `channel` param to always be present, and not return a null channel. --- src/redux/actions/comments.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index 0bcb8cb..a150a88 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -42,7 +42,7 @@ export function doCommentList(uri: string, page: number = 1, pageSize: number = export function doCommentCreate( comment: string = '', claim_id: string = '', - channel: ?string, + channel: string, parent_id?: string ) { return (dispatch: Dispatch, getState: GetState) => { -- 2.45.2 From 971ec8cbb04c4e05a507dd065f0c38345505443a Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 25 Feb 2020 08:52:30 -0500 Subject: [PATCH 281/371] Error toast for non-anonymous comment constraint --- src/redux/actions/comments.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js index a150a88..22b38e4 100644 --- a/src/redux/actions/comments.js +++ b/src/redux/actions/comments.js @@ -50,10 +50,26 @@ export function doCommentCreate( dispatch({ type: ACTIONS.COMMENT_CREATE_STARTED, }); + const myChannels = selectMyChannelClaims(state); const namedChannelClaim = myChannels && myChannels.find(myChannel => myChannel.name === channel); - const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null; + const channel_id = namedChannelClaim.claim_id; + + if (channel_id == null) { + dispatch({ + type: ACTIONS.COMMENT_CREATE_FAILED, + data: {}, + }); + dispatch( + doToast({ + message: 'Channel cannot be anonymous, please select a channel and try again.', + isError: true, + }) + ); + return; + } + return Lbry.comment_create({ comment: comment, claim_id: claim_id, -- 2.45.2 From 81d3befa03c6c637e8c8064955f3eac80fe9e08b Mon Sep 17 00:00:00 2001 From: Oleg Silkin Date: Tue, 25 Feb 2020 08:52:39 -0500 Subject: [PATCH 282/371] prettier & lint --- dist/bundle.es.js | 43 +++++++++++++++++++++++++++++--- src/redux/actions/publish.js | 24 +++++++++--------- src/redux/actions/sync.js | 29 ++++++++++++++++++--- src/redux/selectors/file_info.js | 12 ++++----- src/redux/selectors/publish.js | 8 +++--- src/redux/selectors/search.js | 12 +++------ src/util/query-params.js | 10 +++----- 7 files changed, 93 insertions(+), 45 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9202c35..e133858 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1618,7 +1618,14 @@ var _extends$2 = Object.assign || function (target) { for (var i = 1; i < argume function extractUserState(rawObj) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blocked, settings, app_welcome_version, sharing_3P } = rawObj.value; + const { + subscriptions, + tags, + blocked, + settings, + app_welcome_version, + sharing_3P + } = rawObj.value; return _extends$2({}, subscriptions ? { subscriptions } : {}, tags ? { tags } : {}, blocked ? { blocked } : {}, settings ? { settings } : {}, app_welcome_version ? { app_welcome_version } : {}, sharing_3P ? { sharing_3P } : {}); } @@ -1628,10 +1635,24 @@ function extractUserState(rawObj) { function doPopulateSharedUserState(sharedSettings) { return dispatch => { - const { subscriptions, tags, blocked, settings, app_welcome_version, sharing_3P } = extractUserState(sharedSettings); + const { + subscriptions, + tags, + blocked, + settings, + app_welcome_version, + sharing_3P + } = extractUserState(sharedSettings); dispatch({ type: USER_STATE_POPULATE, - data: { subscriptions, tags, blocked, settings, welcomeVersion: app_welcome_version, allowAnalytics: sharing_3P } + data: { + subscriptions, + tags, + blocked, + settings, + welcomeVersion: app_welcome_version, + allowAnalytics: sharing_3P + } }); }; } @@ -4365,9 +4386,23 @@ function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { dispatch({ type: COMMENT_CREATE_STARTED }); + const myChannels = selectMyChannelClaims(state); const namedChannelClaim = myChannels && myChannels.find(myChannel => myChannel.name === channel); - const channel_id = namedChannelClaim ? namedChannelClaim.claim_id : null; + const channel_id = namedChannelClaim.claim_id; + + if (channel_id == null) { + dispatch({ + type: COMMENT_CREATE_FAILED, + data: {} + }); + dispatch(doToast({ + message: 'Channel cannot be anonymous, please select a channel and try again.', + isError: true + })); + return; + } + return lbryProxy.comment_create({ comment: comment, claim_id: claim_id, diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index fb00179..8ef9097 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -119,12 +119,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)); @@ -159,12 +159,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/sync.js b/src/redux/actions/sync.js index 28b8d7a..2fc7a1e 100644 --- a/src/redux/actions/sync.js +++ b/src/redux/actions/sync.js @@ -16,7 +16,14 @@ type SharedData = { function extractUserState(rawObj: SharedData) { if (rawObj && rawObj.version === '0.1' && rawObj.value) { - const { subscriptions, tags, blocked, settings, app_welcome_version, sharing_3P } = rawObj.value; + const { + subscriptions, + tags, + blocked, + settings, + app_welcome_version, + sharing_3P, + } = rawObj.value; return { ...(subscriptions ? { subscriptions } : {}), @@ -24,7 +31,7 @@ function extractUserState(rawObj: SharedData) { ...(blocked ? { blocked } : {}), ...(settings ? { settings } : {}), ...(app_welcome_version ? { app_welcome_version } : {}), - ...(sharing_3P ? { sharing_3P} : {}), + ...(sharing_3P ? { sharing_3P } : {}), }; } @@ -33,10 +40,24 @@ function extractUserState(rawObj: SharedData) { export function doPopulateSharedUserState(sharedSettings: any) { return (dispatch: Dispatch) => { - const { subscriptions, tags, blocked, settings, app_welcome_version, sharing_3P } = extractUserState(sharedSettings); + const { + subscriptions, + tags, + blocked, + settings, + app_welcome_version, + sharing_3P, + } = extractUserState(sharedSettings); dispatch({ type: ACTIONS.USER_STATE_POPULATE, - data: { subscriptions, tags, blocked, settings, welcomeVersion: app_welcome_version, allowAnalytics: sharing_3P }, + data: { + subscriptions, + tags, + blocked, + settings, + welcomeVersion: app_welcome_version, + allowAnalytics: sharing_3P, + }, }); }; } diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index f29f3b1..1ff96d5 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -233,12 +233,12 @@ export const makeSelectSearchDownloadUrlsForPage = (query, page = 1) => return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos.slice(start, end).map(fileInfo => - buildURI({ - streamName: fileInfo.claim_name, - channelName: fileInfo.channel_name, - channelClaimId: fileInfo.channel_claim_id, - }) - ) + buildURI({ + streamName: fileInfo.claim_name, + channelName: fileInfo.channel_name, + channelClaimId: fileInfo.channel_claim_id, + }) + ) : []; } ); diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index 10ed95b..82adce2 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -77,10 +77,10 @@ export const selectMyClaimForUri = createSelector( return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => - !contentName - ? claim.name === claimName - : claim.name === contentName || claim.name === claimName - ); + !contentName + ? claim.name === claimName + : claim.name === contentName || claim.name === claimName + ); } ); diff --git a/src/redux/selectors/search.js b/src/redux/selectors/search.js index e3efd11..b5288fd 100644 --- a/src/redux/selectors/search.js +++ b/src/redux/selectors/search.js @@ -172,21 +172,15 @@ type CustomOptions = { from?: number, related_to?: string, nsfw?: boolean, -} +}; -export const makeSelectQueryWithOptions = ( - customQuery: ?string, - options: CustomOptions, -) => +export const makeSelectQueryWithOptions = (customQuery: ?string, options: CustomOptions) => createSelector( selectSearchValue, selectSearchOptions, (query, defaultOptions) => { const searchOptions = { ...defaultOptions, ...options }; - const queryString = getSearchQueryString( - customQuery || query, - searchOptions, - ); + const queryString = getSearchQueryString(customQuery || query, searchOptions); return queryString; } diff --git a/src/util/query-params.js b/src/util/query-params.js index bb1d5ec..0c207ce 100644 --- a/src/util/query-params.js +++ b/src/util/query-params.js @@ -33,10 +33,7 @@ export function toQueryString(params: { [string]: string | number }) { return parts.join('&'); } -export const getSearchQueryString = ( - query: string, - options: any = {}, -) => { +export const getSearchQueryString = (query: string, options: any = {}) => { const encodedQuery = encodeURIComponent(query); const queryParams = [ `s=${encodedQuery}`, @@ -44,7 +41,8 @@ export const getSearchQueryString = ( `from=${options.from || DEFAULT_SEARCH_RESULT_FROM}`, ]; const { isBackgroundSearch } = options; - const includeUserOptions = typeof isBackgroundSearch === 'undefined' ? false : !isBackgroundSearch; + const includeUserOptions = + typeof isBackgroundSearch === 'undefined' ? false : !isBackgroundSearch; if (includeUserOptions) { const claimType = options[SEARCH_OPTIONS.CLAIM_TYPE]; @@ -70,7 +68,7 @@ export const getSearchQueryString = ( } } - const additionalOptions = {} + const additionalOptions = {}; const { related_to } = options; const { nsfw } = options; if (related_to) additionalOptions['related_to'] = related_to; -- 2.45.2 From 1dd2d4cff5b86dc9169d761198b9257227e9c11d Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 10 Mar 2020 10:08:23 -0400 Subject: [PATCH 283/371] export taglist selector --- dist/bundle.es.js | 1 + src/index.js | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ed167eb..39b13cd 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -6345,6 +6345,7 @@ exports.selectFileListPublishedSort = selectFileListPublishedSort; exports.selectFilteredTransactionCount = selectFilteredTransactionCount; exports.selectFilteredTransactions = selectFilteredTransactions; exports.selectFollowedTags = selectFollowedTags; +exports.selectFollowedTagsList = selectFollowedTagsList; exports.selectGettingNewAddress = selectGettingNewAddress; exports.selectHasTransactions = selectHasTransactions; exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; diff --git a/src/index.js b/src/index.js index 7dd8200..0d84118 100644 --- a/src/index.js +++ b/src/index.js @@ -333,6 +333,7 @@ export { export { selectFollowedTags, + selectFollowedTagsList, selectUnfollowedTags, makeSelectIsFollowingTag, } from 'redux/selectors/tags'; -- 2.45.2 From a097c14c31765658ee3206391b34e57868918944 Mon Sep 17 00:00:00 2001 From: Andrey Beletsky Date: Thu, 12 Mar 2020 15:28:47 +0700 Subject: [PATCH 284/371] Add method name to the API query string --- src/lbry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lbry.js b/src/lbry.js index ea72713..146149d 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -191,7 +191,7 @@ export function apiCall(method: string, params: ?{}, resolve: Function, reject: }), }; - return fetch(Lbry.daemonConnectionString, options) + return fetch(Lbry.daemonConnectionString + '?m=' + method, options) .then(checkAndParse) .then(response => { const error = response.error || (response.result && response.result.error); -- 2.45.2 From 8c106012394db1d6f6a78e992a06a037f081858e Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 12 Mar 2020 11:25:33 -0400 Subject: [PATCH 285/371] update build --- dist/bundle.es.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 39b13cd..1545e0d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1052,7 +1052,7 @@ function apiCall(method, params, resolve, reject) { }) }; - return fetch(Lbry.daemonConnectionString, options).then(checkAndParse).then(response => { + return fetch(Lbry.daemonConnectionString + '?m=' + method, options).then(checkAndParse).then(response => { const error = response.error || response.result && response.result.error; if (error) { -- 2.45.2 From 37a01f56c1948b28fa60c38a7a289f6b53ef38b0 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Thu, 12 Mar 2020 12:21:48 -0400 Subject: [PATCH 286/371] light tag cleanup --- src/constants/tags.js | 41 +++++++++++------------------------------ 1 file changed, 11 insertions(+), 30 deletions(-) diff --git a/src/constants/tags.js b/src/constants/tags.js index 3a1e26d..291336d 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -20,11 +20,11 @@ export const DEFAULT_KNOWN_TAGS = [ 'censorship', 'gaming', 'pop culture', - 'Entertainment', + 'entertainment', 'technology', 'music', 'funny', - 'Education', + 'education', 'learning', 'news', 'gameplay', @@ -32,16 +32,13 @@ export const DEFAULT_KNOWN_TAGS = [ 'beliefs', 'comedy', 'games', - 'sony interactive entertainment', 'film & animation', 'game', 'weapons', - "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', - 'ps4live', 'art', 'pc', 'minecraft', @@ -49,7 +46,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'economics', 'automotive', 'play', - 'ps4share', 'tutorial', 'twitch', 'how to', @@ -60,17 +56,16 @@ export const DEFAULT_KNOWN_TAGS = [ 'lets play', 'fun', 'politics', - 'xbox', - 'autos & vehicles', - 'Travel & Events', + 'travel', 'food', 'science', - 'xbox one', + 'xbox', 'liberal', 'democrat', 'progressive', 'survival', - 'Nonprofits & Activism', + 'non-profits', + 'activism', 'cryptocurrency', 'playstation', 'nintendo', @@ -125,7 +120,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'lol', 'sony', 'god', - "let's", 'dance', 'pvp', 'tech', @@ -133,12 +127,10 @@ export const DEFAULT_KNOWN_TAGS = [ 'zombies', 'fail', 'film', - 'xbox 360', + 'xbox360', 'animation', 'unboxing', 'money', - 'how', - 'travel', 'wwe', 'mods', 'indie', @@ -146,7 +138,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'ios', 'history', 'rap', - 'sony computer entertainment', 'mobile', 'trump', 'hack', @@ -170,7 +161,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'mining', 'daily', 'diy', - 'pets & animals', + 'pets', 'videogame', 'death', 'funny moments', @@ -198,14 +189,12 @@ export const DEFAULT_KNOWN_TAGS = [ 'house', 'fire', 'bass', - 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', - 'grand theft auto v', 'health', 'marvel', 'racing', @@ -239,7 +228,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'dota 2', 'studio', 'star wars', - 'gta 5', 'shooting', 'nasa', 'rock', @@ -272,7 +260,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'world of warcraft', 'industry', 'cartoon', - 'crypto news', 'garden', 'animals', 'windows', @@ -286,7 +273,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'parody', 'rv', 'beats', - 'fortnite battle royale', 'building', 'disney', 'drone', @@ -319,7 +305,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'canon', 'microsoft', 'camping', - 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', @@ -355,7 +340,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'manga', 'howto', 'insane', - 'xbox360', 'press', 'special', 'church', @@ -372,7 +356,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'sound', 'christ', 'duty', - 'Juvenile fiction', + 'juvenile fiction', 'pc game', 'how-to', 'ww2', @@ -411,7 +395,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'style', 'travel trailer', 'rda', - '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 'secret', 'far cry 5', @@ -452,8 +435,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'capcom', 'rta', 'discord', - 'action role-playing game', - 'playthrough part', 'batman', 'player', 'server', @@ -494,7 +475,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'paladins', 'warrior', 'creepypasta', - 'role-playing video game', + 'role-playing', 'solar', 'vr', 'animal', @@ -503,7 +484,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'dota', 'audio', 'mass effect', - 'Humour', + 'humour', 'first look', 'videogames', 'future bass', -- 2.45.2 From 6ed0dde5cbd7c25aa02631d5fa31fb6a4de76876 Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 16 Mar 2020 16:29:52 -0400 Subject: [PATCH 287/371] no default tags --- dist/bundle.es.js | 13 ++++++++----- src/redux/reducers/tags.js | 10 ++++++++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1545e0d..dd4378a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -870,7 +870,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'Entertainment', 'technology', 'music', 'funny', 'Education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'sony interactive entertainment', 'film & animation', 'game', 'weapons', "let's play", 'blockchain', 'video game', 'sports', 'walkthrough', 'ps4live', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'ps4share', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'xbox', 'autos & vehicles', 'Travel & Events', 'food', 'science', 'xbox one', 'liberal', 'democrat', 'progressive', 'survival', 'Nonprofits & Activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', "let's", 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox 360', 'animation', 'unboxing', 'money', 'how', 'travel', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'sony computer entertainment', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets & animals', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'bitcoin news', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'grand theft auto v', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'gta 5', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'crypto news', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'fortnite battle royale', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'cryptocurrency news', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'xbox360', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'Juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', '5859dfec-026f-46ba-bea0-02bf43aa1a6f', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'action role-playing game', 'playthrough part', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing video game', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'Humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry']; // @@ -5653,7 +5653,7 @@ function getDefaultKnownTags() { } const defaultState$8 = { - followedTags: DEFAULT_FOLLOWED_TAGS, + followedTags: [], knownTags: getDefaultKnownTags() }; @@ -5702,9 +5702,12 @@ const tagsReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; - return _extends$g({}, state, { - followedTags: tags && tags.length ? tags : DEFAULT_FOLLOWED_TAGS - }); + if (Array.isArray(tags)) { + return _extends$g({}, state, { + followedTags: tags + }); + } + return _extends$g({}, state); } }, defaultState$8); diff --git a/src/redux/reducers/tags.js b/src/redux/reducers/tags.js index 206abf6..b465376 100644 --- a/src/redux/reducers/tags.js +++ b/src/redux/reducers/tags.js @@ -14,7 +14,7 @@ function getDefaultKnownTags() { } const defaultState: TagState = { - followedTags: DEFAULT_FOLLOWED_TAGS, + followedTags: [], knownTags: getDefaultKnownTags(), }; @@ -70,10 +70,16 @@ export const tagsReducer = handleActions( action: { data: { tags: ?Array } } ) => { const { tags } = action.data; + if (Array.isArray(tags)) { + return { + ...state, + followedTags: tags, + }; + } return { ...state, - followedTags: tags && tags.length ? tags : DEFAULT_FOLLOWED_TAGS, }; + }, }, defaultState -- 2.45.2 From 2f896bac53a2424a6820e1a63aa81d6f755dd4f2 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 17 Mar 2020 21:54:34 +0100 Subject: [PATCH 288/371] resolved related tweak (#290) * handle cases where no claim object is present * fix variable * update bundle * get the title properly --- dist/bundle.es.js | 33 +++++++++++++--------- src/redux/selectors/claims.js | 53 +++++++++++++++++++++-------------- 2 files changed, 51 insertions(+), 35 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index dd4378a..de8a54b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2406,28 +2406,33 @@ const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(sele const selectMyStreamUrlsCount = reselect.createSelector(selectMyClaimUrisWithoutChannels, channels => channels.length); -const makeSelectResolvedRecommendedContentForUri = (uri, size) => reselect.createSelector(makeSelectClaimForUri(uri), selectResolvedSearchResultsByQuery, makeSelectClaimIsNsfw(uri), (claim, resolvedResultsByQuery, isMature) => { +const makeSelectResolvedRecommendedContentForUri = (uri, size, claimId, claimName, claimTitle) => reselect.createSelector(makeSelectClaimForUri(uri), selectResolvedSearchResultsByQuery, makeSelectClaimIsNsfw(uri), (claim, resolvedResultsByQuery, isMature) => { const atVanityURI = !uri.includes('#'); + let currentUri; let recommendedContent; + let title; if (claim) { // always grab full URL - this can change once search returns canonical - const currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); + currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); + title = claim.value ? claim.value.title : null; + } else { + // for cases on mobile where the claim may not have been resolved () + currentUri = buildURI({ streamClaimId: claimId, streamName: claimName }); + title = claimTitle; + } - const { title } = claim.value; + if (!title) { + return; + } - if (!title) { - return; - } + const options = { related_to: claim ? claim.claim_id : claimId, size, isBackgroundSearch: false }; - const options = { related_to: claim.claim_id, size, isBackgroundSearch: false }; - - const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); - let results = resolvedResultsByQuery[searchQuery]; - if (results) { - results = results.filter(result => buildURI({ streamClaimId: result.claimId, streamName: result.name }) !== currentUri); - recommendedContent = results; - } + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); + let results = resolvedResultsByQuery[searchQuery]; + if (results) { + results = results.filter(result => buildURI({ streamClaimId: result.claimId, streamName: result.name }) !== currentUri); + recommendedContent = results; } return recommendedContent; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index f359844..7b0c5dd 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -678,7 +678,13 @@ export const selectMyStreamUrlsCount = createSelector( channels => channels.length ); -export const makeSelectResolvedRecommendedContentForUri = (uri: string, size: number) => +export const makeSelectResolvedRecommendedContentForUri = ( + uri: string, + size: number, + claimId: string, + claimName: string, + claimTitle: string +) => createSelector( makeSelectClaimForUri(uri), selectResolvedSearchResultsByQuery, @@ -686,32 +692,37 @@ export const makeSelectResolvedRecommendedContentForUri = (uri: string, size: nu (claim, resolvedResultsByQuery, isMature) => { const atVanityURI = !uri.includes('#'); + let currentUri; let recommendedContent; + let title; if (claim) { // always grab full URL - this can change once search returns canonical - const currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); + currentUri = buildURI({ streamClaimId: claim.claim_id, streamName: claim.name }); + title = claim.value ? claim.value.title : null; + } else { + // for cases on mobile where the claim may not have been resolved () + currentUri = buildURI({ streamClaimId: claimId, streamName: claimName }); + title = claimTitle; + } - const { title } = claim.value; + if (!title) { + return; + } - if (!title) { - return; - } + const options: { + related_to?: string, + nsfw?: boolean, + isBackgroundSearch?: boolean, + } = { related_to: claim ? claim.claim_id : claimId, size, isBackgroundSearch: false }; - const options: { - related_to?: string, - nsfw?: boolean, - isBackgroundSearch?: boolean, - } = { related_to: claim.claim_id, size, isBackgroundSearch: false }; - - const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); - let results = resolvedResultsByQuery[searchQuery]; - if (results) { - results = results.filter( - result => - buildURI({ streamClaimId: result.claimId, streamName: result.name }) !== currentUri - ); - recommendedContent = results; - } + const searchQuery = getSearchQueryString(title.replace(/\//, ' '), options); + let results = resolvedResultsByQuery[searchQuery]; + if (results) { + results = results.filter( + result => + buildURI({ streamClaimId: result.claimId, streamName: result.name }) !== currentUri + ); + recommendedContent = results; } return recommendedContent; -- 2.45.2 From 81f58e3ac7b0a5f8447cc97af36dc7f130bdc6fa Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Tue, 17 Mar 2020 22:57:27 +0100 Subject: [PATCH 289/371] add connectionStringOverride parameter for resolve and claim_search --- dist/bundle.es.js | 25 +++++++++++++------------ src/lbry.js | 14 ++++++++------ src/redux/actions/claims.js | 13 +++++++------ 3 files changed, 28 insertions(+), 24 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index de8a54b..42313e3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -937,9 +937,9 @@ const Lbry = { version: () => daemonCallWithResult('version', {}), // Claim fetching and manipulation - resolve: params => daemonCallWithResult('resolve', params), + resolve: (params, connectionStringOverride = null) => daemonCallWithResult('resolve', params, connectionStringOverride), get: params => daemonCallWithResult('get', params), - claim_search: params => daemonCallWithResult('claim_search', params), + claim_search: (params, connectionStringOverride = null) => daemonCallWithResult('claim_search', params, connectionStringOverride), claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), channel_update: params => daemonCallWithResult('channel_update', params), @@ -1039,7 +1039,7 @@ function checkAndParse(response) { }); } -function apiCall(method, params, resolve, reject) { +function apiCall(method, params, resolve, reject, connectionStringOverride = null) { const counter = new Date().getTime(); const options = { method: 'POST', @@ -1052,7 +1052,8 @@ function apiCall(method, params, resolve, reject) { }) }; - return fetch(Lbry.daemonConnectionString + '?m=' + method, options).then(checkAndParse).then(response => { + const connectionString = connectionStringOverride ? connectionStringOverride : Lbry.daemonConnectionString; + return fetch(connectionString + '?m=' + method, options).then(checkAndParse).then(response => { const error = response.error || response.result && response.result.error; if (error) { @@ -1062,11 +1063,11 @@ function apiCall(method, params, resolve, reject) { }).catch(reject); } -function daemonCallWithResult(name, params = {}) { +function daemonCallWithResult(name, params = {}, connectionStringOverride = null) { return new Promise((resolve, reject) => { apiCall(name, params, result => { resolve(result); - }, reject); + }, reject, connectionStringOverride); }); } @@ -2870,7 +2871,7 @@ function batchActions(...actions) { var _extends$5 = 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) { +function doResolveUris(uris, returnCachedClaims = false, connectionStringOverride = null) { return (dispatch, getState) => { const normalizedUris = uris.map(normalizeURI); const state = getState(); @@ -2896,7 +2897,7 @@ function doResolveUris(uris, returnCachedClaims = false) { const resolveInfo = {}; - lbryProxy.resolve({ urls: urisToResolve }).then(result => { + lbryProxy.resolve({ urls: urisToResolve }, connectionStringOverride).then(result => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { stream: null, @@ -2936,8 +2937,8 @@ function doResolveUris(uris, returnCachedClaims = false) { }; } -function doResolveUri(uri) { - return doResolveUris([uri]); +function doResolveUri(uri, connectionStringOverride = null) { + return doResolveUris([uri], connectionStringOverride); } function doFetchClaimListMine(page = 1, pageSize = 99999, resolve = true) { @@ -3223,7 +3224,7 @@ function doClaimSearch(options = { no_totals: true, page_size: 10, page: 1 -}) { +}, connectionStringOverride = null) { const query = createNormalizedClaimSearchKey(options); return dispatch => { dispatch({ @@ -3259,7 +3260,7 @@ function doClaimSearch(options = { }); }; - lbryProxy.claim_search(options).then(success, failure); + lbryProxy.claim_search(options, connectionStringOverride).then(success, failure); }; } diff --git a/src/lbry.js b/src/lbry.js index 146149d..ba41147 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -73,9 +73,9 @@ const Lbry: LbryTypes = { version: () => daemonCallWithResult('version', {}), // Claim fetching and manipulation - resolve: params => daemonCallWithResult('resolve', params), + resolve: (params, connectionStringOverride = null) => daemonCallWithResult('resolve', params, connectionStringOverride), get: params => daemonCallWithResult('get', params), - claim_search: params => daemonCallWithResult('claim_search', params), + claim_search: (params, connectionStringOverride = null) => daemonCallWithResult('claim_search', params, connectionStringOverride), claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), channel_update: params => daemonCallWithResult('channel_update', params), @@ -178,7 +178,7 @@ function checkAndParse(response) { }); } -export function apiCall(method: string, params: ?{}, resolve: Function, reject: Function) { +export function apiCall(method: string, params: ?{}, resolve: Function, reject: Function, connectionStringOverride = null) { const counter = new Date().getTime(); const options = { method: 'POST', @@ -191,7 +191,8 @@ export function apiCall(method: string, params: ?{}, resolve: Function, reject: }), }; - return fetch(Lbry.daemonConnectionString + '?m=' + method, options) + const connectionString = connectionStringOverride ? connectionStringOverride : Lbry.daemonConnectionString; + return fetch(connectionString + '?m=' + method, options) .then(checkAndParse) .then(response => { const error = response.error || (response.result && response.result.error); @@ -204,7 +205,7 @@ export function apiCall(method: string, params: ?{}, resolve: Function, reject: .catch(reject); } -function daemonCallWithResult(name: string, params: ?{} = {}) { +function daemonCallWithResult(name: string, params: ?{} = {}, connectionStringOverride = null) { return new Promise((resolve, reject) => { apiCall( name, @@ -212,7 +213,8 @@ function daemonCallWithResult(name: string, params: ?{} = {}) { result => { resolve(result); }, - reject + reject, + connectionStringOverride ); }); } diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index de18fd9..b20f67c 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -15,7 +15,7 @@ import { creditsToString } from 'util/format-credits'; import { batchActions } from 'util/batch-actions'; import { createNormalizedClaimSearchKey } from 'util/claim'; -export function doResolveUris(uris: Array, returnCachedClaims: boolean = false) { +export function doResolveUris(uris: Array, returnCachedClaims: boolean = false, connectionStringOverride: string = null) { return (dispatch: Dispatch, getState: GetState) => { const normalizedUris = uris.map(normalizeURI); const state = getState(); @@ -47,7 +47,7 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = }, } = {}; - Lbry.resolve({ urls: urisToResolve }).then((result: ResolveResponse) => { + Lbry.resolve({ urls: urisToResolve }, connectionStringOverride).then((result: ResolveResponse) => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { stream: null, @@ -90,8 +90,8 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = }; } -export function doResolveUri(uri: string) { - return doResolveUris([uri]); +export function doResolveUri(uri: string, connectionStringOverride: string = null) { + return doResolveUris([uri], connectionStringOverride); } export function doFetchClaimListMine( @@ -426,7 +426,8 @@ export function doClaimSearch( no_totals: true, page_size: 10, page: 1, - } + }, + connectionStringOverride: string = null ) { const query = createNormalizedClaimSearchKey(options); return (dispatch: Dispatch) => { @@ -463,7 +464,7 @@ export function doClaimSearch( }); }; - Lbry.claim_search(options).then(success, failure); + Lbry.claim_search(options, connectionStringOverride).then(success, failure); }; } -- 2.45.2 From 69ffd110dbf3633e5847f61f008751edec033017 Mon Sep 17 00:00:00 2001 From: Akinwale Ariwodola Date: Wed, 18 Mar 2020 18:11:03 +0100 Subject: [PATCH 290/371] update type --- dist/bundle.es.js | 26 ++++++++++++++------------ dist/flow-typed/Lbry.js | 2 ++ flow-typed/Lbry.js | 2 ++ src/lbry.js | 17 ++++++++++------- src/redux/actions/claims.js | 13 ++++++------- 5 files changed, 34 insertions(+), 26 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 42313e3..b538929 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -884,6 +884,8 @@ const Lbry = { isConnected: false, connectPromise: null, daemonConnectionString: 'http://localhost:5279', + alternateConnectionString: '', + methodsUsingAlternateConnectionString: [], apiRequestHeaders: { 'Content-Type': 'application/json-rpc' }, // Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) @@ -937,9 +939,9 @@ const Lbry = { version: () => daemonCallWithResult('version', {}), // Claim fetching and manipulation - resolve: (params, connectionStringOverride = null) => daemonCallWithResult('resolve', params, connectionStringOverride), + resolve: params => daemonCallWithResult('resolve', params), get: params => daemonCallWithResult('get', params), - claim_search: (params, connectionStringOverride = null) => daemonCallWithResult('claim_search', params, connectionStringOverride), + claim_search: params => daemonCallWithResult('claim_search', params), claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), channel_update: params => daemonCallWithResult('channel_update', params), @@ -1039,7 +1041,7 @@ function checkAndParse(response) { }); } -function apiCall(method, params, resolve, reject, connectionStringOverride = null) { +function apiCall(method, params, resolve, reject) { const counter = new Date().getTime(); const options = { method: 'POST', @@ -1052,7 +1054,7 @@ function apiCall(method, params, resolve, reject, connectionStringOverride = nul }) }; - const connectionString = connectionStringOverride ? connectionStringOverride : Lbry.daemonConnectionString; + const connectionString = Lbry.methodsUsingAlternateConnectionString.includes(method) ? Lbry.alternateConnectionString : Lbry.daemonConnectionString; return fetch(connectionString + '?m=' + method, options).then(checkAndParse).then(response => { const error = response.error || response.result && response.result.error; @@ -1063,11 +1065,11 @@ function apiCall(method, params, resolve, reject, connectionStringOverride = nul }).catch(reject); } -function daemonCallWithResult(name, params = {}, connectionStringOverride = null) { +function daemonCallWithResult(name, params = {}) { return new Promise((resolve, reject) => { apiCall(name, params, result => { resolve(result); - }, reject, connectionStringOverride); + }, reject); }); } @@ -2871,7 +2873,7 @@ function batchActions(...actions) { var _extends$5 = 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, connectionStringOverride = null) { +function doResolveUris(uris, returnCachedClaims = false) { return (dispatch, getState) => { const normalizedUris = uris.map(normalizeURI); const state = getState(); @@ -2897,7 +2899,7 @@ function doResolveUris(uris, returnCachedClaims = false, connectionStringOverrid const resolveInfo = {}; - lbryProxy.resolve({ urls: urisToResolve }, connectionStringOverride).then(result => { + lbryProxy.resolve({ urls: urisToResolve }).then(result => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { stream: null, @@ -2937,8 +2939,8 @@ function doResolveUris(uris, returnCachedClaims = false, connectionStringOverrid }; } -function doResolveUri(uri, connectionStringOverride = null) { - return doResolveUris([uri], connectionStringOverride); +function doResolveUri(uri) { + return doResolveUris([uri]); } function doFetchClaimListMine(page = 1, pageSize = 99999, resolve = true) { @@ -3224,7 +3226,7 @@ function doClaimSearch(options = { no_totals: true, page_size: 10, page: 1 -}, connectionStringOverride = null) { +}) { const query = createNormalizedClaimSearchKey(options); return dispatch => { dispatch({ @@ -3260,7 +3262,7 @@ function doClaimSearch(options = { }); }; - lbryProxy.claim_search(options, connectionStringOverride).then(success, failure); + lbryProxy.claim_search(options).then(success, failure); }; } diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index ba88d27..9f43627 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -221,6 +221,8 @@ declare type LbryTypes = { connectPromise: ?Promise, connect: () => void, daemonConnectionString: string, + alternateConnectionString: string, + methodsUsingAlternateConnectionString: Array, apiRequestHeaders: { [key: string]: string }, setDaemonConnectionString: string => void, setApiHeader: (string, string) => void, diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index ba88d27..9f43627 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -221,6 +221,8 @@ declare type LbryTypes = { connectPromise: ?Promise, connect: () => void, daemonConnectionString: string, + alternateConnectionString: string, + methodsUsingAlternateConnectionString: Array, apiRequestHeaders: { [key: string]: string }, setDaemonConnectionString: string => void, setApiHeader: (string, string) => void, diff --git a/src/lbry.js b/src/lbry.js index ba41147..33b57c0 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -11,6 +11,8 @@ const Lbry: LbryTypes = { isConnected: false, connectPromise: null, daemonConnectionString: 'http://localhost:5279', + alternateConnectionString: '', + methodsUsingAlternateConnectionString: [], apiRequestHeaders: { 'Content-Type': 'application/json-rpc' }, // Allow overriding daemon connection string (e.g. to `/api/proxy` for lbryweb) @@ -73,9 +75,9 @@ const Lbry: LbryTypes = { version: () => daemonCallWithResult('version', {}), // Claim fetching and manipulation - resolve: (params, connectionStringOverride = null) => daemonCallWithResult('resolve', params, connectionStringOverride), + resolve: params => daemonCallWithResult('resolve', params), get: params => daemonCallWithResult('get', params), - claim_search: (params, connectionStringOverride = null) => daemonCallWithResult('claim_search', params, connectionStringOverride), + claim_search: params => daemonCallWithResult('claim_search', params), claim_list: params => daemonCallWithResult('claim_list', params), channel_create: params => daemonCallWithResult('channel_create', params), channel_update: params => daemonCallWithResult('channel_update', params), @@ -178,7 +180,7 @@ function checkAndParse(response) { }); } -export function apiCall(method: string, params: ?{}, resolve: Function, reject: Function, connectionStringOverride = null) { +export function apiCall(method: string, params: ?{}, resolve: Function, reject: Function) { const counter = new Date().getTime(); const options = { method: 'POST', @@ -191,7 +193,9 @@ export function apiCall(method: string, params: ?{}, resolve: Function, reject: }), }; - const connectionString = connectionStringOverride ? connectionStringOverride : Lbry.daemonConnectionString; + const connectionString = Lbry.methodsUsingAlternateConnectionString.includes(method) + ? Lbry.alternateConnectionString + : Lbry.daemonConnectionString; return fetch(connectionString + '?m=' + method, options) .then(checkAndParse) .then(response => { @@ -205,7 +209,7 @@ export function apiCall(method: string, params: ?{}, resolve: Function, reject: .catch(reject); } -function daemonCallWithResult(name: string, params: ?{} = {}, connectionStringOverride = null) { +function daemonCallWithResult(name: string, params: ?{} = {}) { return new Promise((resolve, reject) => { apiCall( name, @@ -213,8 +217,7 @@ function daemonCallWithResult(name: string, params: ?{} = {}, connectionStringOv result => { resolve(result); }, - reject, - connectionStringOverride + reject ); }); } diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index b20f67c..de18fd9 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -15,7 +15,7 @@ import { creditsToString } from 'util/format-credits'; import { batchActions } from 'util/batch-actions'; import { createNormalizedClaimSearchKey } from 'util/claim'; -export function doResolveUris(uris: Array, returnCachedClaims: boolean = false, connectionStringOverride: string = null) { +export function doResolveUris(uris: Array, returnCachedClaims: boolean = false) { return (dispatch: Dispatch, getState: GetState) => { const normalizedUris = uris.map(normalizeURI); const state = getState(); @@ -47,7 +47,7 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = }, } = {}; - Lbry.resolve({ urls: urisToResolve }, connectionStringOverride).then((result: ResolveResponse) => { + Lbry.resolve({ urls: urisToResolve }).then((result: ResolveResponse) => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { stream: null, @@ -90,8 +90,8 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = }; } -export function doResolveUri(uri: string, connectionStringOverride: string = null) { - return doResolveUris([uri], connectionStringOverride); +export function doResolveUri(uri: string) { + return doResolveUris([uri]); } export function doFetchClaimListMine( @@ -426,8 +426,7 @@ export function doClaimSearch( no_totals: true, page_size: 10, page: 1, - }, - connectionStringOverride: string = null + } ) { const query = createNormalizedClaimSearchKey(options); return (dispatch: Dispatch) => { @@ -464,7 +463,7 @@ export function doClaimSearch( }); }; - Lbry.claim_search(options, connectionStringOverride).then(success, failure); + Lbry.claim_search(options).then(success, failure); }; } -- 2.45.2 From d2f0cf1ca67b10441b5d385b7140ec5987080619 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Thu, 19 Mar 2020 12:54:13 -0400 Subject: [PATCH 291/371] add reposted property --- flow-typed/Claim.js | 1 + 1 file changed, 1 insertion(+) diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 5ebe5e9..8a6d8e8 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -43,6 +43,7 @@ declare type GenericClaim = { expiration_height: number, is_controlling: boolean, support_amount: string, + reposted: number, trending_global: number, trending_group: number, trending_local: number, -- 2.45.2 From 5d2fc0d22e26359c9097ac31dc151affd62936fa Mon Sep 17 00:00:00 2001 From: seanyesmunt Date: Thu, 19 Mar 2020 13:20:58 -0400 Subject: [PATCH 292/371] update build --- dist/flow-typed/Claim.js | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 5ebe5e9..8a6d8e8 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -43,6 +43,7 @@ declare type GenericClaim = { expiration_height: number, is_controlling: boolean, support_amount: string, + reposted: number, trending_global: number, trending_group: number, trending_local: number, -- 2.45.2 From 369a0046cececb3e734c5908c453d2271697242a Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 26 Mar 2020 16:17:19 -0400 Subject: [PATCH 293/371] fix falsely anonymous channels in publishes --- dist/bundle.es.js | 11 ++++++++--- src/redux/selectors/claims.js | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b538929..be62858 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2354,12 +2354,17 @@ const makeSelectFirstRecommendedFileForUri = uri => reselect.createSelector(make // accepts a regular claim uri lbry://something // returns the channel uri that created this claim lbry://@channel const makeSelectChannelForClaimUri = (uri, includePrefix = false) => reselect.createSelector(makeSelectClaimForUri(uri), claim => { - if (!claim || !claim.signing_channel || !claim.signing_channel.canonical_url) { + if (!claim || !claim.signing_channel) { return null; } - const { canonical_url: canonicalUrl } = claim.signing_channel; - return includePrefix ? canonicalUrl : canonicalUrl.slice('lbry://'.length); + const { canonical_url: canonicalUrl, permanent_url: permanentUrl } = claim.signing_channel; + + if (canonicalUrl) { + return includePrefix ? canonicalUrl : canonicalUrl.slice('lbry://'.length); + } else { + return includePrefix ? permanentUrl : permanentUrl.slice('lbry://'.length); + } }); const makeSelectTagsForUri = uri => reselect.createSelector(makeSelectMetadataForUri(uri), metadata => { diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 7b0c5dd..2020d45 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -576,12 +576,17 @@ export const makeSelectChannelForClaimUri = (uri: string, includePrefix: boolean createSelector( makeSelectClaimForUri(uri), (claim: ?Claim) => { - if (!claim || !claim.signing_channel || !claim.signing_channel.canonical_url) { + if (!claim || !claim.signing_channel) { return null; } - const { canonical_url: canonicalUrl } = claim.signing_channel; - return includePrefix ? canonicalUrl : canonicalUrl.slice('lbry://'.length); + const { canonical_url: canonicalUrl, permanent_url: permanentUrl } = claim.signing_channel; + + if (canonicalUrl) { + return includePrefix ? canonicalUrl : canonicalUrl.slice('lbry://'.length); + } else { + return includePrefix ? permanentUrl : permanentUrl.slice('lbry://'.length); + } } ); -- 2.45.2 From 6c0436cf140d2cc839f32ce1a780fc2068d55b85 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 27 Mar 2020 11:52:35 -0400 Subject: [PATCH 294/371] make sure channel is valid before reading permanent_url --- 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 be62858..25f72ed 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2354,7 +2354,7 @@ const makeSelectFirstRecommendedFileForUri = uri => reselect.createSelector(make // accepts a regular claim uri lbry://something // returns the channel uri that created this claim lbry://@channel const makeSelectChannelForClaimUri = (uri, includePrefix = false) => reselect.createSelector(makeSelectClaimForUri(uri), claim => { - if (!claim || !claim.signing_channel) { + if (!claim || !claim.signing_channel || !claim.is_channel_signature_valid) { return null; } diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 2020d45..07f87bf 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -576,7 +576,7 @@ export const makeSelectChannelForClaimUri = (uri: string, includePrefix: boolean createSelector( makeSelectClaimForUri(uri), (claim: ?Claim) => { - if (!claim || !claim.signing_channel) { + if (!claim || !claim.signing_channel || !claim.is_channel_signature_valid) { return null; } -- 2.45.2 From 81138e1a7a963329861e14570ca15571d93e2bec Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 30 Mar 2020 14:19:43 -0400 Subject: [PATCH 295/371] save optimize check state to allow page navigation --- dist/bundle.es.js | 4 ++++ src/redux/reducers/publish.js | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 25f72ed..ab03500 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5492,6 +5492,10 @@ function _objectWithoutProperties$3(obj, keys) { var target = {}; for (var i in const defaultState$6 = { editingURI: undefined, filePath: undefined, + checkFileDur: 0, + checkFileSize: 0, + checkFileVid: false, + canOptimize: undefined, contentIsFree: true, fee: { amount: 1, diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js index 79e88f0..d28a47d 100644 --- a/src/redux/reducers/publish.js +++ b/src/redux/reducers/publish.js @@ -9,6 +9,10 @@ type PublishState = { editingURI: ?string, filePath: ?string, contentIsFree: boolean, + canOptimize: ?boolean, + checkFileDur: number, + checkFileSize: number, + checkFileVid: boolean, fee: { amount: number, currency: string, @@ -34,6 +38,10 @@ type PublishState = { const defaultState: PublishState = { editingURI: undefined, filePath: undefined, + checkFileDur: 0, + checkFileSize: 0, + checkFileVid: false, + canOptimize: undefined, contentIsFree: true, fee: { amount: 1, @@ -72,7 +80,9 @@ export const publishReducer = handleActions( }; }, [ACTIONS.CLEAR_PUBLISH]: (state: PublishState): PublishState => ({ - ...defaultState, bid: state.bid, optimize: state.optimize, + ...defaultState, + bid: state.bid, + optimize: state.optimize, }), [ACTIONS.PUBLISH_START]: (state: PublishState): PublishState => ({ ...state, -- 2.45.2 From 430f989809fed1ac310dbcacef926eb41bf6e6e5 Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 31 Mar 2020 10:05:12 -0400 Subject: [PATCH 296/371] review changes --- dist/bundle.es.js | 11 ++++++----- src/redux/reducers/publish.js | 14 ++++++-------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ab03500..e5b0a35 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5492,10 +5492,9 @@ function _objectWithoutProperties$3(obj, keys) { var target = {}; for (var i in const defaultState$6 = { editingURI: undefined, filePath: undefined, - checkFileDur: 0, - checkFileSize: 0, - checkFileVid: false, - canOptimize: undefined, + fileDur: 0, + fileSize: 0, + fileVid: false, contentIsFree: true, fee: { amount: 1, @@ -5529,7 +5528,9 @@ const publishReducer = handleActions({ const { data } = action; return _extends$e({}, state, data); }, - [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$6, { bid: state.bid, optimize: state.optimize + [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$6, { + bid: state.bid, + optimize: state.optimize }), [PUBLISH_START]: state => _extends$e({}, state, { publishing: true, diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js index d28a47d..ae7313d 100644 --- a/src/redux/reducers/publish.js +++ b/src/redux/reducers/publish.js @@ -9,10 +9,9 @@ type PublishState = { editingURI: ?string, filePath: ?string, contentIsFree: boolean, - canOptimize: ?boolean, - checkFileDur: number, - checkFileSize: number, - checkFileVid: boolean, + fileDur: number, + fileSize: number, + fileVid: boolean, fee: { amount: number, currency: string, @@ -38,10 +37,9 @@ type PublishState = { const defaultState: PublishState = { editingURI: undefined, filePath: undefined, - checkFileDur: 0, - checkFileSize: 0, - checkFileVid: false, - canOptimize: undefined, + fileDur: 0, + fileSize: 0, + fileVid: false, contentIsFree: true, fee: { amount: 1, -- 2.45.2 From af48f6ecd63abbe4f7ad81272372b0a2f83b6a6b Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 31 Mar 2020 11:58:31 -0400 Subject: [PATCH 297/371] add claim search query to claimSearchByQuery when the result times out --- dist/bundle.es.js | 9 +++++++-- src/redux/reducers/claims.js | 7 ++++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 25f72ed..f625234 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4951,11 +4951,16 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { }; reducers[CLAIM_SEARCH_FAILED] = (state, action) => { + const { query } = action.data; + const claimSearchByQuery = Object.assign({}, state.claimSearchByQuery); const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); - delete fetchingClaimSearchByQuery[action.data.query]; + + delete fetchingClaimSearchByQuery[query]; + claimSearchByQuery[query] = null; return Object.assign({}, state, { - fetchingClaimSearchByQuery + fetchingClaimSearchByQuery, + claimSearchByQuery }); }; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 7ca9745..2dd835b 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -457,11 +457,16 @@ reducers[ACTIONS.CLAIM_SEARCH_COMPLETED] = (state: State, action: any): State => }; reducers[ACTIONS.CLAIM_SEARCH_FAILED] = (state: State, action: any): State => { + const { query } = action.data; + const claimSearchByQuery = Object.assign({}, state.claimSearchByQuery); const fetchingClaimSearchByQuery = Object.assign({}, state.fetchingClaimSearchByQuery); - delete fetchingClaimSearchByQuery[action.data.query]; + + delete fetchingClaimSearchByQuery[query]; + claimSearchByQuery[query] = null; return Object.assign({}, state, { fetchingClaimSearchByQuery, + claimSearchByQuery, }); }; -- 2.45.2 From 181883913312c243178f0175792da706b1e8ebce Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 31 Mar 2020 12:26:46 -0400 Subject: [PATCH 298/371] add is_synced to types --- dist/flow-typed/Lbry.js | 1 + flow-typed/Lbry.js | 1 + 2 files changed, 2 insertions(+) diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 9f43627..8bbbb04 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -187,6 +187,7 @@ declare type WalletListResponse = Array<{ declare type WalletStatusResponse = { is_encrypted: boolean, is_locked: boolean, + is_synced: boolean, }; declare type SyncApplyResponse = { diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 9f43627..8bbbb04 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -187,6 +187,7 @@ declare type WalletListResponse = Array<{ declare type WalletStatusResponse = { is_encrypted: boolean, is_locked: boolean, + is_synced: boolean, }; declare type SyncApplyResponse = { -- 2.45.2 From 625a624b9c2d5839e25c1a592d69b9f312944fe0 Mon Sep 17 00:00:00 2001 From: Thomas Zarebczan Date: Tue, 31 Mar 2020 12:33:08 -0400 Subject: [PATCH 299/371] is_syncing! --- dist/flow-typed/Lbry.js | 2 +- flow-typed/Lbry.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 8bbbb04..97e2f20 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -187,7 +187,7 @@ declare type WalletListResponse = Array<{ declare type WalletStatusResponse = { is_encrypted: boolean, is_locked: boolean, - is_synced: boolean, + is_syncing: boolean, }; declare type SyncApplyResponse = { diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 8bbbb04..97e2f20 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -187,7 +187,7 @@ declare type WalletListResponse = Array<{ declare type WalletStatusResponse = { is_encrypted: boolean, is_locked: boolean, - is_synced: boolean, + is_syncing: boolean, }; declare type SyncApplyResponse = { -- 2.45.2 From 1d461ec0886b8a4c3bbfb3aa7115864894c595d4 Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 24 Mar 2020 22:46:35 -0400 Subject: [PATCH 300/371] tip management on claim properly handle pending respond to review --- dist/bundle.es.js | 191 ++++++++++++++++++++++++++++------ src/constants/action_types.js | 4 + src/index.js | 4 + src/redux/actions/wallet.js | 93 ++++++++++++++++- src/redux/reducers/claims.js | 30 ++++-- src/redux/reducers/wallet.js | 24 +++++ src/redux/selectors/claims.js | 22 +++- src/redux/selectors/wallet.js | 18 +++- 8 files changed, 342 insertions(+), 44 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8c0c6e3..01a1227 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -62,6 +62,10 @@ const FETCH_SUPPORTS_STARTED = 'FETCH_SUPPORTS_STARTED'; const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED'; const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED'; const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED'; +const ABANDON_CLAIM_SUPPORT_STARTED = 'ABANDON_CLAIM_SUPPORT_STARTED'; +const ABANDON_CLAIM_SUPPORT_COMPLETED = 'ABANDON_CLAIM_SUPPORT_COMPLETED'; +const ABANDON_CLAIM_SUPPORT_FAILED = 'ABANDON_CLAIM_SUPPORT_FAILED'; +const PENDING_SUPPORTS_UPDATED = 'PENDING_SUPPORTS_UPDATED'; const UPDATE_BALANCE = 'UPDATE_BALANCE'; const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; @@ -327,6 +331,10 @@ var action_types = /*#__PURE__*/Object.freeze({ FETCH_SUPPORTS_COMPLETED: FETCH_SUPPORTS_COMPLETED, ABANDON_SUPPORT_STARTED: ABANDON_SUPPORT_STARTED, ABANDON_SUPPORT_COMPLETED: ABANDON_SUPPORT_COMPLETED, + ABANDON_CLAIM_SUPPORT_STARTED: ABANDON_CLAIM_SUPPORT_STARTED, + ABANDON_CLAIM_SUPPORT_COMPLETED: ABANDON_CLAIM_SUPPORT_COMPLETED, + ABANDON_CLAIM_SUPPORT_FAILED: ABANDON_CLAIM_SUPPORT_FAILED, + PENDING_SUPPORTS_UPDATED: PENDING_SUPPORTS_UPDATED, UPDATE_BALANCE: UPDATE_BALANCE, UPDATE_TOTAL_BALANCE: UPDATE_TOTAL_BALANCE, CHECK_ADDRESS_IS_MINE_STARTED: CHECK_ADDRESS_IS_MINE_STARTED, @@ -1791,6 +1799,15 @@ const selectWalletEncryptPending = reselect.createSelector(selectState$1, state const selectWalletEncryptSucceeded = reselect.createSelector(selectState$1, state => state.walletEncryptSucceded); +const selectPendingSupportTransactions = reselect.createSelector(selectState$1, state => state.pendingSupportTransactions); + +const makeSelectPendingAmountByUri = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingSupportTransactions, (claimIdsByUri, pendingSupports) => { + const uriEntry = Object.entries(claimIdsByUri).find(([u, cid]) => u === uri); + const claimId = uriEntry && uriEntry[1]; + const pendingSupport = claimId && pendingSupports[claimId]; + return pendingSupport ? pendingSupport.effective : undefined; +}); + const selectWalletEncryptResult = reselect.createSelector(selectState$1, state => state.walletEncryptResult); const selectWalletDecryptPending = reselect.createSelector(selectState$1, state => state.walletDecryptPending); @@ -1993,29 +2010,13 @@ function createNormalizedClaimSearchKey(options) { return query; } -function concatClaims(claimList = [], concatClaimList = []) { - if (!claimList || claimList.length === 0) { - if (!concatClaimList) { - return []; - } - return concatClaimList.slice(); - } - - const claims = claimList.slice(); - concatClaimList.forEach(claim => { - if (!claims.some(item => item.claim_id === claim.claim_id)) { - claims.push(claim); - } - }); - - return claims; -} - var _extends$4 = 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; }; const selectState$2 = state => state.claims || {}; const selectClaimsById = reselect.createSelector(selectState$2, state => state.byId || {}); +const selectClaimIdsByUri = reselect.createSelector(selectState$2, state => state.claimsByUri || {}); + const selectCurrentChannelPage = reselect.createSelector(selectState$2, state => state.currentChannelPage || 1); const selectCreatingChannel = reselect.createSelector(selectState$2, state => state.creatingChannel); @@ -2112,7 +2113,21 @@ const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelec } }); -const selectMyClaimsRaw = reselect.createSelector(selectState$2, state => state.myClaims); +const selectMyClaimsRaw = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { + const ids = state.myClaims; + if (!ids) { + return ids; + } + + const claims = []; + ids.forEach(id => { + if (byId[id]) { + // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544 + claims.push(byId[id]); + } + }); + return claims; +}); const selectAbandoningIds = reselect.createSelector(selectState$2, state => Object.keys(state.abandoningById || {})); @@ -2799,6 +2814,34 @@ function doWalletUnlock(password) { }; } +function doSupportAbandonForClaim(claimId, claimType, keep, preview) { + return dispatch => { + if (!preview) { + dispatch({ + type: ABANDON_CLAIM_SUPPORT_STARTED + }); + } + const params = { claim_id: claimId }; + if (preview) params['preview'] = true; + if (keep) params['keep'] = keep; + return lbryProxy.support_abandon(params).then(res => { + if (!preview) { + dispatch({ + type: ABANDON_CLAIM_SUPPORT_COMPLETED, + data: { claimId, txid: res.txid, effective: res.outputs[0].amount, type: claimType } // add to pendingSupportTransactions, + }); + dispatch(doCheckPendingTxs()); + } + return res; + }).catch(e => { + dispatch({ + type: ABANDON_CLAIM_SUPPORT_FAILED, + data: e.message + }); + }); + }; +} + function doWalletReconnect() { return dispatch => { dispatch({ @@ -2868,6 +2911,62 @@ function doUpdateBlockHeight() { }); } +// Calls transaction_show on txes until any pending txes are confirmed +const doCheckPendingTxs = () => (dispatch, getState) => { + const state = getState(); + const pendingTxsById = selectPendingSupportTransactions(state); // {} + if (!Object.keys(pendingTxsById).length) { + return; + } + let txCheckInterval; + const checkTxList = () => { + const state = getState(); + const pendingTxs = selectPendingSupportTransactions(state); // {} + const promises = []; + const newPendingTxes = {}; + const types = new Set([]); + let changed = false; + Object.entries(pendingTxs).forEach(([claim, data]) => { + promises.push(lbryProxy.transaction_show({ txid: data.txid })); + types.add(data.type); + }); + + Promise.all(promises).then(txShows => { + txShows.forEach(result => { + if (result.height <= 0) { + const entries = Object.entries(pendingTxs); + const match = entries.find(entry => entry[1].txid === result.txid); + newPendingTxes[match[0]] = match[1]; + } else { + changed = true; + } + }); + }).then(() => { + if (changed) { + dispatch({ + type: PENDING_SUPPORTS_UPDATED, + data: newPendingTxes + }); + if (types.has('channel')) { + dispatch(doFetchChannelListMine()); + } + if (types.has('stream')) { + dispatch(doFetchClaimListMine()); + } + } + if (Object.keys(newPendingTxes).length === 0) clearInterval(txCheckInterval); + }); + + if (!Object.keys(pendingTxsById).length) { + clearInterval(txCheckInterval); + } + }; + + txCheckInterval = setInterval(() => { + checkTxList(); + }, 30000); +}; + // https://github.com/reactjs/redux/issues/911 function batchActions(...actions) { return { @@ -4681,19 +4780,23 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById = Object.assign({}, state.pendingById); - const myClaims = state.myClaims ? state.myClaims.slice() : []; + let myClaimIds = new Set(state.myClaims); claims.forEach(claim => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - + const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { if (claim.confirmations < 1) { - pendingById[claim.claim_id] = claim; - delete byId[claim.claim_id]; - delete byUri[claim.claim_id]; + pendingById[claimId] = claim; + delete byId[claimId]; + delete byUri[claimId]; } else { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; + byId[claimId] = claim; + byUri[uri] = claimId; + } + myClaimIds.add(claimId); + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; } } }); @@ -4708,7 +4811,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { return Object.assign({}, state, { isFetchingClaimListMine: false, - myClaims: concatClaims(myClaims, claims), + myClaims: myClaimIds, byId, claimsByUri: byUri, pendingById @@ -4720,8 +4823,8 @@ reducers[FETCH_CHANNEL_LIST_STARTED] = state => Object.assign({}, state, { fetch reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { const { claims } = action.data; const myClaims = state.myClaims || []; + let myClaimIds = new Set(state.myClaims); const pendingById = Object.assign(state.pendingById); - let myChannelClaims; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); @@ -4747,6 +4850,11 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { byId[claimId] = claim; } + myClaimIds.add(claimId); + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; + } + if (pendingById[claimId] && claim.confirmations > 0) { delete pendingById[claimId]; } @@ -4759,7 +4867,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { channelClaimCounts, fetchingMyChannels: false, myChannelClaims, - myClaims: concatClaims(myClaims, claims) + myClaims: myClaimIds }); }; @@ -5805,7 +5913,8 @@ const defaultState$a = { walletLockSucceded: null, walletLockResult: null, transactionListFilter: 'all', - walletReconnecting: false + walletReconnecting: false, + pendingSupportTransactions: {} }; const walletReducer = handleActions({ @@ -5868,6 +5977,24 @@ const walletReducer = handleActions({ }); }, + [ABANDON_CLAIM_SUPPORT_COMPLETED]: (state, action) => { + const { claimId, type, txid, effective } = action.data; + const pendingtxs = Object.assign({}, state.pendingSupportTransactions); + + pendingtxs[claimId] = { txid, type, effective }; + + return _extends$i({}, state, { + pendingSupportTransactions: pendingtxs + }); + }, + + [PENDING_SUPPORTS_UPDATED]: (state, action) => { + + return _extends$i({}, state, { + pendingSupportTransactions: action.data + }); + }, + [GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, { gettingNewAddress: true }), @@ -6245,6 +6372,7 @@ exports.doSetDraftTransactionAddress = doSetDraftTransactionAddress; exports.doSetDraftTransactionAmount = doSetDraftTransactionAmount; exports.doSetFileListSort = doSetFileListSort; exports.doSetTransactionListFilter = doSetTransactionListFilter; +exports.doSupportAbandonForClaim = doSupportAbandonForClaim; exports.doToast = doToast; exports.doToggleBlockChannel = doToggleBlockChannel; exports.doToggleTagFollow = doToggleTagFollow; @@ -6301,6 +6429,7 @@ exports.makeSelectMyStreamUrlsForPage = makeSelectMyStreamUrlsForPage; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectOmittedCountForChannel = makeSelectOmittedCountForChannel; +exports.makeSelectPendingAmountByUri = makeSelectPendingAmountByUri; exports.makeSelectPendingByUri = makeSelectPendingByUri; exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; @@ -6343,6 +6472,7 @@ exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; exports.selectChannelImportPending = selectChannelImportPending; exports.selectChannelIsBlocked = selectChannelIsBlocked; +exports.selectClaimIdsByUri = selectClaimIdsByUri; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; exports.selectClaimsBalance = selectClaimsBalance; @@ -6395,6 +6525,7 @@ exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount; exports.selectPendingById = selectPendingById; exports.selectPendingClaims = selectPendingClaims; +exports.selectPendingSupportTransactions = selectPendingSupportTransactions; exports.selectPlayingUri = selectPlayingUri; exports.selectPublishFormValues = selectPublishFormValues; exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index b66893b..05eba19 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -39,6 +39,10 @@ export const FETCH_SUPPORTS_STARTED = 'FETCH_SUPPORTS_STARTED'; export const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED'; export const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED'; export const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED'; +export const ABANDON_CLAIM_SUPPORT_STARTED = 'ABANDON_CLAIM_SUPPORT_STARTED'; +export const ABANDON_CLAIM_SUPPORT_COMPLETED = 'ABANDON_CLAIM_SUPPORT_COMPLETED'; +export const ABANDON_CLAIM_SUPPORT_FAILED = 'ABANDON_CLAIM_SUPPORT_FAILED'; +export const PENDING_SUPPORTS_UPDATED = 'PENDING_SUPPORTS_UPDATED'; export const UPDATE_BALANCE = 'UPDATE_BALANCE'; export const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; export const CHECK_ADDRESS_IS_MINE_STARTED = 'CHECK_ADDRESS_IS_MINE_STARTED'; diff --git a/src/index.js b/src/index.js index 0d84118..8b26154 100644 --- a/src/index.js +++ b/src/index.js @@ -120,6 +120,7 @@ export { doSetTransactionListFilter, doUpdateBlockHeight, doClearSupport, + doSupportAbandonForClaim, } from 'redux/actions/wallet'; export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; @@ -236,6 +237,7 @@ export { selectMyStreamUrlsCount, selectRepostError, selectRepostLoading, + selectClaimIdsByUri, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; @@ -329,6 +331,8 @@ export { makeSelectFilteredTransactionsForPage, selectFilteredTransactionCount, selectIsWalletReconnecting, + selectPendingSupportTransactions, + makeSelectPendingAmountByUri, } from 'redux/selectors/wallet'; export { diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index fe0a4f1..d4af422 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -1,9 +1,10 @@ import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import { doToast } from 'redux/actions/notifications'; -import { selectBalance } from 'redux/selectors/wallet'; +import { selectBalance, selectPendingSupportTransactions } from 'redux/selectors/wallet'; import { creditsToString } from 'util/format-credits'; import { selectMyClaimsRaw } from 'redux/selectors/claims'; +import { doFetchChannelListMine, doFetchClaimListMine } from 'redux/actions/claims'; let walletBalancePromise = null; export function doUpdateBalance() { @@ -342,6 +343,37 @@ export function doWalletLock() { }; } +export function doSupportAbandonForClaim(claimId, claimType, keep, preview) { + return dispatch => { + if (!preview) { + dispatch({ + type: ACTIONS.ABANDON_CLAIM_SUPPORT_STARTED, + }); + } + const params = {claim_id: claimId}; + if (preview) params['preview'] = true; + if (keep) params['keep'] = keep; + return ( + Lbry.support_abandon(params) + .then((res) => { + if (!preview) { + dispatch({ + type: ACTIONS.ABANDON_CLAIM_SUPPORT_COMPLETED, + data: { claimId, txid: res.txid, effective: res.outputs[0].amount, type: claimType}, // add to pendingSupportTransactions, + }); + dispatch(doCheckPendingTxs()); + } + return res; + }) + .catch(e => { + dispatch({ + type: ACTIONS.ABANDON_CLAIM_SUPPORT_FAILED, + data: e.message, + }); + })); + }; +} + export function doWalletReconnect() { return dispatch => { dispatch({ @@ -413,3 +445,62 @@ export function doUpdateBlockHeight() { } }); } + +// Calls transaction_show on txes until any pending txes are confirmed +export const doCheckPendingTxs = () => ( + dispatch, + getState +) => { + const state = getState(); + const pendingTxsById = selectPendingSupportTransactions(state); // {} + if (!Object.keys(pendingTxsById).length) { + return; + } + let txCheckInterval; + const checkTxList = () => { + const state = getState(); + const pendingTxs = selectPendingSupportTransactions(state); // {} + const promises = []; + const newPendingTxes = {}; + const types = new Set([]); + let changed = false; + Object.entries(pendingTxs).forEach(([claim, data]) => { + promises.push(Lbry.transaction_show({txid: data.txid})); + types.add(data.type); + }); + + Promise.all(promises).then(txShows => { + txShows.forEach(result => { + if (result.height <= 0) { + const entries = Object.entries(pendingTxs); + const match = entries.find((entry) => entry[1].txid === result.txid); + newPendingTxes[match[0]] = match[1]; + } else { + changed = true; + } + }); + }).then(() => { + if (changed) { + dispatch({ + type: ACTIONS.PENDING_SUPPORTS_UPDATED, + data: newPendingTxes, + }); + if (types.has('channel')) { + dispatch(doFetchChannelListMine()); + } + if (types.has('stream')) { + dispatch(doFetchClaimListMine()); + } + } + if (Object.keys(newPendingTxes).length === 0) clearInterval(txCheckInterval); + }); + + if (!Object.keys(pendingTxsById).length) { + clearInterval(txCheckInterval); + } + }; + + txCheckInterval = setInterval(() => { + checkTxList(); + }, 30000); +}; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 2dd835b..66ec5f7 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -10,7 +10,6 @@ import * as ACTIONS from 'constants/action_types'; import { buildURI, parseURI } from 'lbryURI'; -import { concatClaims } from 'util/claim'; type State = { createChannelError: ?string, @@ -167,19 +166,23 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); - const myClaims = state.myClaims ? state.myClaims.slice() : []; + let myClaimIds = new Set(state.myClaims); claims.forEach((claim: Claim) => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - + const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { if (claim.confirmations < 1) { - pendingById[claim.claim_id] = claim; - delete byId[claim.claim_id]; - delete byUri[claim.claim_id]; + pendingById[claimId] = claim; + delete byId[claimId]; + delete byUri[claimId]; } else { - byId[claim.claim_id] = claim; - byUri[uri] = claim.claim_id; + byId[claimId] = claim; + byUri[uri] = claimId; + } + myClaimIds.add(claimId); + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; } } }); @@ -195,7 +198,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): return Object.assign({}, state, { isFetchingClaimListMine: false, - myClaims: concatClaims(myClaims, claims), + myClaims: myClaimIds, byId, claimsByUri: byUri, pendingById, @@ -208,8 +211,8 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_STARTED] = (state: State): State => reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): State => { const { claims }: { claims: Array } = action.data; const myClaims = state.myClaims || []; + let myClaimIds = new Set(state.myClaims); const pendingById = Object.assign(state.pendingById); - let myChannelClaims; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); @@ -236,6 +239,11 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St byId[claimId] = claim; } + myClaimIds.add(claimId); + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; + } + if (pendingById[claimId] && claim.confirmations > 0) { delete pendingById[claimId]; } @@ -248,7 +256,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St channelClaimCounts, fetchingMyChannels: false, myChannelClaims, - myClaims: concatClaims(myClaims, claims), + myClaims: myClaimIds, }); }; diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index 26639a2..dc5553f 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -14,6 +14,8 @@ type ActionResult = { result: any, }; + + type WalletState = { balance: any, totalBalance: any, @@ -43,6 +45,7 @@ type WalletState = { walletLockSucceded: ?boolean, walletLockResult: ?boolean, walletReconnecting: boolean, + pendingSupportTransactions: {}, // { claimId: {txid: 123, amount 12.3}, } }; const defaultState = { @@ -76,6 +79,7 @@ const defaultState = { walletLockResult: null, transactionListFilter: 'all', walletReconnecting: false, + pendingSupportTransactions: {}, }; export const walletReducer = handleActions( @@ -144,6 +148,26 @@ export const walletReducer = handleActions( }; }, + [ACTIONS.ABANDON_CLAIM_SUPPORT_COMPLETED]: (state: WalletState, action: any): WalletState => { + const { claimId, type, txid, effective }: { claimId: string, type: string, txid: string, effective: string } = action.data; + const pendingtxs = Object.assign({}, state.pendingSupportTransactions); + + pendingtxs[claimId] = {txid, type, effective}; + + return { + ...state, + pendingSupportTransactions: pendingtxs, + }; + }, + + [ACTIONS.PENDING_SUPPORTS_UPDATED]: (state: WalletState, action: any): WalletState => { + + return { + ...state, + pendingSupportTransactions: action.data, + }; + }, + [ACTIONS.GET_NEW_ADDRESS_STARTED]: (state: WalletState) => ({ ...state, gettingNewAddress: true, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 07f87bf..2200069 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -16,6 +16,11 @@ export const selectClaimsById = createSelector( state => state.byId || {} ); +export const selectClaimIdsByUri = createSelector( + selectState, + state => state.claimsByUri || {} +); + export const selectCurrentChannelPage = createSelector( selectState, state => state.currentChannelPage || 1 @@ -156,7 +161,22 @@ export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) export const selectMyClaimsRaw = createSelector( selectState, - state => state.myClaims + selectClaimsById, + (state, byId) => { + const ids = state.myClaims; + if (!ids) { + return ids; + } + + const claims = []; + ids.forEach(id => { + if (byId[id]) { + // I'm not sure why this check is necessary, but it ought to be a quick fix for https://github.com/lbryio/lbry-desktop/issues/544 + claims.push(byId[id]); + } + }); + return claims; + } ); export const selectAbandoningIds = createSelector( diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 77b1bb3..38347d7 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -1,7 +1,7 @@ import { createSelector } from 'reselect'; import * as TRANSACTIONS from 'constants/transaction_types'; import { PAGE_SIZE, LATEST_PAGE_SIZE } from 'constants/transaction_list'; - +import { selectClaimIdsByUri } from 'redux/selectors/claims'; export const selectState = state => state.wallet || {}; export const selectWalletState = selectState; @@ -21,6 +21,22 @@ export const selectWalletEncryptSucceeded = createSelector( state => state.walletEncryptSucceded ); +export const selectPendingSupportTransactions = createSelector( + selectState, + state => state.pendingSupportTransactions +); + +export const makeSelectPendingAmountByUri = (uri) => createSelector( + selectClaimIdsByUri, + selectPendingSupportTransactions, + (claimIdsByUri, pendingSupports) => { + const uriEntry = Object.entries(claimIdsByUri).find(([u, cid]) => u === uri); + const claimId = uriEntry && uriEntry[1]; + const pendingSupport = claimId && pendingSupports[claimId]; + return pendingSupport ? pendingSupport.effective : undefined; + } +); + export const selectWalletEncryptResult = createSelector( selectState, state => state.walletEncryptResult -- 2.45.2 From 273c325d37db821d0b0ad265d72d67581f7ac3ff Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 1 Apr 2020 10:37:50 -0400 Subject: [PATCH 301/371] check for confirmations when sorting my own claims because of timestamp issues with pending claims --- dist/bundle.es.js | 23 ++++++++++++++--------- src/redux/selectors/claims.js | 18 +++++++++++------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 01a1227..0a5e917 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2237,15 +2237,19 @@ const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaim const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp)); -const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => myClaims.sort((a, b) => { - if (!a.timestamp) { - return -1; - } else if (!b.timestamp) { - return 1; - } else { - return b.timestamp - a.timestamp; - } -}).map(claim => claim.canonical_url)); +const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsWithoutChannels, myClaims => { + return myClaims.sort((a, b) => { + if (a.height < 1) { + return -1; + } else if (b.height < 1) { + return 1; + } else { + return b.timestamp - a.timestamp; + } + }).map(claim => { + return claim.canonical_url || claim.permanent_url; + }); +}); const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); @@ -2424,6 +2428,7 @@ const selectUpdateChannelError = reselect.createSelector(selectState$2, state => const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(selectMyClaimUrisWithoutChannels, urls => { const start = (Number(page) - 1) * Number(PAGE_SIZE); const end = Number(page) * Number(PAGE_SIZE); + return urls && urls.length ? urls.slice(start, end) : []; }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 2200069..ec860a2 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -310,8 +310,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -386,18 +386,21 @@ export const selectMyClaimsWithoutChannels = createSelector( export const selectMyClaimUrisWithoutChannels = createSelector( selectMyClaimsWithoutChannels, - myClaims => - myClaims + myClaims => { + return myClaims .sort((a, b) => { - if (!a.timestamp) { + if (a.height < 1) { return -1; - } else if (!b.timestamp) { + } else if (b.height < 1) { return 1; } else { return b.timestamp - a.timestamp; } }) - .map(claim => claim.canonical_url) + .map(claim => { + return claim.canonical_url || claim.permanent_url; + }); + } ); export const selectAllMyClaimsByOutpoint = createSelector( @@ -694,6 +697,7 @@ export const makeSelectMyStreamUrlsForPage = (page: number = 1) => urls => { const start = (Number(page) - 1) * Number(PAGE_SIZE); const end = Number(page) * Number(PAGE_SIZE); + return urls && urls.length ? urls.slice(start, end) : []; } ); -- 2.45.2 From de41f6bb8e04ec70433196224b748c6e5fd40819 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 1 Apr 2020 14:26:38 -0400 Subject: [PATCH 302/371] adds abandonClaiSupportError to wallet reducer --- dist/bundle.es.js | 30 +++++++++++++++++++++++------- src/index.js | 1 + src/redux/actions/wallet.js | 9 ++++----- src/redux/reducers/wallet.js | 17 +++++++++++++++++ src/redux/selectors/wallet.js | 5 +++++ 5 files changed, 50 insertions(+), 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 0a5e917..1e2e361 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1801,6 +1801,8 @@ const selectWalletEncryptSucceeded = reselect.createSelector(selectState$1, stat const selectPendingSupportTransactions = reselect.createSelector(selectState$1, state => state.pendingSupportTransactions); +const selectAbandonClaimSupportError = reselect.createSelector(selectState$1, state => state.abandonClaimSupportError); + const makeSelectPendingAmountByUri = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingSupportTransactions, (claimIdsByUri, pendingSupports) => { const uriEntry = Object.entries(claimIdsByUri).find(([u, cid]) => u === uri); const claimId = uriEntry && uriEntry[1]; @@ -2821,11 +2823,10 @@ function doWalletUnlock(password) { function doSupportAbandonForClaim(claimId, claimType, keep, preview) { return dispatch => { - if (!preview) { - dispatch({ - type: ABANDON_CLAIM_SUPPORT_STARTED - }); - } + dispatch({ + type: ABANDON_CLAIM_SUPPORT_STARTED + }); + const params = { claim_id: claimId }; if (preview) params['preview'] = true; if (keep) params['keep'] = keep; @@ -5919,7 +5920,8 @@ const defaultState$a = { walletLockResult: null, transactionListFilter: 'all', walletReconnecting: false, - pendingSupportTransactions: {} + pendingSupportTransactions: {}, + abandonClaimSupportError: undefined }; const walletReducer = handleActions({ @@ -5982,6 +5984,12 @@ const walletReducer = handleActions({ }); }, + [ABANDON_CLAIM_SUPPORT_STARTED]: (state, action) => { + return _extends$i({}, state, { + abandonClaimSupportError: undefined + }); + }, + [ABANDON_CLAIM_SUPPORT_COMPLETED]: (state, action) => { const { claimId, type, txid, effective } = action.data; const pendingtxs = Object.assign({}, state.pendingSupportTransactions); @@ -5989,7 +5997,14 @@ const walletReducer = handleActions({ pendingtxs[claimId] = { txid, type, effective }; return _extends$i({}, state, { - pendingSupportTransactions: pendingtxs + pendingSupportTransactions: pendingtxs, + abandonClaimSupportError: undefined + }); + }, + + [ABANDON_CLAIM_SUPPORT_FAILED]: (state, action) => { + return _extends$i({}, state, { + abandonClaimSupportError: action.data }); }, @@ -6466,6 +6481,7 @@ exports.regexAddress = regexAddress; exports.regexInvalidURI = regexInvalidURI; exports.savePosition = savePosition; exports.searchReducer = searchReducer; +exports.selectAbandonClaimSupportError = selectAbandonClaimSupportError; exports.selectAbandoningIds = selectAbandoningIds; exports.selectAllClaimsByChannel = selectAllClaimsByChannel; exports.selectAllFetchingChannelClaims = selectAllFetchingChannelClaims; diff --git a/src/index.js b/src/index.js index 8b26154..d1096ff 100644 --- a/src/index.js +++ b/src/index.js @@ -332,6 +332,7 @@ export { selectFilteredTransactionCount, selectIsWalletReconnecting, selectPendingSupportTransactions, + selectAbandonClaimSupportError, makeSelectPendingAmountByUri, } from 'redux/selectors/wallet'; diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index d4af422..16d4a5c 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -345,11 +345,10 @@ export function doWalletLock() { export function doSupportAbandonForClaim(claimId, claimType, keep, preview) { return dispatch => { - if (!preview) { - dispatch({ - type: ACTIONS.ABANDON_CLAIM_SUPPORT_STARTED, - }); - } + dispatch({ + type: ACTIONS.ABANDON_CLAIM_SUPPORT_STARTED, + }); + const params = {claim_id: claimId}; if (preview) params['preview'] = true; if (keep) params['keep'] = keep; diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index dc5553f..d718fc4 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -46,6 +46,7 @@ type WalletState = { walletLockResult: ?boolean, walletReconnecting: boolean, pendingSupportTransactions: {}, // { claimId: {txid: 123, amount 12.3}, } + abandonClaimSupportError?: string, }; const defaultState = { @@ -80,6 +81,7 @@ const defaultState = { transactionListFilter: 'all', walletReconnecting: false, pendingSupportTransactions: {}, + abandonClaimSupportError: undefined, }; export const walletReducer = handleActions( @@ -148,6 +150,13 @@ export const walletReducer = handleActions( }; }, + [ACTIONS.ABANDON_CLAIM_SUPPORT_STARTED]: (state: WalletState, action: any): WalletState => { + return { + ...state, + abandonClaimSupportError: undefined, + }; + }, + [ACTIONS.ABANDON_CLAIM_SUPPORT_COMPLETED]: (state: WalletState, action: any): WalletState => { const { claimId, type, txid, effective }: { claimId: string, type: string, txid: string, effective: string } = action.data; const pendingtxs = Object.assign({}, state.pendingSupportTransactions); @@ -157,6 +166,14 @@ export const walletReducer = handleActions( return { ...state, pendingSupportTransactions: pendingtxs, + abandonClaimSupportError: undefined, + }; + }, + + [ACTIONS.ABANDON_CLAIM_SUPPORT_FAILED]: (state: WalletState, action: any): WalletState => { + return { + ...state, + abandonClaimSupportError: action.data, }; }, diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 38347d7..4da48db 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -26,6 +26,11 @@ export const selectPendingSupportTransactions = createSelector( state => state.pendingSupportTransactions ); +export const selectAbandonClaimSupportError = createSelector( + selectState, + state => state.abandonClaimSupportError +); + export const makeSelectPendingAmountByUri = (uri) => createSelector( selectClaimIdsByUri, selectPendingSupportTransactions, -- 2.45.2 From 1097a63d44a20b87e443fbaa48f95fe3ea5e3f70 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 1 Apr 2020 14:36:11 -0400 Subject: [PATCH 303/371] add preview action --- dist/bundle.es.js | 20 +++++++++++++++++--- src/constants/action_types.js | 1 + src/redux/actions/wallet.js | 12 +++++++++--- src/redux/reducers/wallet.js | 7 +++++++ 4 files changed, 34 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1e2e361..3e7cffa 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -65,6 +65,7 @@ const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED'; const ABANDON_CLAIM_SUPPORT_STARTED = 'ABANDON_CLAIM_SUPPORT_STARTED'; const ABANDON_CLAIM_SUPPORT_COMPLETED = 'ABANDON_CLAIM_SUPPORT_COMPLETED'; const ABANDON_CLAIM_SUPPORT_FAILED = 'ABANDON_CLAIM_SUPPORT_FAILED'; +const ABANDON_CLAIM_SUPPORT_PREVIEW = 'ABANDON_CLAIM_SUPPORT_PREVIEW'; const PENDING_SUPPORTS_UPDATED = 'PENDING_SUPPORTS_UPDATED'; const UPDATE_BALANCE = 'UPDATE_BALANCE'; const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; @@ -334,6 +335,7 @@ var action_types = /*#__PURE__*/Object.freeze({ ABANDON_CLAIM_SUPPORT_STARTED: ABANDON_CLAIM_SUPPORT_STARTED, ABANDON_CLAIM_SUPPORT_COMPLETED: ABANDON_CLAIM_SUPPORT_COMPLETED, ABANDON_CLAIM_SUPPORT_FAILED: ABANDON_CLAIM_SUPPORT_FAILED, + ABANDON_CLAIM_SUPPORT_PREVIEW: ABANDON_CLAIM_SUPPORT_PREVIEW, PENDING_SUPPORTS_UPDATED: PENDING_SUPPORTS_UPDATED, UPDATE_BALANCE: UPDATE_BALANCE, UPDATE_TOTAL_BALANCE: UPDATE_TOTAL_BALANCE, @@ -2823,9 +2825,15 @@ function doWalletUnlock(password) { function doSupportAbandonForClaim(claimId, claimType, keep, preview) { return dispatch => { - dispatch({ - type: ABANDON_CLAIM_SUPPORT_STARTED - }); + if (preview) { + dispatch({ + type: ABANDON_CLAIM_SUPPORT_PREVIEW + }); + } else { + dispatch({ + type: ABANDON_CLAIM_SUPPORT_STARTED + }); + } const params = { claim_id: claimId }; if (preview) params['preview'] = true; @@ -5990,6 +5998,12 @@ const walletReducer = handleActions({ }); }, + [ABANDON_CLAIM_SUPPORT_PREVIEW]: (state, action) => { + return _extends$i({}, state, { + abandonClaimSupportError: undefined + }); + }, + [ABANDON_CLAIM_SUPPORT_COMPLETED]: (state, action) => { const { claimId, type, txid, effective } = action.data; const pendingtxs = Object.assign({}, state.pendingSupportTransactions); diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 05eba19..ee82147 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -42,6 +42,7 @@ export const ABANDON_SUPPORT_COMPLETED = 'ABANDON_SUPPORT_COMPLETED'; export const ABANDON_CLAIM_SUPPORT_STARTED = 'ABANDON_CLAIM_SUPPORT_STARTED'; export const ABANDON_CLAIM_SUPPORT_COMPLETED = 'ABANDON_CLAIM_SUPPORT_COMPLETED'; export const ABANDON_CLAIM_SUPPORT_FAILED = 'ABANDON_CLAIM_SUPPORT_FAILED'; +export const ABANDON_CLAIM_SUPPORT_PREVIEW = 'ABANDON_CLAIM_SUPPORT_PREVIEW'; export const PENDING_SUPPORTS_UPDATED = 'PENDING_SUPPORTS_UPDATED'; export const UPDATE_BALANCE = 'UPDATE_BALANCE'; export const UPDATE_TOTAL_BALANCE = 'UPDATE_TOTAL_BALANCE'; diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 16d4a5c..627316b 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -345,9 +345,15 @@ export function doWalletLock() { export function doSupportAbandonForClaim(claimId, claimType, keep, preview) { return dispatch => { - dispatch({ - type: ACTIONS.ABANDON_CLAIM_SUPPORT_STARTED, - }); + if (preview) { + dispatch({ + type: ACTIONS.ABANDON_CLAIM_SUPPORT_PREVIEW, + }); + } else { + dispatch({ + type: ACTIONS.ABANDON_CLAIM_SUPPORT_STARTED, + }); + } const params = {claim_id: claimId}; if (preview) params['preview'] = true; diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index d718fc4..5a97e8a 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -157,6 +157,13 @@ export const walletReducer = handleActions( }; }, + [ACTIONS.ABANDON_CLAIM_SUPPORT_PREVIEW]: (state: WalletState, action: any): WalletState => { + return { + ...state, + abandonClaimSupportError: undefined, + }; + }, + [ACTIONS.ABANDON_CLAIM_SUPPORT_COMPLETED]: (state: WalletState, action: any): WalletState => { const { claimId, type, txid, effective }: { claimId: string, type: string, txid: string, effective: string } = action.data; const pendingtxs = Object.assign({}, state.pendingSupportTransactions); -- 2.45.2 From f18fc99933e4c056a74e605f598ac79bc684b317 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Tue, 14 Apr 2020 13:45:02 -0400 Subject: [PATCH 304/371] add some tags for topical events --- src/constants/tags.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/constants/tags.js b/src/constants/tags.js index 291336d..39fa295 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -494,4 +494,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'dantdm', 'teaser', 'lbry', + 'coronavirus', + 'covidcuts', + 'covid-19' ]; -- 2.45.2 From 320c6c5b704607b1cc66cb1427508471d0148124 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Tue, 14 Apr 2020 13:45:40 -0400 Subject: [PATCH 305/371] add trailing comma --- src/constants/tags.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/constants/tags.js b/src/constants/tags.js index 39fa295..66500ad 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -496,5 +496,5 @@ export const DEFAULT_KNOWN_TAGS = [ 'lbry', 'coronavirus', 'covidcuts', - 'covid-19' + 'covid-19', ]; -- 2.45.2 From 677dd256437f4cefa3eba96f0a28a814d07736c8 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 14 Apr 2020 13:54:59 -0400 Subject: [PATCH 306/371] update build --- dist/bundle.es.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3e7cffa..85f9e3b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -880,7 +880,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; // -- 2.45.2 From 1e505184dc9f523d14f240aca3d9a32acc64f86c Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 10 Apr 2020 08:16:27 -0400 Subject: [PATCH 307/371] add txo list by params fix set.slice() error add txopage reducer move txo constants to redux abandon bug abandon callback --- dist/bundle.es.js | 255 ++++++++++++++++++++++++++++++++-- dist/flow-typed/Txo.js | 24 ++++ flow-typed/Txo.js | 24 ++++ src/constants/action_types.js | 4 + src/constants/txo_list.js | 35 +++++ src/index.js | 11 ++ src/redux/actions/claims.js | 93 +++++++++++-- src/redux/actions/wallet.js | 39 +++++- src/redux/reducers/claims.js | 18 ++- src/redux/reducers/wallet.js | 44 +++++- src/redux/selectors/wallet.js | 30 ++++ 11 files changed, 547 insertions(+), 30 deletions(-) create mode 100644 dist/flow-typed/Txo.js create mode 100644 flow-typed/Txo.js create mode 100644 src/constants/txo_list.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 85f9e3b..0b3c8f9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -58,6 +58,10 @@ const GET_NEW_ADDRESS_STARTED = 'GET_NEW_ADDRESS_STARTED'; const GET_NEW_ADDRESS_COMPLETED = 'GET_NEW_ADDRESS_COMPLETED'; const FETCH_TRANSACTIONS_STARTED = 'FETCH_TRANSACTIONS_STARTED'; const FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'; +const FETCH_TXO_PAGE_STARTED = 'FETCH_TXO_PAGE_STARTED'; +const FETCH_TXO_PAGE_COMPLETED = 'FETCH_TXO_PAGE_COMPLETED'; +const FETCH_TXO_PAGE_FAILED = 'FETCH_TXO_PAGE_FAILED'; +const UPDATE_TXO_FETCH_PARAMS = 'UPDATE_TXO_FETCH_PARAMS'; const FETCH_SUPPORTS_STARTED = 'FETCH_SUPPORTS_STARTED'; const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED'; const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED'; @@ -328,6 +332,10 @@ var action_types = /*#__PURE__*/Object.freeze({ GET_NEW_ADDRESS_COMPLETED: GET_NEW_ADDRESS_COMPLETED, FETCH_TRANSACTIONS_STARTED: FETCH_TRANSACTIONS_STARTED, FETCH_TRANSACTIONS_COMPLETED: FETCH_TRANSACTIONS_COMPLETED, + FETCH_TXO_PAGE_STARTED: FETCH_TXO_PAGE_STARTED, + FETCH_TXO_PAGE_COMPLETED: FETCH_TXO_PAGE_COMPLETED, + FETCH_TXO_PAGE_FAILED: FETCH_TXO_PAGE_FAILED, + UPDATE_TXO_FETCH_PARAMS: UPDATE_TXO_FETCH_PARAMS, FETCH_SUPPORTS_STARTED: FETCH_SUPPORTS_STARTED, FETCH_SUPPORTS_COMPLETED: FETCH_SUPPORTS_COMPLETED, ABANDON_SUPPORT_STARTED: ABANDON_SUPPORT_STARTED, @@ -749,6 +757,71 @@ var transaction_list = /*#__PURE__*/Object.freeze({ LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); +const ACTIVE = 'active'; // spent, active, all +const TYPE = 'type'; // all, payment, support, channel, stream, repost +const SUB_TYPE = 'subtype'; // other, purchase, tip +const PAGE_SIZE$2 = 'page_size'; +const PAGE = 'page'; +const ALL$1 = 'all'; +// dropdown types +const SENT = 'sent'; +const RECEIVED = 'received'; +const SUPPORT$1 = 'support'; +const CHANNEL$2 = 'channel'; +const PUBLISH$2 = 'publish'; +const REPOST = 'repost'; +const DROPDOWN_TYPES = [ALL$1, SENT, RECEIVED, SUPPORT$1, CHANNEL$2, PUBLISH$2, REPOST]; +// dropdown subtypes +const TIP$1 = 'tip'; +const PURCHASE = 'purchase'; +const PAYMENT = 'payment'; +const DROPDOWN_SUBTYPES = [ALL$1, TIP$1, PURCHASE, PAYMENT]; + +// rpc params +const TX_TYPE = 'type'; // = other, stream, repost, channel, support, purchase +const IS_SPENT = 'is_spent'; +const IS_NOT_SPENT = 'is_not_spent'; +const IS_MY_INPUT = 'is_my_input'; +const IS_MY_OUTPUT = 'is_my_output'; +const IS_NOT_MY_INPUT = 'is_not_my_input'; +const IS_NOT_MY_OUTPUT = 'is_not_my_output'; // use to further distinguish payments to self / from self. + +// sdk unique types +const OTHER$1 = 'other'; +const STREAM = 'stream'; + +const PAGE_SIZE_DEFAULT = 20; + +var txo_list = /*#__PURE__*/Object.freeze({ + ACTIVE: ACTIVE, + TYPE: TYPE, + SUB_TYPE: SUB_TYPE, + PAGE_SIZE: PAGE_SIZE$2, + PAGE: PAGE, + ALL: ALL$1, + SENT: SENT, + RECEIVED: RECEIVED, + SUPPORT: SUPPORT$1, + CHANNEL: CHANNEL$2, + PUBLISH: PUBLISH$2, + REPOST: REPOST, + DROPDOWN_TYPES: DROPDOWN_TYPES, + TIP: TIP$1, + PURCHASE: PURCHASE, + PAYMENT: PAYMENT, + DROPDOWN_SUBTYPES: DROPDOWN_SUBTYPES, + TX_TYPE: TX_TYPE, + IS_SPENT: IS_SPENT, + IS_NOT_SPENT: IS_NOT_SPENT, + IS_MY_INPUT: IS_MY_INPUT, + IS_MY_OUTPUT: IS_MY_OUTPUT, + IS_NOT_MY_INPUT: IS_NOT_MY_INPUT, + IS_NOT_MY_OUTPUT: IS_NOT_MY_OUTPUT, + OTHER: OTHER$1, + STREAM: STREAM, + PAGE_SIZE_DEFAULT: PAGE_SIZE_DEFAULT +}); + const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; @@ -1966,6 +2039,18 @@ const selectFilteredTransactions = reselect.createSelector(selectTransactionItem }); }); +const selectTxoPageParams = reselect.createSelector(selectState$1, state => state.txoFetchParams); + +const selectTxoPage = reselect.createSelector(selectState$1, state => state.txoPage && state.txoPage.items || []); + +const selectTxoPageNumber = reselect.createSelector(selectState$1, state => state.txoPage && state.txoPage.page || 1); + +const selectTxoItemCount = reselect.createSelector(selectState$1, state => state.txoPage && state.txoPage.total_items || 1); + +const selectFetchingTxosError = reselect.createSelector(selectState$1, state => state.fetchingTxosError); + +const selectIsFetchingTxos = reselect.createSelector(selectState$1, state => state.fetchingTxos); + const makeSelectFilteredTransactionsForPage = (page = 1) => reselect.createSelector(selectFilteredTransactions, filteredTransactions => { const start = (Number(page) - 1) * Number(PAGE_SIZE$1); const end = Number(page) * Number(PAGE_SIZE$1); @@ -2591,6 +2676,40 @@ function doFetchTransactions(page = 1, pageSize = 99999) { }; } +function doFetchTxoPage() { + return (dispatch, getState) => { + dispatch({ + type: FETCH_TXO_PAGE_STARTED + }); + + const state = getState(); + const queryParams = selectTxoPageParams(state); + + lbryProxy.txo_list(queryParams).then(res => { + dispatch({ + type: FETCH_TXO_PAGE_COMPLETED, + data: res + }); + }).catch(e => { + dispatch({ + type: FETCH_TXO_PAGE_COMPLETED, + data: e.message + }); + }); + }; +} + +function doUpdateTxoPageParams(params) { + return dispatch => { + dispatch({ + type: UPDATE_TXO_FETCH_PARAMS, + data: params + }); + + dispatch(doFetchTxoPage()); + }; +} + function doFetchSupports(page = 1, pageSize = 99999) { return dispatch => { dispatch({ @@ -3081,6 +3200,77 @@ function doFetchClaimListMine(page = 1, pageSize = 99999, resolve = true) { }; } +function doAbandonTxo(txo, cb) { + return dispatch => { + const isClaim = txo.type === 'claim'; + const isSupport = txo.type === 'support' && txo.is_my_input === true; + const isTip = txo.type === 'support' && txo.is_my_input === false; + + const data = isClaim ? { claimId: txo.claim_id } : { outpoint: `${txo.txid}:${txo.nout}` }; + + const startedActionType = isClaim ? ABANDON_CLAIM_STARTED : ABANDON_SUPPORT_STARTED; + const completedActionType = isClaim ? ABANDON_CLAIM_SUCCEEDED : ABANDON_SUPPORT_COMPLETED; + + dispatch({ + type: startedActionType, + data + }); + + const errorCallback = () => { + dispatch(doToast({ + message: isClaim ? 'Error abandoning your claim/support' : 'Error unlocking your tip', + isError: true + })); + }; + + const successCallback = () => { + dispatch({ + type: completedActionType, + data + }); + + let abandonMessage; + if (isClaim) { + abandonMessage = 'Successfully abandoned your claim.'; + } else if (isSupport) { + abandonMessage = 'Successfully abandoned your support.'; + } else { + abandonMessage = 'Successfully unlocked your tip!'; + } + if (cb) cb(); + + dispatch(doToast({ + message: abandonMessage + })); + }; + + const abandonParams = { + blocking: true + }; + if (isClaim) { + abandonParams['claim_id'] = txo.claim_id; + } else { + abandonParams['txid'] = txo.txid; + abandonParams['nout'] = txo.nout; + } + + let method; + if (isSupport || isTip) { + method = 'support_abandon'; + } else if (isClaim) { + const { normalized_name: claimName } = txo; + method = claimName.startsWith('@') ? 'channel_abandon' : 'stream_abandon'; + } + + if (!method) { + console.error('No "method" chosen for claim or support abandon'); + return; + } + + lbryProxy[method](abandonParams).then(successCallback, errorCallback); + }; +} + function doAbandonClaim(txid, nout) { const outpoint = `${txid}:${nout}`; @@ -3134,13 +3324,7 @@ function doAbandonClaim(txid, nout) { dispatch(doToast({ message: abandonMessage })); - - // After abandoning, fetch transactions to show the new abandon transaction - // Only fetch the latest few transactions since we don't care about old ones - // Not very robust, but better than calling the entire list for large wallets - const page = 1; - const pageSize = 10; - dispatch(doFetchTransactions(page, pageSize)); + dispatch(doFetchTxoPage()); }; const abandonParams = { @@ -4825,7 +5009,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { return Object.assign({}, state, { isFetchingClaimListMine: false, - myClaims: myClaimIds, + myClaims: Array.from(myClaimIds), byId, claimsByUri: byUri, pendingById @@ -4880,8 +5064,8 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { claimsByUri: byUri, channelClaimCounts, fetchingMyChannels: false, - myChannelClaims, - myClaims: myClaimIds + myChannelClaims: Array.from(myChannelClaims), + myClaims: Array.from(myClaimIds) }); }; @@ -4960,6 +5144,7 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { const { claimId } = action.data; const byId = Object.assign({}, state.byId); const newMyClaims = state.myClaims ? state.myClaims.slice() : []; + const newMyChannelClaims = state.myChannelClaims ? state.myChannelClaims.slice() : []; const claimsByUri = Object.assign({}, state.claimsByUri); Object.keys(claimsByUri).forEach(uri => { @@ -4967,11 +5152,14 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { delete claimsByUri[uri]; } }); - const myClaims = newMyClaims.filter(i => i.claim_id && i.claim_id !== claimId); + const myClaims = newMyClaims.filter(i => i !== claimId); + const myChannelClaims = newMyChannelClaims.filter(i => i !== claimId); + delete byId[claimId]; return Object.assign({}, state, { myClaims, + myChannelClaims, byId, claimsByUri }); @@ -4995,7 +5183,7 @@ reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { return Object.assign({}, state, { byId, pendingById, - myChannelClaims, + myChannelClaims: Array.from(myChannelClaims), creatingChannel: false }); }; @@ -5907,6 +6095,7 @@ const defaultState$a = { latestBlock: undefined, transactions: {}, fetchingTransactions: false, + fetchingTransactionsError: undefined, supports: {}, fetchingSupports: false, abandoningSupportsByOutpoint: {}, @@ -5928,6 +6117,10 @@ const defaultState$a = { walletLockResult: null, transactionListFilter: 'all', walletReconnecting: false, + txoFetchParams: {}, + txoPage: {}, + fetchingTxos: false, + fetchingTxosError: undefined, pendingSupportTransactions: {}, abandonClaimSupportError: undefined }; @@ -5951,6 +6144,34 @@ const walletReducer = handleActions({ }); }, + [FETCH_TXO_PAGE_STARTED]: state => { + return _extends$i({}, state, { + fetchingTxos: true, + fetchingTxosError: undefined + }); + }, + + [FETCH_TXO_PAGE_COMPLETED]: (state, action) => { + return _extends$i({}, state, { + txoPage: action.data, + fetchingTxos: false + }); + }, + + [FETCH_TXO_PAGE_FAILED]: (state, action) => { + return _extends$i({}, state, { + txoPage: {}, + fetchingTxos: false, + fetchingTxosError: action.data + }); + }, + + [UPDATE_TXO_FETCH_PARAMS]: (state, action) => { + return _extends$i({}, state, { + txoFetchParams: action.data + }); + }, + [FETCH_SUPPORTS_STARTED]: state => _extends$i({}, state, { fetchingSupports: true }), @@ -6344,6 +6565,7 @@ exports.SORT_OPTIONS = sort_options; exports.SPEECH_URLS = speech_urls; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; +exports.TXO_LIST = txo_list; exports.TX_LIST = transaction_list; exports.apiCall = apiCall; exports.batchActions = batchActions; @@ -6357,6 +6579,7 @@ exports.convertToShareLink = convertToShareLink; exports.createNormalizedClaimSearchKey = createNormalizedClaimSearchKey; exports.creditsToString = creditsToString; exports.doAbandonClaim = doAbandonClaim; +exports.doAbandonTxo = doAbandonTxo; exports.doAddTag = doAddTag; exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; @@ -6383,6 +6606,7 @@ exports.doFetchClaimsByChannel = doFetchClaimsByChannel; exports.doFetchFileInfo = doFetchFileInfo; exports.doFetchFileInfosAndPublishedClaims = doFetchFileInfosAndPublishedClaims; exports.doFetchTransactions = doFetchTransactions; +exports.doFetchTxoPage = doFetchTxoPage; exports.doFileGet = doFileGet; exports.doFileList = doFileList; exports.doFocusSearchInput = doFocusSearchInput; @@ -6416,6 +6640,7 @@ exports.doUpdateChannel = doUpdateChannel; exports.doUpdatePublishForm = doUpdatePublishForm; exports.doUpdateSearchOptions = doUpdateSearchOptions; exports.doUpdateSearchQuery = doUpdateSearchQuery; +exports.doUpdateTxoPageParams = doUpdateTxoPageParams; exports.doUploadThumbnail = doUploadThumbnail; exports.doWalletDecrypt = doWalletDecrypt; exports.doWalletEncrypt = doWalletEncrypt; @@ -6529,6 +6754,7 @@ exports.selectFailedPurchaseUris = selectFailedPurchaseUris; exports.selectFetchingClaimSearch = selectFetchingClaimSearch; exports.selectFetchingClaimSearchByQuery = selectFetchingClaimSearchByQuery; exports.selectFetchingMyChannels = selectFetchingMyChannels; +exports.selectFetchingTxosError = selectFetchingTxosError; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; exports.selectFileListDownloadedSort = selectFileListDownloadedSort; @@ -6543,6 +6769,7 @@ exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; exports.selectIsFetchingFileList = selectIsFetchingFileList; exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileListDownloadedOrPublished; exports.selectIsFetchingTransactions = selectIsFetchingTransactions; +exports.selectIsFetchingTxos = selectIsFetchingTxos; exports.selectIsResolvingPublishUris = selectIsResolvingPublishUris; exports.selectIsSearching = selectIsSearching; exports.selectIsSendingSupport = selectIsSendingSupport; @@ -6590,6 +6817,10 @@ exports.selectTotalSupports = selectTotalSupports; exports.selectTransactionItems = selectTransactionItems; exports.selectTransactionListFilter = selectTransactionListFilter; exports.selectTransactionsById = selectTransactionsById; +exports.selectTxoItemCount = selectTxoItemCount; +exports.selectTxoPage = selectTxoPage; +exports.selectTxoPageNumber = selectTxoPageNumber; +exports.selectTxoPageParams = selectTxoPageParams; exports.selectUnfollowedTags = selectUnfollowedTags; exports.selectUpdateChannelError = selectUpdateChannelError; exports.selectUpdatingChannel = selectUpdatingChannel; diff --git a/dist/flow-typed/Txo.js b/dist/flow-typed/Txo.js new file mode 100644 index 0000000..5950c99 --- /dev/null +++ b/dist/flow-typed/Txo.js @@ -0,0 +1,24 @@ +declare type Txo = { + amount: number, + claim_id: string, + normalized_name: string, + nout: number, + txid: string, + type: string, + value_type: string, + timestamp: number, + is_my_output: boolean, + is_my_input: boolean, + is_spent: boolean, +}; + +declare type TxoListParams = { + page: number, + page_size: number, + type: string, + is_my_input?: boolean, + is_my_output?: boolean, + is_not_my_input?: boolean, + is_not_my_output?: boolean, + is_spent?: boolean, +} diff --git a/flow-typed/Txo.js b/flow-typed/Txo.js new file mode 100644 index 0000000..5950c99 --- /dev/null +++ b/flow-typed/Txo.js @@ -0,0 +1,24 @@ +declare type Txo = { + amount: number, + claim_id: string, + normalized_name: string, + nout: number, + txid: string, + type: string, + value_type: string, + timestamp: number, + is_my_output: boolean, + is_my_input: boolean, + is_spent: boolean, +}; + +declare type TxoListParams = { + page: number, + page_size: number, + type: string, + is_my_input?: boolean, + is_my_output?: boolean, + is_not_my_input?: boolean, + is_not_my_output?: boolean, + is_spent?: boolean, +} diff --git a/src/constants/action_types.js b/src/constants/action_types.js index ee82147..ed2cb93 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -35,6 +35,10 @@ export const GET_NEW_ADDRESS_STARTED = 'GET_NEW_ADDRESS_STARTED'; export const GET_NEW_ADDRESS_COMPLETED = 'GET_NEW_ADDRESS_COMPLETED'; export const FETCH_TRANSACTIONS_STARTED = 'FETCH_TRANSACTIONS_STARTED'; export const FETCH_TRANSACTIONS_COMPLETED = 'FETCH_TRANSACTIONS_COMPLETED'; +export const FETCH_TXO_PAGE_STARTED = 'FETCH_TXO_PAGE_STARTED'; +export const FETCH_TXO_PAGE_COMPLETED = 'FETCH_TXO_PAGE_COMPLETED'; +export const FETCH_TXO_PAGE_FAILED = 'FETCH_TXO_PAGE_FAILED'; +export const UPDATE_TXO_FETCH_PARAMS = 'UPDATE_TXO_FETCH_PARAMS'; export const FETCH_SUPPORTS_STARTED = 'FETCH_SUPPORTS_STARTED'; export const FETCH_SUPPORTS_COMPLETED = 'FETCH_SUPPORTS_COMPLETED'; export const ABANDON_SUPPORT_STARTED = 'ABANDON_SUPPORT_STARTED'; diff --git a/src/constants/txo_list.js b/src/constants/txo_list.js new file mode 100644 index 0000000..b143bef --- /dev/null +++ b/src/constants/txo_list.js @@ -0,0 +1,35 @@ +export const ACTIVE = 'active'; // spent, active, all +export const TYPE = 'type'; // all, payment, support, channel, stream, repost +export const SUB_TYPE = 'subtype'; // other, purchase, tip +export const PAGE_SIZE = 'page_size'; +export const PAGE = 'page'; +export const ALL = 'all'; +// dropdown types +export const SENT = 'sent'; +export const RECEIVED = 'received'; +export const SUPPORT = 'support'; +export const CHANNEL = 'channel'; +export const PUBLISH = 'publish'; +export const REPOST = 'repost'; +export const DROPDOWN_TYPES = [ALL, SENT, RECEIVED, SUPPORT, CHANNEL, PUBLISH, REPOST]; +// dropdown subtypes +export const TIP = 'tip'; +export const PURCHASE = 'purchase'; +export const PAYMENT = 'payment'; +export const DROPDOWN_SUBTYPES = [ALL, TIP, PURCHASE, PAYMENT]; + +// rpc params +export const TX_TYPE = 'type'; // = other, stream, repost, channel, support, purchase +export const IS_SPENT = 'is_spent'; +export const IS_NOT_SPENT = 'is_not_spent'; +export const IS_MY_INPUT = 'is_my_input'; +export const IS_MY_OUTPUT = 'is_my_output'; +export const IS_NOT_MY_INPUT = 'is_not_my_input'; +export const IS_NOT_MY_OUTPUT = 'is_not_my_output'; // use to further distinguish payments to self / from self. + +// sdk unique types +export const OTHER = 'other'; +export const STREAM = 'stream'; + +export const PAGE_SIZE_DEFAULT = 20; + diff --git a/src/index.js b/src/index.js index d1096ff..ac96c7c 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import * as SORT_OPTIONS from 'constants/sort_options'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as TRANSACTIONS from 'constants/transaction_types'; import * as TX_LIST from 'constants/transaction_list'; +import * as TXO_LIST from 'constants/txo_list'; import * as SPEECH_URLS from 'constants/speech_urls'; import * as DAEMON_SETTINGS from 'constants/daemon_settings'; import * as SHARED_PREFERENCES from 'constants/shared_preferences'; @@ -27,6 +28,7 @@ export { DAEMON_SETTINGS, TRANSACTIONS, TX_LIST, + TXO_LIST, SORT_OPTIONS, PAGES, DEFAULT_KNOWN_TAGS, @@ -60,6 +62,7 @@ export { doFetchClaimsByChannel, doFetchClaimListMine, doAbandonClaim, + doAbandonTxo, doResolveUris, doResolveUri, doFetchChannelListMine, @@ -106,6 +109,8 @@ export { doUpdateBalance, doBalanceSubscribe, doFetchTransactions, + doFetchTxoPage, + doUpdateTxoPageParams, doGetNewAddress, doCheckAddressIsMine, doSendDraftTransaction, @@ -327,6 +332,12 @@ export { selectWalletUnlockResult, selectTransactionListFilter, selectFilteredTransactions, + selectTxoPageParams, + selectTxoPage, + selectTxoPageNumber, + selectTxoItemCount, + selectIsFetchingTxos, + selectFetchingTxosError, makeSelectLatestTransactions, makeSelectFilteredTransactionsForPage, selectFilteredTransactionCount, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index de18fd9..5a1e45f 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -9,7 +9,7 @@ import { selectClaimsByUri, selectMyChannelClaims, } from 'redux/selectors/claims'; -import { doFetchTransactions } from 'redux/actions/wallet'; +import { doFetchTxoPage } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { creditsToString } from 'util/format-credits'; import { batchActions } from 'util/batch-actions'; @@ -120,6 +120,89 @@ export function doFetchClaimListMine( }; } +export function doAbandonTxo(txo: Txo, cb: any => void) { + return (dispatch: Dispatch) => { + const isClaim = txo.type === 'claim'; + const isSupport = txo.type === 'support' && txo.is_my_input === true; + const isTip = txo.type === 'support' && txo.is_my_input === false; + + const data = isClaim ? { claimId: txo.claim_id } : { outpoint: `${txo.txid}:${txo.nout}` }; + + const startedActionType = isClaim + ? ACTIONS.ABANDON_CLAIM_STARTED + : ACTIONS.ABANDON_SUPPORT_STARTED; + const completedActionType = isClaim + ? ACTIONS.ABANDON_CLAIM_SUCCEEDED + : ACTIONS.ABANDON_SUPPORT_COMPLETED; + + dispatch({ + type: startedActionType, + data, + }); + + const errorCallback = () => { + dispatch( + doToast({ + message: isClaim ? 'Error abandoning your claim/support' : 'Error unlocking your tip', + isError: true, + }) + ); + }; + + const successCallback = () => { + dispatch({ + type: completedActionType, + data, + }); + + let abandonMessage; + if (isClaim) { + abandonMessage = 'Successfully abandoned your claim.'; + } else if (isSupport) { + abandonMessage = 'Successfully abandoned your support.'; + } else { + abandonMessage = 'Successfully unlocked your tip!'; + } + if (cb) cb(); + + dispatch( + doToast({ + message: abandonMessage, + }) + ); + }; + + const abandonParams: { + claim_id?: string, + txid?: string, + nout?: number, + } = { + blocking: true, + }; + if (isClaim) { + abandonParams['claim_id'] = txo.claim_id; + } else { + abandonParams['txid'] = txo.txid; + abandonParams['nout'] = txo.nout; + } + + let method; + if (isSupport || isTip) { + method = 'support_abandon'; + } else if (isClaim) { + const { normalized_name: claimName } = txo; + method = claimName.startsWith('@') ? 'channel_abandon' : 'stream_abandon'; + } + + if (!method) { + console.error('No "method" chosen for claim or support abandon'); + return; + } + + Lbry[method](abandonParams).then(successCallback, errorCallback); + }; +} + export function doAbandonClaim(txid: string, nout: number) { const outpoint = `${txid}:${nout}`; @@ -183,13 +266,7 @@ export function doAbandonClaim(txid: string, nout: number) { message: abandonMessage, }) ); - - // After abandoning, fetch transactions to show the new abandon transaction - // Only fetch the latest few transactions since we don't care about old ones - // Not very robust, but better than calling the entire list for large wallets - const page = 1; - const pageSize = 10; - dispatch(doFetchTransactions(page, pageSize)); + dispatch(doFetchTxoPage()); }; const abandonParams = { diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 627316b..7e300d0 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -1,7 +1,7 @@ import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import { doToast } from 'redux/actions/notifications'; -import { selectBalance, selectPendingSupportTransactions } from 'redux/selectors/wallet'; +import { selectBalance, selectPendingSupportTransactions, selectTxoPageParams } from 'redux/selectors/wallet'; import { creditsToString } from 'util/format-credits'; import { selectMyClaimsRaw } from 'redux/selectors/claims'; import { doFetchChannelListMine, doFetchClaimListMine } from 'redux/actions/claims'; @@ -72,6 +72,42 @@ export function doFetchTransactions(page = 1, pageSize = 99999) { }; } +export function doFetchTxoPage() { + return (dispatch, getState) => { + dispatch({ + type: ACTIONS.FETCH_TXO_PAGE_STARTED, + }); + + const state = getState(); + const queryParams = selectTxoPageParams(state); + + Lbry.txo_list(queryParams) + .then(res => { + dispatch({ + type: ACTIONS.FETCH_TXO_PAGE_COMPLETED, + data: res, + }); + }) + .catch(e => { + dispatch({ + type: ACTIONS.FETCH_TXO_PAGE_COMPLETED, + data: e.message, + }); + }); + }; +} + +export function doUpdateTxoPageParams(params: TxoListParams) { + return dispatch => { + dispatch({ + type: ACTIONS.UPDATE_TXO_FETCH_PARAMS, + data: params, + }); + + dispatch(doFetchTxoPage()); + }; +} + export function doFetchSupports(page = 1, pageSize = 99999) { return dispatch => { dispatch({ @@ -432,6 +468,7 @@ export function doWalletStatus() { }; } + export function doSetTransactionListFilter(filterOption) { return { type: ACTIONS.SET_TRANSACTION_LIST_FILTER, diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 66ec5f7..2198011 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -18,8 +18,8 @@ type State = { byId: { [string]: Claim }, resolvingUris: Array, pendingById: { [string]: Claim }, - myClaims: ?Array, - myChannelClaims: ?Set, + myClaims: ?Array, + myChannelClaims: ?Array, abandoningById: { [string]: boolean }, fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, @@ -198,7 +198,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): return Object.assign({}, state, { isFetchingClaimListMine: false, - myClaims: myClaimIds, + myClaims: Array.from(myClaimIds), byId, claimsByUri: byUri, pendingById, @@ -255,8 +255,8 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St claimsByUri: byUri, channelClaimCounts, fetchingMyChannels: false, - myChannelClaims, - myClaims: myClaimIds, + myChannelClaims: Array.from(myChannelClaims), + myClaims: Array.from(myClaimIds), }); }; @@ -342,6 +342,7 @@ reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State = const { claimId }: { claimId: string } = action.data; const byId = Object.assign({}, state.byId); const newMyClaims = state.myClaims ? state.myClaims.slice() : []; + const newMyChannelClaims = state.myChannelClaims ? state.myChannelClaims.slice() : []; const claimsByUri = Object.assign({}, state.claimsByUri); Object.keys(claimsByUri).forEach(uri => { @@ -349,11 +350,14 @@ reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State = delete claimsByUri[uri]; } }); - const myClaims = newMyClaims.filter(i => i.claim_id && i.claim_id !== claimId); + const myClaims = newMyClaims.filter(i => i !== claimId); + const myChannelClaims = newMyChannelClaims.filter(i => i !== claimId); + delete byId[claimId]; return Object.assign({}, state, { myClaims, + myChannelClaims, byId, claimsByUri, }); @@ -378,7 +382,7 @@ reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State return Object.assign({}, state, { byId, pendingById, - myChannelClaims, + myChannelClaims: Array.from(myChannelClaims), creatingChannel: false, }); }; diff --git a/src/redux/reducers/wallet.js b/src/redux/reducers/wallet.js index 5a97e8a..d4e894b 100644 --- a/src/redux/reducers/wallet.js +++ b/src/redux/reducers/wallet.js @@ -14,8 +14,6 @@ type ActionResult = { result: any, }; - - type WalletState = { balance: any, totalBalance: any, @@ -28,6 +26,7 @@ type WalletState = { supports: { [string]: Support }, abandoningSupportsByOutpoint: { [string]: boolean }, fetchingTransactions: boolean, + fetchingTransactionsError: string, gettingNewAddress: boolean, draftTransaction: any, sendingSupport: boolean, @@ -45,6 +44,10 @@ type WalletState = { walletLockSucceded: ?boolean, walletLockResult: ?boolean, walletReconnecting: boolean, + txoFetchParams: {}, + txoPage: any, + fetchingTxos: boolean, + fetchingTxosError?: string, pendingSupportTransactions: {}, // { claimId: {txid: 123, amount 12.3}, } abandonClaimSupportError?: string, }; @@ -59,6 +62,7 @@ const defaultState = { latestBlock: undefined, transactions: {}, fetchingTransactions: false, + fetchingTransactionsError: undefined, supports: {}, fetchingSupports: false, abandoningSupportsByOutpoint: {}, @@ -80,6 +84,10 @@ const defaultState = { walletLockResult: null, transactionListFilter: 'all', walletReconnecting: false, + txoFetchParams: {}, + txoPage: {}, + fetchingTxos: false, + fetchingTxosError: undefined, pendingSupportTransactions: {}, abandonClaimSupportError: undefined, }; @@ -106,6 +114,38 @@ export const walletReducer = handleActions( }; }, + [ACTIONS.FETCH_TXO_PAGE_STARTED]: (state: WalletState) => { + return { + ...state, + fetchingTxos: true, + fetchingTxosError: undefined, + }; + }, + + [ACTIONS.FETCH_TXO_PAGE_COMPLETED]: (state: WalletState, action) => { + return { + ...state, + txoPage: action.data, + fetchingTxos: false, + }; + }, + + [ACTIONS.FETCH_TXO_PAGE_FAILED]: (state: WalletState, action) => { + return { + ...state, + txoPage: {}, + fetchingTxos: false, + fetchingTxosError: action.data, + }; + }, + + [ACTIONS.UPDATE_TXO_FETCH_PARAMS]: (state: WalletState, action) => { + return { + ...state, + txoFetchParams: action.data, + }; + }, + [ACTIONS.FETCH_SUPPORTS_STARTED]: (state: WalletState) => ({ ...state, fetchingSupports: true, diff --git a/src/redux/selectors/wallet.js b/src/redux/selectors/wallet.js index 4da48db..6765f59 100644 --- a/src/redux/selectors/wallet.js +++ b/src/redux/selectors/wallet.js @@ -321,6 +321,36 @@ export const selectFilteredTransactions = createSelector( } ); +export const selectTxoPageParams = createSelector( + selectState, + state => state.txoFetchParams +); + +export const selectTxoPage = createSelector( + selectState, + state => (state.txoPage && state.txoPage.items) || [], +); + +export const selectTxoPageNumber = createSelector( + selectState, + state => (state.txoPage && state.txoPage.page) || 1, +); + +export const selectTxoItemCount = createSelector( + selectState, + state => (state.txoPage && state.txoPage.total_items) || 1, +); + +export const selectFetchingTxosError = createSelector( + selectState, + state => state.fetchingTxosError, +); + +export const selectIsFetchingTxos = createSelector( + selectState, + state => state.fetchingTxos, +); + export const makeSelectFilteredTransactionsForPage = (page = 1) => createSelector( selectFilteredTransactions, -- 2.45.2 From cd3fa330663a21e21cb36f29104ab2a408d5412d Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 14 Apr 2020 16:26:15 -0400 Subject: [PATCH 308/371] callback for abandons --- dist/bundle.es.js | 17 ++++++++++++++++- src/constants/abandon_txo_states.js | 4 ++++ src/index.js | 2 ++ src/redux/actions/claims.js | 7 +++++-- 4 files changed, 27 insertions(+), 3 deletions(-) create mode 100644 src/constants/abandon_txo_states.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 0b3c8f9..c81f072 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -757,6 +757,18 @@ var transaction_list = /*#__PURE__*/Object.freeze({ LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); +const PENDING = 'pending'; +const DONE = 'done'; +const READY$1 = 'ready'; +const ERROR = 'error'; + +var abandon_txo_states = /*#__PURE__*/Object.freeze({ + PENDING: PENDING, + DONE: DONE, + READY: READY$1, + ERROR: ERROR +}); + const ACTIVE = 'active'; // spent, active, all const TYPE = 'type'; // all, payment, support, channel, stream, repost const SUB_TYPE = 'subtype'; // other, purchase, tip @@ -3202,6 +3214,7 @@ function doFetchClaimListMine(page = 1, pageSize = 99999, resolve = true) { function doAbandonTxo(txo, cb) { return dispatch => { + if (cb) cb(PENDING); const isClaim = txo.type === 'claim'; const isSupport = txo.type === 'support' && txo.is_my_input === true; const isTip = txo.type === 'support' && txo.is_my_input === false; @@ -3217,6 +3230,7 @@ function doAbandonTxo(txo, cb) { }); const errorCallback = () => { + if (cb) cb(ERROR); dispatch(doToast({ message: isClaim ? 'Error abandoning your claim/support' : 'Error unlocking your tip', isError: true @@ -3237,7 +3251,7 @@ function doAbandonTxo(txo, cb) { } else { abandonMessage = 'Successfully unlocked your tip!'; } - if (cb) cb(); + if (cb) cb(DONE); dispatch(doToast({ message: abandonMessage @@ -6565,6 +6579,7 @@ exports.SORT_OPTIONS = sort_options; exports.SPEECH_URLS = speech_urls; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; +exports.TXO_ABANDON_STATES = abandon_txo_states; exports.TXO_LIST = txo_list; exports.TX_LIST = transaction_list; exports.apiCall = apiCall; diff --git a/src/constants/abandon_txo_states.js b/src/constants/abandon_txo_states.js new file mode 100644 index 0000000..3761c9e --- /dev/null +++ b/src/constants/abandon_txo_states.js @@ -0,0 +1,4 @@ +export const PENDING = 'pending'; +export const DONE = 'done'; +export const READY = 'ready'; +export const ERROR = 'error'; diff --git a/src/index.js b/src/index.js index ac96c7c..e41bdf7 100644 --- a/src/index.js +++ b/src/index.js @@ -7,6 +7,7 @@ import * as SORT_OPTIONS from 'constants/sort_options'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as TRANSACTIONS from 'constants/transaction_types'; import * as TX_LIST from 'constants/transaction_list'; +import * as TXO_ABANDON_STATES from 'constants/abandon_txo_states'; import * as TXO_LIST from 'constants/txo_list'; import * as SPEECH_URLS from 'constants/speech_urls'; import * as DAEMON_SETTINGS from 'constants/daemon_settings'; @@ -29,6 +30,7 @@ export { TRANSACTIONS, TX_LIST, TXO_LIST, + TXO_ABANDON_STATES, SORT_OPTIONS, PAGES, DEFAULT_KNOWN_TAGS, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 5a1e45f..234e211 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -1,5 +1,6 @@ // @flow import * as ACTIONS from 'constants/action_types'; +import * as TXO_STATES from 'constants/abandon_txo_states'; import Lbry from 'lbry'; import { normalizeURI } from 'lbryURI'; import { doToast } from 'redux/actions/notifications'; @@ -120,8 +121,9 @@ export function doFetchClaimListMine( }; } -export function doAbandonTxo(txo: Txo, cb: any => void) { +export function doAbandonTxo(txo: Txo, cb: string => void) { return (dispatch: Dispatch) => { + if (cb) cb(TXO_STATES.PENDING); const isClaim = txo.type === 'claim'; const isSupport = txo.type === 'support' && txo.is_my_input === true; const isTip = txo.type === 'support' && txo.is_my_input === false; @@ -141,6 +143,7 @@ export function doAbandonTxo(txo: Txo, cb: any => void) { }); const errorCallback = () => { + if (cb) cb(TXO_STATES.ERROR); dispatch( doToast({ message: isClaim ? 'Error abandoning your claim/support' : 'Error unlocking your tip', @@ -163,7 +166,7 @@ export function doAbandonTxo(txo: Txo, cb: any => void) { } else { abandonMessage = 'Successfully unlocked your tip!'; } - if (cb) cb(); + if (cb) cb(TXO_STATES.DONE); dispatch( doToast({ -- 2.45.2 From a5f93bd2f75493b3e8def2cb7e0b4150edb8e9a4 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 15 Apr 2020 10:15:52 -0400 Subject: [PATCH 309/371] i18n strings in abandon --- dist/bundle.es.js | 12 ++++++------ src/redux/actions/claims.js | 12 ++++++------ 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c81f072..1bf5a80 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3245,11 +3245,11 @@ function doAbandonTxo(txo, cb) { let abandonMessage; if (isClaim) { - abandonMessage = 'Successfully abandoned your claim.'; + abandonMessage = __('Successfully abandoned your claim.'); } else if (isSupport) { - abandonMessage = 'Successfully abandoned your support.'; + abandonMessage = __('Successfully abandoned your support.'); } else { - abandonMessage = 'Successfully unlocked your tip!'; + abandonMessage = __('Successfully unlocked your tip!'); } if (cb) cb(DONE); @@ -3328,11 +3328,11 @@ function doAbandonClaim(txid, nout) { let abandonMessage; if (isClaim) { - abandonMessage = 'Successfully abandoned your claim.'; + abandonMessage = __('Successfully abandoned your claim.'); } else if (supportToAbandon) { - abandonMessage = 'Successfully abandoned your support.'; + abandonMessage = __('Successfully abandoned your support.'); } else { - abandonMessage = 'Successfully unlocked your tip!'; + abandonMessage = __('Successfully unlocked your tip!'); } dispatch(doToast({ diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 234e211..538b853 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -160,11 +160,11 @@ export function doAbandonTxo(txo: Txo, cb: string => void) { let abandonMessage; if (isClaim) { - abandonMessage = 'Successfully abandoned your claim.'; + abandonMessage = __('Successfully abandoned your claim.'); } else if (isSupport) { - abandonMessage = 'Successfully abandoned your support.'; + abandonMessage = __('Successfully abandoned your support.'); } else { - abandonMessage = 'Successfully unlocked your tip!'; + abandonMessage = __('Successfully unlocked your tip!'); } if (cb) cb(TXO_STATES.DONE); @@ -257,11 +257,11 @@ export function doAbandonClaim(txid: string, nout: number) { let abandonMessage; if (isClaim) { - abandonMessage = 'Successfully abandoned your claim.'; + abandonMessage = __('Successfully abandoned your claim.'); } else if (supportToAbandon) { - abandonMessage = 'Successfully abandoned your support.'; + abandonMessage = __('Successfully abandoned your support.'); } else { - abandonMessage = 'Successfully unlocked your tip!'; + abandonMessage = __('Successfully unlocked your tip!'); } dispatch( -- 2.45.2 From 1bd142caa16e279d4cb446382291feae9226d8bd Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 15 Apr 2020 11:51:08 -0400 Subject: [PATCH 310/371] fix empty channel claims --- dist/bundle.es.js | 2 +- src/redux/reducers/claims.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1bf5a80..7f8640b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5044,7 +5044,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { if (!claims.length) { // $FlowFixMe - myChannelClaims = null; + myChannelClaims = []; } else { myChannelClaims = new Set(state.myChannelClaims); claims.forEach(claim => { diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 2198011..d72cde4 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -220,7 +220,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St if (!claims.length) { // $FlowFixMe - myChannelClaims = null; + myChannelClaims = []; } else { myChannelClaims = new Set(state.myChannelClaims); claims.forEach(claim => { -- 2.45.2 From 5994f9fb9ebf66b8c685b069abbf184e70ba55f8 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 15 Apr 2020 13:36:29 -0400 Subject: [PATCH 311/371] add txo exclude internal transfers constant --- dist/bundle.es.js | 2 ++ src/constants/txo_list.js | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1bf5a80..1716cfb 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -797,6 +797,7 @@ const IS_MY_INPUT = 'is_my_input'; const IS_MY_OUTPUT = 'is_my_output'; const IS_NOT_MY_INPUT = 'is_not_my_input'; const IS_NOT_MY_OUTPUT = 'is_not_my_output'; // use to further distinguish payments to self / from self. +const EXCLUDE_INTERNAL_TRANSFERS = 'exclude_internal_transfers'; // sdk unique types const OTHER$1 = 'other'; @@ -829,6 +830,7 @@ var txo_list = /*#__PURE__*/Object.freeze({ IS_MY_OUTPUT: IS_MY_OUTPUT, IS_NOT_MY_INPUT: IS_NOT_MY_INPUT, IS_NOT_MY_OUTPUT: IS_NOT_MY_OUTPUT, + EXCLUDE_INTERNAL_TRANSFERS: EXCLUDE_INTERNAL_TRANSFERS, OTHER: OTHER$1, STREAM: STREAM, PAGE_SIZE_DEFAULT: PAGE_SIZE_DEFAULT diff --git a/src/constants/txo_list.js b/src/constants/txo_list.js index b143bef..afd28f9 100644 --- a/src/constants/txo_list.js +++ b/src/constants/txo_list.js @@ -26,10 +26,10 @@ export const IS_MY_INPUT = 'is_my_input'; export const IS_MY_OUTPUT = 'is_my_output'; export const IS_NOT_MY_INPUT = 'is_not_my_input'; export const IS_NOT_MY_OUTPUT = 'is_not_my_output'; // use to further distinguish payments to self / from self. +export const EXCLUDE_INTERNAL_TRANSFERS = 'exclude_internal_transfers'; // sdk unique types export const OTHER = 'other'; export const STREAM = 'stream'; export const PAGE_SIZE_DEFAULT = 20; - -- 2.45.2 From df043f3ef6076b52cec11be76069e0c7c9c19e0a Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 15 Apr 2020 17:36:48 -0400 Subject: [PATCH 312/371] fix empty channels betterer --- dist/bundle.es.js | 4 ++-- src/redux/reducers/claims.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index fdebb3a..f4adcc3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5046,7 +5046,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { if (!claims.length) { // $FlowFixMe - myChannelClaims = []; + myChannelClaims = null; } else { myChannelClaims = new Set(state.myChannelClaims); claims.forEach(claim => { @@ -5080,7 +5080,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { claimsByUri: byUri, channelClaimCounts, fetchingMyChannels: false, - myChannelClaims: Array.from(myChannelClaims), + myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, myClaims: Array.from(myClaimIds) }); }; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index d72cde4..28caae4 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -220,7 +220,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St if (!claims.length) { // $FlowFixMe - myChannelClaims = []; + myChannelClaims = null; } else { myChannelClaims = new Set(state.myChannelClaims); claims.forEach(claim => { @@ -255,7 +255,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St claimsByUri: byUri, channelClaimCounts, fetchingMyChannels: false, - myChannelClaims: Array.from(myChannelClaims), + myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, myClaims: Array.from(myClaimIds), }); }; -- 2.45.2 From 28c9c3e3381fdf1c9a0ccb275313ad79b137185b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2020 11:43:38 +0000 Subject: [PATCH 313/371] Bump https-proxy-agent from 2.2.1 to 2.2.4 Bumps [https-proxy-agent](https://github.com/TooTallNate/node-https-proxy-agent) from 2.2.1 to 2.2.4. - [Release notes](https://github.com/TooTallNate/node-https-proxy-agent/releases) - [Commits](https://github.com/TooTallNate/node-https-proxy-agent/compare/2.2.1...2.2.4) Signed-off-by: dependabot[bot] --- yarn.lock | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/yarn.lock b/yarn.lock index 230a0ba..d0ab3dc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -170,10 +170,10 @@ acorn@^6.0.7, acorn@^6.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== -agent-base@4, agent-base@^4.1.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.2.1.tgz#d89e5999f797875674c07d87f260fc41e83e8ca9" - integrity sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg== +agent-base@4, agent-base@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.3.0.tgz#8165f01c436009bccad0b1d122f05ed770efc6ee" + integrity sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg== dependencies: es6-promisify "^5.0.0" @@ -1491,7 +1491,7 @@ date-fns@^1.27.2: resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" integrity sha512-lbTXWZ6M20cWH8N9S6afb0SBm6tMk+uUg6z3MqHPKE9atmsY3kJkTm8vKe93izJ2B2+q5MV990sM2CHgtAZaOw== -debug@3.1.0, debug@^3.1.0: +debug@3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== @@ -1505,6 +1505,13 @@ debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: dependencies: ms "2.0.0" +debug@^3.1.0: + version "3.2.6" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" + integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== + dependencies: + ms "^2.1.1" + debug@^4.0.1: version "4.1.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" @@ -1682,9 +1689,9 @@ es-to-primitive@^1.2.0: is-symbol "^1.0.2" es6-promise@^4.0.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.4.tgz#dc4221c2b16518760bd8c39a52d8f356fc00ed29" - integrity sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ== + version "4.2.8" + resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" + integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== es6-promisify@^5.0.0: version "5.0.0" @@ -2523,11 +2530,11 @@ http-signature@~1.2.0: sshpk "^1.7.0" https-proxy-agent@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz#51552970fa04d723e04c56d04178c3f92592bbc0" - integrity sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ== + version "2.2.4" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz#4ee7a737abd92678a293d9b34a1af4d0d08c787b" + integrity sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg== dependencies: - agent-base "^4.1.0" + agent-base "^4.3.0" debug "^3.1.0" husky@^0.14.3: @@ -3575,9 +3582,9 @@ ms@2.0.0: integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g= ms@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== mute-stream@0.0.7: version "0.0.7" -- 2.45.2 From ee29e9a024f8a24e7eb70ecc901bb05ff3d4a87d Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 16 Apr 2020 21:08:11 -0400 Subject: [PATCH 314/371] add is_my_input_or_output constant --- dist/bundle.es.js | 2 ++ src/constants/txo_list.js | 1 + 2 files changed, 3 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f4adcc3..9708fd5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -797,6 +797,7 @@ const IS_MY_INPUT = 'is_my_input'; const IS_MY_OUTPUT = 'is_my_output'; const IS_NOT_MY_INPUT = 'is_not_my_input'; const IS_NOT_MY_OUTPUT = 'is_not_my_output'; // use to further distinguish payments to self / from self. +const IS_MY_INPUT_OR_OUTPUT = 'is_my_input_or_output'; const EXCLUDE_INTERNAL_TRANSFERS = 'exclude_internal_transfers'; // sdk unique types @@ -830,6 +831,7 @@ var txo_list = /*#__PURE__*/Object.freeze({ IS_MY_OUTPUT: IS_MY_OUTPUT, IS_NOT_MY_INPUT: IS_NOT_MY_INPUT, IS_NOT_MY_OUTPUT: IS_NOT_MY_OUTPUT, + IS_MY_INPUT_OR_OUTPUT: IS_MY_INPUT_OR_OUTPUT, EXCLUDE_INTERNAL_TRANSFERS: EXCLUDE_INTERNAL_TRANSFERS, OTHER: OTHER$1, STREAM: STREAM, diff --git a/src/constants/txo_list.js b/src/constants/txo_list.js index afd28f9..b702f34 100644 --- a/src/constants/txo_list.js +++ b/src/constants/txo_list.js @@ -26,6 +26,7 @@ export const IS_MY_INPUT = 'is_my_input'; export const IS_MY_OUTPUT = 'is_my_output'; export const IS_NOT_MY_INPUT = 'is_not_my_input'; export const IS_NOT_MY_OUTPUT = 'is_not_my_output'; // use to further distinguish payments to self / from self. +export const IS_MY_INPUT_OR_OUTPUT = 'is_my_input_or_output'; export const EXCLUDE_INTERNAL_TRANSFERS = 'exclude_internal_transfers'; // sdk unique types -- 2.45.2 From 9b63b1c7e359e47d6b01ad135419660f60ab5062 Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 20 Apr 2020 14:22:15 -0400 Subject: [PATCH 315/371] release utxo before txo list --- dist/bundle.es.js | 2 +- src/redux/actions/wallet.js | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9708fd5..b698cd0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2701,7 +2701,7 @@ function doFetchTxoPage() { const state = getState(); const queryParams = selectTxoPageParams(state); - lbryProxy.txo_list(queryParams).then(res => { + lbryProxy.utxo_release().then(() => lbryProxy.txo_list(queryParams)).then(res => { dispatch({ type: FETCH_TXO_PAGE_COMPLETED, data: res diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 7e300d0..5fd9baa 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -81,7 +81,8 @@ export function doFetchTxoPage() { const state = getState(); const queryParams = selectTxoPageParams(state); - Lbry.txo_list(queryParams) + Lbry.utxo_release() + .then(() => Lbry.txo_list(queryParams)) .then(res => { dispatch({ type: ACTIONS.FETCH_TXO_PAGE_COMPLETED, -- 2.45.2 From a64d5039b9873d2551600e42adea9f42b43e29a8 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 22 Apr 2020 11:33:04 -0400 Subject: [PATCH 316/371] update list of known tags --- dist/bundle.es.js | 2 +- src/constants/tags.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b698cd0..b0b5b56 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -969,7 +969,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'whowaswrong', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; // diff --git a/src/constants/tags.js b/src/constants/tags.js index 66500ad..5f34492 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -33,6 +33,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'comedy', 'games', 'film & animation', + 'whowaswrong', 'game', 'weapons', 'blockchain', -- 2.45.2 From 4b4c7f97103d51dc195ddd496be57b29aea5ca54 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 22 Apr 2020 12:14:44 -0400 Subject: [PATCH 317/371] update tag --- dist/bundle.es.js | 2 +- src/constants/tags.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b0b5b56..f397757 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -969,7 +969,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'whowaswrong', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'whothinks', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; // diff --git a/src/constants/tags.js b/src/constants/tags.js index 5f34492..b15d2f2 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -33,7 +33,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'comedy', 'games', 'film & animation', - 'whowaswrong', + 'whothinks', 'game', 'weapons', 'blockchain', -- 2.45.2 From b3b15ab0a3ff20571720270e1153cf9e850f76cc Mon Sep 17 00:00:00 2001 From: jessop Date: Mon, 27 Apr 2020 09:44:59 -0400 Subject: [PATCH 318/371] showReposts flip it reverse it to hideReposts --- dist/bundle.es.js | 4 ++-- src/constants/settings.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f397757..ae9a1f8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -634,7 +634,7 @@ const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; const INVITE_ACKNOWLEDGED = 'invite_acknowledged'; const LANGUAGE = 'language'; const SHOW_MATURE = 'show_mature'; -const SHOW_REPOSTS = 'show_reposts'; +const HIDE_REPOSTS = 'hide_reposts'; const SHOW_ANONYMOUS = 'show_anonymous'; const SHOW_UNAVAILABLE = 'show_unavailable'; const INSTANT_PURCHASE_ENABLED = 'instant_purchase_enabled'; @@ -671,7 +671,7 @@ var settings = /*#__PURE__*/Object.freeze({ INVITE_ACKNOWLEDGED: INVITE_ACKNOWLEDGED, LANGUAGE: LANGUAGE, SHOW_MATURE: SHOW_MATURE, - SHOW_REPOSTS: SHOW_REPOSTS, + HIDE_REPOSTS: HIDE_REPOSTS, SHOW_ANONYMOUS: SHOW_ANONYMOUS, SHOW_UNAVAILABLE: SHOW_UNAVAILABLE, INSTANT_PURCHASE_ENABLED: INSTANT_PURCHASE_ENABLED, diff --git a/src/constants/settings.js b/src/constants/settings.js index 5dbbaf2..6d10806 100644 --- a/src/constants/settings.js +++ b/src/constants/settings.js @@ -9,7 +9,7 @@ export const EMAIL_COLLECTION_ACKNOWLEDGED = 'email_collection_acknowledged'; export const INVITE_ACKNOWLEDGED = 'invite_acknowledged'; export const LANGUAGE = 'language'; export const SHOW_MATURE = 'show_mature'; -export const SHOW_REPOSTS = 'show_reposts'; +export const HIDE_REPOSTS = 'hide_reposts'; export const SHOW_ANONYMOUS = 'show_anonymous'; export const SHOW_UNAVAILABLE = 'show_unavailable'; export const INSTANT_PURCHASE_ENABLED = 'instant_purchase_enabled'; -- 2.45.2 From ce642bbae6a4647e4be77586b6307d6069006776 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 27 Apr 2020 14:13:36 -0400 Subject: [PATCH 319/371] better handle thumbnail upload errors --- dist/bundle.es.js | 41 +++++++++++------------ src/redux/actions/publish.js | 63 ++++++++++++++++-------------------- 2 files changed, 46 insertions(+), 58 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index f397757..b286de1 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4124,6 +4124,23 @@ const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => disp }, doError(error))); }; + const doUpload = data => { + return fetch(SPEECH_PUBLISH, { + method: 'POST', + body: data + }).then(res => res.text()).then(text => text.length ? JSON.parse(text) : {}).then(json => { + return json.success ? dispatch({ + type: UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: COMPLETE, + thumbnail: `${json.data.url}.${fileExt}` + } + }) : uploadError(json.message || __('Thumbnail upload service may be down, try again later.')); + }).catch(err => { + uploadError(err.message); + }); + }; + dispatch({ type: UPDATE_PUBLISH_FORM, data: { uploadThumbnailStatus: IN_PROGRESS } @@ -4140,17 +4157,7 @@ const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => disp data.append('name', name); // $FlowFixMe data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); - - return fetch(SPEECH_PUBLISH, { - method: 'POST', - body: data - }).then(response => response.json()).then(json => json.success ? dispatch({ - type: UPDATE_PUBLISH_FORM, - data: { - uploadThumbnailStatus: COMPLETE, - thumbnail: `${json.data.url}.${fileExt}` - } - }) : uploadError(json.message)).catch(err => uploadError(err.message)); + return doUpload(data); }); } else { if (filePath && fs && path) { @@ -4172,17 +4179,7 @@ const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => disp data.append('name', name); // $FlowFixMe data.append('file', file); - - return fetch(SPEECH_PUBLISH, { - method: 'POST', - body: data - }).then(response => response.json()).then(json => json.success ? dispatch({ - type: UPDATE_PUBLISH_FORM, - data: { - uploadThumbnailStatus: COMPLETE, - thumbnail: `${json.data.url}${fileExt}` - } - }) : uploadError(json.message)).catch(err => uploadError(err.message)); + return doUpload(data); } }; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 1a6a0c5..83cfa3c 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -94,6 +94,31 @@ export const doUploadThumbnail = ( ); }; + const doUpload = data => { + return fetch(SPEECH_PUBLISH, { + method: 'POST', + body: data, + }) + .then(res => res.text()) + .then(text => (text.length ? JSON.parse(text) : {})) + .then(json => { + return json.success + ? dispatch({ + type: ACTIONS.UPDATE_PUBLISH_FORM, + data: { + uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, + thumbnail: `${json.data.url}.${fileExt}`, + }, + }) + : uploadError( + json.message || __('Thumbnail upload service may be down, try again later.') + ); + }) + .catch(err => { + uploadError(err.message); + }); + }; + dispatch({ type: ACTIONS.UPDATE_PUBLISH_FORM, data: { uploadThumbnailStatus: THUMBNAIL_STATUSES.IN_PROGRESS }, @@ -110,24 +135,7 @@ export const doUploadThumbnail = ( data.append('name', name); // $FlowFixMe data.append('file', { uri: 'file://' + filePath, type: fileType, name: fileName }); - - return fetch(SPEECH_PUBLISH, { - method: 'POST', - body: data, - }) - .then(response => response.json()) - .then(json => - json.success - ? dispatch({ - type: ACTIONS.UPDATE_PUBLISH_FORM, - data: { - uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, - thumbnail: `${json.data.url}.${fileExt}`, - }, - }) - : uploadError(json.message) - ) - .catch(err => uploadError(err.message)); + return doUpload(data); }); } else { if (filePath && fs && path) { @@ -150,24 +158,7 @@ export const doUploadThumbnail = ( data.append('name', name); // $FlowFixMe data.append('file', file); - - return fetch(SPEECH_PUBLISH, { - method: 'POST', - body: data, - }) - .then(response => response.json()) - .then(json => - json.success - ? dispatch({ - type: ACTIONS.UPDATE_PUBLISH_FORM, - data: { - uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, - thumbnail: `${json.data.url}${fileExt}`, - }, - }) - : uploadError(json.message) - ) - .catch(err => uploadError(err.message)); + return doUpload(data); } }; -- 2.45.2 From f8c26fbe34f49a9898d48b8a41c956b9ad4ff582 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 1 May 2020 12:01:56 -0400 Subject: [PATCH 320/371] use api response for spee.ch thumbnail instead of re-creating it --- dist/bundle.es.js | 2 +- src/redux/actions/publish.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 7dbf708..a2233e7 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4133,7 +4133,7 @@ const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => disp type: UPDATE_PUBLISH_FORM, data: { uploadThumbnailStatus: COMPLETE, - thumbnail: `${json.data.url}.${fileExt}` + thumbnail: json.data.serveUrl } }) : uploadError(json.message || __('Thumbnail upload service may be down, try again later.')); }).catch(err => { diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 83cfa3c..b03693b 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -107,7 +107,7 @@ export const doUploadThumbnail = ( type: ACTIONS.UPDATE_PUBLISH_FORM, data: { uploadThumbnailStatus: THUMBNAIL_STATUSES.COMPLETE, - thumbnail: `${json.data.url}.${fileExt}`, + thumbnail: json.data.serveUrl, }, }) : uploadError( -- 2.45.2 From 58ff4d8086cf2d038e0f606f50e04d67efec596a Mon Sep 17 00:00:00 2001 From: jessop Date: Sat, 25 Apr 2020 16:31:53 -0400 Subject: [PATCH 321/371] support paginating publishes and removing dependencies on full claim list mine fix pending repost fix --- dist/bundle.es.js | 206 ++++++++++++++---- ...bandon_txo_states.js => abandon_states.js} | 0 src/constants/action_types.js | 4 + src/index.js | 11 +- src/redux/actions/claims.js | 71 ++++-- src/redux/actions/file_info.js | 8 +- src/redux/actions/publish.js | 55 +++-- src/redux/reducers/claims.js | 90 +++++++- src/redux/selectors/claims.js | 32 ++- src/redux/selectors/publish.js | 8 +- 10 files changed, 370 insertions(+), 115 deletions(-) rename src/constants/{abandon_txo_states.js => abandon_states.js} (100%) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index a2233e7..36ff66b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -141,6 +141,10 @@ const CLAIM_REPOST_STARTED = 'CLAIM_REPOST_STARTED'; const CLAIM_REPOST_COMPLETED = 'CLAIM_REPOST_COMPLETED'; const CLAIM_REPOST_FAILED = 'CLAIM_REPOST_FAILED'; const CLEAR_REPOST_ERROR = 'CLEAR_REPOST_ERROR'; +const CHECK_PUBLISH_NAME_STARTED = 'CHECK_PUBLISH_NAME_STARTED'; +const CHECK_PUBLISH_NAME_COMPLETED = 'CHECK_PUBLISH_NAME_COMPLETED'; +const UPDATE_PENDING_CLAIMS = 'UPDATE_PENDING_CLAIMS'; +const UPDATE_CONFIRMED_CLAIMS = 'UPDATE_CONFIRMED_CLAIMS'; // Comments const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; @@ -413,6 +417,10 @@ var action_types = /*#__PURE__*/Object.freeze({ CLAIM_REPOST_COMPLETED: CLAIM_REPOST_COMPLETED, CLAIM_REPOST_FAILED: CLAIM_REPOST_FAILED, CLEAR_REPOST_ERROR: CLEAR_REPOST_ERROR, + CHECK_PUBLISH_NAME_STARTED: CHECK_PUBLISH_NAME_STARTED, + CHECK_PUBLISH_NAME_COMPLETED: CHECK_PUBLISH_NAME_COMPLETED, + UPDATE_PENDING_CLAIMS: UPDATE_PENDING_CLAIMS, + UPDATE_CONFIRMED_CLAIMS: UPDATE_CONFIRMED_CLAIMS, COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, @@ -762,7 +770,7 @@ const DONE = 'done'; const READY$1 = 'ready'; const ERROR = 'error'; -var abandon_txo_states = /*#__PURE__*/Object.freeze({ +var abandon_states = /*#__PURE__*/Object.freeze({ PENDING: PENDING, DONE: DONE, READY: READY$1, @@ -2251,7 +2259,7 @@ const makeSelectClaimIsMine = rawUri => { return false; } - return claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); + return claims && claims[uri] && (claims[uri].is_my_output || claims[uri].claim_id && myClaims.has(claims[uri].claim_id)); }); }; @@ -2328,6 +2336,14 @@ const makeSelectCoverForUri = uri => reselect.createSelector(makeSelectClaimForU const selectIsFetchingClaimListMine = reselect.createSelector(selectState$2, state => state.isFetchingClaimListMine); +const selectMyClaimsPage = reselect.createSelector(selectState$2, state => state.myClaimsPageResults || []); + +const selectMyClaimsPageNumber = reselect.createSelector(selectState$2, state => state.claimListMinePage && state.claimListMinePage.items || [], state => state.txoPage && state.txoPage.page || 1); + +const selectMyClaimsPageItemCount = reselect.createSelector(selectState$2, state => state.myClaimsPageTotalResults || 1); + +const selectFetchingMyClaimsPageError = reselect.createSelector(selectState$2, state => state.fetchingClaimListMinePageError); + const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, (myClaimIds, byId, abandoningIds, pendingClaims) => { const claims = []; @@ -3145,6 +3161,11 @@ function doResolveUris(uris, returnCachedClaims = false) { return; } + const options = {}; + + if (urisToResolve.length === 1) { + options.include_is_my_output = true; + } dispatch({ type: RESOLVE_URIS_STARTED, data: { uris: normalizedUris } @@ -3152,7 +3173,7 @@ function doResolveUris(uris, returnCachedClaims = false) { const resolveInfo = {}; - lbryProxy.resolve({ urls: urisToResolve }).then(result => { + return lbryProxy.resolve(_extends$5({ urls: urisToResolve }, options)).then(result => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { stream: null, @@ -3188,6 +3209,7 @@ function doResolveUris(uris, returnCachedClaims = false) { type: RESOLVE_URIS_COMPLETED, data: { resolveInfo } }); + return result; }); }; } @@ -3203,13 +3225,17 @@ function doFetchClaimListMine(page = 1, pageSize = 99999, resolve = true) { }); // $FlowFixMe - lbryProxy.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'], resolve }).then(result => { - const claims = result.items; - + lbryProxy.claim_list({ + page: page, + page_size: pageSize, + claim_type: ['stream', 'repost'], + resolve + }).then(result => { dispatch({ type: FETCH_CLAIM_LIST_MINE_COMPLETED, data: { - claims + result, + resolve } }); }); @@ -3289,7 +3315,7 @@ function doAbandonTxo(txo, cb) { }; } -function doAbandonClaim(txid, nout) { +function doAbandonClaim(txid, nout, cb) { const outpoint = `${txid}:${nout}`; return (dispatch, getState) => { @@ -3322,6 +3348,7 @@ function doAbandonClaim(txid, nout) { message: isClaim ? 'Error abandoning your claim/support' : 'Error unlocking your tip', isError: true })); + if (cb) cb(ERROR); }; const successCallback = () => { @@ -3329,6 +3356,7 @@ function doAbandonClaim(txid, nout) { type: completedActionType, data }); + if (cb) cb(DONE); let abandonMessage; if (isClaim) { @@ -3379,7 +3407,8 @@ function doFetchClaimsByChannel(uri, page = 1) { channel: uri, valid_channel_signature: true, page: page || 1, - order_by: ['release_time'] + order_by: ['release_time'], + include_is_my_output: true }).then(result => { const { items: claims, total_items: claimsInChannel, page: returnedPage } = result; @@ -3622,6 +3651,30 @@ function doRepost(options) { }; } +function doCheckPublishNameAvailability(name) { + return dispatch => { + dispatch({ + type: CHECK_PUBLISH_NAME_STARTED + }); + + return lbryProxy.claim_list({ name: name }).then(result => { + dispatch({ + type: CHECK_PUBLISH_NAME_COMPLETED + }); + if (result.items.length) { + dispatch({ + type: FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + result, + resolve: false + } + }); + } + return !(result && result.items && result.items.length); + }); + }; +} + function doClearRepostError() { return { type: CLEAR_REPOST_ERROR @@ -3946,13 +3999,10 @@ function doFileList(page = 1, pageSize = 99999) { }; } -function doFetchFileInfosAndPublishedClaims() { +function doFetchFileInfos() { return (dispatch, getState) => { const state = getState(); - const isFetchingClaimListMine = selectIsFetchingClaimListMine(state); const isFetchingFileInfo = selectIsFetchingFileList(state); - - if (!isFetchingClaimListMine) dispatch(doFetchClaimListMine()); if (!isFetchingFileInfo) dispatch(doFileList()); }; } @@ -4352,37 +4402,34 @@ const doPublish = (success, fail) => (dispatch, getState) => { // Calls claim_list_mine until any pending publishes are confirmed const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { - const state = getState(); - const pendingById = selectPendingById(state); - - if (!Object.keys(pendingById).length) { - return; - } - let publishCheckInterval; const checkFileList = () => { - lbryProxy.stream_list({ page: 1, page_size: 10 }).then(result => { + const state = getState(); + const pendingById = selectPendingById(state); + lbryProxy.claim_list({ page: 1, page_size: 10 }).then(result => { const claims = result.items; - + const claimsToConfirm = []; claims.forEach(claim => { - // If it's confirmed, check if it was pending previously if (claim.confirmations > 0 && pendingById[claim.claim_id]) { delete pendingById[claim.claim_id]; + claimsToConfirm.push(claim); if (onConfirmed) { onConfirmed(claim); } } }); - - dispatch({ - type: FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims - } - }); - - if (!Object.keys(pendingById).length) { + if (claimsToConfirm.length) { + dispatch({ + type: UPDATE_CONFIRMED_CLAIMS, + data: { + claims: claimsToConfirm + } + }); + } + return Object.keys(pendingById).length; + }).then(len => { + if (!len) { clearInterval(publishCheckInterval); } }); @@ -4903,7 +4950,13 @@ const defaultState = { createChannelError: undefined, pendingChannelImport: false, repostLoading: false, - repostError: undefined + repostError: undefined, + fetchingClaimListMinePageError: undefined, + myClaimsPageResults: [], + myClaimsPageNumber: undefined, + myClaimsPageTotalResults: undefined, + isFetchingClaimListMine: false, + isCheckingNameForPublish: false }; function handleClaimAction(state, action) { @@ -4989,16 +5042,22 @@ reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { }); reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { - const { claims } = action.data; + const { result, resolve } = action.data; + const claims = result.items; + const page = result.page; + const totalItems = result.total_items; + const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); + let urlPage = []; claims.forEach(claim => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { + urlPage.push(uri); if (claim.confirmations < 1) { pendingById[claimId] = claim; delete byId[claimId]; @@ -5008,26 +5067,31 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { byUri[uri] = claimId; } myClaimIds.add(claimId); - if (pendingById[claimId] && claim.confirmations > 0) { + if (!resolve && pendingById[claimId] && claim.confirmations > 0) { delete pendingById[claimId]; } } }); - // Remove old pending publishes - Object.values(pendingById) - // $FlowFixMe - .filter(pendingClaim => byId[pendingClaim.claim_id]).forEach(pendingClaim => { + // Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0) + if (!resolve) { + Object.values(pendingById) // $FlowFixMe - delete pendingById[pendingClaim.claim_id]; - }); + .filter(pendingClaim => byId[pendingClaim.claim_id]).forEach(pendingClaim => { + // $FlowFixMe + delete pendingById[pendingClaim.claim_id]; + }); + } return Object.assign({}, state, { isFetchingClaimListMine: false, myClaims: Array.from(myClaimIds), byId, claimsByUri: byUri, - pendingById + pendingById, + myClaimsPageResults: urlPage, + myClaimsPageNumber: page, + myClaimsPageTotalResults: totalItems }); }; @@ -5155,6 +5219,55 @@ reducers[ABANDON_CLAIM_STARTED] = (state, action) => { }); }; +reducers[UPDATE_PENDING_CLAIMS] = (state, action) => { + const { claims } = action.data; + const byId = Object.assign({}, state.byId); + const byUri = Object.assign({}, state.claimsByUri); + const pendingById = Object.assign({}, state.pendingById); + let myClaimIds = new Set(state.myClaims); + + claims.forEach(claim => { + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; + if (claim.type && claim.type.match(/claim|update/)) { + pendingById[claimId] = claim; + delete byId[claimId]; + byUri[uri] = claimId; + } + myClaimIds.add(claimId); + }); + return Object.assign({}, state, { + myClaims: Array.from(myClaimIds), + byId, + claimsByUri: byUri, + pendingById + }); +}; + +reducers[UPDATE_CONFIRMED_CLAIMS] = (state, action) => { + const { claims } = action.data; + const byId = Object.assign({}, state.byId); + const byUri = Object.assign({}, state.claimsByUri); + const pendingById = Object.assign({}, state.pendingById); + let myClaimIds = new Set(state.myClaims); + + claims.forEach(claim => { + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; + if (claim.type && claim.type.match(/claim|update/)) { + delete pendingById[claimId]; + byId[claimId] = claim; + } + myClaimIds.add(claimId); + }); + return Object.assign({}, state, { + myClaims: Array.from(myClaimIds), + byId, + claimsByUri: byUri, + pendingById + }); +}; + reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { const { claimId } = action.data; const byId = Object.assign({}, state.byId); @@ -6563,6 +6676,7 @@ const selectChannelIsBlocked = uri => reselect.createSelector(selectBlockedChann return state.includes(uri); }); +exports.ABANDON_STATES = abandon_states; exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; exports.DAEMON_SETTINGS = daemon_settings; @@ -6580,7 +6694,6 @@ exports.SORT_OPTIONS = sort_options; exports.SPEECH_URLS = speech_urls; exports.THUMBNAIL_STATUSES = thumbnail_upload_statuses; exports.TRANSACTIONS = transaction_types; -exports.TXO_ABANDON_STATES = abandon_txo_states; exports.TXO_LIST = txo_list; exports.TX_LIST = transaction_list; exports.apiCall = apiCall; @@ -6601,6 +6714,7 @@ exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCheckPendingPublishes = doCheckPendingPublishes; +exports.doCheckPublishNameAvailability = doCheckPublishNameAvailability; exports.doClaimSearch = doClaimSearch; exports.doClearPublish = doClearPublish; exports.doClearRepostError = doClearRepostError; @@ -6620,7 +6734,7 @@ exports.doFetchChannelListMine = doFetchChannelListMine; exports.doFetchClaimListMine = doFetchClaimListMine; exports.doFetchClaimsByChannel = doFetchClaimsByChannel; exports.doFetchFileInfo = doFetchFileInfo; -exports.doFetchFileInfosAndPublishedClaims = doFetchFileInfosAndPublishedClaims; +exports.doFetchFileInfos = doFetchFileInfos; exports.doFetchTransactions = doFetchTransactions; exports.doFetchTxoPage = doFetchTxoPage; exports.doFileGet = doFileGet; @@ -6770,6 +6884,7 @@ exports.selectFailedPurchaseUris = selectFailedPurchaseUris; exports.selectFetchingClaimSearch = selectFetchingClaimSearch; exports.selectFetchingClaimSearchByQuery = selectFetchingClaimSearchByQuery; exports.selectFetchingMyChannels = selectFetchingMyChannels; +exports.selectFetchingMyClaimsPageError = selectFetchingMyClaimsPageError; exports.selectFetchingTxosError = selectFetchingTxosError; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; @@ -6798,6 +6913,9 @@ exports.selectMyClaimForUri = selectMyClaimForUri; exports.selectMyClaimUrisWithoutChannels = selectMyClaimUrisWithoutChannels; exports.selectMyClaims = selectMyClaims; exports.selectMyClaimsOutpoints = selectMyClaimsOutpoints; +exports.selectMyClaimsPage = selectMyClaimsPage; +exports.selectMyClaimsPageItemCount = selectMyClaimsPageItemCount; +exports.selectMyClaimsPageNumber = selectMyClaimsPageNumber; exports.selectMyClaimsRaw = selectMyClaimsRaw; exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount; diff --git a/src/constants/abandon_txo_states.js b/src/constants/abandon_states.js similarity index 100% rename from src/constants/abandon_txo_states.js rename to src/constants/abandon_states.js diff --git a/src/constants/action_types.js b/src/constants/action_types.js index ed2cb93..deed387 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -118,6 +118,10 @@ export const CLAIM_REPOST_STARTED = 'CLAIM_REPOST_STARTED'; export const CLAIM_REPOST_COMPLETED = 'CLAIM_REPOST_COMPLETED'; export const CLAIM_REPOST_FAILED = 'CLAIM_REPOST_FAILED'; export const CLEAR_REPOST_ERROR = 'CLEAR_REPOST_ERROR'; +export const CHECK_PUBLISH_NAME_STARTED = 'CHECK_PUBLISH_NAME_STARTED'; +export const CHECK_PUBLISH_NAME_COMPLETED = 'CHECK_PUBLISH_NAME_COMPLETED'; +export const UPDATE_PENDING_CLAIMS = 'UPDATE_PENDING_CLAIMS'; +export const UPDATE_CONFIRMED_CLAIMS = 'UPDATE_CONFIRMED_CLAIMS'; // Comments export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; diff --git a/src/index.js b/src/index.js index e41bdf7..1e1b615 100644 --- a/src/index.js +++ b/src/index.js @@ -7,7 +7,7 @@ import * as SORT_OPTIONS from 'constants/sort_options'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as TRANSACTIONS from 'constants/transaction_types'; import * as TX_LIST from 'constants/transaction_list'; -import * as TXO_ABANDON_STATES from 'constants/abandon_txo_states'; +import * as ABANDON_STATES from 'constants/abandon_states'; import * as TXO_LIST from 'constants/txo_list'; import * as SPEECH_URLS from 'constants/speech_urls'; import * as DAEMON_SETTINGS from 'constants/daemon_settings'; @@ -30,7 +30,7 @@ export { TRANSACTIONS, TX_LIST, TXO_LIST, - TXO_ABANDON_STATES, + ABANDON_STATES, SORT_OPTIONS, PAGES, DEFAULT_KNOWN_TAGS, @@ -74,6 +74,7 @@ export { doImportChannel, doRepost, doClearRepostError, + doCheckPublishNameAvailability, } from 'redux/actions/claims'; export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -81,7 +82,7 @@ export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/fi export { doFetchFileInfo, doFileList, - doFetchFileInfosAndPublishedClaims, + doFetchFileInfos, doSetFileListSort, } from 'redux/actions/file_info'; @@ -245,6 +246,10 @@ export { selectRepostError, selectRepostLoading, selectClaimIdsByUri, + selectMyClaimsPage, + selectMyClaimsPageNumber, + selectMyClaimsPageItemCount, + selectFetchingMyClaimsPageError, } 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 538b853..99e1d1d 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -1,6 +1,6 @@ // @flow import * as ACTIONS from 'constants/action_types'; -import * as TXO_STATES from 'constants/abandon_txo_states'; +import * as ABANDON_STATES from 'constants/abandon_states'; import Lbry from 'lbry'; import { normalizeURI } from 'lbryURI'; import { doToast } from 'redux/actions/notifications'; @@ -35,6 +35,11 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = return; } + const options: { include_is_my_output?: boolean } = {}; + + if (urisToResolve.length === 1) { + options.include_is_my_output = true; + } dispatch({ type: ACTIONS.RESOLVE_URIS_STARTED, data: { uris: normalizedUris }, @@ -48,7 +53,7 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = }, } = {}; - Lbry.resolve({ urls: urisToResolve }).then((result: ResolveResponse) => { + return Lbry.resolve({ urls: urisToResolve, ...options }).then((result: ResolveResponse) => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { stream: null, @@ -87,6 +92,7 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = type: ACTIONS.RESOLVE_URIS_COMPLETED, data: { resolveInfo }, }); + return result; }); }; } @@ -106,24 +112,26 @@ export function doFetchClaimListMine( }); // $FlowFixMe - Lbry.claim_list({ page, page_size: pageSize, claim_type: ['stream', 'repost'], resolve }).then( - (result: StreamListResponse) => { - const claims = result.items; - - dispatch({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims, - }, - }); - } - ); + Lbry.claim_list({ + page: page, + page_size: pageSize, + claim_type: ['stream', 'repost'], + resolve, + }).then((result: StreamListResponse) => { + dispatch({ + type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + result, + resolve, + }, + }); + }); }; } export function doAbandonTxo(txo: Txo, cb: string => void) { return (dispatch: Dispatch) => { - if (cb) cb(TXO_STATES.PENDING); + if (cb) cb(ABANDON_STATES.PENDING); const isClaim = txo.type === 'claim'; const isSupport = txo.type === 'support' && txo.is_my_input === true; const isTip = txo.type === 'support' && txo.is_my_input === false; @@ -143,7 +151,7 @@ export function doAbandonTxo(txo: Txo, cb: string => void) { }); const errorCallback = () => { - if (cb) cb(TXO_STATES.ERROR); + if (cb) cb(ABANDON_STATES.ERROR); dispatch( doToast({ message: isClaim ? 'Error abandoning your claim/support' : 'Error unlocking your tip', @@ -166,7 +174,7 @@ export function doAbandonTxo(txo: Txo, cb: string => void) { } else { abandonMessage = __('Successfully unlocked your tip!'); } - if (cb) cb(TXO_STATES.DONE); + if (cb) cb(ABANDON_STATES.DONE); dispatch( doToast({ @@ -206,7 +214,7 @@ export function doAbandonTxo(txo: Txo, cb: string => void) { }; } -export function doAbandonClaim(txid: string, nout: number) { +export function doAbandonClaim(txid: string, nout: number, cb: string => void) { const outpoint = `${txid}:${nout}`; return (dispatch: Dispatch, getState: GetState) => { @@ -247,6 +255,7 @@ export function doAbandonClaim(txid: string, nout: number) { isError: true, }) ); + if (cb) cb(ABANDON_STATES.ERROR); }; const successCallback = () => { @@ -254,6 +263,7 @@ export function doAbandonClaim(txid: string, nout: number) { type: completedActionType, data, }); + if (cb) cb(ABANDON_STATES.DONE); let abandonMessage; if (isClaim) { @@ -307,6 +317,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { valid_channel_signature: true, page: page || 1, order_by: ['release_time'], + include_is_my_output: true, }).then((result: ClaimSearchResponse) => { const { items: claims, total_items: claimsInChannel, page: returnedPage } = result; @@ -583,6 +594,30 @@ export function doRepost(options: StreamRepostOptions) { }; } +export function doCheckPublishNameAvailability(name: string) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.CHECK_PUBLISH_NAME_STARTED, + }); + + return Lbry.claim_list({ name: name }).then(result => { + dispatch({ + type: ACTIONS.CHECK_PUBLISH_NAME_COMPLETED, + }); + if (result.items.length) { + dispatch({ + type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, + data: { + result, + resolve: false, + }, + }); + } + return !(result && result.items && result.items.length); + }); + }; +} + export function doClearRepostError() { return { type: ACTIONS.CLEAR_REPOST_ERROR, diff --git a/src/redux/actions/file_info.js b/src/redux/actions/file_info.js index b218053..99b4da0 100644 --- a/src/redux/actions/file_info.js +++ b/src/redux/actions/file_info.js @@ -1,7 +1,6 @@ import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; -import { doFetchClaimListMine } from 'redux/actions/claims'; -import { selectClaimsByUri, selectIsFetchingClaimListMine } from 'redux/selectors/claims'; +import { selectClaimsByUri } from 'redux/selectors/claims'; import { selectIsFetchingFileList, selectUrisLoading } from 'redux/selectors/file_info'; export function doFetchFileInfo(uri) { @@ -58,13 +57,10 @@ export function doFileList(page = 1, pageSize = 99999) { }; } -export function doFetchFileInfosAndPublishedClaims() { +export function doFetchFileInfos() { return (dispatch, getState) => { const state = getState(); - const isFetchingClaimListMine = selectIsFetchingClaimListMine(state); const isFetchingFileInfo = selectIsFetchingFileList(state); - - if (!isFetchingClaimListMine) dispatch(doFetchClaimListMine()); if (!isFetchingFileInfo) dispatch(doFileList()); }; } diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index b03693b..c5a0ec0 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -359,40 +359,39 @@ export const doCheckPendingPublishes = (onConfirmed: Function) => ( dispatch: Dispatch, getState: GetState ) => { - const state = getState(); - const pendingById = selectPendingById(state); - - if (!Object.keys(pendingById).length) { - return; - } - let publishCheckInterval; const checkFileList = () => { - Lbry.stream_list({ page: 1, page_size: 10 }).then(result => { - const claims = result.items; - - claims.forEach(claim => { - // If it's confirmed, check if it was pending previously - if (claim.confirmations > 0 && pendingById[claim.claim_id]) { - delete pendingById[claim.claim_id]; - if (onConfirmed) { - onConfirmed(claim); + const state = getState(); + const pendingById = selectPendingById(state); + Lbry.claim_list({ page: 1, page_size: 10 }) + .then(result => { + const claims = result.items; + const claimsToConfirm = []; + claims.forEach(claim => { + if (claim.confirmations > 0 && pendingById[claim.claim_id]) { + delete pendingById[claim.claim_id]; + claimsToConfirm.push(claim); + if (onConfirmed) { + onConfirmed(claim); + } } + }); + if (claimsToConfirm.length) { + dispatch({ + type: ACTIONS.UPDATE_CONFIRMED_CLAIMS, + data: { + claims: claimsToConfirm, + }, + }); + } + return Object.keys(pendingById).length; + }) + .then((len) => { + if (!len) { + clearInterval(publishCheckInterval); } }); - - dispatch({ - type: ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED, - data: { - claims, - }, - }); - - if (!Object.keys(pendingById).length) { - clearInterval(publishCheckInterval); - } - }); }; publishCheckInterval = setInterval(() => { diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 28caae4..8dbdd28 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -40,6 +40,12 @@ type State = { pendingChannelImport: string | boolean, repostLoading: boolean, repostError: ?string, + fetchingClaimListMinePageError: ?string, + myClaimsPageResults: Array, + myClaimsPageNumber: ?number, + myClaimsPageTotalResults: ?number, + isFetchingClaimListMine: boolean, + isCheckingNameForPublish: boolean, }; const reducers = {}; @@ -68,6 +74,12 @@ const defaultState = { pendingChannelImport: false, repostLoading: false, repostError: undefined, + fetchingClaimListMinePageError: undefined, + myClaimsPageResults: [], + myClaimsPageNumber: undefined, + myClaimsPageTotalResults: undefined, + isFetchingClaimListMine: false, + isCheckingNameForPublish: false, }; function handleClaimAction(state: State, action: any): State { @@ -162,16 +174,22 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_STARTED] = (state: State): State => }); reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): State => { - const { claims }: { claims: Array } = action.data; + const { result, resolve }: { result: ClaimListResponse, resolve: boolean } = action.data; + const claims = result.items; + const page = result.page; + const totalItems = result.total_items; + const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); + let urlPage = []; claims.forEach((claim: Claim) => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { + urlPage.push(uri); if (claim.confirmations < 1) { pendingById[claimId] = claim; delete byId[claimId]; @@ -181,20 +199,22 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): byUri[uri] = claimId; } myClaimIds.add(claimId); - if (pendingById[claimId] && claim.confirmations > 0) { + if (!resolve && pendingById[claimId] && claim.confirmations > 0) { delete pendingById[claimId]; } } }); - // Remove old pending publishes - Object.values(pendingById) - // $FlowFixMe - .filter(pendingClaim => byId[pendingClaim.claim_id]) - .forEach(pendingClaim => { + // Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0) + if (!resolve) { + Object.values(pendingById) // $FlowFixMe - delete pendingById[pendingClaim.claim_id]; - }); + .filter(pendingClaim => byId[pendingClaim.claim_id]) + .forEach(pendingClaim => { + // $FlowFixMe + delete pendingById[pendingClaim.claim_id]; + }); + } return Object.assign({}, state, { isFetchingClaimListMine: false, @@ -202,6 +222,9 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): byId, claimsByUri: byUri, pendingById, + myClaimsPageResults: urlPage, + myClaimsPageNumber: page, + myClaimsPageTotalResults: totalItems, }); }; @@ -338,6 +361,55 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State => }); }; +reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => { + const { claims }: { claims: Array } = action.data; + const byId = Object.assign({}, state.byId); + const byUri = Object.assign({}, state.claimsByUri); + const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); + let myClaimIds = new Set(state.myClaims); + + claims.forEach((claim: Claim) => { + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; + if (claim.type && claim.type.match(/claim|update/)) { + pendingById[claimId] = claim; + delete byId[claimId]; + byUri[uri] = claimId; + } + myClaimIds.add(claimId); + }); + return Object.assign({}, state, { + myClaims: Array.from(myClaimIds), + byId, + claimsByUri: byUri, + pendingById, + }); +}; + +reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => { + const { claims }: { claims: Array } = action.data; + const byId = Object.assign({}, state.byId); + const byUri = Object.assign({}, state.claimsByUri); + const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); + let myClaimIds = new Set(state.myClaims); + + claims.forEach((claim: Claim) => { + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; + if (claim.type && claim.type.match(/claim|update/)) { + delete pendingById[claimId]; + byId[claimId] = claim; + } + myClaimIds.add(claimId); + }); + return Object.assign({}, state, { + myClaims: Array.from(myClaimIds), + byId, + claimsByUri: byUri, + pendingById, + }); +}; + reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State => { const { claimId }: { claimId: string } = action.data; const byId = Object.assign({}, state.byId); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index ec860a2..a04987c 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -212,7 +212,11 @@ export const makeSelectClaimIsMine = (rawUri: string) => { return false; } - return claims && claims[uri] && claims[uri].claim_id && myClaims.has(claims[uri].claim_id); + return ( + claims && + claims[uri] && + (claims[uri].is_my_output || (claims[uri].claim_id && myClaims.has(claims[uri].claim_id))) + ); } ); }; @@ -310,8 +314,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -360,6 +364,28 @@ export const selectIsFetchingClaimListMine = createSelector( state => state.isFetchingClaimListMine ); +export const selectMyClaimsPage = createSelector( + selectState, + state => state.myClaimsPageResults || [] +); + +export const selectMyClaimsPageNumber = createSelector( + selectState, + state => (state.claimListMinePage && state.claimListMinePage.items) || [], + + state => (state.txoPage && state.txoPage.page) || 1 +); + +export const selectMyClaimsPageItemCount = createSelector( + selectState, + state => state.myClaimsPageTotalResults || 1 +); + +export const selectFetchingMyClaimsPageError = createSelector( + selectState, + state => state.fetchingClaimListMinePageError +); + export const selectMyClaims = createSelector( selectMyActiveClaims, selectClaimsById, diff --git a/src/redux/selectors/publish.js b/src/redux/selectors/publish.js index 82adce2..10ed95b 100644 --- a/src/redux/selectors/publish.js +++ b/src/redux/selectors/publish.js @@ -77,10 +77,10 @@ export const selectMyClaimForUri = createSelector( return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => - !contentName - ? claim.name === claimName - : claim.name === contentName || claim.name === claimName - ); + !contentName + ? claim.name === claimName + : claim.name === contentName || claim.name === claimName + ); } ); -- 2.45.2 From efbc95f383e24e0c2eb8b1865964f7ec75ca59bb Mon Sep 17 00:00:00 2001 From: jessop Date: Fri, 1 May 2020 20:50:24 -0400 Subject: [PATCH 322/371] disable http images --- dist/bundle.es.js | 4 ++-- src/redux/selectors/claims.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 36ff66b..de24332 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2326,12 +2326,12 @@ 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() : undefined; + return thumbnail && thumbnail.url ? thumbnail.url.trim().replace(/^http:\/\//i, 'https://') : undefined; }); const makeSelectCoverForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { const cover = claim && claim.value && claim.value.cover; - return cover && cover.url ? cover.url.trim() : undefined; + return cover && cover.url ? cover.url.trim().replace(/^http:\/\//i, 'https://') : undefined; }); const selectIsFetchingClaimListMine = reselect.createSelector(selectState$2, state => state.isFetchingClaimListMine); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index a04987c..a2cdab1 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -346,7 +346,7 @@ export const makeSelectThumbnailForUri = (uri: string) => makeSelectClaimForUri(uri), claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; - return thumbnail && thumbnail.url ? thumbnail.url.trim() : undefined; + return thumbnail && thumbnail.url ? thumbnail.url.trim().replace(/^http:\/\//i, 'https://') : undefined; } ); @@ -355,7 +355,7 @@ export const makeSelectCoverForUri = (uri: string) => makeSelectClaimForUri(uri), claim => { const cover = claim && claim.value && claim.value.cover; - return cover && cover.url ? cover.url.trim() : undefined; + return cover && cover.url ? cover.url.trim().replace(/^http:\/\//i, 'https://') : undefined; } ); -- 2.45.2 From c30e1eee2c16f0b7a70f40dc974edb22a157986b Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 5 May 2020 09:41:04 -0400 Subject: [PATCH 323/371] update tags --- dist/bundle.es.js | 2 +- src/constants/tags.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 36ff66b..10166d0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -977,7 +977,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'whothinks', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; // diff --git a/src/constants/tags.js b/src/constants/tags.js index b15d2f2..66500ad 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -33,7 +33,6 @@ export const DEFAULT_KNOWN_TAGS = [ 'comedy', 'games', 'film & animation', - 'whothinks', 'game', 'weapons', 'blockchain', -- 2.45.2 From 8d1ebfb9c5836c9a9158f3ba319011c9bcdd8f7f Mon Sep 17 00:00:00 2001 From: Baltazar Gomez Date: Thu, 7 May 2020 10:42:30 -0500 Subject: [PATCH 324/371] enable webp images --- src/lbry.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lbry.js b/src/lbry.js index 33b57c0..61a893b 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -40,7 +40,7 @@ const Lbry: LbryTypes = { const formats = [ [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], - [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], + [/\.(jpeg|jpg|png|gif|svg|webp)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(html|json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], -- 2.45.2 From 88d785a8442bc670be5db291d054fdb6959814ce Mon Sep 17 00:00:00 2001 From: Jeffrey Fisher Date: Thu, 7 May 2020 14:18:40 -0700 Subject: [PATCH 325/371] Support lbry:// links with timestamp --- flow-typed/lbryURI.js | 1 + src/lbryURI.js | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/flow-typed/lbryURI.js b/flow-typed/lbryURI.js index 4365da3..549c991 100644 --- a/flow-typed/lbryURI.js +++ b/flow-typed/lbryURI.js @@ -12,6 +12,7 @@ declare type LbryUrlObj = { secondaryClaimSequence?: number, primaryBidPosition?: number, secondaryBidPosition?: number, + startTime?: number, // Below are considered deprecated and should not be used due to unreliableness with claim.canonical_url claimName?: string, diff --git a/src/lbryURI.js b/src/lbryURI.js index b63c1f2..9b871d7 100644 --- a/src/lbryURI.js +++ b/src/lbryURI.js @@ -60,6 +60,8 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj secondaryModSeparator, secondaryModValue, ] = rest; + const searchParams = new URLSearchParams(qs || ''); + const startTime = searchParams.get('t'); // Validate protocol if (requireProto && !proto) { @@ -121,6 +123,7 @@ export function parseURI(URL: string, requireProto: boolean = false): LbryUrlObj : {}), ...(primaryBidPosition ? { primaryBidPosition: parseInt(primaryBidPosition, 10) } : {}), ...(secondaryBidPosition ? { secondaryBidPosition: parseInt(secondaryBidPosition, 10) } : {}), + ...(startTime ? { startTime: parseInt(startTime, 10) } : {}), // The values below should not be used for new uses of parseURI // They will not work properly with canonical_urls @@ -184,6 +187,7 @@ export function buildURI( primaryBidPosition, secondaryClaimSequence, secondaryBidPosition, + startTime, ...deprecatedParts } = UrlObj; const { claimId, claimName, contentName } = deprecatedParts; @@ -233,7 +237,8 @@ export function buildURI( (secondaryClaimName ? `/${secondaryClaimName}` : '') + (secondaryClaimId ? `#${secondaryClaimId}` : '') + (secondaryClaimSequence ? `:${secondaryClaimSequence}` : '') + - (secondaryBidPosition ? `${secondaryBidPosition}` : '') + (secondaryBidPosition ? `${secondaryBidPosition}` : '') + + (startTime ? `?t=${startTime}` : '') ); } @@ -248,6 +253,7 @@ export function normalizeURI(URL: string) { primaryBidPosition, secondaryClaimSequence, secondaryBidPosition, + startTime, } = parseURI(URL); return buildURI({ @@ -259,6 +265,7 @@ export function normalizeURI(URL: string) { primaryBidPosition, secondaryClaimSequence, secondaryBidPosition, + startTime, }); } -- 2.45.2 From 1e27a854d012ef758c04b234fb80e74e264d5962 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 8 May 2020 13:14:37 -0400 Subject: [PATCH 326/371] update tags --- dist/bundle.es.js | 2 +- src/constants/tags.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 10166d0..383ac2e 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -977,7 +977,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; // diff --git a/src/constants/tags.js b/src/constants/tags.js index 66500ad..1e25ed9 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -39,6 +39,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'video game', 'sports', 'walkthrough', + 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', -- 2.45.2 From 3be6fa52ac1cb6224cf9de45623183e62c2b24ab Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 7 May 2020 07:41:56 -0400 Subject: [PATCH 327/371] track reflecting files --- dist/bundle.es.js | 133 +++++++++++++++++++++++++++++++++- dist/flow-typed/File.js | 3 + dist/flow-typed/Reflector.js | 5 ++ flow-typed/File.js | 3 + flow-typed/Reflector.js | 5 ++ src/constants/action_types.js | 4 + src/index.js | 3 + src/redux/actions/publish.js | 76 ++++++++++++++++++- src/redux/reducers/claims.js | 48 +++++++++++- src/redux/selectors/claims.js | 18 ++++- 10 files changed, 289 insertions(+), 9 deletions(-) create mode 100644 dist/flow-typed/Reflector.js create mode 100644 flow-typed/Reflector.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 383ac2e..35b2ef8 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -145,6 +145,10 @@ const CHECK_PUBLISH_NAME_STARTED = 'CHECK_PUBLISH_NAME_STARTED'; const CHECK_PUBLISH_NAME_COMPLETED = 'CHECK_PUBLISH_NAME_COMPLETED'; const UPDATE_PENDING_CLAIMS = 'UPDATE_PENDING_CLAIMS'; const UPDATE_CONFIRMED_CLAIMS = 'UPDATE_CONFIRMED_CLAIMS'; +const ADD_FILES_REFLECTING = 'ADD_FILES_REFLECTING'; +const UPDATE_FILES_REFLECTING = 'UPDATE_FILES_REFLECTING'; +const TOGGLE_CHECKING_REFLECTING = 'TOGGLE_CHECKING_REFLECTING'; +const TOGGLE_CHECKING_PENDING = 'TOGGLE_CHECKING_PENDING'; // Comments const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; @@ -421,6 +425,10 @@ var action_types = /*#__PURE__*/Object.freeze({ CHECK_PUBLISH_NAME_COMPLETED: CHECK_PUBLISH_NAME_COMPLETED, UPDATE_PENDING_CLAIMS: UPDATE_PENDING_CLAIMS, UPDATE_CONFIRMED_CLAIMS: UPDATE_CONFIRMED_CLAIMS, + ADD_FILES_REFLECTING: ADD_FILES_REFLECTING, + UPDATE_FILES_REFLECTING: UPDATE_FILES_REFLECTING, + TOGGLE_CHECKING_REFLECTING: TOGGLE_CHECKING_REFLECTING, + TOGGLE_CHECKING_PENDING: TOGGLE_CHECKING_PENDING, COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, @@ -2184,6 +2192,7 @@ const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, const claimId = isChannel ? channelClaimId : streamClaimId; return pendingById[claimId]; }); +const selectReflectingById = reselect.createSelector(selectState$2, state => state.reflectingById); const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => { // Check if a claim is pending first @@ -2546,6 +2555,11 @@ const selectUpdatingChannel = reselect.createSelector(selectState$2, state => st const selectUpdateChannelError = reselect.createSelector(selectState$2, state => state.updateChannelError); +const makeSelectReflectingClaimForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), selectReflectingById, (claim, reflectingById) => { + const claimId = claim && claim.claimId; + return reflectingById[claimId]; +}); + const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(selectMyClaimUrisWithoutChannels, urls => { const start = (Number(page) - 1) * Number(PAGE_SIZE); const end = Number(page) * Number(PAGE_SIZE); @@ -4114,6 +4128,8 @@ const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClai var _extends$7 = 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 _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } + const doResetThumbnailStatus = () => dispatch => { dispatch({ type: UPDATE_PUBLISH_FORM, @@ -4400,7 +4416,82 @@ const doPublish = (success, fail) => (dispatch, getState) => { return lbryProxy.publish(publishPayload).then(success, fail); }; -// Calls claim_list_mine until any pending publishes are confirmed +// Calls file_list until any reflecting files are done +const doCheckReflectingFiles = () => (dispatch, getState) => { + const state = getState(); + const { checkingReflector } = state.claims; + let reflectorCheckInterval; + + const checkFileList = (() => { + var _ref = _asyncToGenerator(function* () { + const state = getState(); + const reflectingById = selectReflectingById(state); + const ids = Object.keys(reflectingById); + + const newReflectingById = {}; + const promises = []; + // TODO: just use file_list({claim_id: Array}) + if (Object.keys(reflectingById).length) { + ids.forEach(function (claimId) { + promises.push(lbryProxy.file_list({ claim_id: claimId })); + }); + + Promise.all(promises).then(function (results) { + results.forEach(function (res) { + const fileListItem = res.items[0]; + const fileClaimId = fileListItem.claim_id; + const { + is_fully_reflected: done, + uploading_to_reflector: uploading, + reflector_progress: progress + } = fileListItem; + if (uploading) { + newReflectingById[fileClaimId] = { + fileListItem: fileListItem, + progress, + stalled: !done && !uploading + }; + } + }); + }).then(function () { + dispatch({ + type: UPDATE_FILES_REFLECTING, + data: newReflectingById + }); + if (!Object.keys(newReflectingById).length) { + dispatch({ + type: TOGGLE_CHECKING_REFLECTING, + data: false + }); + clearInterval(reflectorCheckInterval); + } + }); + } else { + dispatch({ + type: TOGGLE_CHECKING_REFLECTING, + data: false + }); + clearInterval(reflectorCheckInterval); + } + }); + + return function checkFileList() { + return _ref.apply(this, arguments); + }; + })(); + // do it once... + checkFileList(); + // then start the interval if it's not already started + if (!checkingReflector) { + dispatch({ + type: TOGGLE_CHECKING_REFLECTING, + data: true + }); + reflectorCheckInterval = setInterval(() => { + checkFileList(); + }, 5000); + } +}; const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { let publishCheckInterval; @@ -4940,6 +5031,7 @@ const defaultState = { fetchingMyChannels: false, abandoningById: {}, pendingById: {}, + reflectingById: {}, claimSearchError: false, claimSearchByQuery: {}, claimSearchByQueryLastPageReached: {}, @@ -4956,7 +5048,9 @@ const defaultState = { myClaimsPageNumber: undefined, myClaimsPageTotalResults: undefined, isFetchingClaimListMine: false, - isCheckingNameForPublish: false + isCheckingNameForPublish: false, + checkingPending: false, + checkingReflecting: false }; function handleClaimAction(state, action) { @@ -5438,6 +5532,38 @@ reducers[CLEAR_REPOST_ERROR] = state => { repostError: null }); }; +reducers[ADD_FILES_REFLECTING] = (state, action) => { + const pendingClaim = action.data; + const { reflectingById } = state; + const claimId = pendingClaim && pendingClaim.claim_id; + + reflectingById[claimId] = { fileListItem: pendingClaim, progress: 0, stalled: false }; + + return Object.assign({}, state, _extends$9({}, state, { + reflectingById: reflectingById + })); +}; +reducers[UPDATE_FILES_REFLECTING] = (state, action) => { + const newReflectingById = action.data; + + return Object.assign({}, state, _extends$9({}, state, { + reflectingById: newReflectingById + })); +}; +reducers[TOGGLE_CHECKING_REFLECTING] = (state, action) => { + const checkingReflecting = action.data; + + return Object.assign({}, state, _extends$9({}, state, { + checkingReflecting + })); +}; +reducers[TOGGLE_CHECKING_PENDING] = (state, action) => { + const checking = action.data; + + return Object.assign({}, state, _extends$9({}, state, { + checkingPending: checking + })); +}; function claimsReducer(state = defaultState, action) { const handler = reducers[action.type]; @@ -6715,6 +6841,7 @@ exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doCheckPublishNameAvailability = doCheckPublishNameAvailability; +exports.doCheckReflectingFiles = doCheckReflectingFiles; exports.doClaimSearch = doClaimSearch; exports.doClearPublish = doClearPublish; exports.doClearRepostError = doClearRepostError; @@ -6824,6 +6951,7 @@ exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri; +exports.makeSelectReflectingClaimForUri = makeSelectReflectingClaimForUri; exports.makeSelectResolvedRecommendedContentForUri = makeSelectResolvedRecommendedContentForUri; exports.makeSelectResolvedSearchResults = makeSelectResolvedSearchResults; exports.makeSelectResolvedSearchResultsLastPageReached = makeSelectResolvedSearchResultsLastPageReached; @@ -6928,6 +7056,7 @@ exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; exports.selectPurchasedUris = selectPurchasedUris; exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; +exports.selectReflectingById = selectReflectingById; exports.selectRepostError = selectRepostError; exports.selectRepostLoading = selectRepostLoading; exports.selectReservedBalance = selectReservedBalance; diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index 71a2523..75a3965 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -20,6 +20,7 @@ declare type FileListItem = { outpoint: string, points_paid: number, protobuf: string, + reflector_progress: number, sd_hash: string, status: string, stopped: false, @@ -29,10 +30,12 @@ declare type FileListItem = { suggested_file_name: string, total_bytes: number, total_bytes_lower_bound: number, + is_fully_reflected: boolean, // TODO: sdk plans to change `tx` // It isn't currently used by the apps tx: {}, txid: string, + uploading_to_reflector: boolean, written_bytes: number, }; diff --git a/dist/flow-typed/Reflector.js b/dist/flow-typed/Reflector.js new file mode 100644 index 0000000..fc6be97 --- /dev/null +++ b/dist/flow-typed/Reflector.js @@ -0,0 +1,5 @@ +declare type ReflectingUpdate = { + fileListItem: FileListItem, + progress: number | boolean, + stalled: boolean, +}; diff --git a/flow-typed/File.js b/flow-typed/File.js index 71a2523..75a3965 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -20,6 +20,7 @@ declare type FileListItem = { outpoint: string, points_paid: number, protobuf: string, + reflector_progress: number, sd_hash: string, status: string, stopped: false, @@ -29,10 +30,12 @@ declare type FileListItem = { suggested_file_name: string, total_bytes: number, total_bytes_lower_bound: number, + is_fully_reflected: boolean, // TODO: sdk plans to change `tx` // It isn't currently used by the apps tx: {}, txid: string, + uploading_to_reflector: boolean, written_bytes: number, }; diff --git a/flow-typed/Reflector.js b/flow-typed/Reflector.js new file mode 100644 index 0000000..fc6be97 --- /dev/null +++ b/flow-typed/Reflector.js @@ -0,0 +1,5 @@ +declare type ReflectingUpdate = { + fileListItem: FileListItem, + progress: number | boolean, + stalled: boolean, +}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index deed387..cbaad87 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -122,6 +122,10 @@ export const CHECK_PUBLISH_NAME_STARTED = 'CHECK_PUBLISH_NAME_STARTED'; export const CHECK_PUBLISH_NAME_COMPLETED = 'CHECK_PUBLISH_NAME_COMPLETED'; export const UPDATE_PENDING_CLAIMS = 'UPDATE_PENDING_CLAIMS'; export const UPDATE_CONFIRMED_CLAIMS = 'UPDATE_CONFIRMED_CLAIMS'; +export const ADD_FILES_REFLECTING = 'ADD_FILES_REFLECTING'; +export const UPDATE_FILES_REFLECTING = 'UPDATE_FILES_REFLECTING'; +export const TOGGLE_CHECKING_REFLECTING = 'TOGGLE_CHECKING_REFLECTING'; +export const TOGGLE_CHECKING_PENDING = 'TOGGLE_CHECKING_PENDING'; // Comments export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; diff --git a/src/index.js b/src/index.js index 1e1b615..a661d00 100644 --- a/src/index.js +++ b/src/index.js @@ -94,6 +94,7 @@ export { doPrepareEdit, doPublish, doCheckPendingPublishes, + doCheckReflectingFiles, } from 'redux/actions/publish'; export { @@ -206,12 +207,14 @@ export { makeSelectChannelForClaimUri, makeSelectClaimIsPending, makeSelectPendingByUri, + makeSelectReflectingClaimForUri, makeSelectClaimsInChannelForCurrentPageState, makeSelectShortUrlForUri, makeSelectCanonicalUrlForUri, makeSelectPermanentUrlForUri, makeSelectSupportsForUri, selectPendingById, + selectReflectingById, selectClaimsById, selectClaimsByUri, selectAllClaimsByChannel, diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index c5a0ec0..23d6d74 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -12,6 +12,7 @@ import { selectMyChannelClaims, selectPendingById, selectMyClaimsWithoutChannels, + selectReflectingById, } from 'redux/selectors/claims'; import { selectPublishFormValues, selectMyClaimForUri } from 'redux/selectors/publish'; @@ -354,7 +355,78 @@ export const doPublish = (success: Function, fail: Function) => ( return Lbry.publish(publishPayload).then(success, fail); }; -// Calls claim_list_mine until any pending publishes are confirmed +// Calls file_list until any reflecting files are done +export const doCheckReflectingFiles = () => (dispatch: Dispatch, getState: GetState) => { + const state = getState(); + const { checkingReflector } = state.claims; + let reflectorCheckInterval; + + const checkFileList = async() => { + const state = getState(); + const reflectingById = selectReflectingById(state); + const ids = Object.keys(reflectingById); + + const newReflectingById = {}; + const promises = []; + // TODO: just use file_list({claim_id: Array}) + if (Object.keys(reflectingById).length) { + ids.forEach(claimId => { + promises.push(Lbry.file_list({ claim_id: claimId })); + }); + + Promise.all(promises) + .then(results => { + results.forEach(res => { + const fileListItem = res.items[0]; + const fileClaimId = fileListItem.claim_id; + const { + is_fully_reflected: done, + uploading_to_reflector: uploading, + reflector_progress: progress, + } = fileListItem; + if (uploading) { + newReflectingById[fileClaimId] = { + fileListItem: fileListItem, + progress, + stalled: !done && !uploading, + }; + } + }); + }) + .then(() => { + dispatch({ + type: ACTIONS.UPDATE_FILES_REFLECTING, + data: newReflectingById, + }); + if (!Object.keys(newReflectingById).length) { + dispatch({ + type: ACTIONS.TOGGLE_CHECKING_REFLECTING, + data: false, + }); + clearInterval(reflectorCheckInterval); + } + }); + } else { + dispatch({ + type: ACTIONS.TOGGLE_CHECKING_REFLECTING, + data: false, + }); + clearInterval(reflectorCheckInterval); + } + }; + // do it once... + checkFileList(); + // then start the interval if it's not already started + if (!checkingReflector) { + dispatch({ + type: ACTIONS.TOGGLE_CHECKING_REFLECTING, + data: true, + }); + reflectorCheckInterval = setInterval(() => { + checkFileList(); + }, 5000); + } +}; export const doCheckPendingPublishes = (onConfirmed: Function) => ( dispatch: Dispatch, getState: GetState @@ -387,7 +459,7 @@ export const doCheckPendingPublishes = (onConfirmed: Function) => ( } return Object.keys(pendingById).length; }) - .then((len) => { + .then(len => { if (!len) { clearInterval(publishCheckInterval); } diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 8dbdd28..ee9e85c 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -18,6 +18,7 @@ type State = { byId: { [string]: Claim }, resolvingUris: Array, pendingById: { [string]: Claim }, + reflectingById: { [string]: ReflectingUpdate }, myClaims: ?Array, myChannelClaims: ?Array, abandoningById: { [string]: boolean }, @@ -46,6 +47,8 @@ type State = { myClaimsPageTotalResults: ?number, isFetchingClaimListMine: boolean, isCheckingNameForPublish: boolean, + checkingPending: boolean, + checkingReflecting: boolean, }; const reducers = {}; @@ -63,6 +66,7 @@ const defaultState = { fetchingMyChannels: false, abandoningById: {}, pendingById: {}, + reflectingById: {}, claimSearchError: false, claimSearchByQuery: {}, claimSearchByQueryLastPageReached: {}, @@ -80,6 +84,8 @@ const defaultState = { myClaimsPageTotalResults: undefined, isFetchingClaimListMine: false, isCheckingNameForPublish: false, + checkingPending: false, + checkingReflecting: false, }; function handleClaimAction(state: State, action: any): State { @@ -362,7 +368,7 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State => }; reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => { - const { claims }: { claims: Array } = action.data; + const { claims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); @@ -387,13 +393,13 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => }; reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => { - const { claims }: { claims: Array } = action.data; + const { claims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); - claims.forEach((claim: Claim) => { + claims.forEach((claim: GenericClaim) => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { @@ -594,6 +600,42 @@ reducers[ACTIONS.CLEAR_REPOST_ERROR] = (state: State): State => { repostError: null, }; }; +reducers[ACTIONS.ADD_FILES_REFLECTING] = (state: State, action): State => { + const pendingClaim = action.data; + const { reflectingById } = state; + const claimId = pendingClaim && pendingClaim.claim_id; + + reflectingById[claimId] = { fileListItem: pendingClaim, progress: 0, stalled: false }; + + return Object.assign({}, state, { + ...state, + reflectingById: reflectingById, + }); +}; +reducers[ACTIONS.UPDATE_FILES_REFLECTING] = (state: State, action): State => { + const newReflectingById = action.data; + + return Object.assign({}, state, { + ...state, + reflectingById: newReflectingById, + }); +}; +reducers[ACTIONS.TOGGLE_CHECKING_REFLECTING] = (state: State, action): State => { + const checkingReflecting = action.data; + + return Object.assign({}, state, { + ...state, + checkingReflecting, + }); +}; +reducers[ACTIONS.TOGGLE_CHECKING_PENDING] = (state: State, action): State => { + const checking = action.data; + + return Object.assign({}, state, { + ...state, + checkingPending: checking, + }); +}; export function claimsReducer(state: State = defaultState, action: any) { const handler = reducers[action.type]; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index a04987c..78b5a71 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -111,6 +111,10 @@ export const makeSelectPendingByUri = (uri: string) => return pendingById[claimId]; } ); +export const selectReflectingById = createSelector( + selectState, + state => state.reflectingById +); export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) => createSelector( @@ -314,8 +318,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -717,6 +721,16 @@ export const selectUpdateChannelError = createSelector( state => state.updateChannelError ); +export const makeSelectReflectingClaimForUri = (uri: string) => + createSelector( + makeSelectClaimForUri(uri), + selectReflectingById, + (claim, reflectingById) => { + const claimId = claim && claim.claimId; + return reflectingById[claimId]; + } + ); + export const makeSelectMyStreamUrlsForPage = (page: number = 1) => createSelector( selectMyClaimUrisWithoutChannels, -- 2.45.2 From 259317250af62391718ac0cb8b8e25f172dc4223 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 11 May 2020 10:09:38 -0400 Subject: [PATCH 328/371] update build --- dist/bundle.es.js | 19 ++++++++++++------- dist/flow-typed/lbryURI.js | 1 + 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 35b2ef8..9fe02e5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1025,7 +1025,7 @@ const Lbry = { // Returns a human readable media type based on the content type or extension of a file that is returned by the sdk getMediaType: (contentType, fileName) => { if (fileName) { - const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif|svg)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(html|json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; + const formats = [[/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'], [/\.(jpeg|jpg|png|gif|svg|webp)$/i, 'image'], [/\.(h|go|ja|java|js|jsx|c|cpp|cs|css|rb|scss|sh|php|py)$/i, 'script'], [/\.(html|json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'], [/\.(pdf|odf|doc|docx|epub|org|rtf)$/i, 'e-book'], [/\.(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(cbr|cbt|cbz)$/i, 'comic-book'], [/\.(lbry)$/i, 'application']]; const res = formats.reduce((ret, testpair) => { switch (testpair[0].test(ret)) { @@ -1318,6 +1318,8 @@ function parseURI(URL, requireProto = false) { const [proto, ...rest] = regexMatch.slice(1).map(match => match || null); const path = rest.join(''); const [streamNameOrChannelName, primaryModSeparator, primaryModValue, pathSep, possibleStreamName, secondaryModSeparator, secondaryModValue] = rest; + const searchParams = new URLSearchParams(qs || ''); + const startTime = searchParams.get('t'); // Validate protocol if (requireProto && !proto) { @@ -1361,7 +1363,7 @@ function parseURI(URL, requireProto = false) { return _extends({ isChannel, path - }, streamName ? { streamName } : {}, streamClaimId ? { streamClaimId } : {}, channelName ? { channelName } : {}, channelClaimId ? { channelClaimId } : {}, primaryClaimSequence ? { primaryClaimSequence: parseInt(primaryClaimSequence, 10) } : {}, secondaryClaimSequence ? { secondaryClaimSequence: parseInt(secondaryClaimSequence, 10) } : {}, primaryBidPosition ? { primaryBidPosition: parseInt(primaryBidPosition, 10) } : {}, secondaryBidPosition ? { secondaryBidPosition: parseInt(secondaryBidPosition, 10) } : {}, { + }, streamName ? { streamName } : {}, streamClaimId ? { streamClaimId } : {}, channelName ? { channelName } : {}, channelClaimId ? { channelClaimId } : {}, primaryClaimSequence ? { primaryClaimSequence: parseInt(primaryClaimSequence, 10) } : {}, secondaryClaimSequence ? { secondaryClaimSequence: parseInt(secondaryClaimSequence, 10) } : {}, primaryBidPosition ? { primaryBidPosition: parseInt(primaryBidPosition, 10) } : {}, secondaryBidPosition ? { secondaryBidPosition: parseInt(secondaryBidPosition, 10) } : {}, startTime ? { startTime: parseInt(startTime, 10) } : {}, { // The values below should not be used for new uses of parseURI // They will not work properly with canonical_urls @@ -1418,9 +1420,10 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { primaryClaimSequence, primaryBidPosition, secondaryClaimSequence, - secondaryBidPosition + secondaryBidPosition, + startTime } = UrlObj, - deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition']); + deprecatedParts = _objectWithoutProperties(UrlObj, ['streamName', 'streamClaimId', 'channelName', 'channelClaimId', 'primaryClaimSequence', 'primaryBidPosition', 'secondaryClaimSequence', 'secondaryBidPosition', 'startTime']); const { claimId, claimName, contentName } = deprecatedParts; if (!claimName && !channelName && !streamName) { @@ -1436,7 +1439,7 @@ function buildURI(UrlObj, includeProto = true, protoDefault = 'lbry://') { return (includeProto ? protoDefault : '') + // primaryClaimName will always exist here because we throw above if there is no "name" value passed in // $FlowFixMe - primaryClaimName + (primaryClaimId ? `#${primaryClaimId}` : '') + (primaryClaimSequence ? `:${primaryClaimSequence}` : '') + (primaryBidPosition ? `${primaryBidPosition}` : '') + (secondaryClaimName ? `/${secondaryClaimName}` : '') + (secondaryClaimId ? `#${secondaryClaimId}` : '') + (secondaryClaimSequence ? `:${secondaryClaimSequence}` : '') + (secondaryBidPosition ? `${secondaryBidPosition}` : ''); + primaryClaimName + (primaryClaimId ? `#${primaryClaimId}` : '') + (primaryClaimSequence ? `:${primaryClaimSequence}` : '') + (primaryBidPosition ? `${primaryBidPosition}` : '') + (secondaryClaimName ? `/${secondaryClaimName}` : '') + (secondaryClaimId ? `#${secondaryClaimId}` : '') + (secondaryClaimSequence ? `:${secondaryClaimSequence}` : '') + (secondaryBidPosition ? `${secondaryBidPosition}` : '') + (startTime ? `?t=${startTime}` : ''); } /* Takes a parseable LBRY URL and converts it to standard, canonical format */ @@ -1449,7 +1452,8 @@ function normalizeURI(URL) { primaryClaimSequence, primaryBidPosition, secondaryClaimSequence, - secondaryBidPosition + secondaryBidPosition, + startTime } = parseURI(URL); return buildURI({ @@ -1460,7 +1464,8 @@ function normalizeURI(URL) { primaryClaimSequence, primaryBidPosition, secondaryClaimSequence, - secondaryBidPosition + secondaryBidPosition, + startTime }); } diff --git a/dist/flow-typed/lbryURI.js b/dist/flow-typed/lbryURI.js index 4365da3..549c991 100644 --- a/dist/flow-typed/lbryURI.js +++ b/dist/flow-typed/lbryURI.js @@ -12,6 +12,7 @@ declare type LbryUrlObj = { secondaryClaimSequence?: number, primaryBidPosition?: number, secondaryBidPosition?: number, + startTime?: number, // Below are considered deprecated and should not be used due to unreliableness with claim.canonical_url claimName?: string, -- 2.45.2 From 278e12dcbe268c7808f7854b8265b933dc915251 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 8 May 2020 16:47:33 -0400 Subject: [PATCH 329/371] add purchase_list --- dist/bundle.es.js | 171 +++++++++++++++++++++++++++++-- dist/flow-typed/Claim.js | 18 +++- dist/flow-typed/Lbry.js | 17 +++ flow-typed/Claim.js | 18 +++- flow-typed/Lbry.js | 17 +++ src/constants/action_types.js | 3 + src/index.js | 7 ++ src/lbry.js | 1 + src/redux/actions/claims.js | 42 +++++++- src/redux/reducers/claims.js | 73 ++++++++++++- src/redux/selectors/claims.js | 58 ++++++++++- src/redux/selectors/file_info.js | 13 +-- src/util/claim.js | 17 +++ 13 files changed, 421 insertions(+), 34 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9fe02e5..066e944 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -149,6 +149,9 @@ const ADD_FILES_REFLECTING = 'ADD_FILES_REFLECTING'; const UPDATE_FILES_REFLECTING = 'UPDATE_FILES_REFLECTING'; const TOGGLE_CHECKING_REFLECTING = 'TOGGLE_CHECKING_REFLECTING'; const TOGGLE_CHECKING_PENDING = 'TOGGLE_CHECKING_PENDING'; +const PURCHASE_LIST_STARTED = 'PURCHASE_LIST_STARTED'; +const PURCHASE_LIST_COMPLETED = 'PURCHASE_LIST_COMPLETED'; +const PURCHASE_LIST_FAILED = 'PURCHASE_LIST_FAILED'; // Comments const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; @@ -429,6 +432,9 @@ var action_types = /*#__PURE__*/Object.freeze({ UPDATE_FILES_REFLECTING: UPDATE_FILES_REFLECTING, TOGGLE_CHECKING_REFLECTING: TOGGLE_CHECKING_REFLECTING, TOGGLE_CHECKING_PENDING: TOGGLE_CHECKING_PENDING, + PURCHASE_LIST_STARTED: PURCHASE_LIST_STARTED, + PURCHASE_LIST_COMPLETED: PURCHASE_LIST_COMPLETED, + PURCHASE_LIST_FAILED: PURCHASE_LIST_FAILED, COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, @@ -1090,6 +1096,7 @@ const Lbry = { transaction_list: (params = {}) => daemonCallWithResult('transaction_list', params), utxo_release: (params = {}) => daemonCallWithResult('utxo_release', params), support_abandon: (params = {}) => daemonCallWithResult('support_abandon', params), + purchase_list: (params = {}) => daemonCallWithResult('purchase_list', params), sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), @@ -2136,7 +2143,21 @@ function createNormalizedClaimSearchKey(options) { return query; } +function filterClaims(claims, query) { + if (query) { + const queryMatchRegExp = new RegExp(query, 'i'); + return claims.filter(claim => { + const { value } = claim; + + return value.title && value.title.match(queryMatchRegExp) || claim.signing_channel && claim.signing_channel.name.match(queryMatchRegExp) || claim.name && claim.name.match(queryMatchRegExp); + }); + } + + return claims; +} + var _extends$4 = 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; }; + const selectState$2 = state => state.claims || {}; const selectClaimsById = reselect.createSelector(selectState$2, state => state.byId || {}); @@ -2277,6 +2298,30 @@ const makeSelectClaimIsMine = rawUri => { }); }; +const selectMyPurchases = reselect.createSelector(selectState$2, state => state.myPurchases); + +const selectMyPurchasesCount = reselect.createSelector(selectState$2, state => state.myPurchasesPageTotalResults); + +const selectIsFetchingMyPurchases = reselect.createSelector(selectState$2, state => state.fetchingMyPurchases); + +const selectFetchingMyPurchasesError = reselect.createSelector(selectState$2, state => state.fetchingMyPurchasesError); + +const makeSelectMyPurchasesForPage = (query, page = 1) => reselect.createSelector(selectMyPurchases, selectClaimsByUri, (myPurchases, claimsByUri) => { + if (!myPurchases) { + return undefined; + } + + const fileInfos = myPurchases.map(uri => claimsByUri[uri]); + const matchingFileInfos = filterClaims(fileInfos, query); + const start = (Number(page) - 1) * Number(PAGE_SIZE); + const end = Number(page) * Number(PAGE_SIZE); + return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos.slice(start, end).map(fileInfo => fileInfo.canonical_url || fileInfo.permanent_url) : []; +}); + +const makeSelectClaimWasPurchased = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => { + return claim && claim.purchase_receipt !== undefined; +}); + const selectAllFetchingChannelClaims = reselect.createSelector(selectState$2, state => state.fetchingChannelClaims || {}); const makeSelectFetchingChannelClaims = uri => reselect.createSelector(selectAllFetchingChannelClaims, fetching => fetching && fetching[uri]); @@ -2540,7 +2585,7 @@ const makeSelectCanonicalUrlForUri = uri => reselect.createSelector(makeSelectCl const makeSelectPermanentUrlForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), claim => claim && claim.permanent_url); const makeSelectSupportsForUri = uri => reselect.createSelector(selectSupportsByOutpoint, makeSelectClaimForUri(uri), (byOutpoint, claim) => { - if (!claim || !claim.is_mine) { + if (!claim || !claim.is_my_output) { return null; } @@ -3180,7 +3225,9 @@ function doResolveUris(uris, returnCachedClaims = false) { return; } - const options = {}; + const options = { + include_purchase_receipt: true + }; if (urisToResolve.length === 1) { options.include_is_my_output = true; @@ -3427,7 +3474,8 @@ function doFetchClaimsByChannel(uri, page = 1) { valid_channel_signature: true, page: page || 1, order_by: ['release_time'], - include_is_my_output: true + include_is_my_output: true, + include_purchase_receipt: true }).then(result => { const { items: claims, total_items: claimsInChannel, page: returnedPage } = result; @@ -3630,7 +3678,9 @@ function doClaimSearch(options = { }); }; - lbryProxy.claim_search(options).then(success, failure); + lbryProxy.claim_search(_extends$5({}, options, { + include_purchase_receipt: true + })).then(success, failure); }; } @@ -3700,6 +3750,38 @@ function doClearRepostError() { }; } +function doPurchaseList(page = 1, pageSize = 99999) { + return dispatch => { + dispatch({ + type: PURCHASE_LIST_STARTED + }); + + const success = result => { + return dispatch({ + type: PURCHASE_LIST_COMPLETED, + data: { + result + } + }); + }; + + const failure = error => { + dispatch({ + type: PURCHASE_LIST_FAILED, + data: { + error: error.message + } + }); + }; + + lbryProxy.purchase_list({ + page: page, + page_size: pageSize, + resolve: true + }).then(success, failure); + }; +} + const selectState$3 = state => state.fileInfo || {}; const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); @@ -3820,6 +3902,7 @@ function filterFileInfos(fileInfos, query) { const queryMatchRegExp = new RegExp(query, 'i'); return fileInfos.filter(fileInfo => { const { metadata } = fileInfo; + return metadata.title && metadata.title.match(queryMatchRegExp) || fileInfo.channel_name && fileInfo.channel_name.match(queryMatchRegExp) || fileInfo.claim_name && fileInfo.claim_name.match(queryMatchRegExp); }); } @@ -5021,6 +5104,8 @@ const doToggleBlockChannel = uri => ({ var _extends$9 = 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$3(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 reducers = {}; const defaultState = { byId: {}, @@ -5029,10 +5114,13 @@ const defaultState = { channelClaimCounts: {}, fetchingChannelClaims: {}, resolvingUris: [], - // This should not be a Set - // Storing sets in reducers can cause issues myChannelClaims: undefined, myClaims: undefined, + myPurchases: undefined, + myPurchasesPageNumber: undefined, + myPurchasesPageTotalResults: undefined, + fetchingMyPurchases: false, + fetchingMyPurchasesError: undefined, fetchingMyChannels: false, abandoningById: {}, pendingById: {}, @@ -5053,6 +5141,7 @@ const defaultState = { myClaimsPageNumber: undefined, myClaimsPageTotalResults: undefined, isFetchingClaimListMine: false, + isFetchingMyPurchases: false, isCheckingNameForPublish: false, checkingPending: false, checkingReflecting: false @@ -5150,13 +5239,13 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { const byUri = Object.assign({}, state.claimsByUri); const pendingById = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); - let urlPage = []; + let urlsForCurrentPage = []; claims.forEach(claim => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { - urlPage.push(uri); + urlsForCurrentPage.push(uri); if (claim.confirmations < 1) { pendingById[claimId] = claim; delete byId[claimId]; @@ -5188,7 +5277,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { byId, claimsByUri: byUri, pendingById, - myClaimsPageResults: urlPage, + myClaimsPageResults: urlsForCurrentPage, myClaimsPageNumber: page, myClaimsPageTotalResults: totalItems }); @@ -5325,6 +5414,7 @@ reducers[UPDATE_PENDING_CLAIMS] = (state, action) => { const pendingById = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); + // $FlowFixMe claims.forEach(claim => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { claim_id: claimId } = claim; @@ -5570,6 +5660,58 @@ reducers[TOGGLE_CHECKING_PENDING] = (state, action) => { })); }; +reducers[PURCHASE_LIST_STARTED] = state => { + return _extends$9({}, state, { + fetchingMyPurchases: true, + fetchingMyPurchasesError: null + }); +}; + +reducers[PURCHASE_LIST_COMPLETED] = (state, action) => { + const { result } = action.data; + const page = result.page; + const totalItems = result.total_items; + + let byId = Object.assign({}, state.byId); + let byUri = Object.assign({}, state.claimsByUri); + let urlsForCurrentPage = []; + + result.items.forEach(item => { + if (!item.claim) { + // Abandoned claim + return; + } + + const { claim } = item, + purchaseInfo = _objectWithoutProperties$3(item, ['claim']); + claim.purchase_receipt = purchaseInfo; + const claimId = claim.claim_id; + const uri = claim.canonical_url; + + byId[claimId] = claim; + byUri[uri] = claimId; + urlsForCurrentPage.push(uri); + }); + + return Object.assign({}, state, { + byId, + claimsByUri: byUri, + myPurchases: urlsForCurrentPage, + myPurchasesPageNumber: page, + myPurchasesPageTotalResults: totalItems, + fetchingMyPurchases: false + }); +}; + +reducers[PURCHASE_LIST_FAILED] = (state, action) => { + const { error } = action.data; + + return _extends$9({}, state, { + fetchingMyPurchases: false, + fetchingMyPurchasesError: error + }); +}; + function claimsReducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); @@ -6061,7 +6203,7 @@ const notificationsReducer = handleActions({ var _extends$e = 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$3(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$4(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, @@ -6118,7 +6260,7 @@ const publishReducer = handleActions({ publishSuccess: true }), [DO_PREPARE_EDIT]: (state, action) => { - const publishData = _objectWithoutProperties$3(action.data, []); + const publishData = _objectWithoutProperties$4(action.data, []); const { channel, name, uri } = publishData; // The short uri is what is presented to the user @@ -6879,6 +7021,7 @@ exports.doPreferenceGet = doPreferenceGet; exports.doPreferenceSet = doPreferenceSet; exports.doPrepareEdit = doPrepareEdit; exports.doPublish = doPublish; +exports.doPurchaseList = doPurchaseList; exports.doPurchaseUri = doPurchaseUri; exports.doRepost = doRepost; exports.doResetThumbnailStatus = doResetThumbnailStatus; @@ -6924,6 +7067,7 @@ exports.makeSelectClaimForUri = makeSelectClaimForUri; exports.makeSelectClaimIsMine = makeSelectClaimIsMine; exports.makeSelectClaimIsNsfw = makeSelectClaimIsNsfw; exports.makeSelectClaimIsPending = makeSelectClaimIsPending; +exports.makeSelectClaimWasPurchased = makeSelectClaimWasPurchased; exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannelForCurrentPageState; exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; exports.makeSelectCommentsForUri = makeSelectCommentsForUri; @@ -6946,6 +7090,7 @@ exports.makeSelectLoadingForUri = makeSelectLoadingForUri; exports.makeSelectMediaTypeForUri = makeSelectMediaTypeForUri; exports.makeSelectMetadataForUri = makeSelectMetadataForUri; exports.makeSelectMetadataItemForUri = makeSelectMetadataItemForUri; +exports.makeSelectMyPurchasesForPage = makeSelectMyPurchasesForPage; exports.makeSelectMyStreamUrlsForPage = makeSelectMyStreamUrlsForPage; exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; @@ -7018,6 +7163,7 @@ exports.selectFetchingClaimSearch = selectFetchingClaimSearch; exports.selectFetchingClaimSearchByQuery = selectFetchingClaimSearchByQuery; exports.selectFetchingMyChannels = selectFetchingMyChannels; exports.selectFetchingMyClaimsPageError = selectFetchingMyClaimsPageError; +exports.selectFetchingMyPurchasesError = selectFetchingMyPurchasesError; exports.selectFetchingTxosError = selectFetchingTxosError; exports.selectFileInfosByOutpoint = selectFileInfosByOutpoint; exports.selectFileInfosDownloaded = selectFileInfosDownloaded; @@ -7032,6 +7178,7 @@ exports.selectHasTransactions = selectHasTransactions; exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; exports.selectIsFetchingFileList = selectIsFetchingFileList; exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileListDownloadedOrPublished; +exports.selectIsFetchingMyPurchases = selectIsFetchingMyPurchases; exports.selectIsFetchingTransactions = selectIsFetchingTransactions; exports.selectIsFetchingTxos = selectIsFetchingTxos; exports.selectIsResolvingPublishUris = selectIsResolvingPublishUris; @@ -7051,6 +7198,8 @@ exports.selectMyClaimsPageItemCount = selectMyClaimsPageItemCount; exports.selectMyClaimsPageNumber = selectMyClaimsPageNumber; exports.selectMyClaimsRaw = selectMyClaimsRaw; exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; +exports.selectMyPurchases = selectMyPurchases; +exports.selectMyPurchasesCount = selectMyPurchasesCount; exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount; exports.selectPendingById = selectPendingById; exports.selectPendingClaims = selectPendingClaims; diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 8a6d8e8..c9732bd 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -3,12 +3,10 @@ declare type Claim = StreamClaim | ChannelClaim; declare type ChannelClaim = GenericClaim & { - is_channel_signature_valid?: boolean, // we may have signed channels in the future value: ChannelMetadata, }; declare type StreamClaim = GenericClaim & { - is_channel_signature_valid?: boolean, value: StreamMetadata, }; @@ -23,7 +21,8 @@ declare type GenericClaim = { decoded_claim: boolean, // Not available currently https://github.com/lbryio/lbry/issues/2044 timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed - is_mine: boolean, + is_channel_signature_valid?: boolean, + is_my_output: true, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx @@ -34,6 +33,7 @@ declare type GenericClaim = { value_type: 'stream' | 'channel', signing_channel?: ChannelClaim, repost_channel_url?: string, + purchase_receipt?: PurchaseReceipt, meta: { activation_height: number, claims_in_channel?: number, @@ -121,3 +121,15 @@ declare type Fee = { currency: string, address: string, }; + +declare type PurchaseReceipt = { + address: string, + amount: string, + claim_id: string, + confirmations: number, + height: number, + nout: number, + timestamp: number, + txid: string, + type: 'purchase', +}; diff --git a/dist/flow-typed/Lbry.js b/dist/flow-typed/Lbry.js index 97e2f20..d7c0430 100644 --- a/dist/flow-typed/Lbry.js +++ b/dist/flow-typed/Lbry.js @@ -214,6 +214,22 @@ declare type StreamRepostOptions = { declare type StreamRepostResponse = GenericTxResponse; +declare type PurchaseListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; + +declare type PurchaseListOptions = { + page: number, + page_size: number, + resolve: boolean, + claim_id?: string, + channel_id?: string, +}; + // // Types used in the generic Lbry object that is exported // @@ -253,6 +269,7 @@ declare type LbryTypes = { support_list: (params: {}) => Promise, support_abandon: (params: {}) => Promise, stream_repost: (params: StreamRepostOptions) => Promise, + purchase_list: (params: PurchaseListOptions) => Promise, // File fetching and manipulation file_list: (params: {}) => Promise, diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 8a6d8e8..c9732bd 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -3,12 +3,10 @@ declare type Claim = StreamClaim | ChannelClaim; declare type ChannelClaim = GenericClaim & { - is_channel_signature_valid?: boolean, // we may have signed channels in the future value: ChannelMetadata, }; declare type StreamClaim = GenericClaim & { - is_channel_signature_valid?: boolean, value: StreamMetadata, }; @@ -23,7 +21,8 @@ declare type GenericClaim = { decoded_claim: boolean, // Not available currently https://github.com/lbryio/lbry/issues/2044 timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed - is_mine: boolean, + is_channel_signature_valid?: boolean, + is_my_output: true, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx @@ -34,6 +33,7 @@ declare type GenericClaim = { value_type: 'stream' | 'channel', signing_channel?: ChannelClaim, repost_channel_url?: string, + purchase_receipt?: PurchaseReceipt, meta: { activation_height: number, claims_in_channel?: number, @@ -121,3 +121,15 @@ declare type Fee = { currency: string, address: string, }; + +declare type PurchaseReceipt = { + address: string, + amount: string, + claim_id: string, + confirmations: number, + height: number, + nout: number, + timestamp: number, + txid: string, + type: 'purchase', +}; diff --git a/flow-typed/Lbry.js b/flow-typed/Lbry.js index 97e2f20..d7c0430 100644 --- a/flow-typed/Lbry.js +++ b/flow-typed/Lbry.js @@ -214,6 +214,22 @@ declare type StreamRepostOptions = { declare type StreamRepostResponse = GenericTxResponse; +declare type PurchaseListResponse = { + items: Array, + page: number, + page_size: number, + total_items: number, + total_pages: number, +}; + +declare type PurchaseListOptions = { + page: number, + page_size: number, + resolve: boolean, + claim_id?: string, + channel_id?: string, +}; + // // Types used in the generic Lbry object that is exported // @@ -253,6 +269,7 @@ declare type LbryTypes = { support_list: (params: {}) => Promise, support_abandon: (params: {}) => Promise, stream_repost: (params: StreamRepostOptions) => Promise, + purchase_list: (params: PurchaseListOptions) => Promise, // File fetching and manipulation file_list: (params: {}) => Promise, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index cbaad87..dc3e0e6 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -126,6 +126,9 @@ export const ADD_FILES_REFLECTING = 'ADD_FILES_REFLECTING'; export const UPDATE_FILES_REFLECTING = 'UPDATE_FILES_REFLECTING'; export const TOGGLE_CHECKING_REFLECTING = 'TOGGLE_CHECKING_REFLECTING'; export const TOGGLE_CHECKING_PENDING = 'TOGGLE_CHECKING_PENDING'; +export const PURCHASE_LIST_STARTED = 'PURCHASE_LIST_STARTED'; +export const PURCHASE_LIST_COMPLETED = 'PURCHASE_LIST_COMPLETED'; +export const PURCHASE_LIST_FAILED = 'PURCHASE_LIST_FAILED'; // Comments export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; diff --git a/src/index.js b/src/index.js index a661d00..7fb59be 100644 --- a/src/index.js +++ b/src/index.js @@ -75,6 +75,7 @@ export { doRepost, doClearRepostError, doCheckPublishNameAvailability, + doPurchaseList, } from 'redux/actions/claims'; export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -213,6 +214,8 @@ export { makeSelectCanonicalUrlForUri, makeSelectPermanentUrlForUri, makeSelectSupportsForUri, + makeSelectMyPurchasesForPage, + makeSelectClaimWasPurchased, selectPendingById, selectReflectingById, selectClaimsById, @@ -253,6 +256,10 @@ export { selectMyClaimsPageNumber, selectMyClaimsPageItemCount, selectFetchingMyClaimsPageError, + selectMyPurchases, + selectIsFetchingMyPurchases, + selectFetchingMyPurchasesError, + selectMyPurchasesCount, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; diff --git a/src/lbry.js b/src/lbry.js index 61a893b..51f4111 100644 --- a/src/lbry.js +++ b/src/lbry.js @@ -111,6 +111,7 @@ const Lbry: LbryTypes = { transaction_list: (params = {}) => daemonCallWithResult('transaction_list', params), utxo_release: (params = {}) => daemonCallWithResult('utxo_release', params), support_abandon: (params = {}) => daemonCallWithResult('support_abandon', params), + purchase_list: (params = {}) => daemonCallWithResult('purchase_list', params), sync_hash: (params = {}) => daemonCallWithResult('sync_hash', params), sync_apply: (params = {}) => daemonCallWithResult('sync_apply', params), diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 99e1d1d..c42a984 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -35,7 +35,9 @@ export function doResolveUris(uris: Array, returnCachedClaims: boolean = return; } - const options: { include_is_my_output?: boolean } = {}; + const options: { include_is_my_output?: boolean, include_purchase_receipt: boolean } = { + include_purchase_receipt: true, + }; if (urisToResolve.length === 1) { options.include_is_my_output = true; @@ -318,6 +320,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { page: page || 1, order_by: ['release_time'], include_is_my_output: true, + include_purchase_receipt: true, }).then((result: ClaimSearchResponse) => { const { items: claims, total_items: claimsInChannel, page: returnedPage } = result; @@ -554,7 +557,10 @@ export function doClaimSearch( }); }; - Lbry.claim_search(options).then(success, failure); + Lbry.claim_search({ + ...options, + include_purchase_receipt: true, + }).then(success, failure); }; } @@ -623,3 +629,35 @@ export function doClearRepostError() { type: ACTIONS.CLEAR_REPOST_ERROR, }; } + +export function doPurchaseList(page: number = 1, pageSize: number = 99999) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.PURCHASE_LIST_STARTED, + }); + + const success = (result: PurchaseListResponse) => { + return dispatch({ + type: ACTIONS.PURCHASE_LIST_COMPLETED, + data: { + result, + }, + }); + }; + + const failure = error => { + dispatch({ + type: ACTIONS.PURCHASE_LIST_FAILED, + data: { + error: error.message, + }, + }); + }; + + Lbry.purchase_list({ + page: page, + page_size: pageSize, + resolve: true, + }).then(success, failure); + }; +} diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index ee9e85c..207c955 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -25,6 +25,11 @@ type State = { fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, fetchingClaimSearchByQuery: { [string]: boolean }, + myPurchases: ?Array, + myPurchasesPageNumber: ?number, + myPurchasesPageTotalResults: ?number, + fetchingMyPurchases: boolean, + fetchingMyPurchasesError: ?string, claimSearchByQuery: { [string]: Array }, claimSearchByQueryLastPageReached: { [string]: Array }, creatingChannel: boolean, @@ -59,10 +64,13 @@ const defaultState = { channelClaimCounts: {}, fetchingChannelClaims: {}, resolvingUris: [], - // This should not be a Set - // Storing sets in reducers can cause issues myChannelClaims: undefined, myClaims: undefined, + myPurchases: undefined, + myPurchasesPageNumber: undefined, + myPurchasesPageTotalResults: undefined, + fetchingMyPurchases: false, + fetchingMyPurchasesError: undefined, fetchingMyChannels: false, abandoningById: {}, pendingById: {}, @@ -83,6 +91,7 @@ const defaultState = { myClaimsPageNumber: undefined, myClaimsPageTotalResults: undefined, isFetchingClaimListMine: false, + isFetchingMyPurchases: false, isCheckingNameForPublish: false, checkingPending: false, checkingReflecting: false, @@ -189,13 +198,13 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const byUri = Object.assign({}, state.claimsByUri); const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); - let urlPage = []; + let urlsForCurrentPage = []; claims.forEach((claim: Claim) => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { - urlPage.push(uri); + urlsForCurrentPage.push(uri); if (claim.confirmations < 1) { pendingById[claimId] = claim; delete byId[claimId]; @@ -228,7 +237,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): byId, claimsByUri: byUri, pendingById, - myClaimsPageResults: urlPage, + myClaimsPageResults: urlsForCurrentPage, myClaimsPageNumber: page, myClaimsPageTotalResults: totalItems, }); @@ -374,6 +383,7 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); + // $FlowFixMe claims.forEach((claim: Claim) => { const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); const { claim_id: claimId } = claim; @@ -637,6 +647,59 @@ reducers[ACTIONS.TOGGLE_CHECKING_PENDING] = (state: State, action): State => { }); }; +reducers[ACTIONS.PURCHASE_LIST_STARTED] = (state: State): State => { + return { + ...state, + fetchingMyPurchases: true, + fetchingMyPurchasesError: null, + }; +}; + +reducers[ACTIONS.PURCHASE_LIST_COMPLETED] = (state: State, action: any): State => { + const { result }: { result: PurchaseListResponse, resolve: boolean } = action.data; + const page = result.page; + const totalItems = result.total_items; + + let byId = Object.assign({}, state.byId); + let byUri = Object.assign({}, state.claimsByUri); + let urlsForCurrentPage = []; + + result.items.forEach(item => { + if (!item.claim) { + // Abandoned claim + return; + } + + const { claim, ...purchaseInfo } = item; + claim.purchase_receipt = purchaseInfo; + const claimId = claim.claim_id; + const uri = claim.canonical_url; + + byId[claimId] = claim; + byUri[uri] = claimId; + urlsForCurrentPage.push(uri); + }); + + return Object.assign({}, state, { + byId, + claimsByUri: byUri, + myPurchases: urlsForCurrentPage, + myPurchasesPageNumber: page, + myPurchasesPageTotalResults: totalItems, + fetchingMyPurchases: false, + }); +}; + +reducers[ACTIONS.PURCHASE_LIST_FAILED] = (state: State, action: any): State => { + const { error } = action.data; + + return { + ...state, + fetchingMyPurchases: false, + fetchingMyPurchasesError: error, + }; +}; + export function claimsReducer(state: State = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 78b5a71..b38731c 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -6,9 +6,10 @@ import { } from 'redux/selectors/search'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { createSelector } from 'reselect'; -import { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; +import { isClaimNsfw, createNormalizedClaimSearchKey, filterClaims } from 'util/claim'; import { getSearchQueryString } from 'util/query-params'; import { PAGE_SIZE } from 'constants/claim'; + const selectState = state => state.claims || {}; export const selectClaimsById = createSelector( @@ -225,6 +226,55 @@ export const makeSelectClaimIsMine = (rawUri: string) => { ); }; +export const selectMyPurchases = createSelector( + selectState, + state => state.myPurchases +); + +export const selectMyPurchasesCount = createSelector( + selectState, + state => state.myPurchasesPageTotalResults +); + +export const selectIsFetchingMyPurchases = createSelector( + selectState, + state => state.fetchingMyPurchases +); + +export const selectFetchingMyPurchasesError = createSelector( + selectState, + state => state.fetchingMyPurchasesError +); + +export const makeSelectMyPurchasesForPage = (query: ?string, page: number = 1) => + createSelector( + selectMyPurchases, + selectClaimsByUri, + (myPurchases: Array, claimsByUri: { [string]: Claim }) => { + if (!myPurchases) { + return undefined; + } + + const fileInfos = myPurchases.map(uri => claimsByUri[uri]); + const matchingFileInfos = filterClaims(fileInfos, query); + const start = (Number(page) - 1) * Number(PAGE_SIZE); + const end = Number(page) * Number(PAGE_SIZE); + return matchingFileInfos && matchingFileInfos.length + ? matchingFileInfos + .slice(start, end) + .map(fileInfo => fileInfo.canonical_url || fileInfo.permanent_url) + : []; + } + ); + +export const makeSelectClaimWasPurchased = (uri: string) => + createSelector( + makeSelectClaimForUri(uri), + claim => { + return claim && claim.purchase_receipt !== undefined; + } + ); + export const selectAllFetchingChannelClaims = createSelector( selectState, state => state.fetchingChannelClaims || {} @@ -318,8 +368,8 @@ export const makeSelectDateForUri = (uri: string) => (claim.value.release_time ? claim.value.release_time * 1000 : claim.meta && claim.meta.creation_timestamp - ? claim.meta.creation_timestamp * 1000 - : null); + ? claim.meta.creation_timestamp * 1000 + : null); if (!timestamp) { return undefined; } @@ -694,7 +744,7 @@ export const makeSelectSupportsForUri = (uri: string) => selectSupportsByOutpoint, makeSelectClaimForUri(uri), (byOutpoint, claim: ?StreamClaim) => { - if (!claim || !claim.is_mine) { + if (!claim || !claim.is_my_output) { return null; } diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 1ff96d5..53fcc96 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -212,6 +212,7 @@ function filterFileInfos(fileInfos, query) { const queryMatchRegExp = new RegExp(query, 'i'); return fileInfos.filter(fileInfo => { const { metadata } = fileInfo; + return ( (metadata.title && metadata.title.match(queryMatchRegExp)) || (fileInfo.channel_name && fileInfo.channel_name.match(queryMatchRegExp)) || @@ -233,12 +234,12 @@ export const makeSelectSearchDownloadUrlsForPage = (query, page = 1) => return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos.slice(start, end).map(fileInfo => - buildURI({ - streamName: fileInfo.claim_name, - channelName: fileInfo.channel_name, - channelClaimId: fileInfo.channel_claim_id, - }) - ) + buildURI({ + streamName: fileInfo.claim_name, + channelName: fileInfo.channel_name, + channelClaimId: fileInfo.channel_claim_id, + }) + ) : []; } ); diff --git a/src/util/claim.js b/src/util/claim.js index cfde696..aa685f8 100644 --- a/src/util/claim.js +++ b/src/util/claim.js @@ -51,3 +51,20 @@ export function concatClaims( return claims; } + +export function filterClaims(claims: Array, query: ?string): Array { + if (query) { + const queryMatchRegExp = new RegExp(query, 'i'); + return claims.filter(claim => { + const { value } = claim; + + return ( + (value.title && value.title.match(queryMatchRegExp)) || + (claim.signing_channel && claim.signing_channel.name.match(queryMatchRegExp)) || + (claim.name && claim.name.match(queryMatchRegExp)) + ); + }); + } + + return claims; +} -- 2.45.2 From f660f1070ca21a9f4c0bb6229f3be10801e62fde Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 18 May 2020 16:40:33 -0400 Subject: [PATCH 330/371] paid file changes for lbry.tv --- dist/bundle.es.js | 384 +++++++++++++------------------ dist/flow-typed/File.js | 1 + flow-typed/File.js | 1 + src/index.js | 11 +- src/redux/actions/file.js | 23 +- src/redux/reducers/claims.js | 33 +++ src/redux/reducers/file.js | 89 ------- src/redux/selectors/claims.js | 9 +- src/redux/selectors/file.js | 36 --- src/redux/selectors/file_info.js | 20 +- 10 files changed, 235 insertions(+), 372 deletions(-) delete mode 100644 src/redux/reducers/file.js delete mode 100644 src/redux/selectors/file.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b63ab60..c5abcd6 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2300,6 +2300,8 @@ const makeSelectClaimIsMine = rawUri => { const selectMyPurchases = reselect.createSelector(selectState$2, state => state.myPurchases); +const selectPurchaseUriSuccess = reselect.createSelector(selectState$2, state => state.purchaseUriSuccess); + const selectMyPurchasesCount = reselect.createSelector(selectState$2, state => state.myPurchasesPageTotalResults); const selectIsFetchingMyPurchases = reselect.createSelector(selectState$2, state => state.fetchingMyPurchases); @@ -3926,18 +3928,6 @@ const makeSelectSearchDownloadUrlsCount = query => reselect.createSelector(selec return fileInfos && fileInfos.length ? filterFileInfos(fileInfos, query).length : 0; }); -// - -const selectState$4 = state => state.file || {}; - -const selectPurchaseUriErrorMessage = reselect.createSelector(selectState$4, state => state.purchaseUriErrorMessage); - -const selectFailedPurchaseUris = reselect.createSelector(selectState$4, state => state.failedPurchaseUris); - -const selectPurchasedUris = reselect.createSelector(selectState$4, state => state.purchasedUris); - -const selectLastPurchasedUri = reselect.createSelector(selectState$4, state => state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null); - const makeSelectStreamingUrlForUri = uri => reselect.createSelector(makeSelectFileInfoForUri(uri), fileInfo => { return fileInfo && fileInfo.streaming_url; }); @@ -3960,7 +3950,6 @@ function doFileGet(uri, saveFile = true, onSuccess) { // set save_file argument to True to save the file (old behaviour) lbryProxy.get({ uri, save_file: saveFile }).then(streamInfo => { const timeout = streamInfo === null || typeof streamInfo !== 'object' || streamInfo.error === 'Timeout'; - if (timeout) { dispatch({ type: FETCH_FILE_INFO_FAILED, @@ -3969,11 +3958,12 @@ function doFileGet(uri, saveFile = true, onSuccess) { dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); } else { - // purchase was completed successfully - dispatch({ - type: PURCHASE_URI_COMPLETED, - data: { uri } - }); + if (streamInfo.content_fee) { + dispatch({ + type: PURCHASE_URI_COMPLETED, + data: { uri, purchaseReceipt: streamInfo.content_fee } + }); + } dispatch({ type: FETCH_FILE_INFO_COMPLETED, data: { @@ -3986,10 +3976,10 @@ function doFileGet(uri, saveFile = true, onSuccess) { onSuccess(streamInfo); } } - }).catch(() => { + }).catch(error => { dispatch({ type: PURCHASE_URI_FAILED, - data: { uri } + data: { uri, error } }); dispatch({ @@ -4120,10 +4110,10 @@ var _extends$6 = Object.assign || function (target) { for (var i = 1; i < argume 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 selectState$5 = state => state.publish || {}; +const selectState$4 = state => state.publish || {}; // Is the current uri the same as the uri they clicked "edit" on -const selectIsStillEditing = reselect.createSelector(selectState$5, publishState => { +const selectIsStillEditing = reselect.createSelector(selectState$4, publishState => { const { editingURI, uri } = publishState; if (!editingURI || !uri) { @@ -4148,7 +4138,7 @@ const selectIsStillEditing = reselect.createSelector(selectState$5, publishState return currentName === editName; }); -const selectPublishFormValues = reselect.createSelector(selectState$5, selectIsStillEditing, (state, isStillEditing) => { +const selectPublishFormValues = reselect.createSelector(selectState$4, selectIsStillEditing, (state, isStillEditing) => { const { pendingPublish, language, languages } = state, formValues = _objectWithoutProperties$2(state, ['pendingPublish', 'language', 'languages']); @@ -4161,7 +4151,7 @@ const selectPublishFormValues = reselect.createSelector(selectState$5, selectIsS } return _extends$6({}, formValues, { language: actualLanguage }); }); -const makeSelectPublishFormValue = item => reselect.createSelector(selectState$5, state => state[item]); +const makeSelectPublishFormValue = item => reselect.createSelector(selectState$4, state => state[item]); const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, selectIsStillEditing, selectClaimsById, selectMyClaimsWithoutChannels, ({ editingURI, uri }, isStillEditing, claimsById, myClaims) => { const { channelName: contentName, streamName: claimName } = parseURI(uri); @@ -4174,7 +4164,7 @@ const selectMyClaimForUri = reselect.createSelector(selectPublishFormValues, sel return isStillEditing ? claimsById[editClaimId] : myClaims.find(claim => !contentName ? claim.name === claimName : claim.name === contentName || claim.name === claimName); }); -const selectIsResolvingPublishUris = reselect.createSelector(selectState$5, selectResolvingUris, ({ uri, name }, resolvingUris) => { +const selectIsResolvingPublishUris = reselect.createSelector(selectState$4, selectResolvingUris, ({ uri, name }, resolvingUris) => { if (uri) { const isResolvingUri = resolvingUris.includes(uri); const { isChannel } = parseURI(uri); @@ -4191,7 +4181,7 @@ const selectIsResolvingPublishUris = reselect.createSelector(selectState$5, sele return false; }); -const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => { +const selectTakeOverAmount = reselect.createSelector(selectState$4, selectMyClaimForUri, selectClaimsByUri, ({ name }, myClaimForUri, claimsByUri) => { if (!name) { return null; } @@ -5119,6 +5109,7 @@ const defaultState = { myPurchases: undefined, myPurchasesPageNumber: undefined, myPurchasesPageTotalResults: undefined, + purchaseUriSuccess: false, fetchingMyPurchases: false, fetchingMyPurchasesError: undefined, fetchingMyChannels: false, @@ -5712,6 +5703,34 @@ reducers[PURCHASE_LIST_FAILED] = (state, action) => { }); }; +reducers[PURCHASE_URI_COMPLETED] = (state, action) => { + const { uri, purchaseReceipt } = action.data; + + let byId = Object.assign({}, state.byId); + let byUri = Object.assign({}, state.claimsByUri); + let myPurchases = state.myPurchases ? state.myPurchases.slice() : []; + + const claimId = byUri[uri]; + if (claimId) { + let claim = byId[claimId]; + claim.purchase_receipt = purchaseReceipt; + } + + myPurchases.push(uri); + + return _extends$9({}, state, { + byId, + myPurchases, + purchaseUriSuccess: true + }); +}; + +reducers[PURCHASE_URI_FAILED] = state => { + return _extends$9({}, state, { + purchaseUriSuccess: false + }); +}; + function claimsReducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); @@ -6051,80 +6070,7 @@ function fileInfoReducer(state = defaultState$3, action) { var _extends$c = 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; }; -const reducers$3 = {}; const defaultState$4 = { - failedPurchaseUris: [], - purchasedUris: [], - purchaseUriErrorMessage: '' -}; - -reducers$3[PURCHASE_URI_STARTED] = (state, action) => { - const { uri } = action.data; - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - if (newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); - } - - return _extends$c({}, state, { - failedPurchaseUris: newFailedPurchaseUris, - purchaseUriErrorMessage: '' - }); -}; - -reducers$3[PURCHASE_URI_COMPLETED] = (state, action) => { - const { uri } = action.data; - const newPurchasedUris = state.purchasedUris.slice(); - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - - if (!newPurchasedUris.includes(uri)) { - newPurchasedUris.push(uri); - } - if (newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); - } - - return _extends$c({}, state, { - failedPurchaseUris: newFailedPurchaseUris, - purchasedUris: newPurchasedUris, - purchaseUriErrorMessage: '' - }); -}; - -reducers$3[PURCHASE_URI_FAILED] = (state, action) => { - const { uri, error } = action.data; - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - - if (!newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.push(uri); - } - - return _extends$c({}, state, { - failedPurchaseUris: newFailedPurchaseUris, - purchaseUriErrorMessage: error - }); -}; - -reducers$3[DELETE_PURCHASED_URI] = (state, action) => { - const { uri } = action.data; - const newPurchasedUris = state.purchasedUris.slice(); - if (newPurchasedUris.includes(uri)) { - newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); - } - - return _extends$c({}, state, { - purchasedUris: newPurchasedUris - }); -}; - -function fileReducer(state = defaultState$4, action) { - const handler = reducers$3[action.type]; - if (handler) return handler(state, action); - return state; -} - -var _extends$d = 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; }; - -const defaultState$5 = { notifications: [], toasts: [], errors: [] @@ -6137,7 +6083,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$d({}, state, { + return _extends$c({}, state, { toasts: newToasts }); }, @@ -6145,7 +6091,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$d({}, state, { + return _extends$c({}, state, { toasts: newToasts }); }, @@ -6156,7 +6102,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$d({}, state, { + return _extends$c({}, state, { notifications: newNotifications }); }, @@ -6167,7 +6113,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$d({}, state, { + return _extends$c({}, state, { notifications }); }, @@ -6176,7 +6122,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$d({}, state, { + return _extends$c({}, state, { notifications: newNotifications }); }, @@ -6187,7 +6133,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$d({}, state, { + return _extends$c({}, state, { errors: newErrors }); }, @@ -6195,17 +6141,17 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$d({}, state, { + return _extends$c({}, state, { errors: newErrors }); } -}, defaultState$5); +}, defaultState$4); -var _extends$e = 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; }; +var _extends$d = 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$4(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 = { +const defaultState$5 = { editingURI: undefined, filePath: undefined, fileDur: 0, @@ -6242,20 +6188,20 @@ const defaultState$6 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$e({}, state, data); + return _extends$d({}, state, data); }, - [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$6, { + [CLEAR_PUBLISH]: state => _extends$d({}, defaultState$5, { bid: state.bid, optimize: state.optimize }), - [PUBLISH_START]: state => _extends$e({}, state, { + [PUBLISH_START]: state => _extends$d({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$e({}, state, { + [PUBLISH_FAIL]: state => _extends$d({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$e({}, state, { + [PUBLISH_SUCCESS]: state => _extends$d({}, state, { publishing: false, publishSuccess: true }), @@ -6270,16 +6216,16 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$e({}, defaultState$6, publishData, { + return _extends$d({}, defaultState$5, publishData, { editingURI: uri, uri: shortUri }); } -}, defaultState$6); +}, defaultState$5); -var _extends$f = 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; }; +var _extends$e = 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; }; -const defaultState$7 = { +const defaultState$6 = { 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 @@ -6299,23 +6245,23 @@ const defaultState$7 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$f({}, state, { + [SEARCH_START]: state => _extends$e({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$f({}, state, { + return _extends$e({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$f({}, state, { + [SEARCH_FAIL]: state => _extends$e({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$f({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$e({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -6333,24 +6279,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$f({}, state, { + return _extends$e({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$f({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$e({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$f({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$e({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$f({}, state, { - suggestions: _extends$f({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$e({}, state, { + suggestions: _extends$e({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -6358,35 +6304,35 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$f({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$e({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$f({}, state, { + [SEARCH_FOCUS]: state => _extends$e({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$f({}, state, { + [SEARCH_BLUR]: state => _extends$e({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$f({}, oldOptions, newOptions); - return _extends$f({}, state, { + const options = _extends$e({}, oldOptions, newOptions); + return _extends$e({}, state, { options }); } -}, defaultState$7); +}, defaultState$6); -var _extends$g = 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; }; +var _extends$f = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$g({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$f({}, tagsMap, { [tag]: { name: tag } }), {}); } -const defaultState$8 = { +const defaultState$7 = { followedTags: [], knownTags: getDefaultKnownTags() }; @@ -6404,7 +6350,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$g({}, state, { + return _extends$f({}, state, { followedTags: newFollowedTags }); }, @@ -6413,10 +6359,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$g({}, knownTags); + let newKnownTags = _extends$f({}, knownTags); newKnownTags[name] = { name }; - return _extends$g({}, state, { + return _extends$f({}, state, { knownTags: newKnownTags }); }, @@ -6425,11 +6371,11 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$g({}, knownTags); + let newKnownTags = _extends$f({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$g({}, state, { + return _extends$f({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -6437,17 +6383,17 @@ const tagsReducer = handleActions({ [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; if (Array.isArray(tags)) { - return _extends$g({}, state, { + return _extends$f({}, state, { followedTags: tags }); } - return _extends$g({}, state); + return _extends$f({}, state); } -}, defaultState$8); +}, defaultState$7); -var _extends$h = 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; }; +var _extends$g = 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; }; -const defaultState$9 = { +const defaultState$8 = { blockedChannels: [] }; @@ -6469,13 +6415,13 @@ const blockedReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { blocked } = action.data; - return _extends$h({}, state, { + return _extends$g({}, state, { blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } -}, defaultState$9); +}, defaultState$8); -var _extends$i = 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; }; +var _extends$h = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -6486,7 +6432,7 @@ const buildDraftTransaction = () => ({ // See details in https://github.com/lbryio/lbry/issues/1307 -const defaultState$a = { +const defaultState$9 = { balance: undefined, totalBalance: undefined, reservedBalance: undefined, @@ -6527,40 +6473,40 @@ const defaultState$a = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$i({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$h({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$i({}, state.transactions); + const byId = _extends$h({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$i({}, state, { + return _extends$h({}, state, { transactions: byId, fetchingTransactions: false }); }, [FETCH_TXO_PAGE_STARTED]: state => { - return _extends$i({}, state, { + return _extends$h({}, state, { fetchingTxos: true, fetchingTxosError: undefined }); }, [FETCH_TXO_PAGE_COMPLETED]: (state, action) => { - return _extends$i({}, state, { + return _extends$h({}, state, { txoPage: action.data, fetchingTxos: false }); }, [FETCH_TXO_PAGE_FAILED]: (state, action) => { - return _extends$i({}, state, { + return _extends$h({}, state, { txoPage: {}, fetchingTxos: false, fetchingTxosError: action.data @@ -6568,12 +6514,12 @@ const walletReducer = handleActions({ }, [UPDATE_TXO_FETCH_PARAMS]: (state, action) => { - return _extends$i({}, state, { + return _extends$h({}, state, { txoFetchParams: action.data }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$i({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$h({}, state, { fetchingSupports: true }), @@ -6586,7 +6532,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$i({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$h({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -6595,7 +6541,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$i({}, state, { + return _extends$h({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -6608,20 +6554,20 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$i({}, state, { + return _extends$h({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, [ABANDON_CLAIM_SUPPORT_STARTED]: (state, action) => { - return _extends$i({}, state, { + return _extends$h({}, state, { abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_PREVIEW]: (state, action) => { - return _extends$i({}, state, { + return _extends$h({}, state, { abandonClaimSupportError: undefined }); }, @@ -6632,36 +6578,36 @@ const walletReducer = handleActions({ pendingtxs[claimId] = { txid, type, effective }; - return _extends$i({}, state, { + return _extends$h({}, state, { pendingSupportTransactions: pendingtxs, abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_FAILED]: (state, action) => { - return _extends$i({}, state, { + return _extends$h({}, state, { abandonClaimSupportError: action.data }); }, [PENDING_SUPPORTS_UPDATED]: (state, action) => { - return _extends$i({}, state, { + return _extends$h({}, state, { pendingSupportTransactions: action.data }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$h({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$i({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$h({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$i({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$h({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -6670,32 +6616,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$i({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$h({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$i({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$h({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$i({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$h({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$i({}, state, { draftTransaction: newDraft }); + return _extends$h({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$i({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$h({}, oldDraft, { address: action.data.address }); - return _extends$i({}, state, { draftTransaction: newDraft }); + return _extends$h({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$i({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$h({}, state.draftTransaction, { sending: true }); - return _extends$i({}, state, { draftTransaction: newDraftTransaction }); + return _extends$h({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -6708,123 +6654,123 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$i({}, state, { draftTransaction: newDraftTransaction }); + return _extends$h({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$i({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$h({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$i({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$h({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$i({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$h({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$i({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$h({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$h({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$i({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$h({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$h({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$i({}, state, { + [WALLET_DECRYPT_START]: state => _extends$h({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$h({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$i({}, state, { + [WALLET_UNLOCK_START]: state => _extends$h({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$h({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$h({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$i({}, state, { + [WALLET_LOCK_START]: state => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$i({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$h({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$i({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$h({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$i({}, state, { + [WALLET_RESTART]: state => _extends$h({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$i({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$h({}, state, { walletReconnecting: false }) -}, defaultState$a); +}, defaultState$9); // -const selectState$6 = state => state.content || {}; +const selectState$5 = state => state.content || {}; -const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$6, makeSelectClaimForUri(uri), (state, claim) => { +const makeSelectContentPositionForUri = uri => reselect.createSelector(selectState$5, makeSelectClaimForUri(uri), (state, claim) => { if (!claim) { return null; } @@ -6833,14 +6779,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$j = 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; }; +var _extends$i = 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; }; -const selectState$7 = state => state.notifications || {}; +const selectState$6 = state => state.notifications || {}; -const selectToast = reselect.createSelector(selectState$7, state => { +const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$j({ + return _extends$i({ id }, params); } @@ -6848,7 +6794,7 @@ const selectToast = reselect.createSelector(selectState$7, state => { return null; }); -const selectError = reselect.createSelector(selectState$7, state => { +const selectError = reselect.createSelector(selectState$6, state => { if (state.errors.length) { const { error } = state.errors[0]; return { @@ -6861,11 +6807,11 @@ const selectError = reselect.createSelector(selectState$7, state => { // -const selectState$8 = state => state.comments || {}; +const selectState$7 = state => state.comments || {}; -const selectCommentsById = reselect.createSelector(selectState$8, state => state.commentById || {}); +const selectCommentsById = reselect.createSelector(selectState$7, state => state.commentById || {}); -const selectCommentsByClaimId = reselect.createSelector(selectState$8, selectCommentsById, (state, byId) => { +const selectCommentsByClaimId = reselect.createSelector(selectState$7, selectCommentsById, (state, byId) => { const byClaimId = state.byId || {}; const comments = {}; @@ -6887,7 +6833,7 @@ const selectCommentsByClaimId = reselect.createSelector(selectState$8, selectCom selectState, state => state.byId || {} ); */ -const selectCommentsByUri = reselect.createSelector(selectState$8, state => { +const selectCommentsByUri = reselect.createSelector(selectState$7, state => { const byUri = state.commentsByUri || {}; const comments = {}; Object.keys(byUri).forEach(uri => { @@ -6912,11 +6858,11 @@ const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsBy // -const selectState$9 = state => state.tags || {}; +const selectState$8 = state => state.tags || {}; -const selectKnownTagsByName = reselect.createSelector(selectState$9, state => state.knownTags); +const selectKnownTagsByName = reselect.createSelector(selectState$8, state => state.knownTags); -const selectFollowedTagsList = reselect.createSelector(selectState$9, state => state.followedTags.filter(tag => typeof tag === 'string')); +const selectFollowedTagsList = reselect.createSelector(selectState$8, state => state.followedTags.filter(tag => typeof tag === 'string')); const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag.toLowerCase() })).sort((a, b) => a.name.localeCompare(b.name))); @@ -6939,9 +6885,9 @@ const makeSelectIsFollowingTag = tag => reselect.createSelector(selectFollowedTa // -const selectState$a = state => state.blocked || {}; +const selectState$9 = state => state.blocked || {}; -const selectBlockedChannels = reselect.createSelector(selectState$a, state => state.blockedChannels); +const selectBlockedChannels = reselect.createSelector(selectState$9, state => state.blockedChannels); const selectBlockedChannelsCount = reselect.createSelector(selectBlockedChannels, state => state.length); @@ -7053,7 +6999,6 @@ exports.doWalletReconnect = doWalletReconnect; exports.doWalletStatus = doWalletStatus; exports.doWalletUnlock = doWalletUnlock; exports.fileInfoReducer = fileInfoReducer; -exports.fileReducer = fileReducer; exports.formatCredits = formatCredits; exports.formatFullPrice = formatFullPrice; exports.isClaimNsfw = isClaimNsfw; @@ -7158,7 +7103,6 @@ exports.selectDraftTransactionAddress = selectDraftTransactionAddress; exports.selectDraftTransactionAmount = selectDraftTransactionAmount; exports.selectDraftTransactionError = selectDraftTransactionError; exports.selectError = selectError; -exports.selectFailedPurchaseUris = selectFailedPurchaseUris; exports.selectFetchingClaimSearch = selectFetchingClaimSearch; exports.selectFetchingClaimSearchByQuery = selectFetchingClaimSearchByQuery; exports.selectFetchingMyChannels = selectFetchingMyChannels; @@ -7186,7 +7130,6 @@ exports.selectIsSearching = selectIsSearching; exports.selectIsSendingSupport = selectIsSendingSupport; exports.selectIsStillEditing = selectIsStillEditing; exports.selectIsWalletReconnecting = selectIsWalletReconnecting; -exports.selectLastPurchasedUri = selectLastPurchasedUri; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; exports.selectMyClaimForUri = selectMyClaimForUri; @@ -7206,8 +7149,7 @@ exports.selectPendingClaims = selectPendingClaims; exports.selectPendingSupportTransactions = selectPendingSupportTransactions; exports.selectPlayingUri = selectPlayingUri; exports.selectPublishFormValues = selectPublishFormValues; -exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage; -exports.selectPurchasedUris = selectPurchasedUris; +exports.selectPurchaseUriSuccess = selectPurchaseUriSuccess; exports.selectReceiveAddress = selectReceiveAddress; exports.selectRecentTransactions = selectRecentTransactions; exports.selectReflectingById = selectReflectingById; diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index 75a3965..e74d7de 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -11,6 +11,7 @@ declare type FileListItem = { claim_id: string, claim_name: string, completed: false, + content_fee?: {}, download_directory: string, download_path: string, file_name: string, diff --git a/flow-typed/File.js b/flow-typed/File.js index 75a3965..e74d7de 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -11,6 +11,7 @@ declare type FileListItem = { claim_id: string, claim_name: string, completed: false, + content_fee?: {}, download_directory: string, download_path: string, file_name: string, diff --git a/src/index.js b/src/index.js index 7fb59be..b780f88 100644 --- a/src/index.js +++ b/src/index.js @@ -158,7 +158,6 @@ export { claimsReducer } from 'redux/reducers/claims'; export { commentReducer } from 'redux/reducers/comments'; export { contentReducer } from 'redux/reducers/content'; export { fileInfoReducer } from 'redux/reducers/file_info'; -export { fileReducer } from 'redux/reducers/file'; export { notificationsReducer } from 'redux/reducers/notifications'; export { publishReducer } from 'redux/reducers/publish'; export { searchReducer } from 'redux/reducers/search'; @@ -171,14 +170,6 @@ export { makeSelectContentPositionForUri } from 'redux/selectors/content'; export { selectToast, selectError } from 'redux/selectors/notifications'; -export { - selectFailedPurchaseUris, - selectPurchasedUris, - selectPurchaseUriErrorMessage, - selectLastPurchasedUri, - makeSelectStreamingUrlForUri, -} from 'redux/selectors/file'; - export { makeSelectClaimForUri, makeSelectClaimIsMine, @@ -260,6 +251,7 @@ export { selectIsFetchingMyPurchases, selectFetchingMyPurchasesError, selectMyPurchasesCount, + selectPurchaseUriSuccess, } from 'redux/selectors/claims'; export { makeSelectCommentsForUri } from 'redux/selectors/comments'; @@ -287,6 +279,7 @@ export { makeSelectSearchDownloadUrlsForPage, makeSelectSearchDownloadUrlsCount, selectDownloadUrlsCount, + makeSelectStreamingUrlForUri, } from 'redux/selectors/file_info'; export { diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index f6befff..056fc78 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -3,8 +3,11 @@ import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import { doToast } from 'redux/actions/notifications'; import { selectBalance } from 'redux/selectors/wallet'; -import { makeSelectFileInfoForUri, selectDownloadingByOutpoint } from 'redux/selectors/file_info'; -import { makeSelectStreamingUrlForUri } from 'redux/selectors/file'; +import { + makeSelectFileInfoForUri, + selectDownloadingByOutpoint, + makeSelectStreamingUrlForUri, +} from 'redux/selectors/file_info'; import { makeSelectClaimForUri } from 'redux/selectors/claims'; type Dispatch = (action: any) => any; @@ -28,7 +31,6 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get .then((streamInfo: GetResponse) => { const timeout = streamInfo === null || typeof streamInfo !== 'object' || streamInfo.error === 'Timeout'; - if (timeout) { dispatch({ type: ACTIONS.FETCH_FILE_INFO_FAILED, @@ -37,11 +39,12 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); } else { - // purchase was completed successfully - dispatch({ - type: ACTIONS.PURCHASE_URI_COMPLETED, - data: { uri }, - }); + if (streamInfo.content_fee) { + dispatch({ + type: ACTIONS.PURCHASE_URI_COMPLETED, + data: { uri, purchaseReceipt: streamInfo.content_fee }, + }); + } dispatch({ type: ACTIONS.FETCH_FILE_INFO_COMPLETED, data: { @@ -55,10 +58,10 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get } } }) - .catch(() => { + .catch(error => { dispatch({ type: ACTIONS.PURCHASE_URI_FAILED, - data: { uri }, + data: { uri, error }, }); dispatch({ diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 207c955..f133067 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -25,6 +25,7 @@ type State = { fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, fetchingClaimSearchByQuery: { [string]: boolean }, + purchaseUriSuccess: boolean, myPurchases: ?Array, myPurchasesPageNumber: ?number, myPurchasesPageTotalResults: ?number, @@ -69,6 +70,7 @@ const defaultState = { myPurchases: undefined, myPurchasesPageNumber: undefined, myPurchasesPageTotalResults: undefined, + purchaseUriSuccess: false, fetchingMyPurchases: false, fetchingMyPurchasesError: undefined, fetchingMyChannels: false, @@ -700,6 +702,37 @@ reducers[ACTIONS.PURCHASE_LIST_FAILED] = (state: State, action: any): State => { }; }; +reducers[ACTIONS.PURCHASE_URI_COMPLETED] = (state: State, action: any): State => { + const { uri, purchaseReceipt } = action.data; + + let byId = Object.assign({}, state.byId); + let byUri = Object.assign({}, state.claimsByUri); + let myPurchases = state.myPurchases ? state.myPurchases.slice() : []; + let urlsForCurrentPage = []; + + const claimId = byUri[uri]; + if (claimId) { + let claim = byId[claimId]; + claim.purchase_receipt = purchaseReceipt; + } + + myPurchases.push(uri); + + return { + ...state, + byId, + myPurchases, + purchaseUriSuccess: true, + }; +}; + +reducers[ACTIONS.PURCHASE_URI_FAILED] = (state: State): State => { + return { + ...state, + purchaseUriSuccess: false, + }; +}; + export function claimsReducer(state: State = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); diff --git a/src/redux/reducers/file.js b/src/redux/reducers/file.js deleted file mode 100644 index 0e9a40e..0000000 --- a/src/redux/reducers/file.js +++ /dev/null @@ -1,89 +0,0 @@ -// @flow -import * as ACTIONS from 'constants/action_types'; - -const reducers = {}; -const defaultState = { - failedPurchaseUris: [], - purchasedUris: [], - purchaseUriErrorMessage: '', -}; - -reducers[ACTIONS.PURCHASE_URI_STARTED] = ( - state: FileState, - action: PurchaseUriStarted -): FileState => { - const { uri } = action.data; - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - if (newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); - } - - return { - ...state, - failedPurchaseUris: newFailedPurchaseUris, - purchaseUriErrorMessage: '', - }; -}; - -reducers[ACTIONS.PURCHASE_URI_COMPLETED] = ( - state: FileState, - action: PurchaseUriCompleted -): FileState => { - const { uri } = action.data; - const newPurchasedUris = state.purchasedUris.slice(); - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - - if (!newPurchasedUris.includes(uri)) { - newPurchasedUris.push(uri); - } - if (newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); - } - - return { - ...state, - failedPurchaseUris: newFailedPurchaseUris, - purchasedUris: newPurchasedUris, - purchaseUriErrorMessage: '', - }; -}; - -reducers[ACTIONS.PURCHASE_URI_FAILED] = ( - state: FileState, - action: PurchaseUriFailed -): FileState => { - const { uri, error } = action.data; - const newFailedPurchaseUris = state.failedPurchaseUris.slice(); - - if (!newFailedPurchaseUris.includes(uri)) { - newFailedPurchaseUris.push(uri); - } - - return { - ...state, - failedPurchaseUris: newFailedPurchaseUris, - purchaseUriErrorMessage: error, - }; -}; - -reducers[ACTIONS.DELETE_PURCHASED_URI] = ( - state: FileState, - action: DeletePurchasedUri -): FileState => { - const { uri } = action.data; - const newPurchasedUris = state.purchasedUris.slice(); - if (newPurchasedUris.includes(uri)) { - newPurchasedUris.splice(newPurchasedUris.indexOf(uri), 1); - } - - return { - ...state, - purchasedUris: newPurchasedUris, - }; -}; - -export function fileReducer(state: FileState = defaultState, action: any) { - const handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index d9b5a5a..12e33ae 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -231,6 +231,11 @@ export const selectMyPurchases = createSelector( state => state.myPurchases ); +export const selectPurchaseUriSuccess = createSelector( + selectState, + state => state.purchaseUriSuccess +); + export const selectMyPurchasesCount = createSelector( selectState, state => state.myPurchasesPageTotalResults @@ -400,7 +405,9 @@ export const makeSelectThumbnailForUri = (uri: string) => makeSelectClaimForUri(uri), claim => { const thumbnail = claim && claim.value && claim.value.thumbnail; - return thumbnail && thumbnail.url ? thumbnail.url.trim().replace(/^http:\/\//i, 'https://') : undefined; + return thumbnail && thumbnail.url + ? thumbnail.url.trim().replace(/^http:\/\//i, 'https://') + : undefined; } ); diff --git a/src/redux/selectors/file.js b/src/redux/selectors/file.js deleted file mode 100644 index dbdb0be..0000000 --- a/src/redux/selectors/file.js +++ /dev/null @@ -1,36 +0,0 @@ -// @flow -import { createSelector } from 'reselect'; -import { makeSelectFileInfoForUri } from 'redux/selectors/file_info'; - -type State = { file: FileState }; - -export const selectState = (state: State): FileState => state.file || {}; - -export const selectPurchaseUriErrorMessage: (state: State) => string = createSelector( - selectState, - state => state.purchaseUriErrorMessage -); - -export const selectFailedPurchaseUris: (state: State) => Array = createSelector( - selectState, - state => state.failedPurchaseUris -); - -export const selectPurchasedUris: (state: State) => Array = createSelector( - selectState, - state => state.purchasedUris -); - -export const selectLastPurchasedUri: (state: State) => string = createSelector( - selectState, - state => - state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null -); - -export const makeSelectStreamingUrlForUri = (uri: string) => - createSelector( - makeSelectFileInfoForUri(uri), - fileInfo => { - return fileInfo && fileInfo.streaming_url; - } - ); diff --git a/src/redux/selectors/file_info.js b/src/redux/selectors/file_info.js index 53fcc96..d52987f 100644 --- a/src/redux/selectors/file_info.js +++ b/src/redux/selectors/file_info.js @@ -234,12 +234,12 @@ export const makeSelectSearchDownloadUrlsForPage = (query, page = 1) => return matchingFileInfos && matchingFileInfos.length ? matchingFileInfos.slice(start, end).map(fileInfo => - buildURI({ - streamName: fileInfo.claim_name, - channelName: fileInfo.channel_name, - channelClaimId: fileInfo.channel_claim_id, - }) - ) + buildURI({ + streamName: fileInfo.claim_name, + channelName: fileInfo.channel_name, + channelClaimId: fileInfo.channel_claim_id, + }) + ) : []; } ); @@ -251,3 +251,11 @@ export const makeSelectSearchDownloadUrlsCount = query => return fileInfos && fileInfos.length ? filterFileInfos(fileInfos, query).length : 0; } ); + +export const makeSelectStreamingUrlForUri = uri => + createSelector( + makeSelectFileInfoForUri(uri), + fileInfo => { + return fileInfo && fileInfo.streaming_url; + } + ); -- 2.45.2 From 4a59abf30c2453be40ebb3122ce3eb70785c2585 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 18 May 2020 22:13:18 -0400 Subject: [PATCH 331/371] add doClearPurchasedUriSuccess --- dist/bundle.es.js | 17 +++++++++++------ dist/flow-typed/File.js | 2 +- flow-typed/File.js | 2 +- src/constants/action_types.js | 2 +- src/index.js | 2 +- src/redux/actions/file.js | 5 ++--- src/redux/reducers/claims.js | 7 +++++++ 7 files changed, 24 insertions(+), 13 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c5abcd6..17d88f5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -191,7 +191,7 @@ const SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; const PURCHASE_URI_STARTED = 'PURCHASE_URI_STARTED'; const PURCHASE_URI_COMPLETED = 'PURCHASE_URI_COMPLETED'; const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; -const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; +const CLEAR_PURCHASED_URI_SUCCESS = 'CLEAR_PURCHASED_URI_SUCCESS'; // Search const SEARCH_START = 'SEARCH_START'; @@ -470,7 +470,7 @@ var action_types = /*#__PURE__*/Object.freeze({ PURCHASE_URI_STARTED: PURCHASE_URI_STARTED, PURCHASE_URI_COMPLETED: PURCHASE_URI_COMPLETED, PURCHASE_URI_FAILED: PURCHASE_URI_FAILED, - DELETE_PURCHASED_URI: DELETE_PURCHASED_URI, + CLEAR_PURCHASED_URI_SUCCESS: CLEAR_PURCHASED_URI_SUCCESS, SEARCH_START: SEARCH_START, SEARCH_SUCCESS: SEARCH_SUCCESS, SEARCH_FAIL: SEARCH_FAIL, @@ -4030,10 +4030,9 @@ function doPurchaseUri(uri, costInfo, saveFile = true, onSuccess) { }; } -function doDeletePurchasedUri(uri) { +function doClearPurchasedUriSuccess() { return { - type: DELETE_PURCHASED_URI, - data: { uri } + type: CLEAR_PURCHASED_URI_SUCCESS }; } @@ -5731,6 +5730,12 @@ reducers[PURCHASE_URI_FAILED] = state => { }); }; +reducers[CLEAR_PURCHASED_URI_SUCCESS] = state => { + return _extends$9({}, state, { + purchaseUriSuccess: false + }); +}; + function claimsReducer(state = defaultState, action) { const handler = reducers[action.type]; if (handler) return handler(state, action); @@ -6937,6 +6942,7 @@ exports.doCheckPublishNameAvailability = doCheckPublishNameAvailability; exports.doCheckReflectingFiles = doCheckReflectingFiles; exports.doClaimSearch = doClaimSearch; exports.doClearPublish = doClearPublish; +exports.doClearPurchasedUriSuccess = doClearPurchasedUriSuccess; exports.doClearRepostError = doClearRepostError; exports.doClearSupport = doClearSupport; exports.doCommentAbandon = doCommentAbandon; @@ -6945,7 +6951,6 @@ exports.doCommentHide = doCommentHide; exports.doCommentList = doCommentList; exports.doCommentUpdate = doCommentUpdate; exports.doCreateChannel = doCreateChannel; -exports.doDeletePurchasedUri = doDeletePurchasedUri; exports.doDeleteTag = doDeleteTag; exports.doDismissError = doDismissError; exports.doDismissToast = doDismissToast; diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index e74d7de..5c29dd4 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -70,7 +70,7 @@ declare type PurchaseUriStarted = { }; declare type DeletePurchasedUri = { - type: ACTIONS.DELETE_PURCHASED_URI, + type: ACTIONS.CLEAR_PURCHASED_URI_SUCCESS, data: { uri: string, }, diff --git a/flow-typed/File.js b/flow-typed/File.js index e74d7de..5c29dd4 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -70,7 +70,7 @@ declare type PurchaseUriStarted = { }; declare type DeletePurchasedUri = { - type: ACTIONS.DELETE_PURCHASED_URI, + type: ACTIONS.CLEAR_PURCHASED_URI_SUCCESS, data: { uri: string, }, diff --git a/src/constants/action_types.js b/src/constants/action_types.js index dc3e0e6..8be3f24 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -168,7 +168,7 @@ export const SET_FILE_LIST_SORT = 'SET_FILE_LIST_SORT'; export const PURCHASE_URI_STARTED = 'PURCHASE_URI_STARTED'; export const PURCHASE_URI_COMPLETED = 'PURCHASE_URI_COMPLETED'; export const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; -export const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; +export const CLEAR_PURCHASED_URI_SUCCESS = 'CLEAR_PURCHASED_URI_SUCCESS'; // Search export const SEARCH_START = 'SEARCH_START'; diff --git a/src/index.js b/src/index.js index b780f88..483b152 100644 --- a/src/index.js +++ b/src/index.js @@ -78,7 +78,7 @@ export { doPurchaseList, } from 'redux/actions/claims'; -export { doDeletePurchasedUri, doPurchaseUri, doFileGet } from 'redux/actions/file'; +export { doClearPurchasedUriSuccess, doPurchaseUri, doFileGet } from 'redux/actions/file'; export { doFetchFileInfo, diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 056fc78..6ad2a0b 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -123,9 +123,8 @@ export function doPurchaseUri( }; } -export function doDeletePurchasedUri(uri: string) { +export function doClearPurchasedUriSuccess() { return { - type: ACTIONS.DELETE_PURCHASED_URI, - data: { uri }, + type: ACTIONS.CLEAR_PURCHASED_URI_SUCCESS, }; } diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index f133067..cdb34fc 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -733,6 +733,13 @@ reducers[ACTIONS.PURCHASE_URI_FAILED] = (state: State): State => { }; }; +reducers[ACTIONS.CLEAR_PURCHASED_URI_SUCCESS] = (state: State): State => { + return { + ...state, + purchaseUriSuccess: false, + }; +}; + export function claimsReducer(state: State = defaultState, action: any) { const handler = reducers[action.type]; if (handler) return handler(state, action); -- 2.45.2 From 0730becb359ba49867380719b09208a81d0d98e4 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 19 May 2020 13:52:42 -0400 Subject: [PATCH 332/371] add more mature tags --- dist/bundle.es.js | 2 +- src/constants/tags.js | 23 ++++++++++++++++++++++- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 17d88f5..c0dccdd 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -989,7 +989,7 @@ const SEARCH_OPTIONS = { const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'economics', 'education', 'gaming', 'music', 'news', 'science', 'sports', 'technology']; -const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; +const MATURE_TAGS = ['porn', 'porno', 'nsfw', 'mature', 'xxx', 'sex', 'creampie', 'blowjob', 'handjob', 'vagina', 'boobs', 'big boobgs', 'big dick', 'pussy', 'cumshot', 'anal', 'hard fucking', 'ass', 'fuck', 'hentai']; const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; diff --git a/src/constants/tags.js b/src/constants/tags.js index 1e25ed9..1b72738 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -13,7 +13,28 @@ export const DEFAULT_FOLLOWED_TAGS = [ 'technology', ]; -export const MATURE_TAGS = ['porn', 'nsfw', 'mature', 'xxx']; +export const MATURE_TAGS = [ + 'porn', + 'porno', + 'nsfw', + 'mature', + 'xxx', + 'sex', + 'creampie', + 'blowjob', + 'handjob', + 'vagina', + 'boobs', + 'big boobgs', + 'big dick', + 'pussy', + 'cumshot', + 'anal', + 'hard fucking', + 'ass', + 'fuck', + 'hentai', +]; export const DEFAULT_KNOWN_TAGS = [ 'free speech', -- 2.45.2 From 02831fe35959df0cbc3f7ccbcd1fdddaaba9aae5 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 19 May 2020 14:25:46 -0400 Subject: [PATCH 333/371] use purchase_receipt instead of content_fee --- dist/bundle.es.js | 4 ++-- dist/flow-typed/File.js | 2 +- flow-typed/File.js | 2 +- src/redux/actions/file.js | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index c0dccdd..2640f15 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3958,10 +3958,10 @@ function doFileGet(uri, saveFile = true, onSuccess) { dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); } else { - if (streamInfo.content_fee) { + if (streamInfo.purchase_receipt) { dispatch({ type: PURCHASE_URI_COMPLETED, - data: { uri, purchaseReceipt: streamInfo.content_fee } + data: { uri, purchaseReceipt: streamInfo.purchase_receipt } }); } dispatch({ diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index 5c29dd4..9a5f2ae 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -11,7 +11,7 @@ declare type FileListItem = { claim_id: string, claim_name: string, completed: false, - content_fee?: {}, + purchase_receipt?: {}, download_directory: string, download_path: string, file_name: string, diff --git a/flow-typed/File.js b/flow-typed/File.js index 5c29dd4..9a5f2ae 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -11,7 +11,7 @@ declare type FileListItem = { claim_id: string, claim_name: string, completed: false, - content_fee?: {}, + purchase_receipt?: {}, download_directory: string, download_path: string, file_name: string, diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 6ad2a0b..9af8bc3 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -39,10 +39,10 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); } else { - if (streamInfo.content_fee) { + if (streamInfo.purchase_receipt) { dispatch({ type: ACTIONS.PURCHASE_URI_COMPLETED, - data: { uri, purchaseReceipt: streamInfo.content_fee }, + data: { uri, purchaseReceipt: streamInfo.purchase_receipt }, }); } dispatch({ -- 2.45.2 From 58e59acb10f43f8cfe6521377e254c9d01251242 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 20 May 2020 12:06:38 -0400 Subject: [PATCH 334/371] update types --- dist/bundle.es.js | 4 ++-- dist/flow-typed/File.js | 3 ++- flow-typed/File.js | 3 ++- src/redux/actions/file.js | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2640f15..ce66a5b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3958,10 +3958,10 @@ function doFileGet(uri, saveFile = true, onSuccess) { dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); } else { - if (streamInfo.purchase_receipt) { + if (streamInfo.purchase_receipt || streamInfo.content_fee) { dispatch({ type: PURCHASE_URI_COMPLETED, - data: { uri, purchaseReceipt: streamInfo.purchase_receipt } + data: { uri, purchaseReceipt: streamInfo.purchase_receipt || streamInfo.content_fee } }); } dispatch({ diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index 9a5f2ae..4b5bb12 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -11,7 +11,8 @@ declare type FileListItem = { claim_id: string, claim_name: string, completed: false, - purchase_receipt?: {}, + content_fee?: { txid: string }, + purchase_receipt?: { txid: string }, download_directory: string, download_path: string, file_name: string, diff --git a/flow-typed/File.js b/flow-typed/File.js index 9a5f2ae..4b5bb12 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -11,7 +11,8 @@ declare type FileListItem = { claim_id: string, claim_name: string, completed: false, - purchase_receipt?: {}, + content_fee?: { txid: string }, + purchase_receipt?: { txid: string }, download_directory: string, download_path: string, file_name: string, diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 9af8bc3..2622fb5 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -39,10 +39,10 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); } else { - if (streamInfo.purchase_receipt) { + if (streamInfo.purchase_receipt || streamInfo.content_fee) { dispatch({ type: ACTIONS.PURCHASE_URI_COMPLETED, - data: { uri, purchaseReceipt: streamInfo.purchase_receipt }, + data: { uri, purchaseReceipt: streamInfo.purchase_receipt || streamInfo.content_fee }, }); } dispatch({ -- 2.45.2 From f6e5b69e5aa337d50503a2f5ebb5efe4eda4ac57 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 20 May 2020 13:42:36 -0400 Subject: [PATCH 335/371] update types --- dist/flow-typed/File.js | 2 +- flow-typed/File.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/flow-typed/File.js b/dist/flow-typed/File.js index 4b5bb12..44dc4f3 100644 --- a/dist/flow-typed/File.js +++ b/dist/flow-typed/File.js @@ -12,7 +12,7 @@ declare type FileListItem = { claim_name: string, completed: false, content_fee?: { txid: string }, - purchase_receipt?: { txid: string }, + purchase_receipt?: { txid: string, amount: string }, download_directory: string, download_path: string, file_name: string, diff --git a/flow-typed/File.js b/flow-typed/File.js index 4b5bb12..44dc4f3 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -12,7 +12,7 @@ declare type FileListItem = { claim_name: string, completed: false, content_fee?: { txid: string }, - purchase_receipt?: { txid: string }, + purchase_receipt?: { txid: string, amount: string }, download_directory: string, download_path: string, file_name: string, -- 2.45.2 From 910b55f0590d2967d93624ca18b6d07552082415 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 20 May 2020 15:40:25 -0400 Subject: [PATCH 336/371] don't use outpoint from get response because it might not exist --- dist/bundle.es.js | 2 +- src/redux/actions/file.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ce66a5b..31130bf 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -3968,7 +3968,7 @@ function doFileGet(uri, saveFile = true, onSuccess) { type: FETCH_FILE_INFO_COMPLETED, data: { fileInfo: streamInfo, - outpoint: streamInfo.outpoint + outpoint: outpoint } }); diff --git a/src/redux/actions/file.js b/src/redux/actions/file.js index 2622fb5..b7dc699 100644 --- a/src/redux/actions/file.js +++ b/src/redux/actions/file.js @@ -49,7 +49,7 @@ export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: Get type: ACTIONS.FETCH_FILE_INFO_COMPLETED, data: { fileInfo: streamInfo, - outpoint: streamInfo.outpoint, + outpoint: outpoint, }, }); -- 2.45.2 From aa2cfa789670e899824d3d3ac1ae677172a7ad4e Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 21 May 2020 09:38:30 -0400 Subject: [PATCH 337/371] fix myPurchases selector --- dist/bundle.es.js | 7 ++++++- src/redux/actions/claims.js | 3 ++- src/redux/selectors/claims.js | 5 +++++ 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 31130bf..ccd51fa 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2313,6 +2313,11 @@ const makeSelectMyPurchasesForPage = (query, page = 1) => reselect.createSelecto return undefined; } + if (!query) { + // ensure no duplicates from double purchase bugs + return [...new Set(myPurchases)]; + } + const fileInfos = myPurchases.map(uri => claimsByUri[uri]); const matchingFileInfos = filterClaims(fileInfos, query); const start = (Number(page) - 1) * Number(PAGE_SIZE); @@ -3752,7 +3757,7 @@ function doClearRepostError() { }; } -function doPurchaseList(page = 1, pageSize = 99999) { +function doPurchaseList(page = 1, pageSize = PAGE_SIZE) { return dispatch => { dispatch({ type: PURCHASE_LIST_STARTED diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index c42a984..484a45a 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -15,6 +15,7 @@ import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { creditsToString } from 'util/format-credits'; import { batchActions } from 'util/batch-actions'; import { createNormalizedClaimSearchKey } from 'util/claim'; +import { PAGE_SIZE } from 'constants/claim'; export function doResolveUris(uris: Array, returnCachedClaims: boolean = false) { return (dispatch: Dispatch, getState: GetState) => { @@ -630,7 +631,7 @@ export function doClearRepostError() { }; } -export function doPurchaseList(page: number = 1, pageSize: number = 99999) { +export function doPurchaseList(page: number = 1, pageSize: number = PAGE_SIZE) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.PURCHASE_LIST_STARTED, diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 12e33ae..422530e 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -260,6 +260,11 @@ export const makeSelectMyPurchasesForPage = (query: ?string, page: number = 1) = return undefined; } + if (!query) { + // ensure no duplicates from double purchase bugs + return [...new Set(myPurchases)]; + } + const fileInfos = myPurchases.map(uri => claimsByUri[uri]); const matchingFileInfos = filterClaims(fileInfos, query); const start = (Number(page) - 1) * Number(PAGE_SIZE); -- 2.45.2 From d2079111b3372eb926d2753991bed860e57a970a Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 25 May 2020 14:00:22 -0400 Subject: [PATCH 338/371] add selector for commet loading state --- dist/bundle.es.js | 3 +++ src/index.js | 2 +- src/redux/selectors/comments.js | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ccd51fa..63eafa3 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -6821,6 +6821,8 @@ const selectState$7 = state => state.comments || {}; const selectCommentsById = reselect.createSelector(selectState$7, state => state.commentById || {}); +const selectIsFetchingComments = reselect.createSelector(selectState$7, state => state.isLoading); + const selectCommentsByClaimId = reselect.createSelector(selectState$7, selectCommentsById, (state, byId) => { const byClaimId = state.byId || {}; const comments = {}; @@ -7130,6 +7132,7 @@ exports.selectFollowedTagsList = selectFollowedTagsList; exports.selectGettingNewAddress = selectGettingNewAddress; exports.selectHasTransactions = selectHasTransactions; exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; +exports.selectIsFetchingComments = selectIsFetchingComments; exports.selectIsFetchingFileList = selectIsFetchingFileList; exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileListDownloadedOrPublished; exports.selectIsFetchingMyPurchases = selectIsFetchingMyPurchases; diff --git a/src/index.js b/src/index.js index 483b152..76f5ed6 100644 --- a/src/index.js +++ b/src/index.js @@ -254,7 +254,7 @@ export { selectPurchaseUriSuccess, } from 'redux/selectors/claims'; -export { makeSelectCommentsForUri } from 'redux/selectors/comments'; +export { makeSelectCommentsForUri, selectIsFetchingComments } from 'redux/selectors/comments'; export { makeSelectFileInfoForUri, diff --git a/src/redux/selectors/comments.js b/src/redux/selectors/comments.js index c3a2f2d..d8033ff 100644 --- a/src/redux/selectors/comments.js +++ b/src/redux/selectors/comments.js @@ -8,6 +8,11 @@ export const selectCommentsById = createSelector( state => state.commentById || {} ); +export const selectIsFetchingComments = createSelector( + selectState, + state => state.isLoading +); + export const selectCommentsByClaimId = createSelector( selectState, selectCommentsById, -- 2.45.2 From ed68f01ff50e16b78131298a545fa499d6927deb Mon Sep 17 00:00:00 2001 From: Clayton Hickey Date: Tue, 26 May 2020 08:36:38 -0400 Subject: [PATCH 339/371] add case for when amount is undefined in formatCredits instead of returning '0' --- dist/bundle.es.js | 2 ++ src/util/format-credits.js | 2 ++ 2 files changed, 4 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 63eafa3..9e3c06a 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2665,6 +2665,8 @@ function numberWithCommas(x) { } function formatCredits(amount, precision, shortFormat = false) { + if (!amount) return '--'; + let actualAmount = parseFloat(amount); let actualPrecision = parseFloat(precision); let suffix = ''; diff --git a/src/util/format-credits.js b/src/util/format-credits.js index a090a33..627037d 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -5,6 +5,8 @@ function numberWithCommas(x) { } export function formatCredits(amount, precision, shortFormat = false) { + if (!amount) return '--'; + let actualAmount = parseFloat(amount); let actualPrecision = parseFloat(precision); let suffix = ''; -- 2.45.2 From a6dce0eccff555ca9ecc188070c69c4dfc5c8dac Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 26 May 2020 17:11:27 -0400 Subject: [PATCH 340/371] fix uploading state selector --- dist/bundle.es.js | 4 ++-- src/redux/selectors/claims.js | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9e3c06a..e7ded8d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2612,8 +2612,8 @@ const selectUpdatingChannel = reselect.createSelector(selectState$2, state => st const selectUpdateChannelError = reselect.createSelector(selectState$2, state => state.updateChannelError); -const makeSelectReflectingClaimForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), selectReflectingById, (claim, reflectingById) => { - const claimId = claim && claim.claimId; +const makeSelectReflectingClaimForUri = uri => reselect.createSelector(selectClaimIdsByUri, selectReflectingById, (claimIdsByUri, reflectingById) => { + const claimId = claimIdsByUri[normalizeURI(uri)]; return reflectingById[claimId]; }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 422530e..e2ced6c 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -785,10 +785,10 @@ export const selectUpdateChannelError = createSelector( export const makeSelectReflectingClaimForUri = (uri: string) => createSelector( - makeSelectClaimForUri(uri), + selectClaimIdsByUri, selectReflectingById, - (claim, reflectingById) => { - const claimId = claim && claim.claimId; + (claimIdsByUri, reflectingById) => { + const claimId = claimIdsByUri[normalizeURI(uri)]; return reflectingById[claimId]; } ); -- 2.45.2 From 09ff7b0b996cbc80b382b271e40d2cec94f85026 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 26 May 2020 22:10:52 -0400 Subject: [PATCH 341/371] remove placeholder return value --- dist/bundle.es.js | 2 -- src/util/format-credits.js | 2 -- 2 files changed, 4 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index e7ded8d..8aeabd9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2665,8 +2665,6 @@ function numberWithCommas(x) { } function formatCredits(amount, precision, shortFormat = false) { - if (!amount) return '--'; - let actualAmount = parseFloat(amount); let actualPrecision = parseFloat(precision); let suffix = ''; diff --git a/src/util/format-credits.js b/src/util/format-credits.js index 627037d..a090a33 100644 --- a/src/util/format-credits.js +++ b/src/util/format-credits.js @@ -5,8 +5,6 @@ function numberWithCommas(x) { } export function formatCredits(amount, precision, shortFormat = false) { - if (!amount) return '--'; - let actualAmount = parseFloat(amount); let actualPrecision = parseFloat(precision); let suffix = ''; -- 2.45.2 From 7f1fc91b8a2349ab47076947924f4c37c69aeb76 Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Sun, 31 May 2020 09:31:46 -0400 Subject: [PATCH 342/371] add tag for current events --- src/constants/tags.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/constants/tags.js b/src/constants/tags.js index 1b72738..e3d9df4 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -517,6 +517,7 @@ export const DEFAULT_KNOWN_TAGS = [ 'teaser', 'lbry', 'coronavirus', + '2020protests', 'covidcuts', 'covid-19', ]; -- 2.45.2 From f379c724bb50476eef50384148373e04515db57f Mon Sep 17 00:00:00 2001 From: Jeremy Kauffman Date: Sun, 31 May 2020 10:12:48 -0400 Subject: [PATCH 343/371] update bundle --- dist/bundle.es.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 8aeabd9..b8b524f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,6 +15,7 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ + __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -312,6 +313,7 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ + __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -592,6 +594,7 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ + __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -622,6 +625,7 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ + __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -686,6 +690,7 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ + __proto__: null, SHOW_NSFW: SHOW_NSFW, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, @@ -727,6 +732,7 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ + __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -740,6 +746,7 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ + __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -759,6 +766,7 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ + __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -775,6 +783,7 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ + __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -785,6 +794,7 @@ const READY$1 = 'ready'; const ERROR = 'error'; var abandon_states = /*#__PURE__*/Object.freeze({ + __proto__: null, PENDING: PENDING, DONE: DONE, READY: READY$1, @@ -829,6 +839,7 @@ const STREAM = 'stream'; const PAGE_SIZE_DEFAULT = 20; var txo_list = /*#__PURE__*/Object.freeze({ + __proto__: null, ACTIVE: ACTIVE, TYPE: TYPE, SUB_TYPE: SUB_TYPE, @@ -864,6 +875,7 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ + __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -909,6 +921,7 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ + __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -963,6 +976,7 @@ const WALLET_SERVERS = LBRYUM_SERVERS; const SHARE_USAGE_DATA$1 = SHARE_USAGE_DATA; var shared_preferences = /*#__PURE__*/Object.freeze({ + __proto__: null, WALLET_SERVERS: WALLET_SERVERS, SHARE_USAGE_DATA: SHARE_USAGE_DATA$1 }); @@ -991,7 +1005,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'porno', 'nsfw', 'mature', 'xxx', 'sex', 'creampie', 'blowjob', 'handjob', 'vagina', 'boobs', 'big boobgs', 'big dick', 'pussy', 'cumshot', 'anal', 'hard fucking', 'ass', 'fuck', 'hentai']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', 'covidcuts', 'covid-19']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', '2020protests', 'covidcuts', 'covid-19']; // -- 2.45.2 From b2d49c275538164ea6a8eee8eaf913c09b2a4992 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 1 Jun 2020 14:26:07 -0400 Subject: [PATCH 344/371] add case for channel_list failing --- dist/bundle.es.js | 17 ++++++++++++++++- src/constants/action_types.js | 1 + src/redux/actions/claims.js | 9 ++++++++- src/redux/reducers/claims.js | 6 ++++++ 4 files changed, 31 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index b8b524f..268c716 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -115,6 +115,7 @@ const ABANDON_CLAIM_STARTED = 'ABANDON_CLAIM_STARTED'; const ABANDON_CLAIM_SUCCEEDED = 'ABANDON_CLAIM_SUCCEEDED'; const FETCH_CHANNEL_LIST_STARTED = 'FETCH_CHANNEL_LIST_STARTED'; const FETCH_CHANNEL_LIST_COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED'; +const FETCH_CHANNEL_LIST_FAILED = 'FETCH_CHANNEL_LIST_FAILED'; const CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED'; const CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; const CREATE_CHANNEL_FAILED = 'CREATE_CHANNEL_FAILED'; @@ -399,6 +400,7 @@ var action_types = /*#__PURE__*/Object.freeze({ ABANDON_CLAIM_SUCCEEDED: ABANDON_CLAIM_SUCCEEDED, FETCH_CHANNEL_LIST_STARTED: FETCH_CHANNEL_LIST_STARTED, FETCH_CHANNEL_LIST_COMPLETED: FETCH_CHANNEL_LIST_COMPLETED, + FETCH_CHANNEL_LIST_FAILED: FETCH_CHANNEL_LIST_FAILED, CREATE_CHANNEL_STARTED: CREATE_CHANNEL_STARTED, CREATE_CHANNEL_COMPLETED: CREATE_CHANNEL_COMPLETED, CREATE_CHANNEL_FAILED: CREATE_CHANNEL_FAILED, @@ -3655,7 +3657,14 @@ function doFetchChannelListMine(page = 1, pageSize = 99999, resolve = true) { }); }; - lbryProxy.channel_list({ page, page_size: pageSize, resolve }).then(callback); + const failure = error => { + dispatch({ + type: FETCH_CHANNEL_LIST_FAILED, + data: error + }); + }; + + lbryProxy.channel_list({ page, page_size: pageSize, resolve }).then(callback, failure); }; } @@ -5345,6 +5354,12 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { }); }; +reducers[FETCH_CHANNEL_LIST_FAILED] = (state, action) => { + return Object.assign({}, state, { + fetchingMyChannels: false + }); +}; + reducers[FETCH_CHANNEL_CLAIMS_STARTED] = (state, action) => { const { uri, page } = action.data; const fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 8be3f24..b14cfb8 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -91,6 +91,7 @@ export const ABANDON_CLAIM_STARTED = 'ABANDON_CLAIM_STARTED'; export const ABANDON_CLAIM_SUCCEEDED = 'ABANDON_CLAIM_SUCCEEDED'; export const FETCH_CHANNEL_LIST_STARTED = 'FETCH_CHANNEL_LIST_STARTED'; export const FETCH_CHANNEL_LIST_COMPLETED = 'FETCH_CHANNEL_LIST_COMPLETED'; +export const FETCH_CHANNEL_LIST_FAILED = 'FETCH_CHANNEL_LIST_FAILED'; export const CREATE_CHANNEL_STARTED = 'CREATE_CHANNEL_STARTED'; export const CREATE_CHANNEL_COMPLETED = 'CREATE_CHANNEL_COMPLETED'; export const CREATE_CHANNEL_FAILED = 'CREATE_CHANNEL_FAILED'; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 484a45a..56a4baf 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -502,7 +502,14 @@ export function doFetchChannelListMine( }); }; - Lbry.channel_list({ page, page_size: pageSize, resolve }).then(callback); + const failure = error => { + dispatch({ + type: ACTIONS.FETCH_CHANNEL_LIST_FAILED, + data: error, + }); + }; + + Lbry.channel_list({ page, page_size: pageSize, resolve }).then(callback, failure); }; } diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index cdb34fc..d74ffd1 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -300,6 +300,12 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St }); }; +reducers[ACTIONS.FETCH_CHANNEL_LIST_FAILED] = (state: State, action: any): State => { + return Object.assign({}, state, { + fetchingMyChannels: false, + }); +}; + reducers[ACTIONS.FETCH_CHANNEL_CLAIMS_STARTED] = (state: State, action: any): State => { const { uri, page } = action.data; const fetchingChannelClaims = Object.assign({}, state.fetchingChannelClaims); -- 2.45.2 From c7de10be2df2f6ec3e8091c288ef0899954d25d6 Mon Sep 17 00:00:00 2001 From: Michael Mitnick Date: Tue, 2 Jun 2020 22:26:59 -0400 Subject: [PATCH 345/371] Default tags to spanish --- src/constants/tags.js | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/constants/tags.js b/src/constants/tags.js index e3d9df4..4c06e97 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -520,4 +520,21 @@ export const DEFAULT_KNOWN_TAGS = [ '2020protests', 'covidcuts', 'covid-19', + 'español', + 'tecnología', + 'criptomonedas', + 'economía', + 'bitcoin', + 'educación', + 'videojuegos', + 'música', + 'noticias', + 'ciencia', + 'deportes', + 'latinoamérica', + 'latam', + 'conspiración', + 'humor', + 'política', + 'tutoriales', ]; -- 2.45.2 From 4e0c59ee8d0a405cac52ae7dc3dd8db43a09263a Mon Sep 17 00:00:00 2001 From: Michael Mitnick Date: Tue, 2 Jun 2020 22:40:42 -0400 Subject: [PATCH 346/371] Default tags to spanish --- dist/bundle.es.js | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 268c716..52cbd8b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,7 +15,6 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ - __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -314,7 +313,6 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ - __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -596,7 +594,6 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ - __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -627,7 +624,6 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ - __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -692,7 +688,6 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ - __proto__: null, SHOW_NSFW: SHOW_NSFW, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, @@ -734,7 +729,6 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -748,7 +742,6 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -768,7 +761,6 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ - __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -785,7 +777,6 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ - __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -796,7 +787,6 @@ const READY$1 = 'ready'; const ERROR = 'error'; var abandon_states = /*#__PURE__*/Object.freeze({ - __proto__: null, PENDING: PENDING, DONE: DONE, READY: READY$1, @@ -841,7 +831,6 @@ const STREAM = 'stream'; const PAGE_SIZE_DEFAULT = 20; var txo_list = /*#__PURE__*/Object.freeze({ - __proto__: null, ACTIVE: ACTIVE, TYPE: TYPE, SUB_TYPE: SUB_TYPE, @@ -877,7 +866,6 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ - __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -923,7 +911,6 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ - __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -978,7 +965,6 @@ const WALLET_SERVERS = LBRYUM_SERVERS; const SHARE_USAGE_DATA$1 = SHARE_USAGE_DATA; var shared_preferences = /*#__PURE__*/Object.freeze({ - __proto__: null, WALLET_SERVERS: WALLET_SERVERS, SHARE_USAGE_DATA: SHARE_USAGE_DATA$1 }); @@ -1007,7 +993,7 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'porno', 'nsfw', 'mature', 'xxx', 'sex', 'creampie', 'blowjob', 'handjob', 'vagina', 'boobs', 'big boobgs', 'big dick', 'pussy', 'cumshot', 'anal', 'hard fucking', 'ass', 'fuck', 'hentai']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', '2020protests', 'covidcuts', 'covid-19']; +const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', '2020protests', 'covidcuts', 'covid-19', 'español', 'tecnología', 'criptomonedas', 'economía', 'bitcoin', 'educación', 'videojuegos', 'música', 'noticias', 'ciencia', 'deportes', 'latinoamérica', 'latam', 'conspiración', 'humor', 'política', 'tutoriales']; // -- 2.45.2 From a9f1f7b61d6d3abe836a8f72eee392f66786a26f Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 4 Jun 2020 11:40:52 -0400 Subject: [PATCH 347/371] fix typo --- dist/bundle.es.js | 16 +--------------- src/constants/tags.js | 2 +- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 268c716..f501f04 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -15,7 +15,6 @@ const CHANNEL_NEW = 'new'; const PAGE_SIZE = 20; var claim = /*#__PURE__*/Object.freeze({ - __proto__: null, MINIMUM_PUBLISH_BID: MINIMUM_PUBLISH_BID, CHANNEL_ANONYMOUS: CHANNEL_ANONYMOUS, CHANNEL_NEW: CHANNEL_NEW, @@ -314,7 +313,6 @@ const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; var action_types = /*#__PURE__*/Object.freeze({ - __proto__: null, WINDOW_FOCUSED: WINDOW_FOCUSED, DAEMON_READY: DAEMON_READY, DAEMON_VERSION_MATCH: DAEMON_VERSION_MATCH, @@ -596,7 +594,6 @@ const OTHER = 'other'; const COPYRIGHT = 'copyright'; var licenses = /*#__PURE__*/Object.freeze({ - __proto__: null, CC_LICENSES: CC_LICENSES, NONE: NONE, PUBLIC_DOMAIN: PUBLIC_DOMAIN, @@ -627,7 +624,6 @@ const HISTORY = 'user_history'; const WALLET = 'wallet'; var pages = /*#__PURE__*/Object.freeze({ - __proto__: null, AUTH: AUTH, BACKUP: BACKUP, CHANNEL: CHANNEL, @@ -692,7 +688,6 @@ const RECEIVE_INTERESTS_NOTIFICATIONS = 'receiveInterestsNotifications'; const RECEIVE_CREATOR_NOTIFICATIONS = 'receiveCreatorNotifications'; var settings = /*#__PURE__*/Object.freeze({ - __proto__: null, SHOW_NSFW: SHOW_NSFW, CREDIT_REQUIRED_ACKNOWLEDGED: CREDIT_REQUIRED_ACKNOWLEDGED, NEW_USER_ACKNOWLEDGED: NEW_USER_ACKNOWLEDGED, @@ -734,7 +729,6 @@ const TITLE = 'title'; const FILENAME = 'filename'; var sort_options = /*#__PURE__*/Object.freeze({ - __proto__: null, DATE_NEW: DATE_NEW, DATE_OLD: DATE_OLD, TITLE: TITLE, @@ -748,7 +742,6 @@ const COMPLETE = 'complete'; const MANUAL = 'manual'; var thumbnail_upload_statuses = /*#__PURE__*/Object.freeze({ - __proto__: null, API_DOWN: API_DOWN, READY: READY, IN_PROGRESS: IN_PROGRESS, @@ -768,7 +761,6 @@ const UPDATE = 'update'; const ABANDON = 'abandon'; var transaction_types = /*#__PURE__*/Object.freeze({ - __proto__: null, ALL: ALL, SPEND: SPEND, RECEIVE: RECEIVE, @@ -785,7 +777,6 @@ const PAGE_SIZE$1 = 50; const LATEST_PAGE_SIZE = 20; var transaction_list = /*#__PURE__*/Object.freeze({ - __proto__: null, PAGE_SIZE: PAGE_SIZE$1, LATEST_PAGE_SIZE: LATEST_PAGE_SIZE }); @@ -796,7 +787,6 @@ const READY$1 = 'ready'; const ERROR = 'error'; var abandon_states = /*#__PURE__*/Object.freeze({ - __proto__: null, PENDING: PENDING, DONE: DONE, READY: READY$1, @@ -841,7 +831,6 @@ const STREAM = 'stream'; const PAGE_SIZE_DEFAULT = 20; var txo_list = /*#__PURE__*/Object.freeze({ - __proto__: null, ACTIVE: ACTIVE, TYPE: TYPE, SUB_TYPE: SUB_TYPE, @@ -877,7 +866,6 @@ const SPEECH_STATUS = 'https://spee.ch/api/config/site/publishing'; const SPEECH_PUBLISH = 'https://spee.ch/api/claim/publish'; var speech_urls = /*#__PURE__*/Object.freeze({ - __proto__: null, SPEECH_STATUS: SPEECH_STATUS, SPEECH_PUBLISH: SPEECH_PUBLISH }); @@ -923,7 +911,6 @@ const WALLET_DIR = 'wallet_dir'; const WALLETS = 'wallets'; var daemon_settings = /*#__PURE__*/Object.freeze({ - __proto__: null, ANNOUNCE_HEAD_AND_SD_ONLY: ANNOUNCE_HEAD_AND_SD_ONLY, API: API, BLOB_DOWNLOAD_TIMEOUT: BLOB_DOWNLOAD_TIMEOUT, @@ -978,7 +965,6 @@ const WALLET_SERVERS = LBRYUM_SERVERS; const SHARE_USAGE_DATA$1 = SHARE_USAGE_DATA; var shared_preferences = /*#__PURE__*/Object.freeze({ - __proto__: null, WALLET_SERVERS: WALLET_SERVERS, SHARE_USAGE_DATA: SHARE_USAGE_DATA$1 }); @@ -1005,7 +991,7 @@ const SEARCH_OPTIONS = { const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'economics', 'education', 'gaming', 'music', 'news', 'science', 'sports', 'technology']; -const MATURE_TAGS = ['porn', 'porno', 'nsfw', 'mature', 'xxx', 'sex', 'creampie', 'blowjob', 'handjob', 'vagina', 'boobs', 'big boobgs', 'big dick', 'pussy', 'cumshot', 'anal', 'hard fucking', 'ass', 'fuck', 'hentai']; +const MATURE_TAGS = ['porn', 'porno', 'nsfw', 'mature', 'xxx', 'sex', 'creampie', 'blowjob', 'handjob', 'vagina', 'boobs', 'big boobs', 'big dick', 'pussy', 'cumshot', 'anal', 'hard fucking', 'ass', 'fuck', 'hentai']; const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', '2020protests', 'covidcuts', 'covid-19']; diff --git a/src/constants/tags.js b/src/constants/tags.js index e3d9df4..3974d15 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -25,7 +25,7 @@ export const MATURE_TAGS = [ 'handjob', 'vagina', 'boobs', - 'big boobgs', + 'big boobs', 'big dick', 'pussy', 'cumshot', -- 2.45.2 From a883c4f56c2b4f34c9b3a04571cc862c779f34f6 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 5 Jun 2020 11:11:03 -0400 Subject: [PATCH 348/371] separate spansing and english tags --- dist/bundle.es.js | 6 +++++- src/constants/tags.js | 7 ++++++- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 52cbd8b..f17bd15 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -993,7 +993,11 @@ const DEFAULT_FOLLOWED_TAGS = ['art', 'automotive', 'blockchain', 'comedy', 'eco const MATURE_TAGS = ['porn', 'porno', 'nsfw', 'mature', 'xxx', 'sex', 'creampie', 'blowjob', 'handjob', 'vagina', 'boobs', 'big boobgs', 'big dick', 'pussy', 'cumshot', 'anal', 'hard fucking', 'ass', 'fuck', 'hentai']; -const DEFAULT_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', '2020protests', 'covidcuts', 'covid-19', 'español', 'tecnología', 'criptomonedas', 'economía', 'bitcoin', 'educación', 'videojuegos', 'música', 'noticias', 'ciencia', 'deportes', 'latinoamérica', 'latam', 'conspiración', 'humor', 'política', 'tutoriales']; +const DEFAULT_ENGLISH_KNOWN_TAGS = ['free speech', 'censorship', 'gaming', 'pop culture', 'entertainment', 'technology', 'music', 'funny', 'education', 'learning', 'news', 'gameplay', 'nature', 'beliefs', 'comedy', 'games', 'film & animation', 'game', 'weapons', 'blockchain', 'video game', 'sports', 'walkthrough', 'lbrytvpaidbeta', 'art', 'pc', 'minecraft', 'playthrough', 'economics', 'automotive', 'play', 'tutorial', 'twitch', 'how to', 'ps4', 'bitcoin', 'fortnite', 'commentary', 'lets play', 'fun', 'politics', 'travel', 'food', 'science', 'xbox', 'liberal', 'democrat', 'progressive', 'survival', 'non-profits', 'activism', 'cryptocurrency', 'playstation', 'nintendo', 'government', 'steam', 'podcast', 'gamer', 'horror', 'conservative', 'reaction', 'trailer', 'love', 'cnn', 'republican', 'political', 'hangoutsonair', 'hoa', 'msnbc', 'cbs', 'anime', 'donald trump', 'fiction', 'fox news', 'crypto', 'ethereum', 'call of duty', 'android', 'multiplayer', 'epic', 'rpg', 'adventure', 'secular talk', 'btc', 'atheist', 'atheism', 'video games', 'ps3', 'cod', 'online', 'agnostic', 'movie', 'fps', 'lets', 'mod', 'world', 'reviews', 'sharefactory', 'space', 'pokemon', 'stream', 'hilarious', 'lol', 'sony', 'god', 'dance', 'pvp', 'tech', 'strategy', 'zombies', 'fail', 'film', 'xbox360', 'animation', 'unboxing', 'money', 'wwe', 'mods', 'indie', 'pubg', 'ios', 'history', 'rap', 'mobile', 'trump', 'hack', 'flat earth', 'trap', 'humor', 'vlogging', 'fox', 'news radio', 'facebook', 'edm', 'fitness', 'vaping', 'hip hop', 'secular', 'jesus', 'song', 'vape', 'guitar', 'remix', 'mining', 'daily', 'diy', 'pets', 'videogame', 'death', 'funny moments', 'religion', 'media', 'viral', 'war', 'nbc', 'freedom', 'gold', 'family', 'meme', 'zombie', 'photography', 'chill', 'sniper', 'computer', 'iphone', 'dragon', 'bible', 'pro', 'overwatch', 'litecoin', 'gta', 'house', 'fire', 'bass', 'truth', 'crash', 'mario', 'league of legends', 'wii', 'mmorpg', 'health', 'marvel', 'racing', 'apple', 'instrumental', 'earth', 'destiny', 'satire', 'race', 'training', 'electronic', 'boss', 'roblox', 'family friendly', 'california', 'react', 'christian', 'mmo', 'twitter', 'help', 'star', 'cars', 'random', 'top 10', 'ninja', 'guns', 'linux', 'lessons', 'vegan', 'future', 'dota 2', 'studio', 'star wars', 'shooting', 'nasa', 'rock', 'league', 'subscribe', 'water', 'gta v', 'car', 'samsung', 'music video', 'skyrim', 'dog', 'comics', 'shooter game', 'bo3', 'halloween', 'liberty', 'eth', 'conspiracy', 'knife', 'fashion', 'stories', 'vapor', 'nvidia', 'cute', 'beat', 'nintendo switch', 'fantasy', 'christmas', 'world of warcraft', 'industry', 'cartoon', 'garden', 'animals', 'windows', 'happy', 'magic', 'memes', 'design', 'tactical', 'fallout 4', 'puzzle', 'parody', 'rv', 'beats', 'building', 'disney', 'drone', 'ps2', 'beach', 'metal', 'christianity', 'business', 'mix', 'bo2', 'cover', 'senate', '4k', 'united states', 'final', 'hero', 'playing', 'dlc', 'ubisoft', 'halo', 'pc gaming', 'raw', 'investing', 'online learning', 'software', 'ark', 'mojang', 'console', 'battle royale', 'canon', 'microsoft', 'camping', 'ufo', 'progressive talk', 'switch', 'fpv', 'arcade', 'school', 'driving', 'bodybuilding', 'drama', 'retro', 'science fiction', 'eggs', 'australia', 'modded', 'rainbow', 'gamers', 'resident evil', 'drawing', 'brasil', 'england', 'hillary clinton', 'singing', 'final fantasy', 'hiphop', 'video blog', 'mature', 'quad', 'noob', 'simulation', 'illuminati', 'poetry', 'dayz', 'manga', 'howto', 'insane', 'press', 'special', 'church', 'ico', 'weird', 'libertarian', 'crafting', 'level', 'comic', 'sandbox', 'daily vlog', 'outdoor', 'black ops', 'sound', 'christ', 'duty', 'juvenile fiction', 'pc game', 'how-to', 'ww2', 'creepy', 'artist', 'galaxy', 'destiny 2', 'new music', 'quest', 'lee', 'pacman', 'super smash bros', 'day', 'survival horror', 'patreon', 'bitcoin price', 'trending', 'open world', 'wii u', 'dope', 'reaper', 'sniping', 'dubstep', 'truck', 'planet', 'dc', 'amazon', 'spirituality', 'universe', 'video game culture', 'community', 'cat', 'aliens', 'tourism', 'altcoins', 'style', 'travel trailer', 'rda', 'gun', 'secret', 'far cry 5', 'auto', 'culture', 'dj', 'mw2', 'lord', 'full time rving', 'role-playing game', 'prank', 'grand theft auto', 'master', 'wrestling', 'sci-fi', 'workout', 'ghost', 'fake news', 'silly', 'season', 'bo4', 'trading', 'extreme', 'economy', 'combat', 'plays', 'muslim', 'pubg mobile', 'clips', 'bo1', 'paypal', 'sims', 'exploration', 'light', 'ripple', 'paranormal', 'football', 'capcom', 'rta', 'discord', 'batman', 'player', 'server', 'anarchy', 'military', 'playlist', 'cosplay', 'rv park', 'rant', 'edit', 'germany', 'reading', 'chris', 'flash', 'loot', 'bitcoin gratis', 'game reviews', 'movies', 'stupid', 'latest news', 'squad gameplay', 'guru', 'timelapse', 'black ops 3', 'holiday', 'soul', 'motivation', 'mw3', 'vacation', 'sega', '19th century', 'pop', 'sims 4', 'post', 'smok', 'island', 'scotland', 'paladins', 'warrior', 'creepypasta', 'role-playing', 'solar', 'vr', 'animal', 'peace', 'consciousness', 'dota', 'audio', 'mass effect', 'humour', 'first look', 'videogames', 'future bass', 'freestyle', 'hardcore', 'portugal', 'dantdm', 'teaser', 'lbry', 'coronavirus', '2020protests', 'covidcuts', 'covid-19']; + +const DEFAULT_SPANISH_KNOWN_TAGS = ['español', 'tecnología', 'criptomonedas', 'economía', 'bitcoin', 'educación', 'videojuegos', 'música', 'noticias', 'ciencia', 'deportes', 'latinoamérica', 'latam', 'conspiración', 'humor', 'política', 'tutoriales']; + +const DEFAULT_KNOWN_TAGS = [...DEFAULT_ENGLISH_KNOWN_TAGS, ...DEFAULT_SPANISH_KNOWN_TAGS]; // diff --git a/src/constants/tags.js b/src/constants/tags.js index 4c06e97..12949e7 100644 --- a/src/constants/tags.js +++ b/src/constants/tags.js @@ -36,7 +36,7 @@ export const MATURE_TAGS = [ 'hentai', ]; -export const DEFAULT_KNOWN_TAGS = [ +const DEFAULT_ENGLISH_KNOWN_TAGS = [ 'free speech', 'censorship', 'gaming', @@ -520,6 +520,9 @@ export const DEFAULT_KNOWN_TAGS = [ '2020protests', 'covidcuts', 'covid-19', +]; + +const DEFAULT_SPANISH_KNOWN_TAGS = [ 'español', 'tecnología', 'criptomonedas', @@ -538,3 +541,5 @@ export const DEFAULT_KNOWN_TAGS = [ 'política', 'tutoriales', ]; + +export const DEFAULT_KNOWN_TAGS = [...DEFAULT_ENGLISH_KNOWN_TAGS, ...DEFAULT_SPANISH_KNOWN_TAGS]; -- 2.45.2 From 7216d2befd5e6e09f9e16ea7ed89d6bc7d1892b0 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 10 Jun 2020 18:06:12 -0400 Subject: [PATCH 349/371] signed support functionality --- dist/bundle.es.js | 307 ++++++++++++++++++------------------ src/redux/actions/wallet.js | 113 ++++++------- 2 files changed, 211 insertions(+), 209 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index d4a1f5e..171bd30 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2723,6 +2723,8 @@ function creditsToString(amount) { return creditString; } +var _extends$5 = 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; }; + let walletBalancePromise = null; function doUpdateBalance() { return (dispatch, getState) => { @@ -2938,15 +2940,15 @@ function doSetDraftTransactionAddress(address) { }; } -function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { +function doSendTip(params, isSupport, successCallback, errorCallback) { return (dispatch, getState) => { const state = getState(); const balance = selectBalance(state); const myClaims = selectMyClaimsRaw(state); - const shouldSupport = isSupport || (myClaims ? myClaims.find(claim => claim.claim_id === claimId) : false); + const shouldSupport = isSupport || (myClaims ? myClaims.find(claim => claim.claim_id === params.claim_id) : false); - if (balance - amount <= 0) { + if (balance - params.amount <= 0) { dispatch(doToast({ message: __('Insufficient credits'), isError: true @@ -2956,7 +2958,7 @@ function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { const success = () => { dispatch(doToast({ - message: shouldSupport ? __('You deposited %amount% LBC as a support!', { amount }) : __('You sent %amount% LBC as a tip, Mahalo!', { amount }), + message: shouldSupport ? __('You deposited %amount% LBC as a support!', { amount: params.amount }) : __('You sent %amount% LBC as a tip, Mahalo!', { amount: params.amount }), linkText: __('History'), linkTarget: __('/wallet') })); @@ -2992,12 +2994,11 @@ function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { type: SUPPORT_TRANSACTION_STARTED }); - lbryProxy.support_create({ - claim_id: claimId, - amount: creditsToString(amount), + lbryProxy.support_create(_extends$5({}, params, { tip: !shouldSupport, - blocking: true - }).then(success, error); + blocking: true, + amount: creditsToString(params.amount) + })).then(success, error); }; } @@ -3217,7 +3218,7 @@ function batchActions(...actions) { }; } -var _extends$5 = 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; }; +var _extends$6 = 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) { return (dispatch, getState) => { @@ -3252,7 +3253,7 @@ function doResolveUris(uris, returnCachedClaims = false) { const resolveInfo = {}; - return lbryProxy.resolve(_extends$5({ urls: urisToResolve }, options)).then(result => { + return lbryProxy.resolve(_extends$6({ urls: urisToResolve }, options)).then(result => { Object.entries(result).forEach(([uri, uriResolveInfo]) => { const fallbackResolveInfo = { stream: null, @@ -3264,7 +3265,7 @@ function doResolveUris(uris, returnCachedClaims = false) { // https://github.com/facebook/flow/issues/2221 if (uriResolveInfo) { if (uriResolveInfo.error) { - resolveInfo[uri] = _extends$5({}, fallbackResolveInfo); + resolveInfo[uri] = _extends$6({}, fallbackResolveInfo); } else { let result = {}; if (uriResolveInfo.value_type === 'channel') { @@ -3698,7 +3699,7 @@ function doClaimSearch(options = { }); }; - lbryProxy.claim_search(_extends$5({}, options, { + lbryProxy.claim_search(_extends$6({}, options, { include_purchase_receipt: true })).then(success, failure); }; @@ -4123,7 +4124,7 @@ function doSetFileListSort(page, value) { }; } -var _extends$6 = 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; }; +var _extends$7 = 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$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; } @@ -4166,7 +4167,7 @@ const selectPublishFormValues = reselect.createSelector(selectState$4, selectIsS } else { actualLanguage = language || 'en'; } - return _extends$6({}, formValues, { language: actualLanguage }); + return _extends$7({}, formValues, { language: actualLanguage }); }); const makeSelectPublishFormValue = item => reselect.createSelector(selectState$4, state => state[item]); @@ -4221,7 +4222,7 @@ const selectTakeOverAmount = reselect.createSelector(selectState$4, selectMyClai return null; }); -var _extends$7 = 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; }; +var _extends$8 = 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 _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; } @@ -4261,7 +4262,7 @@ const doClearPublish = () => dispatch => { const doUpdatePublishForm = publishFormValue => dispatch => dispatch({ type: UPDATE_PUBLISH_FORM, - data: _extends$7({}, publishFormValue) + data: _extends$8({}, publishFormValue) }); const doUploadThumbnail = (filePath, thumbnailBlob, fsAdapter, fs, path) => dispatch => { @@ -4653,7 +4654,7 @@ function handleFetchResponse(response) { return response.status === 200 ? Promise.resolve(response.json()) : Promise.reject(new Error(response.statusText)); } -var _extends$8 = 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; }; +var _extends$9 = 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; }; const DEBOUNCED_SEARCH_SUGGESTION_MS = 300; @@ -4795,11 +4796,11 @@ from, isBackgroundSearch = false, options = {}, nsfw) => (dispatch, getState) => return; } - const optionsWithFrom = _extends$8({}, size ? { size } : {}, from ? { from } : {}, { + const optionsWithFrom = _extends$9({}, size ? { size } : {}, from ? { from } : {}, { isBackgroundSearch }, options); - const optionsWithoutFrom = _extends$8({}, size ? { size } : {}, { + const optionsWithoutFrom = _extends$9({}, size ? { size } : {}, { isBackgroundSearch }, options); @@ -5109,7 +5110,7 @@ const doToggleBlockChannel = uri => ({ } }); -var _extends$9 = 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; }; +var _extends$a = 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$3(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; } @@ -5230,7 +5231,7 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$9({}, handleClaimAction(state, action)); + return _extends$a({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -5496,7 +5497,7 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; -reducers[CREATE_CHANNEL_STARTED] = state => _extends$9({}, state, { +reducers[CREATE_CHANNEL_STARTED] = state => _extends$a({}, state, { creatingChannel: true, createChannelError: null }); @@ -5584,7 +5585,7 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { delete fetchingClaimSearchByQuery[query]; - return Object.assign({}, state, _extends$9({}, handleClaimAction(state, action), { + return Object.assign({}, state, _extends$a({}, handleClaimAction(state, action), { claimSearchByQuery, claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery @@ -5606,22 +5607,22 @@ reducers[CLAIM_SEARCH_FAILED] = (state, action) => { }; reducers[CLAIM_REPOST_STARTED] = state => { - return _extends$9({}, state, { + return _extends$a({}, state, { repostLoading: true, repostError: null }); }; reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { const { originalClaimId, repostClaim } = action.data; - const byId = _extends$9({}, state.byId); - const claimsByUri = _extends$9({}, state.claimsByUri); + const byId = _extends$a({}, state.byId); + const claimsByUri = _extends$a({}, state.claimsByUri); const claimThatWasReposted = byId[originalClaimId]; - const repostStub = _extends$9({}, repostClaim, { reposted_claim: claimThatWasReposted }); + const repostStub = _extends$a({}, repostClaim, { reposted_claim: claimThatWasReposted }); byId[repostStub.claim_id] = repostStub; claimsByUri[repostStub.permanent_url] = repostStub.claim_id; - return _extends$9({}, state, { + return _extends$a({}, state, { byId, claimsByUri, repostLoading: false, @@ -5631,13 +5632,13 @@ reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { reducers[CLAIM_REPOST_FAILED] = (state, action) => { const { error } = action.data; - return _extends$9({}, state, { + return _extends$a({}, state, { repostLoading: false, repostError: error }); }; reducers[CLEAR_REPOST_ERROR] = state => { - return _extends$9({}, state, { + return _extends$a({}, state, { repostError: null }); }; @@ -5648,34 +5649,34 @@ reducers[ADD_FILES_REFLECTING] = (state, action) => { reflectingById[claimId] = { fileListItem: pendingClaim, progress: 0, stalled: false }; - return Object.assign({}, state, _extends$9({}, state, { + return Object.assign({}, state, _extends$a({}, state, { reflectingById: reflectingById })); }; reducers[UPDATE_FILES_REFLECTING] = (state, action) => { const newReflectingById = action.data; - return Object.assign({}, state, _extends$9({}, state, { + return Object.assign({}, state, _extends$a({}, state, { reflectingById: newReflectingById })); }; reducers[TOGGLE_CHECKING_REFLECTING] = (state, action) => { const checkingReflecting = action.data; - return Object.assign({}, state, _extends$9({}, state, { + return Object.assign({}, state, _extends$a({}, state, { checkingReflecting })); }; reducers[TOGGLE_CHECKING_PENDING] = (state, action) => { const checking = action.data; - return Object.assign({}, state, _extends$9({}, state, { + return Object.assign({}, state, _extends$a({}, state, { checkingPending: checking })); }; reducers[PURCHASE_LIST_STARTED] = state => { - return _extends$9({}, state, { + return _extends$a({}, state, { fetchingMyPurchases: true, fetchingMyPurchasesError: null }); @@ -5720,7 +5721,7 @@ reducers[PURCHASE_LIST_COMPLETED] = (state, action) => { reducers[PURCHASE_LIST_FAILED] = (state, action) => { const { error } = action.data; - return _extends$9({}, state, { + return _extends$a({}, state, { fetchingMyPurchases: false, fetchingMyPurchasesError: error }); @@ -5741,7 +5742,7 @@ reducers[PURCHASE_URI_COMPLETED] = (state, action) => { myPurchases.push(uri); - return _extends$9({}, state, { + return _extends$a({}, state, { byId, myPurchases, purchaseUriSuccess: true @@ -5749,13 +5750,13 @@ reducers[PURCHASE_URI_COMPLETED] = (state, action) => { }; reducers[PURCHASE_URI_FAILED] = state => { - return _extends$9({}, state, { + return _extends$a({}, state, { purchaseUriSuccess: false }); }; reducers[CLEAR_PURCHASED_URI_SUCCESS] = state => { - return _extends$9({}, state, { + return _extends$a({}, state, { purchaseUriSuccess: false }); }; @@ -5784,7 +5785,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -var _extends$a = 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; }; +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; }; const defaultState$1 = { commentById: {}, // commentId -> Comment @@ -5795,11 +5796,11 @@ const defaultState$1 = { }; const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$a({}, state, { + [COMMENT_CREATE_STARTED]: (state, action) => _extends$b({}, state, { isLoading: true }), - [COMMENT_CREATE_FAILED]: (state, action) => _extends$a({}, state, { + [COMMENT_CREATE_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }), @@ -5817,14 +5818,14 @@ const commentReducer = handleActions({ newCommentIds.unshift(comment.comment_id); byId[claimId] = newCommentIds; - return _extends$a({}, state, { + return _extends$b({}, state, { commentById, byId, isLoading: false }); }, - [COMMENT_LIST_STARTED]: state => _extends$a({}, state, { isLoading: true }), + [COMMENT_LIST_STARTED]: state => _extends$b({}, state, { isLoading: true }), [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; @@ -5848,7 +5849,7 @@ const commentReducer = handleActions({ byId[claimId] = commentIds; commentsByUri[uri] = claimId; } - return _extends$a({}, state, { + return _extends$b({}, state, { byId, commentById, commentsByUri, @@ -5856,10 +5857,10 @@ const commentReducer = handleActions({ }); }, - [COMMENT_LIST_FAILED]: (state, action) => _extends$a({}, state, { + [COMMENT_LIST_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }), - [COMMENT_ABANDON_STARTED]: (state, action) => _extends$a({}, state, { + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$b({}, state, { isLoading: true }), [COMMENT_ABANDON_COMPLETED]: (state, action) => { @@ -5877,18 +5878,18 @@ const commentReducer = handleActions({ } delete commentById[comment_id]; - return _extends$a({}, state, { + return _extends$b({}, state, { commentById, byId, isLoading: false }); }, // do nothing - [COMMENT_ABANDON_FAILED]: (state, action) => _extends$a({}, state, { + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }), // do nothing - [COMMENT_UPDATE_STARTED]: (state, action) => _extends$a({}, state, { + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$b({}, state, { isLoading: true }), // replace existing comment with comment returned here under its comment_id @@ -5897,29 +5898,29 @@ const commentReducer = handleActions({ const commentById = Object.assign({}, state.commentById); commentById[comment.comment_id] = comment; - return _extends$a({}, state, { + return _extends$b({}, state, { commentById, isLoading: false }); }, // nothing can be done here - [COMMENT_UPDATE_FAILED]: (state, action) => _extends$a({}, state, { + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }), // nothing can really be done here - [COMMENT_HIDE_STARTED]: (state, action) => _extends$a({}, state, { + [COMMENT_HIDE_STARTED]: (state, action) => _extends$b({}, state, { isLoading: true }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$a({}, state, { // todo: add HiddenComments state & create selectors + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$b({}, state, { // todo: add HiddenComments state & create selectors isLoading: false }), // nothing can be done here - [COMMENT_HIDE_FAILED]: (state, action) => _extends$a({}, state, { + [COMMENT_HIDE_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }) }, defaultState$1); -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; }; +var _extends$c = 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; }; const reducers$1 = {}; const defaultState$2 = { @@ -5928,9 +5929,9 @@ const defaultState$2 = { reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$b({}, state, { - positions: _extends$b({}, state.positions, { - [claimId]: _extends$b({}, state.positions[claimId], { + return _extends$c({}, state, { + positions: _extends$c({}, state.positions, { + [claimId]: _extends$c({}, state.positions[claimId], { [outpoint]: position }) }) @@ -6097,7 +6098,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -var _extends$c = 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; }; +var _extends$d = 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; }; const defaultState$4 = { notifications: [], @@ -6112,7 +6113,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$c({}, state, { + return _extends$d({}, state, { toasts: newToasts }); }, @@ -6120,7 +6121,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$c({}, state, { + return _extends$d({}, state, { toasts: newToasts }); }, @@ -6131,7 +6132,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$c({}, state, { + return _extends$d({}, state, { notifications: newNotifications }); }, @@ -6142,7 +6143,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$c({}, state, { + return _extends$d({}, state, { notifications }); }, @@ -6151,7 +6152,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$c({}, state, { + return _extends$d({}, state, { notifications: newNotifications }); }, @@ -6162,7 +6163,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$c({}, state, { + return _extends$d({}, state, { errors: newErrors }); }, @@ -6170,13 +6171,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$c({}, state, { + return _extends$d({}, state, { errors: newErrors }); } }, defaultState$4); -var _extends$d = 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; }; +var _extends$e = 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$4(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; } @@ -6217,20 +6218,20 @@ const defaultState$5 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$d({}, state, data); + return _extends$e({}, state, data); }, - [CLEAR_PUBLISH]: state => _extends$d({}, defaultState$5, { + [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$5, { bid: state.bid, optimize: state.optimize }), - [PUBLISH_START]: state => _extends$d({}, state, { + [PUBLISH_START]: state => _extends$e({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$d({}, state, { + [PUBLISH_FAIL]: state => _extends$e({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$d({}, state, { + [PUBLISH_SUCCESS]: state => _extends$e({}, state, { publishing: false, publishSuccess: true }), @@ -6245,14 +6246,14 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$d({}, defaultState$5, publishData, { + return _extends$e({}, defaultState$5, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$5); -var _extends$e = 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; }; +var _extends$f = 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; }; const defaultState$6 = { isActive: false, // does the user have any typed text in the search input @@ -6274,23 +6275,23 @@ const defaultState$6 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$e({}, state, { + [SEARCH_START]: state => _extends$f({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$e({}, state, { + return _extends$f({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$e({}, state, { + [SEARCH_FAIL]: state => _extends$f({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$e({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$f({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -6308,24 +6309,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$e({}, state, { + return _extends$f({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$e({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$f({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$e({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$f({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$e({}, state, { - suggestions: _extends$e({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$f({}, state, { + suggestions: _extends$f({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -6333,30 +6334,30 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$e({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$f({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$e({}, state, { + [SEARCH_FOCUS]: state => _extends$f({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$e({}, state, { + [SEARCH_BLUR]: state => _extends$f({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$e({}, oldOptions, newOptions); - return _extends$e({}, state, { + const options = _extends$f({}, oldOptions, newOptions); + return _extends$f({}, state, { options }); } }, defaultState$6); -var _extends$f = 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; }; +var _extends$g = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$f({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$g({}, tagsMap, { [tag]: { name: tag } }), {}); } @@ -6379,7 +6380,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$f({}, state, { + return _extends$g({}, state, { followedTags: newFollowedTags }); }, @@ -6388,10 +6389,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$f({}, knownTags); + let newKnownTags = _extends$g({}, knownTags); newKnownTags[name] = { name }; - return _extends$f({}, state, { + return _extends$g({}, state, { knownTags: newKnownTags }); }, @@ -6400,11 +6401,11 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$f({}, knownTags); + let newKnownTags = _extends$g({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$f({}, state, { + return _extends$g({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -6412,15 +6413,15 @@ const tagsReducer = handleActions({ [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; if (Array.isArray(tags)) { - return _extends$f({}, state, { + return _extends$g({}, state, { followedTags: tags }); } - return _extends$f({}, state); + return _extends$g({}, state); } }, defaultState$7); -var _extends$g = 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; }; +var _extends$h = 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; }; const defaultState$8 = { blockedChannels: [] @@ -6444,13 +6445,13 @@ const blockedReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { blocked } = action.data; - return _extends$g({}, state, { + return _extends$h({}, state, { blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } }, defaultState$8); -var _extends$h = 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; }; +var _extends$i = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -6502,40 +6503,40 @@ const defaultState$9 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$h({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$i({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$h({}, state.transactions); + const byId = _extends$i({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$h({}, state, { + return _extends$i({}, state, { transactions: byId, fetchingTransactions: false }); }, [FETCH_TXO_PAGE_STARTED]: state => { - return _extends$h({}, state, { + return _extends$i({}, state, { fetchingTxos: true, fetchingTxosError: undefined }); }, [FETCH_TXO_PAGE_COMPLETED]: (state, action) => { - return _extends$h({}, state, { + return _extends$i({}, state, { txoPage: action.data, fetchingTxos: false }); }, [FETCH_TXO_PAGE_FAILED]: (state, action) => { - return _extends$h({}, state, { + return _extends$i({}, state, { txoPage: {}, fetchingTxos: false, fetchingTxosError: action.data @@ -6543,12 +6544,12 @@ const walletReducer = handleActions({ }, [UPDATE_TXO_FETCH_PARAMS]: (state, action) => { - return _extends$h({}, state, { + return _extends$i({}, state, { txoFetchParams: action.data }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$h({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$i({}, state, { fetchingSupports: true }), @@ -6561,7 +6562,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$h({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$i({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -6570,7 +6571,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$h({}, state, { + return _extends$i({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -6583,20 +6584,20 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$h({}, state, { + return _extends$i({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, [ABANDON_CLAIM_SUPPORT_STARTED]: (state, action) => { - return _extends$h({}, state, { + return _extends$i({}, state, { abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_PREVIEW]: (state, action) => { - return _extends$h({}, state, { + return _extends$i({}, state, { abandonClaimSupportError: undefined }); }, @@ -6607,36 +6608,36 @@ const walletReducer = handleActions({ pendingtxs[claimId] = { txid, type, effective }; - return _extends$h({}, state, { + return _extends$i({}, state, { pendingSupportTransactions: pendingtxs, abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_FAILED]: (state, action) => { - return _extends$h({}, state, { + return _extends$i({}, state, { abandonClaimSupportError: action.data }); }, [PENDING_SUPPORTS_UPDATED]: (state, action) => { - return _extends$h({}, state, { + return _extends$i({}, state, { pendingSupportTransactions: action.data }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$h({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$h({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$i({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$h({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$i({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -6645,32 +6646,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$h({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$i({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$h({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$i({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$h({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$i({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$h({}, state, { draftTransaction: newDraft }); + return _extends$i({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$h({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$i({}, oldDraft, { address: action.data.address }); - return _extends$h({}, state, { draftTransaction: newDraft }); + return _extends$i({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$h({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$i({}, state.draftTransaction, { sending: true }); - return _extends$h({}, state, { draftTransaction: newDraftTransaction }); + return _extends$i({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -6683,114 +6684,114 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$h({}, state, { draftTransaction: newDraftTransaction }); + return _extends$i({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$h({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$i({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$h({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$i({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$h({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$i({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$h({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$i({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$i({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$h({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$i({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$i({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$h({}, state, { + [WALLET_DECRYPT_START]: state => _extends$i({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$i({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$h({}, state, { + [WALLET_UNLOCK_START]: state => _extends$i({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$i({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$i({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$h({}, state, { + [WALLET_LOCK_START]: state => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$h({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$i({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$h({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$i({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$h({}, state, { + [WALLET_RESTART]: state => _extends$i({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$h({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$i({}, state, { walletReconnecting: false }) }, defaultState$9); @@ -6808,14 +6809,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$i = 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; }; +var _extends$j = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$i({ + return _extends$j({ id }, params); } diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 5fd9baa..896ec69 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -1,7 +1,11 @@ import * as ACTIONS from 'constants/action_types'; import Lbry from 'lbry'; import { doToast } from 'redux/actions/notifications'; -import { selectBalance, selectPendingSupportTransactions, selectTxoPageParams } from 'redux/selectors/wallet'; +import { + selectBalance, + selectPendingSupportTransactions, + selectTxoPageParams, +} from 'redux/selectors/wallet'; import { creditsToString } from 'util/format-credits'; import { selectMyClaimsRaw } from 'redux/selectors/claims'; import { doFetchChannelListMine, doFetchClaimListMine } from 'redux/actions/claims'; @@ -98,7 +102,7 @@ export function doFetchTxoPage() { }; } -export function doUpdateTxoPageParams(params: TxoListParams) { +export function doUpdateTxoPageParams(params) { return dispatch => { dispatch({ type: ACTIONS.UPDATE_TXO_FETCH_PARAMS, @@ -236,16 +240,16 @@ export function doSetDraftTransactionAddress(address) { }; } -export function doSendTip(amount, claimId, isSupport, successCallback, errorCallback) { +export function doSendTip(params, isSupport, successCallback, errorCallback) { return (dispatch, getState) => { const state = getState(); const balance = selectBalance(state); const myClaims = selectMyClaimsRaw(state); const shouldSupport = - isSupport || (myClaims ? myClaims.find(claim => claim.claim_id === claimId) : false); + isSupport || (myClaims ? myClaims.find(claim => claim.claim_id === params.claim_id) : false); - if (balance - amount <= 0) { + if (balance - params.amount <= 0) { dispatch( doToast({ message: __('Insufficient credits'), @@ -259,8 +263,8 @@ export function doSendTip(amount, claimId, isSupport, successCallback, errorCall dispatch( doToast({ message: shouldSupport - ? __('You deposited %amount% LBC as a support!', { amount }) - : __('You sent %amount% LBC as a tip, Mahalo!', { amount }), + ? __('You deposited %amount% LBC as a support!', { amount: params.amount }) + : __('You sent %amount% LBC as a tip, Mahalo!', { amount: params.amount }), linkText: __('History'), linkTarget: __('/wallet'), }) @@ -300,10 +304,10 @@ export function doSendTip(amount, claimId, isSupport, successCallback, errorCall }); Lbry.support_create({ - claim_id: claimId, - amount: creditsToString(amount), + ...params, tip: !shouldSupport, blocking: true, + amount: creditsToString(params.amount), }).then(success, error); }; } @@ -380,7 +384,7 @@ export function doWalletLock() { }; } -export function doSupportAbandonForClaim(claimId, claimType, keep, preview) { +export function doSupportAbandonForClaim(claimId, claimType, keep, preview) { return dispatch => { if (preview) { dispatch({ @@ -392,27 +396,26 @@ export function doSupportAbandonForClaim(claimId, claimType, keep, preview) { }); } - const params = {claim_id: claimId}; + const params = { claim_id: claimId }; if (preview) params['preview'] = true; if (keep) params['keep'] = keep; - return ( - Lbry.support_abandon(params) - .then((res) => { - if (!preview) { - dispatch({ - type: ACTIONS.ABANDON_CLAIM_SUPPORT_COMPLETED, - data: { claimId, txid: res.txid, effective: res.outputs[0].amount, type: claimType}, // add to pendingSupportTransactions, - }); - dispatch(doCheckPendingTxs()); - } - return res; - }) - .catch(e => { + return Lbry.support_abandon(params) + .then(res => { + if (!preview) { dispatch({ - type: ACTIONS.ABANDON_CLAIM_SUPPORT_FAILED, - data: e.message, + type: ACTIONS.ABANDON_CLAIM_SUPPORT_COMPLETED, + data: { claimId, txid: res.txid, effective: res.outputs[0].amount, type: claimType }, // add to pendingSupportTransactions, }); - })); + dispatch(doCheckPendingTxs()); + } + return res; + }) + .catch(e => { + dispatch({ + type: ACTIONS.ABANDON_CLAIM_SUPPORT_FAILED, + data: e.message, + }); + }); }; } @@ -469,7 +472,6 @@ export function doWalletStatus() { }; } - export function doSetTransactionListFilter(filterOption) { return { type: ACTIONS.SET_TRANSACTION_LIST_FILTER, @@ -490,10 +492,7 @@ export function doUpdateBlockHeight() { } // Calls transaction_show on txes until any pending txes are confirmed -export const doCheckPendingTxs = () => ( - dispatch, - getState -) => { +export const doCheckPendingTxs = () => (dispatch, getState) => { const state = getState(); const pendingTxsById = selectPendingSupportTransactions(state); // {} if (!Object.keys(pendingTxsById).length) { @@ -508,35 +507,37 @@ export const doCheckPendingTxs = () => ( const types = new Set([]); let changed = false; Object.entries(pendingTxs).forEach(([claim, data]) => { - promises.push(Lbry.transaction_show({txid: data.txid})); + promises.push(Lbry.transaction_show({ txid: data.txid })); types.add(data.type); }); - Promise.all(promises).then(txShows => { - txShows.forEach(result => { - if (result.height <= 0) { - const entries = Object.entries(pendingTxs); - const match = entries.find((entry) => entry[1].txid === result.txid); - newPendingTxes[match[0]] = match[1]; - } else { - changed = true; - } - }); - }).then(() => { - if (changed) { - dispatch({ - type: ACTIONS.PENDING_SUPPORTS_UPDATED, - data: newPendingTxes, + Promise.all(promises) + .then(txShows => { + txShows.forEach(result => { + if (result.height <= 0) { + const entries = Object.entries(pendingTxs); + const match = entries.find(entry => entry[1].txid === result.txid); + newPendingTxes[match[0]] = match[1]; + } else { + changed = true; + } }); - if (types.has('channel')) { - dispatch(doFetchChannelListMine()); + }) + .then(() => { + if (changed) { + dispatch({ + type: ACTIONS.PENDING_SUPPORTS_UPDATED, + data: newPendingTxes, + }); + if (types.has('channel')) { + dispatch(doFetchChannelListMine()); + } + if (types.has('stream')) { + dispatch(doFetchClaimListMine()); + } } - if (types.has('stream')) { - dispatch(doFetchClaimListMine()); - } - } - if (Object.keys(newPendingTxes).length === 0) clearInterval(txCheckInterval); - }); + if (Object.keys(newPendingTxes).length === 0) clearInterval(txCheckInterval); + }); if (!Object.keys(pendingTxsById).length) { clearInterval(txCheckInterval); -- 2.45.2 From c9492522431bade4a23bd9e9bf64a1ddf890fc97 Mon Sep 17 00:00:00 2001 From: TigerxWood Date: Wed, 17 Jun 2020 01:03:29 +0300 Subject: [PATCH 350/371] Update string for translation --- src/redux/actions/wallet.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index 896ec69..a554590 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -169,8 +169,8 @@ export function doSendDraftTransaction(address, amount) { if (balance - amount <= 0) { dispatch( doToast({ - title: 'Insufficient credits', - message: 'Insufficient credits', + title: __('Insufficient credits'), + message: __('Insufficient credits'), }) ); return; @@ -187,8 +187,8 @@ export function doSendDraftTransaction(address, amount) { }); dispatch( doToast({ - message: `You sent ${amount} LBC`, - linkText: 'History', + message: __('You sent ${amount} LBC'), + linkText: __('History'), linkTarget: '/wallet', }) ); @@ -199,7 +199,7 @@ export function doSendDraftTransaction(address, amount) { }); dispatch( doToast({ - message: 'Transaction failed', + message: __('Transaction failed'), isError: true, }) ); @@ -213,7 +213,7 @@ export function doSendDraftTransaction(address, amount) { }); dispatch( doToast({ - message: 'Transaction failed', + message: __('Transaction failed'), isError: true, }) ); @@ -266,7 +266,7 @@ export function doSendTip(params, isSupport, successCallback, errorCallback) { ? __('You deposited %amount% LBC as a support!', { amount: params.amount }) : __('You sent %amount% LBC as a tip, Mahalo!', { amount: params.amount }), linkText: __('History'), - linkTarget: __('/wallet'), + linkTarget: '/wallet', }) ); -- 2.45.2 From b32f6d0ddccbd458226d78427a64b77ded44ee2a Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 16 Jun 2020 21:56:51 -0400 Subject: [PATCH 351/371] support pending channels --- dist/bundle.es.js | 588 +++++++++++++++++----------------- dist/flow-typed/Claim.js | 2 +- flow-typed/Claim.js | 2 +- src/index.js | 6 +- src/redux/actions/claims.js | 63 +++- src/redux/actions/publish.js | 44 --- src/redux/reducers/claims.js | 165 +++++----- src/redux/selectors/claims.js | 75 ++--- src/util/merge-claim.js | 7 + 9 files changed, 469 insertions(+), 483 deletions(-) create mode 100644 src/util/merge-claim.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 171bd30..3da1f70 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2180,8 +2180,7 @@ const selectRepostLoading = reselect.createSelector(selectState$2, state => stat const selectRepostError = reselect.createSelector(selectState$2, state => state.repostError); -const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { - const byUri = state.claimsByUri || {}; +const selectClaimsByUri = reselect.createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => { const claims = {}; Object.keys(byUri).forEach(uri => { @@ -2202,52 +2201,32 @@ const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsByI const selectAllClaimsByChannel = reselect.createSelector(selectState$2, state => state.paginatedClaimsByChannel || {}); -const selectPendingById = reselect.createSelector(selectState$2, state => state.pendingById || {}); +const selectPendingIds = reselect.createSelector(selectState$2, state => state.pendingIds || []); -const selectPendingClaims = reselect.createSelector(selectState$2, state => Object.values(state.pendingById || [])); - -const makeSelectClaimIsPending = uri => reselect.createSelector(selectPendingById, pendingById => { - let claimId; - - try { - const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); - claimId = isChannel ? channelClaimId : streamClaimId; - } catch (e) {} +const makeSelectClaimIsPending = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingIds, (idsByUri, pendingIds) => { + const claimId = idsByUri(normalizeURI(uri)); if (claimId) { - return Boolean(pendingById[claimId]); + return pendingIds.some(i => i === claimId); } + return false; }); -const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, pendingById => { - const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); - const claimId = isChannel ? channelClaimId : streamClaimId; - return pendingById[claimId]; -}); const selectReflectingById = reselect.createSelector(selectState$2, state => state.reflectingById); -const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => { - // Check if a claim is pending first - // It won't be in claimsByUri because resolving it will return nothing - - let valid; +const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => { + let validUri; let channelClaimId; let streamClaimId; let isChannel; try { ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); - valid = true; + validUri = true; } catch (e) {} - if (valid && byUri) { - const claimId = isChannel ? channelClaimId : streamClaimId; - const pendingClaim = pendingById[claimId]; - - if (pendingClaim) { - return pendingClaim; - } - - const claim = byUri[normalizeURI(uri)]; + if (validUri && byUri) { + const claimId = uri && byUri[normalizeURI(uri)]; + const claim = byId[claimId]; if (claim === undefined || claim === null) { // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) return claim; @@ -2416,7 +2395,7 @@ const selectMyClaimsPageItemCount = reselect.createSelector(selectState$2, state const selectFetchingMyClaimsPageError = reselect.createSelector(selectState$2, state => state.fetchingClaimListMinePageError); -const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, (myClaimIds, byId, abandoningIds, pendingClaims) => { +const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, (myClaimIds, byId, abandoningIds) => { const claims = []; myClaimIds.forEach(id => { @@ -2425,7 +2404,7 @@ const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaim if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); }); - return [...claims, ...pendingClaims]; + return [...claims]; }); const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp)); @@ -2444,6 +2423,8 @@ const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsW }); }); +const selectMyChannelUrls = reselect.createSelector(selectState$2, state => state.myChannelUrls); + const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); const selectMyClaimsOutpoints = reselect.createSelector(selectMyClaims, myClaims => { @@ -3506,7 +3487,7 @@ function doFetchClaimsByChannel(uri, page = 1) { }; } -function doCreateChannel(name, amount, optionalParams) { +function doCreateChannel(name, amount, optionalParams, cb) { return dispatch => { dispatch({ type: CREATE_CHANNEL_STARTED @@ -3551,6 +3532,11 @@ function doCreateChannel(name, amount, optionalParams) { type: CREATE_CHANNEL_COMPLETED, data: { channelClaim } }); + dispatch({ + type: UPDATE_PENDING_CLAIMS, + data: [channelClaim] + }); + dispatch(doCheckPendingClaims(cb)); return channelClaim; }).catch(error => { dispatch({ @@ -3562,7 +3548,7 @@ function doCreateChannel(name, amount, optionalParams) { }; } -function doUpdateChannel(params) { +function doUpdateChannel(params, cb) { return (dispatch, getState) => { dispatch({ type: UPDATE_CHANNEL_STARTED @@ -3607,7 +3593,14 @@ function doUpdateChannel(params) { type: UPDATE_CHANNEL_COMPLETED, data: { channelClaim } }); - }).catch(error => { + dispatch({ + type: UPDATE_PENDING_CLAIMS, + data: { + claims: [channelClaim] + } + }); + dispatch(doCheckPendingClaims(cb)); + }).then().catch(error => { dispatch({ type: UPDATE_CHANNEL_FAILED, data: error @@ -3803,6 +3796,46 @@ function doPurchaseList(page = 1, pageSize = PAGE_SIZE) { }; } +const doCheckPendingClaims = onConfirmed => (dispatch, getState) => { + let claimCheckInterval; + + const checkClaimList = () => { + const state = getState(); + const pendingIdSet = new Set(selectPendingIds(state)); + lbryProxy.claim_list({ page: 1, page_size: 10 }).then(result => { + const claims = result.items; + const claimsToConfirm = []; + claims.forEach(claim => { + const { claim_id: claimId } = claim; + if (claim.confirmations > 0 && pendingIdSet.has(claimId)) { + pendingIdSet.delete(claimId); + claimsToConfirm.push(claim); + if (onConfirmed) { + onConfirmed(claim); + } + } + }); + if (claimsToConfirm.length) { + dispatch({ + type: UPDATE_CONFIRMED_CLAIMS, + data: { + claims: claimsToConfirm + } + }); + } + return pendingIdSet.size; + }).then(len => { + if (!len) { + clearInterval(claimCheckInterval); + } + }); + }; + + claimCheckInterval = setInterval(() => { + checkClaimList(); + }, 30000); +}; + const selectState$3 = state => state.fileInfo || {}; const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); @@ -4588,44 +4621,6 @@ const doCheckReflectingFiles = () => (dispatch, getState) => { }, 5000); } }; -const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { - let publishCheckInterval; - - const checkFileList = () => { - const state = getState(); - const pendingById = selectPendingById(state); - lbryProxy.claim_list({ page: 1, page_size: 10 }).then(result => { - const claims = result.items; - const claimsToConfirm = []; - claims.forEach(claim => { - if (claim.confirmations > 0 && pendingById[claim.claim_id]) { - delete pendingById[claim.claim_id]; - claimsToConfirm.push(claim); - if (onConfirmed) { - onConfirmed(claim); - } - } - }); - if (claimsToConfirm.length) { - dispatch({ - type: UPDATE_CONFIRMED_CLAIMS, - data: { - claims: claimsToConfirm - } - }); - } - return Object.keys(pendingById).length; - }).then(len => { - if (!len) { - clearInterval(publishCheckInterval); - } - }); - }; - - publishCheckInterval = setInterval(() => { - checkFileList(); - }, 30000); -}; // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for @@ -5112,6 +5107,16 @@ const doToggleBlockChannel = uri => ({ var _extends$a = 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; }; +/* +new claim = { ...maybeResolvedClaim, ...pendingClaim, meta: maybeResolvedClaim['meta'] } + */ + +function mergeClaims(maybeResolved, pending) { + return _extends$a({}, maybeResolved, pending, { meta: maybeResolved.meta }); +} + +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$3(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 reducers = {}; @@ -5123,6 +5128,7 @@ const defaultState = { fetchingChannelClaims: {}, resolvingUris: [], myChannelClaims: undefined, + myChannelUrls: undefined, myClaims: undefined, myPurchases: undefined, myPurchasesPageNumber: undefined, @@ -5132,7 +5138,7 @@ const defaultState = { fetchingMyPurchasesError: undefined, fetchingMyChannels: false, abandoningById: {}, - pendingById: {}, + pendingIds: [], reflectingById: {}, claimSearchError: false, claimSearchByQuery: {}, @@ -5163,18 +5169,19 @@ function handleClaimAction(state, action) { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + const pendingIds = state.pendingIds; let newResolvingUrls = new Set(state.resolvingUris); Object.entries(resolveInfo).forEach(([url, resolveResponse]) => { // $FlowFixMe const { claimsInChannel, stream, channel } = resolveResponse; - if (claimsInChannel) { - channelClaimCounts[url] = claimsInChannel; - channelClaimCounts[channel.canonical_url] = claimsInChannel; - } if (stream) { - byId[stream.claim_id] = stream; + if (pendingIds.includes(stream.claim_id)) { + byId[stream.claim_id] = mergeClaims(stream, byId[stream.claim_id]); // merge them + } else { + byId[stream.claim_id] = stream; + } byUri[url] = stream.claim_id; // If url isn't a canonical_url, make sure that is added too @@ -5186,12 +5193,18 @@ function handleClaimAction(state, action) { newResolvingUrls.delete(stream.permanent_url); } - if (channel) { - if (!stream) { - byUri[url] = channel.claim_id; + if (channel && channel.claim_id) { + if (claimsInChannel) { + channelClaimCounts[url] = claimsInChannel; + channelClaimCounts[channel.canonical_url] = claimsInChannel; } + byUri[url] = channel.claim_id; - byId[channel.claim_id] = channel; + if (pendingIds.includes(channel.claim_id)) { + byId[channel.claim_id] = mergeClaims(channel, byId[channel.claim_id]); + } else { + byId[channel.claim_id] = channel; + } // Also add the permanent_url here until lighthouse returns canonical_url for search results byUri[channel.permanent_url] = channel.claim_id; byUri[channel.canonical_url] = channel.claim_id; @@ -5231,7 +5244,7 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$a({}, handleClaimAction(state, action)); + return _extends$b({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -5246,46 +5259,37 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById = Object.assign({}, state.pendingById); + const pendingIds = state.pendingIds || []; let myClaimIds = new Set(state.myClaims); let urlsForCurrentPage = []; + const pendingIdSet = new Set(pendingIds); + claims.forEach(claim => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; + const { permanent_url: permanentUri, claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { - urlsForCurrentPage.push(uri); + urlsForCurrentPage.push(permanentUri); if (claim.confirmations < 1) { - pendingById[claimId] = claim; - delete byId[claimId]; - delete byUri[claimId]; + pendingIdSet.add(claimId); + } else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) { + pendingIdSet.delete(claimId); + } + if (pendingIds.includes(claimId)) { + byId[claimId] = mergeClaims(claim, byId[claimId]); } else { - byId[claimId] = claim; - byUri[uri] = claimId; + byId[claimId] = claim; // just add } + byUri[permanentUri] = claimId; myClaimIds.add(claimId); - if (!resolve && pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } } }); - // Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0) - if (!resolve) { - Object.values(pendingById) - // $FlowFixMe - .filter(pendingClaim => byId[pendingClaim.claim_id]).forEach(pendingClaim => { - // $FlowFixMe - delete pendingById[pendingClaim.claim_id]; - }); - } - return Object.assign({}, state, { isFetchingClaimListMine: false, myClaims: Array.from(myClaimIds), byId, + pendingIds: Array.from(pendingIdSet), claimsByUri: byUri, - pendingById, myClaimsPageResults: urlsForCurrentPage, myClaimsPageNumber: page, myClaimsPageTotalResults: totalItems @@ -5298,8 +5302,9 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { const { claims } = action.data; const myClaims = state.myClaims || []; let myClaimIds = new Set(state.myClaims); - const pendingById = Object.assign(state.pendingById); + const pendingIds = state.pendingIds || []; let myChannelClaims; + let myChannelUrls = []; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); @@ -5307,8 +5312,10 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { if (!claims.length) { // $FlowFixMe myChannelClaims = null; + myChannelUrls = null; } else { myChannelClaims = new Set(state.myChannelClaims); + myChannelUrls = []; claims.forEach(claim => { const { claims_in_channel: claimsInChannel } = claim.meta; const { canonical_url: canonicalUrl, permanent_url: permanentUrl, claim_id: claimId } = claim; @@ -5320,18 +5327,11 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { // $FlowFixMe myChannelClaims.add(claimId); - if (!byId[claimId]) { + if (!pendingIds.some(c => c === claimId)) { byId[claimId] = claim; } - + myChannelUrls.push(permanentUrl); myClaimIds.add(claimId); - if (pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } - - if (pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } }); } @@ -5341,7 +5341,8 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { channelClaimCounts, fetchingMyChannels: false, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, - myClaims: Array.from(myClaimIds) + myClaims: myClaimIds ? Array.from(myClaimIds) : null, + myChannelUrls }); }; @@ -5423,19 +5424,31 @@ reducers[ABANDON_CLAIM_STARTED] = (state, action) => { }; reducers[UPDATE_PENDING_CLAIMS] = (state, action) => { - const { claims } = action.data; + const { claims: pendingClaims } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById = Object.assign({}, state.pendingById); + const pendingIds = state.pendingIds; + const pendingIdSet = new Set(pendingIds); let myClaimIds = new Set(state.myClaims); + const myChannelClaims = new Set(state.myChannelClaims); // $FlowFixMe - claims.forEach(claim => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; - if (claim.type && claim.type.match(/claim|update/)) { - pendingById[claimId] = claim; - delete byId[claimId]; + pendingClaims.forEach(claim => { + let newClaim; + const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim; + pendingIdSet.add(claimId); + const oldClaim = byId[claimId]; + if (oldClaim && oldClaim.canonical_url) { + newClaim = mergeClaims(oldClaim, claim); + } else { + newClaim = claim; + } + if (valueType === 'channel') { + myChannelClaims.add(claimId); + } + + if (type && type.match(/claim|update/)) { + byId[claimId] = newClaim; byUri[uri] = claimId; } myClaimIds.add(claimId); @@ -5443,32 +5456,35 @@ reducers[UPDATE_PENDING_CLAIMS] = (state, action) => { return Object.assign({}, state, { myClaims: Array.from(myClaimIds), byId, + myChannelClaims: Array.from(myChannelClaims), claimsByUri: byUri, - pendingById + pendingIds: Array.from(pendingIdSet) }); }; reducers[UPDATE_CONFIRMED_CLAIMS] = (state, action) => { - const { claims } = action.data; + const { claims: confirmedClaims } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById = Object.assign({}, state.pendingById); - let myClaimIds = new Set(state.myClaims); + const pendingIds = state.pendingIds; + const pendingIdSet = new Set(pendingIds); - claims.forEach(claim => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; - if (claim.type && claim.type.match(/claim|update/)) { - delete pendingById[claimId]; - byId[claimId] = claim; + confirmedClaims.forEach(claim => { + const { permanent_url: permanentUri, claim_id: claimId, type } = claim; + let newClaim = claim; + const oldClaim = byId[claimId]; + if (oldClaim && oldClaim.canonical_url) { + newClaim = mergeClaims(oldClaim, claim); + } + if (type && type.match(/claim|update|channel/)) { + byId[claimId] = newClaim; + pendingIdSet.delete(claimId); } - myClaimIds.add(claimId); }); return Object.assign({}, state, { - myClaims: Array.from(myClaimIds), + pendingIds: Array.from(pendingIdSet), byId, - claimsByUri: byUri, - pendingById + claimsByUri: byUri }); }; @@ -5497,25 +5513,13 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; -reducers[CREATE_CHANNEL_STARTED] = state => _extends$a({}, state, { +reducers[CREATE_CHANNEL_STARTED] = state => _extends$b({}, state, { creatingChannel: true, createChannelError: null }); reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { - const channelClaim = action.data.channelClaim; - const byId = Object.assign({}, state.byId); - const pendingById = Object.assign({}, state.pendingById); - const myChannelClaims = new Set(state.myChannelClaims); - - byId[channelClaim.claim_id] = channelClaim; - pendingById[channelClaim.claim_id] = channelClaim; - myChannelClaims.add(channelClaim.claim_id); - return Object.assign({}, state, { - byId, - pendingById, - myChannelClaims: Array.from(myChannelClaims), creatingChannel: false }); }; @@ -5535,13 +5539,7 @@ reducers[UPDATE_CHANNEL_STARTED] = (state, action) => { }; reducers[UPDATE_CHANNEL_COMPLETED] = (state, action) => { - const channelClaim = action.data.channelClaim; - const byId = Object.assign({}, state.byId); - - byId[channelClaim.claim_id] = channelClaim; - return Object.assign({}, state, { - byId, updateChannelError: '', updatingChannel: false }); @@ -5585,7 +5583,7 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { delete fetchingClaimSearchByQuery[query]; - return Object.assign({}, state, _extends$a({}, handleClaimAction(state, action), { + return Object.assign({}, state, _extends$b({}, handleClaimAction(state, action), { claimSearchByQuery, claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery @@ -5607,22 +5605,22 @@ reducers[CLAIM_SEARCH_FAILED] = (state, action) => { }; reducers[CLAIM_REPOST_STARTED] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { repostLoading: true, repostError: null }); }; reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { const { originalClaimId, repostClaim } = action.data; - const byId = _extends$a({}, state.byId); - const claimsByUri = _extends$a({}, state.claimsByUri); + const byId = _extends$b({}, state.byId); + const claimsByUri = _extends$b({}, state.claimsByUri); const claimThatWasReposted = byId[originalClaimId]; - const repostStub = _extends$a({}, repostClaim, { reposted_claim: claimThatWasReposted }); + const repostStub = _extends$b({}, repostClaim, { reposted_claim: claimThatWasReposted }); byId[repostStub.claim_id] = repostStub; claimsByUri[repostStub.permanent_url] = repostStub.claim_id; - return _extends$a({}, state, { + return _extends$b({}, state, { byId, claimsByUri, repostLoading: false, @@ -5632,13 +5630,13 @@ reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { reducers[CLAIM_REPOST_FAILED] = (state, action) => { const { error } = action.data; - return _extends$a({}, state, { + return _extends$b({}, state, { repostLoading: false, repostError: error }); }; reducers[CLEAR_REPOST_ERROR] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { repostError: null }); }; @@ -5649,34 +5647,34 @@ reducers[ADD_FILES_REFLECTING] = (state, action) => { reflectingById[claimId] = { fileListItem: pendingClaim, progress: 0, stalled: false }; - return Object.assign({}, state, _extends$a({}, state, { + return Object.assign({}, state, _extends$b({}, state, { reflectingById: reflectingById })); }; reducers[UPDATE_FILES_REFLECTING] = (state, action) => { const newReflectingById = action.data; - return Object.assign({}, state, _extends$a({}, state, { + return Object.assign({}, state, _extends$b({}, state, { reflectingById: newReflectingById })); }; reducers[TOGGLE_CHECKING_REFLECTING] = (state, action) => { const checkingReflecting = action.data; - return Object.assign({}, state, _extends$a({}, state, { + return Object.assign({}, state, _extends$b({}, state, { checkingReflecting })); }; reducers[TOGGLE_CHECKING_PENDING] = (state, action) => { const checking = action.data; - return Object.assign({}, state, _extends$a({}, state, { + return Object.assign({}, state, _extends$b({}, state, { checkingPending: checking })); }; reducers[PURCHASE_LIST_STARTED] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { fetchingMyPurchases: true, fetchingMyPurchasesError: null }); @@ -5721,7 +5719,7 @@ reducers[PURCHASE_LIST_COMPLETED] = (state, action) => { reducers[PURCHASE_LIST_FAILED] = (state, action) => { const { error } = action.data; - return _extends$a({}, state, { + return _extends$b({}, state, { fetchingMyPurchases: false, fetchingMyPurchasesError: error }); @@ -5742,7 +5740,7 @@ reducers[PURCHASE_URI_COMPLETED] = (state, action) => { myPurchases.push(uri); - return _extends$a({}, state, { + return _extends$b({}, state, { byId, myPurchases, purchaseUriSuccess: true @@ -5750,13 +5748,13 @@ reducers[PURCHASE_URI_COMPLETED] = (state, action) => { }; reducers[PURCHASE_URI_FAILED] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { purchaseUriSuccess: false }); }; reducers[CLEAR_PURCHASED_URI_SUCCESS] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { purchaseUriSuccess: false }); }; @@ -5785,7 +5783,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -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; }; +var _extends$c = 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; }; const defaultState$1 = { commentById: {}, // commentId -> Comment @@ -5796,11 +5794,11 @@ const defaultState$1 = { }; const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$b({}, state, { + [COMMENT_CREATE_STARTED]: (state, action) => _extends$c({}, state, { isLoading: true }), - [COMMENT_CREATE_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_CREATE_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }), @@ -5818,14 +5816,14 @@ const commentReducer = handleActions({ newCommentIds.unshift(comment.comment_id); byId[claimId] = newCommentIds; - return _extends$b({}, state, { + return _extends$c({}, state, { commentById, byId, isLoading: false }); }, - [COMMENT_LIST_STARTED]: state => _extends$b({}, state, { isLoading: true }), + [COMMENT_LIST_STARTED]: state => _extends$c({}, state, { isLoading: true }), [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; @@ -5849,7 +5847,7 @@ const commentReducer = handleActions({ byId[claimId] = commentIds; commentsByUri[uri] = claimId; } - return _extends$b({}, state, { + return _extends$c({}, state, { byId, commentById, commentsByUri, @@ -5857,10 +5855,10 @@ const commentReducer = handleActions({ }); }, - [COMMENT_LIST_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_LIST_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }), - [COMMENT_ABANDON_STARTED]: (state, action) => _extends$b({}, state, { + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$c({}, state, { isLoading: true }), [COMMENT_ABANDON_COMPLETED]: (state, action) => { @@ -5878,18 +5876,18 @@ const commentReducer = handleActions({ } delete commentById[comment_id]; - return _extends$b({}, state, { + return _extends$c({}, state, { commentById, byId, isLoading: false }); }, // do nothing - [COMMENT_ABANDON_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }), // do nothing - [COMMENT_UPDATE_STARTED]: (state, action) => _extends$b({}, state, { + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$c({}, state, { isLoading: true }), // replace existing comment with comment returned here under its comment_id @@ -5898,29 +5896,29 @@ const commentReducer = handleActions({ const commentById = Object.assign({}, state.commentById); commentById[comment.comment_id] = comment; - return _extends$b({}, state, { + return _extends$c({}, state, { commentById, isLoading: false }); }, // nothing can be done here - [COMMENT_UPDATE_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }), // nothing can really be done here - [COMMENT_HIDE_STARTED]: (state, action) => _extends$b({}, state, { + [COMMENT_HIDE_STARTED]: (state, action) => _extends$c({}, state, { isLoading: true }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$b({}, state, { // todo: add HiddenComments state & create selectors + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$c({}, state, { // todo: add HiddenComments state & create selectors isLoading: false }), // nothing can be done here - [COMMENT_HIDE_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_HIDE_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }) }, defaultState$1); -var _extends$c = 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; }; +var _extends$d = 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; }; const reducers$1 = {}; const defaultState$2 = { @@ -5929,9 +5927,9 @@ const defaultState$2 = { reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$c({}, state, { - positions: _extends$c({}, state.positions, { - [claimId]: _extends$c({}, state.positions[claimId], { + return _extends$d({}, state, { + positions: _extends$d({}, state.positions, { + [claimId]: _extends$d({}, state.positions[claimId], { [outpoint]: position }) }) @@ -6098,7 +6096,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -var _extends$d = 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; }; +var _extends$e = 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; }; const defaultState$4 = { notifications: [], @@ -6113,7 +6111,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$d({}, state, { + return _extends$e({}, state, { toasts: newToasts }); }, @@ -6121,7 +6119,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$d({}, state, { + return _extends$e({}, state, { toasts: newToasts }); }, @@ -6132,7 +6130,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications: newNotifications }); }, @@ -6143,7 +6141,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications }); }, @@ -6152,7 +6150,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications: newNotifications }); }, @@ -6163,7 +6161,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$d({}, state, { + return _extends$e({}, state, { errors: newErrors }); }, @@ -6171,13 +6169,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$d({}, state, { + return _extends$e({}, state, { errors: newErrors }); } }, defaultState$4); -var _extends$e = 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; }; +var _extends$f = 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$4(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; } @@ -6218,20 +6216,20 @@ const defaultState$5 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$e({}, state, data); + return _extends$f({}, state, data); }, - [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$5, { + [CLEAR_PUBLISH]: state => _extends$f({}, defaultState$5, { bid: state.bid, optimize: state.optimize }), - [PUBLISH_START]: state => _extends$e({}, state, { + [PUBLISH_START]: state => _extends$f({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$e({}, state, { + [PUBLISH_FAIL]: state => _extends$f({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$e({}, state, { + [PUBLISH_SUCCESS]: state => _extends$f({}, state, { publishing: false, publishSuccess: true }), @@ -6246,14 +6244,14 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$e({}, defaultState$5, publishData, { + return _extends$f({}, defaultState$5, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$5); -var _extends$f = 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; }; +var _extends$g = 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; }; const defaultState$6 = { isActive: false, // does the user have any typed text in the search input @@ -6275,23 +6273,23 @@ const defaultState$6 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$f({}, state, { + [SEARCH_START]: state => _extends$g({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$f({}, state, { + return _extends$g({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$f({}, state, { + [SEARCH_FAIL]: state => _extends$g({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$f({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$g({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -6309,24 +6307,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$f({}, state, { + return _extends$g({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$f({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$g({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$f({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$g({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$f({}, state, { - suggestions: _extends$f({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$g({}, state, { + suggestions: _extends$g({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -6334,30 +6332,30 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$f({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$g({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$f({}, state, { + [SEARCH_FOCUS]: state => _extends$g({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$f({}, state, { + [SEARCH_BLUR]: state => _extends$g({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$f({}, oldOptions, newOptions); - return _extends$f({}, state, { + const options = _extends$g({}, oldOptions, newOptions); + return _extends$g({}, state, { options }); } }, defaultState$6); -var _extends$g = 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; }; +var _extends$h = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$g({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$h({}, tagsMap, { [tag]: { name: tag } }), {}); } @@ -6380,7 +6378,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$g({}, state, { + return _extends$h({}, state, { followedTags: newFollowedTags }); }, @@ -6389,10 +6387,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$g({}, knownTags); + let newKnownTags = _extends$h({}, knownTags); newKnownTags[name] = { name }; - return _extends$g({}, state, { + return _extends$h({}, state, { knownTags: newKnownTags }); }, @@ -6401,11 +6399,11 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$g({}, knownTags); + let newKnownTags = _extends$h({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$g({}, state, { + return _extends$h({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -6413,15 +6411,15 @@ const tagsReducer = handleActions({ [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; if (Array.isArray(tags)) { - return _extends$g({}, state, { + return _extends$h({}, state, { followedTags: tags }); } - return _extends$g({}, state); + return _extends$h({}, state); } }, defaultState$7); -var _extends$h = 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; }; +var _extends$i = 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; }; const defaultState$8 = { blockedChannels: [] @@ -6445,13 +6443,13 @@ const blockedReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { blocked } = action.data; - return _extends$h({}, state, { + return _extends$i({}, state, { blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } }, defaultState$8); -var _extends$i = 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; }; +var _extends$j = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -6503,40 +6501,40 @@ const defaultState$9 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$i({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$j({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$i({}, state.transactions); + const byId = _extends$j({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$i({}, state, { + return _extends$j({}, state, { transactions: byId, fetchingTransactions: false }); }, [FETCH_TXO_PAGE_STARTED]: state => { - return _extends$i({}, state, { + return _extends$j({}, state, { fetchingTxos: true, fetchingTxosError: undefined }); }, [FETCH_TXO_PAGE_COMPLETED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { txoPage: action.data, fetchingTxos: false }); }, [FETCH_TXO_PAGE_FAILED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { txoPage: {}, fetchingTxos: false, fetchingTxosError: action.data @@ -6544,12 +6542,12 @@ const walletReducer = handleActions({ }, [UPDATE_TXO_FETCH_PARAMS]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { txoFetchParams: action.data }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$i({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$j({}, state, { fetchingSupports: true }), @@ -6562,7 +6560,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$i({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$j({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -6571,7 +6569,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$i({}, state, { + return _extends$j({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -6584,20 +6582,20 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$i({}, state, { + return _extends$j({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, [ABANDON_CLAIM_SUPPORT_STARTED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_PREVIEW]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: undefined }); }, @@ -6608,36 +6606,36 @@ const walletReducer = handleActions({ pendingtxs[claimId] = { txid, type, effective }; - return _extends$i({}, state, { + return _extends$j({}, state, { pendingSupportTransactions: pendingtxs, abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_FAILED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: action.data }); }, [PENDING_SUPPORTS_UPDATED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { pendingSupportTransactions: action.data }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$j({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$i({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$j({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$i({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$j({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -6646,32 +6644,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$i({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$j({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$i({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$j({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$i({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$j({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$i({}, state, { draftTransaction: newDraft }); + return _extends$j({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$i({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$j({}, oldDraft, { address: action.data.address }); - return _extends$i({}, state, { draftTransaction: newDraft }); + return _extends$j({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$i({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$j({}, state.draftTransaction, { sending: true }); - return _extends$i({}, state, { draftTransaction: newDraftTransaction }); + return _extends$j({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -6684,114 +6682,114 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$i({}, state, { draftTransaction: newDraftTransaction }); + return _extends$j({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$i({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$j({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$i({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$j({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$i({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$j({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$i({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$j({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$j({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$i({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$j({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$j({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$i({}, state, { + [WALLET_DECRYPT_START]: state => _extends$j({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$j({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$i({}, state, { + [WALLET_UNLOCK_START]: state => _extends$j({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$j({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$j({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$i({}, state, { + [WALLET_LOCK_START]: state => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$i({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$j({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$i({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$j({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$i({}, state, { + [WALLET_RESTART]: state => _extends$j({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$i({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$j({}, state, { walletReconnecting: false }) }, defaultState$9); @@ -6809,14 +6807,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$j = 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; }; +var _extends$k = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$j({ + return _extends$k({ id }, params); } @@ -6964,7 +6962,7 @@ exports.doAddTag = doAddTag; exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; -exports.doCheckPendingPublishes = doCheckPendingPublishes; +exports.doCheckPendingClaims = doCheckPendingClaims; exports.doCheckPublishNameAvailability = doCheckPublishNameAvailability; exports.doCheckReflectingFiles = doCheckReflectingFiles; exports.doClaimSearch = doClaimSearch; @@ -7073,7 +7071,6 @@ exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectOmittedCountForChannel = makeSelectOmittedCountForChannel; exports.makeSelectPendingAmountByUri = makeSelectPendingAmountByUri; -exports.makeSelectPendingByUri = makeSelectPendingByUri; exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; @@ -7165,6 +7162,7 @@ exports.selectIsStillEditing = selectIsStillEditing; exports.selectIsWalletReconnecting = selectIsWalletReconnecting; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; +exports.selectMyChannelUrls = selectMyChannelUrls; exports.selectMyClaimForUri = selectMyClaimForUri; exports.selectMyClaimUrisWithoutChannels = selectMyClaimUrisWithoutChannels; exports.selectMyClaims = selectMyClaims; @@ -7177,8 +7175,6 @@ exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; exports.selectMyPurchases = selectMyPurchases; exports.selectMyPurchasesCount = selectMyPurchasesCount; exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount; -exports.selectPendingById = selectPendingById; -exports.selectPendingClaims = selectPendingClaims; exports.selectPendingSupportTransactions = selectPendingSupportTransactions; exports.selectPlayingUri = selectPlayingUri; exports.selectPublishFormValues = selectPublishFormValues; diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index c9732bd..0b97c0e 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -22,7 +22,7 @@ declare type GenericClaim = { timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed is_channel_signature_valid?: boolean, - is_my_output: true, + is_my_output: boolean, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index c9732bd..0b97c0e 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -22,7 +22,7 @@ declare type GenericClaim = { timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed is_channel_signature_valid?: boolean, - is_my_output: true, + is_my_output: boolean, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx diff --git a/src/index.js b/src/index.js index 76f5ed6..dcec873 100644 --- a/src/index.js +++ b/src/index.js @@ -76,6 +76,7 @@ export { doClearRepostError, doCheckPublishNameAvailability, doPurchaseList, + doCheckPendingClaims, } from 'redux/actions/claims'; export { doClearPurchasedUriSuccess, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -94,7 +95,6 @@ export { doUploadThumbnail, doPrepareEdit, doPublish, - doCheckPendingPublishes, doCheckReflectingFiles, } from 'redux/actions/publish'; @@ -198,7 +198,6 @@ export { makeSelectFirstRecommendedFileForUri, makeSelectChannelForClaimUri, makeSelectClaimIsPending, - makeSelectPendingByUri, makeSelectReflectingClaimForUri, makeSelectClaimsInChannelForCurrentPageState, makeSelectShortUrlForUri, @@ -207,7 +206,6 @@ export { makeSelectSupportsForUri, makeSelectMyPurchasesForPage, makeSelectClaimWasPurchased, - selectPendingById, selectReflectingById, selectClaimsById, selectClaimsByUri, @@ -217,9 +215,9 @@ export { selectMyActiveClaims, selectAllFetchingChannelClaims, selectIsFetchingClaimListMine, - selectPendingClaims, selectMyClaims, selectMyClaimsWithoutChannels, + selectMyChannelUrls, selectMyClaimUrisWithoutChannels, selectAllMyClaimsByOutpoint, selectMyClaimsOutpoints, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 56a4baf..91039ea 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -9,6 +9,7 @@ import { selectResolvingUris, selectClaimsByUri, selectMyChannelClaims, + selectPendingIds, } from 'redux/selectors/claims'; import { doFetchTxoPage } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; @@ -338,7 +339,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { }; } -export function doCreateChannel(name: string, amount: number, optionalParams: any) { +export function doCreateChannel(name: string, amount: number, optionalParams: any, cb: any) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CREATE_CHANNEL_STARTED, @@ -395,6 +396,11 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an type: ACTIONS.CREATE_CHANNEL_COMPLETED, data: { channelClaim }, }); + dispatch({ + type: ACTIONS.UPDATE_PENDING_CLAIMS, + data: [channelClaim], + }); + dispatch(doCheckPendingClaims(cb)); return channelClaim; }) .catch(error => { @@ -408,7 +414,7 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an }; } -export function doUpdateChannel(params: any) { +export function doUpdateChannel(params: any, cb: any) { return (dispatch: Dispatch, getState: GetState) => { dispatch({ type: ACTIONS.UPDATE_CHANNEL_STARTED, @@ -454,7 +460,15 @@ export function doUpdateChannel(params: any) { type: ACTIONS.UPDATE_CHANNEL_COMPLETED, data: { channelClaim }, }); + dispatch({ + type: ACTIONS.UPDATE_PENDING_CLAIMS, + data: { + claims: [channelClaim], + }, + }); + dispatch(doCheckPendingClaims(cb)); }) + .then() .catch(error => { dispatch({ type: ACTIONS.UPDATE_CHANNEL_FAILED, @@ -669,3 +683,48 @@ export function doPurchaseList(page: number = 1, pageSize: number = PAGE_SIZE) { }).then(success, failure); }; } + +export const doCheckPendingClaims = (onConfirmed: Function) => ( + dispatch: Dispatch, + getState: GetState +) => { + let claimCheckInterval; + + const checkClaimList = () => { + const state = getState(); + const pendingIdSet = new Set(selectPendingIds(state)); + Lbry.claim_list({ page: 1, page_size: 10 }) + .then(result => { + const claims = result.items; + const claimsToConfirm = []; + claims.forEach(claim => { + const { claim_id: claimId } = claim; + if (claim.confirmations > 0 && pendingIdSet.has(claimId)) { + pendingIdSet.delete(claimId); + claimsToConfirm.push(claim); + if (onConfirmed) { + onConfirmed(claim); + } + } + }); + if (claimsToConfirm.length) { + dispatch({ + type: ACTIONS.UPDATE_CONFIRMED_CLAIMS, + data: { + claims: claimsToConfirm, + }, + }); + } + return pendingIdSet.size; + }) + .then(len => { + if (!len) { + clearInterval(claimCheckInterval); + } + }); + }; + + claimCheckInterval = setInterval(() => { + checkClaimList(); + }, 30000); +}; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 23d6d74..c977640 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -10,7 +10,6 @@ import { doError } from 'redux/actions/notifications'; import { isClaimNsfw } from 'util/claim'; import { selectMyChannelClaims, - selectPendingById, selectMyClaimsWithoutChannels, selectReflectingById, } from 'redux/selectors/claims'; @@ -427,46 +426,3 @@ export const doCheckReflectingFiles = () => (dispatch: Dispatch, getState: GetSt }, 5000); } }; -export const doCheckPendingPublishes = (onConfirmed: Function) => ( - dispatch: Dispatch, - getState: GetState -) => { - let publishCheckInterval; - - const checkFileList = () => { - const state = getState(); - const pendingById = selectPendingById(state); - Lbry.claim_list({ page: 1, page_size: 10 }) - .then(result => { - const claims = result.items; - const claimsToConfirm = []; - claims.forEach(claim => { - if (claim.confirmations > 0 && pendingById[claim.claim_id]) { - delete pendingById[claim.claim_id]; - claimsToConfirm.push(claim); - if (onConfirmed) { - onConfirmed(claim); - } - } - }); - if (claimsToConfirm.length) { - dispatch({ - type: ACTIONS.UPDATE_CONFIRMED_CLAIMS, - data: { - claims: claimsToConfirm, - }, - }); - } - return Object.keys(pendingById).length; - }) - .then(len => { - if (!len) { - clearInterval(publishCheckInterval); - } - }); - }; - - publishCheckInterval = setInterval(() => { - checkFileList(); - }, 30000); -}; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index d74ffd1..99a4e4a 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -9,7 +9,7 @@ // - Sean import * as ACTIONS from 'constants/action_types'; -import { buildURI, parseURI } from 'lbryURI'; +import mergeClaim from 'util/merge-claim'; type State = { createChannelError: ?string, @@ -17,10 +17,11 @@ type State = { claimsByUri: { [string]: string }, byId: { [string]: Claim }, resolvingUris: Array, - pendingById: { [string]: Claim }, + pendingIds: Array, reflectingById: { [string]: ReflectingUpdate }, myClaims: ?Array, myChannelClaims: ?Array, + myChannelUrls: ?Array, abandoningById: { [string]: boolean }, fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, @@ -66,6 +67,7 @@ const defaultState = { fetchingChannelClaims: {}, resolvingUris: [], myChannelClaims: undefined, + myChannelUrls: undefined, myClaims: undefined, myPurchases: undefined, myPurchasesPageNumber: undefined, @@ -75,7 +77,7 @@ const defaultState = { fetchingMyPurchasesError: undefined, fetchingMyChannels: false, abandoningById: {}, - pendingById: {}, + pendingIds: [], reflectingById: {}, claimSearchError: false, claimSearchByQuery: {}, @@ -112,18 +114,19 @@ function handleClaimAction(state: State, action: any): State { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + const pendingIds = state.pendingIds; let newResolvingUrls = new Set(state.resolvingUris); Object.entries(resolveInfo).forEach(([url: string, resolveResponse: ResolveResponse]) => { // $FlowFixMe const { claimsInChannel, stream, channel } = resolveResponse; - if (claimsInChannel) { - channelClaimCounts[url] = claimsInChannel; - channelClaimCounts[channel.canonical_url] = claimsInChannel; - } if (stream) { - byId[stream.claim_id] = stream; + if (pendingIds.includes(stream.claim_id)) { + byId[stream.claim_id] = mergeClaim(stream, byId[stream.claim_id]);// merge them + } else { + byId[stream.claim_id] = stream; + } byUri[url] = stream.claim_id; // If url isn't a canonical_url, make sure that is added too @@ -135,12 +138,18 @@ function handleClaimAction(state: State, action: any): State { newResolvingUrls.delete(stream.permanent_url); } - if (channel) { - if (!stream) { - byUri[url] = channel.claim_id; + if (channel && channel.claim_id) { + if (claimsInChannel) { + channelClaimCounts[url] = claimsInChannel; + channelClaimCounts[channel.canonical_url] = claimsInChannel; } + byUri[url] = channel.claim_id; - byId[channel.claim_id] = channel; + if (pendingIds.includes(channel.claim_id)) { + byId[channel.claim_id] = mergeClaim(channel, byId[channel.claim_id]); + } else { + byId[channel.claim_id] = channel; + } // Also add the permanent_url here until lighthouse returns canonical_url for search results byUri[channel.permanent_url] = channel.claim_id; byUri[channel.canonical_url] = channel.claim_id; @@ -198,47 +207,37 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); + const pendingIds = state.pendingIds || []; let myClaimIds = new Set(state.myClaims); let urlsForCurrentPage = []; + const pendingIdSet = new Set(pendingIds); + claims.forEach((claim: Claim) => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; + const { permanent_url: permanentUri, claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { - urlsForCurrentPage.push(uri); + urlsForCurrentPage.push(permanentUri); if (claim.confirmations < 1) { - pendingById[claimId] = claim; - delete byId[claimId]; - delete byUri[claimId]; + pendingIdSet.add(claimId); + } else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) { + pendingIdSet.delete(claimId); + } + if (pendingIds.includes(claimId)) { + byId[claimId] = mergeClaim(claim, byId[claimId]); } else { - byId[claimId] = claim; - byUri[uri] = claimId; + byId[claimId] = claim;// just add } + byUri[permanentUri] = claimId; myClaimIds.add(claimId); - if (!resolve && pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } } }); - // Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0) - if (!resolve) { - Object.values(pendingById) - // $FlowFixMe - .filter(pendingClaim => byId[pendingClaim.claim_id]) - .forEach(pendingClaim => { - // $FlowFixMe - delete pendingById[pendingClaim.claim_id]; - }); - } - return Object.assign({}, state, { isFetchingClaimListMine: false, myClaims: Array.from(myClaimIds), byId, + pendingIds: Array.from(pendingIdSet), claimsByUri: byUri, - pendingById, myClaimsPageResults: urlsForCurrentPage, myClaimsPageNumber: page, myClaimsPageTotalResults: totalItems, @@ -252,8 +251,9 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St const { claims }: { claims: Array } = action.data; const myClaims = state.myClaims || []; let myClaimIds = new Set(state.myClaims); - const pendingById = Object.assign(state.pendingById); + const pendingIds = state.pendingIds || []; let myChannelClaims; + let myChannelUrls = []; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); @@ -261,8 +261,10 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St if (!claims.length) { // $FlowFixMe myChannelClaims = null; + myChannelUrls = null; } else { myChannelClaims = new Set(state.myChannelClaims); + myChannelUrls = []; claims.forEach(claim => { const { meta } = claim; const { claims_in_channel: claimsInChannel } = claim.meta; @@ -275,18 +277,11 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St // $FlowFixMe myChannelClaims.add(claimId); - if (!byId[claimId]) { + if (!pendingIds.some(c => c === claimId)) { byId[claimId] = claim; } - + myChannelUrls.push(permanentUrl); myClaimIds.add(claimId); - if (pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } - - if (pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } }); } @@ -296,7 +291,8 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St channelClaimCounts, fetchingMyChannels: false, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, - myClaims: Array.from(myClaimIds), + myClaims: myClaimIds ? Array.from(myClaimIds) : null, + myChannelUrls, }); }; @@ -385,19 +381,31 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State => }; reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => { - const { claims }: { claims: Array } = action.data; + const { claims: pendingClaims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); + const pendingIds = state.pendingIds; + const pendingIdSet = new Set(pendingIds); let myClaimIds = new Set(state.myClaims); + const myChannelClaims = new Set(state.myChannelClaims); // $FlowFixMe - claims.forEach((claim: Claim) => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; - if (claim.type && claim.type.match(/claim|update/)) { - pendingById[claimId] = claim; - delete byId[claimId]; + pendingClaims.forEach((claim: Claim) => { + let newClaim; + const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim; + pendingIdSet.add(claimId); + const oldClaim = byId[claimId]; + if (oldClaim && oldClaim.canonical_url) { + newClaim = mergeClaim(oldClaim, claim); + } else { + newClaim = claim; + } + if (valueType === 'channel') { + myChannelClaims.add(claimId); + } + + if (type && type.match(/claim|update/)) { + byId[claimId] = newClaim; byUri[uri] = claimId; } myClaimIds.add(claimId); @@ -405,32 +413,35 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => return Object.assign({}, state, { myClaims: Array.from(myClaimIds), byId, + myChannelClaims: Array.from(myChannelClaims), claimsByUri: byUri, - pendingById, + pendingIds: Array.from(pendingIdSet), }); }; reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => { - const { claims }: { claims: Array } = action.data; + const { claims: confirmedClaims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); - let myClaimIds = new Set(state.myClaims); + const pendingIds = state.pendingIds; + const pendingIdSet = new Set(pendingIds); - claims.forEach((claim: GenericClaim) => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; - if (claim.type && claim.type.match(/claim|update/)) { - delete pendingById[claimId]; - byId[claimId] = claim; + confirmedClaims.forEach((claim: GenericClaim) => { + const { permanent_url: permanentUri, claim_id: claimId, type } = claim; + let newClaim = claim; + const oldClaim = byId[claimId]; + if (oldClaim && oldClaim.canonical_url) { + newClaim = mergeClaim(oldClaim, claim); + } + if (type && type.match(/claim|update|channel/)) { + byId[claimId] = newClaim; + pendingIdSet.delete(claimId); } - myClaimIds.add(claimId); }); return Object.assign({}, state, { - myClaims: Array.from(myClaimIds), + pendingIds: Array.from(pendingIdSet), byId, claimsByUri: byUri, - pendingById, }); }; @@ -466,19 +477,7 @@ reducers[ACTIONS.CREATE_CHANNEL_STARTED] = (state: State): State => ({ }); reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { - const channelClaim: ChannelClaim = action.data.channelClaim; - const byId = Object.assign({}, state.byId); - const pendingById = Object.assign({}, state.pendingById); - const myChannelClaims = new Set(state.myChannelClaims); - - byId[channelClaim.claim_id] = channelClaim; - pendingById[channelClaim.claim_id] = channelClaim; - myChannelClaims.add(channelClaim.claim_id); - return Object.assign({}, state, { - byId, - pendingById, - myChannelClaims: Array.from(myChannelClaims), creatingChannel: false, }); }; @@ -498,13 +497,7 @@ reducers[ACTIONS.UPDATE_CHANNEL_STARTED] = (state: State, action: any): State => }; reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { - const channelClaim: ChannelClaim = action.data.channelClaim; - const byId = Object.assign({}, state.byId); - - byId[channelClaim.claim_id] = channelClaim; - return Object.assign({}, state, { - byId, updateChannelError: '', updatingChannel: false, }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index e2ced6c..33a1bf3 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -6,7 +6,7 @@ import { } from 'redux/selectors/search'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { createSelector } from 'reselect'; -import { isClaimNsfw, createNormalizedClaimSearchKey, filterClaims } from 'util/claim'; +import { isClaimNsfw, filterClaims } from 'util/claim'; import { getSearchQueryString } from 'util/query-params'; import { PAGE_SIZE } from 'constants/claim'; @@ -48,10 +48,9 @@ export const selectRepostError = createSelector( ); export const selectClaimsByUri = createSelector( - selectState, + selectClaimIdsByUri, selectClaimsById, - (state, byId) => { - const byUri = state.claimsByUri || {}; + (byUri, byId) => { const claims = {}; Object.keys(byUri).forEach(uri => { @@ -76,42 +75,25 @@ export const selectAllClaimsByChannel = createSelector( state => state.paginatedClaimsByChannel || {} ); -export const selectPendingById = createSelector( +export const selectPendingIds = createSelector( selectState, - state => state.pendingById || {} -); - -export const selectPendingClaims = createSelector( - selectState, - state => Object.values(state.pendingById || []) + state => state.pendingIds || [] ); export const makeSelectClaimIsPending = (uri: string) => createSelector( - selectPendingById, - pendingById => { - let claimId; - - try { - const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); - claimId = isChannel ? channelClaimId : streamClaimId; - } catch (e) {} + selectClaimIdsByUri, + selectPendingIds, + (idsByUri, pendingIds) => { + const claimId = idsByUri(normalizeURI(uri)); if (claimId) { - return Boolean(pendingById[claimId]); + return pendingIds.some(i => i === claimId); } + return false; } ); -export const makeSelectPendingByUri = (uri: string) => - createSelector( - selectPendingById, - pendingById => { - const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); - const claimId = isChannel ? channelClaimId : streamClaimId; - return pendingById[claimId]; - } - ); export const selectReflectingById = createSelector( selectState, state => state.reflectingById @@ -119,30 +101,21 @@ export const selectReflectingById = createSelector( export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) => createSelector( - selectClaimsByUri, - selectPendingById, - (byUri, pendingById) => { - // Check if a claim is pending first - // It won't be in claimsByUri because resolving it will return nothing - - let valid; + selectClaimIdsByUri, + selectClaimsById, + (byUri, byId) => { + let validUri; let channelClaimId; let streamClaimId; let isChannel; try { ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); - valid = true; + validUri = true; } catch (e) {} - if (valid && byUri) { - const claimId = isChannel ? channelClaimId : streamClaimId; - const pendingClaim = pendingById[claimId]; - - if (pendingClaim) { - return pendingClaim; - } - - const claim = byUri[normalizeURI(uri)]; + if (validUri && byUri) { + const claimId = uri && byUri[normalizeURI(uri)]; + const claim = byId[claimId]; if (claim === undefined || claim === null) { // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) return claim; @@ -456,8 +429,7 @@ export const selectMyClaims = createSelector( selectMyActiveClaims, selectClaimsById, selectAbandoningIds, - selectPendingClaims, - (myClaimIds, byId, abandoningIds, pendingClaims) => { + (myClaimIds, byId, abandoningIds) => { const claims = []; myClaimIds.forEach(id => { @@ -466,7 +438,7 @@ export const selectMyClaims = createSelector( if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); }); - return [...claims, ...pendingClaims]; + return [...claims]; } ); @@ -495,6 +467,11 @@ export const selectMyClaimUrisWithoutChannels = createSelector( } ); +export const selectMyChannelUrls = createSelector( + selectState, + state => state.myChannelUrls +); + export const selectAllMyClaimsByOutpoint = createSelector( selectMyClaimsRaw, claims => diff --git a/src/util/merge-claim.js b/src/util/merge-claim.js new file mode 100644 index 0000000..3ab2976 --- /dev/null +++ b/src/util/merge-claim.js @@ -0,0 +1,7 @@ +/* +new claim = { ...maybeResolvedClaim, ...pendingClaim, meta: maybeResolvedClaim['meta'] } + */ + +export default function mergeClaims(maybeResolved, pending){ + return { ...maybeResolved, ...pending, meta: maybeResolved.meta }; +} -- 2.45.2 From 36f36cea8e6159bd2b7a9cea74e67ae5652aea94 Mon Sep 17 00:00:00 2001 From: jessop Date: Wed, 17 Jun 2020 09:56:59 -0400 Subject: [PATCH 352/371] bugfix --- dist/bundle.es.js | 37 ++++++++++++++++------------------- src/redux/actions/claims.js | 5 ++++- src/redux/reducers/claims.js | 13 +++--------- src/redux/selectors/claims.js | 12 ++++++------ 4 files changed, 30 insertions(+), 37 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3da1f70..3748bc6 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2204,7 +2204,7 @@ const selectAllClaimsByChannel = reselect.createSelector(selectState$2, state => const selectPendingIds = reselect.createSelector(selectState$2, state => state.pendingIds || []); const makeSelectClaimIsPending = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingIds, (idsByUri, pendingIds) => { - const claimId = idsByUri(normalizeURI(uri)); + const claimId = idsByUri[normalizeURI(uri)]; if (claimId) { return pendingIds.some(i => i === claimId); @@ -2423,8 +2423,6 @@ const selectMyClaimUrisWithoutChannels = reselect.createSelector(selectMyClaimsW }); }); -const selectMyChannelUrls = reselect.createSelector(selectState$2, state => state.myChannelUrls); - const selectAllMyClaimsByOutpoint = reselect.createSelector(selectMyClaimsRaw, claims => new Set(claims && claims.length ? claims.map(claim => `${claim.txid}:${claim.nout}`) : null)); const selectMyClaimsOutpoints = reselect.createSelector(selectMyClaims, myClaims => { @@ -2454,6 +2452,8 @@ const selectMyChannelClaims = reselect.createSelector(selectState$2, selectClaim return claims; }); +const selectMyChannelUrls = reselect.createSelector(selectMyChannelClaims, claims => claims ? claims.map(claim => claim.canonical_url || claim.permanent_url) : undefined); + const selectResolvingUris = reselect.createSelector(selectState$2, state => state.resolvingUris || []); const selectChannelImportPending = reselect.createSelector(selectState$2, state => state.pendingChannelImport); @@ -2857,8 +2857,8 @@ function doSendDraftTransaction(address, amount) { if (balance - amount <= 0) { dispatch(doToast({ - title: 'Insufficient credits', - message: 'Insufficient credits' + title: __('Insufficient credits'), + message: __('Insufficient credits') })); return; } @@ -2873,8 +2873,8 @@ function doSendDraftTransaction(address, amount) { type: SEND_TRANSACTION_COMPLETED }); dispatch(doToast({ - message: `You sent ${amount} LBC`, - linkText: 'History', + message: __('You sent ${amount} LBC'), + linkText: __('History'), linkTarget: '/wallet' })); } else { @@ -2883,7 +2883,7 @@ function doSendDraftTransaction(address, amount) { data: { error: response } }); dispatch(doToast({ - message: 'Transaction failed', + message: __('Transaction failed'), isError: true })); } @@ -2895,7 +2895,7 @@ function doSendDraftTransaction(address, amount) { data: { error: error.message } }); dispatch(doToast({ - message: 'Transaction failed', + message: __('Transaction failed'), isError: true })); }; @@ -2941,7 +2941,7 @@ function doSendTip(params, isSupport, successCallback, errorCallback) { dispatch(doToast({ message: shouldSupport ? __('You deposited %amount% LBC as a support!', { amount: params.amount }) : __('You sent %amount% LBC as a tip, Mahalo!', { amount: params.amount }), linkText: __('History'), - linkTarget: __('/wallet') + linkTarget: '/wallet' })); dispatch({ @@ -3534,7 +3534,9 @@ function doCreateChannel(name, amount, optionalParams, cb) { }); dispatch({ type: UPDATE_PENDING_CLAIMS, - data: [channelClaim] + data: { + claims: [channelClaim] + } }); dispatch(doCheckPendingClaims(cb)); return channelClaim; @@ -3600,6 +3602,7 @@ function doUpdateChannel(params, cb) { } }); dispatch(doCheckPendingClaims(cb)); + return Boolean(result.outputs[0]); }).then().catch(error => { dispatch({ type: UPDATE_CHANNEL_FAILED, @@ -5128,7 +5131,6 @@ const defaultState = { fetchingChannelClaims: {}, resolvingUris: [], myChannelClaims: undefined, - myChannelUrls: undefined, myClaims: undefined, myPurchases: undefined, myPurchasesPageNumber: undefined, @@ -5178,7 +5180,7 @@ function handleClaimAction(state, action) { if (stream) { if (pendingIds.includes(stream.claim_id)) { - byId[stream.claim_id] = mergeClaims(stream, byId[stream.claim_id]); // merge them + byId[stream.claim_id] = mergeClaims(stream, byId[stream.claim_id]); } else { byId[stream.claim_id] = stream; } @@ -5277,7 +5279,7 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { if (pendingIds.includes(claimId)) { byId[claimId] = mergeClaims(claim, byId[claimId]); } else { - byId[claimId] = claim; // just add + byId[claimId] = claim; } byUri[permanentUri] = claimId; myClaimIds.add(claimId); @@ -5304,7 +5306,6 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { let myClaimIds = new Set(state.myClaims); const pendingIds = state.pendingIds || []; let myChannelClaims; - let myChannelUrls = []; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); @@ -5312,10 +5313,8 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { if (!claims.length) { // $FlowFixMe myChannelClaims = null; - myChannelUrls = null; } else { myChannelClaims = new Set(state.myChannelClaims); - myChannelUrls = []; claims.forEach(claim => { const { claims_in_channel: claimsInChannel } = claim.meta; const { canonical_url: canonicalUrl, permanent_url: permanentUrl, claim_id: claimId } = claim; @@ -5330,7 +5329,6 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { if (!pendingIds.some(c => c === claimId)) { byId[claimId] = claim; } - myChannelUrls.push(permanentUrl); myClaimIds.add(claimId); }); } @@ -5341,8 +5339,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { channelClaimCounts, fetchingMyChannels: false, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, - myClaims: myClaimIds ? Array.from(myClaimIds) : null, - myChannelUrls + myClaims: myClaimIds ? Array.from(myClaimIds) : null }); }; diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 91039ea..615b7a6 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -398,7 +398,9 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an }); dispatch({ type: ACTIONS.UPDATE_PENDING_CLAIMS, - data: [channelClaim], + data: { + claims: [channelClaim], + }, }); dispatch(doCheckPendingClaims(cb)); return channelClaim; @@ -467,6 +469,7 @@ export function doUpdateChannel(params: any, cb: any) { }, }); dispatch(doCheckPendingClaims(cb)); + return Boolean(result.outputs[0]); }) .then() .catch(error => { diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 99a4e4a..f6f2a69 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -21,7 +21,6 @@ type State = { reflectingById: { [string]: ReflectingUpdate }, myClaims: ?Array, myChannelClaims: ?Array, - myChannelUrls: ?Array, abandoningById: { [string]: boolean }, fetchingChannelClaims: { [string]: number }, fetchingMyChannels: boolean, @@ -67,7 +66,6 @@ const defaultState = { fetchingChannelClaims: {}, resolvingUris: [], myChannelClaims: undefined, - myChannelUrls: undefined, myClaims: undefined, myPurchases: undefined, myPurchasesPageNumber: undefined, @@ -123,7 +121,7 @@ function handleClaimAction(state: State, action: any): State { if (stream) { if (pendingIds.includes(stream.claim_id)) { - byId[stream.claim_id] = mergeClaim(stream, byId[stream.claim_id]);// merge them + byId[stream.claim_id] = mergeClaim(stream, byId[stream.claim_id]); } else { byId[stream.claim_id] = stream; } @@ -214,7 +212,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const pendingIdSet = new Set(pendingIds); claims.forEach((claim: Claim) => { - const { permanent_url: permanentUri, claim_id: claimId } = claim; + const { permanent_url: permanentUri, claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { urlsForCurrentPage.push(permanentUri); if (claim.confirmations < 1) { @@ -225,7 +223,7 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): if (pendingIds.includes(claimId)) { byId[claimId] = mergeClaim(claim, byId[claimId]); } else { - byId[claimId] = claim;// just add + byId[claimId] = claim; } byUri[permanentUri] = claimId; myClaimIds.add(claimId); @@ -253,7 +251,6 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St let myClaimIds = new Set(state.myClaims); const pendingIds = state.pendingIds || []; let myChannelClaims; - let myChannelUrls = []; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); @@ -261,10 +258,8 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St if (!claims.length) { // $FlowFixMe myChannelClaims = null; - myChannelUrls = null; } else { myChannelClaims = new Set(state.myChannelClaims); - myChannelUrls = []; claims.forEach(claim => { const { meta } = claim; const { claims_in_channel: claimsInChannel } = claim.meta; @@ -280,7 +275,6 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St if (!pendingIds.some(c => c === claimId)) { byId[claimId] = claim; } - myChannelUrls.push(permanentUrl); myClaimIds.add(claimId); }); } @@ -292,7 +286,6 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St fetchingMyChannels: false, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, myClaims: myClaimIds ? Array.from(myClaimIds) : null, - myChannelUrls, }); }; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index 33a1bf3..b724567 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -85,7 +85,7 @@ export const makeSelectClaimIsPending = (uri: string) => selectClaimIdsByUri, selectPendingIds, (idsByUri, pendingIds) => { - const claimId = idsByUri(normalizeURI(uri)); + const claimId = idsByUri[normalizeURI(uri)]; if (claimId) { return pendingIds.some(i => i === claimId); @@ -467,11 +467,6 @@ export const selectMyClaimUrisWithoutChannels = createSelector( } ); -export const selectMyChannelUrls = createSelector( - selectState, - state => state.myChannelUrls -); - export const selectAllMyClaimsByOutpoint = createSelector( selectMyClaimsRaw, claims => @@ -515,6 +510,11 @@ export const selectMyChannelClaims = createSelector( } ); +export const selectMyChannelUrls = createSelector( + selectMyChannelClaims, + claims => claims ? claims.map(claim => claim.canonical_url || claim.permanent_url) : undefined +); + export const selectResolvingUris = createSelector( selectState, state => state.resolvingUris || [] -- 2.45.2 From 2ec145c50f5a2a960ac6199a7d2c1718a10a76b1 Mon Sep 17 00:00:00 2001 From: jessopb <36554050+jessopb@users.noreply.github.com> Date: Fri, 19 Jun 2020 13:11:31 -0400 Subject: [PATCH 353/371] Revert "support pending channels" --- dist/bundle.es.js | 597 +++++++++++++++++----------------- dist/flow-typed/Claim.js | 2 +- flow-typed/Claim.js | 2 +- src/index.js | 6 +- src/redux/actions/claims.js | 66 +--- src/redux/actions/publish.js | 44 +++ src/redux/reducers/claims.js | 156 +++++---- src/redux/selectors/claims.js | 75 +++-- src/util/merge-claim.js | 7 - 9 files changed, 488 insertions(+), 467 deletions(-) delete mode 100644 src/util/merge-claim.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 3748bc6..171bd30 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2180,7 +2180,8 @@ const selectRepostLoading = reselect.createSelector(selectState$2, state => stat const selectRepostError = reselect.createSelector(selectState$2, state => state.repostError); -const selectClaimsByUri = reselect.createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => { +const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { + const byUri = state.claimsByUri || {}; const claims = {}; Object.keys(byUri).forEach(uri => { @@ -2201,32 +2202,52 @@ const selectClaimsByUri = reselect.createSelector(selectClaimIdsByUri, selectCla const selectAllClaimsByChannel = reselect.createSelector(selectState$2, state => state.paginatedClaimsByChannel || {}); -const selectPendingIds = reselect.createSelector(selectState$2, state => state.pendingIds || []); +const selectPendingById = reselect.createSelector(selectState$2, state => state.pendingById || {}); -const makeSelectClaimIsPending = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingIds, (idsByUri, pendingIds) => { - const claimId = idsByUri[normalizeURI(uri)]; +const selectPendingClaims = reselect.createSelector(selectState$2, state => Object.values(state.pendingById || [])); + +const makeSelectClaimIsPending = uri => reselect.createSelector(selectPendingById, pendingById => { + let claimId; + + try { + const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); + claimId = isChannel ? channelClaimId : streamClaimId; + } catch (e) {} if (claimId) { - return pendingIds.some(i => i === claimId); + return Boolean(pendingById[claimId]); } - return false; }); +const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, pendingById => { + const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); + const claimId = isChannel ? channelClaimId : streamClaimId; + return pendingById[claimId]; +}); const selectReflectingById = reselect.createSelector(selectState$2, state => state.reflectingById); -const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => { - let validUri; +const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => { + // Check if a claim is pending first + // It won't be in claimsByUri because resolving it will return nothing + + let valid; let channelClaimId; let streamClaimId; let isChannel; try { ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); - validUri = true; + valid = true; } catch (e) {} - if (validUri && byUri) { - const claimId = uri && byUri[normalizeURI(uri)]; - const claim = byId[claimId]; + if (valid && byUri) { + const claimId = isChannel ? channelClaimId : streamClaimId; + const pendingClaim = pendingById[claimId]; + + if (pendingClaim) { + return pendingClaim; + } + + const claim = byUri[normalizeURI(uri)]; if (claim === undefined || claim === null) { // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) return claim; @@ -2395,7 +2416,7 @@ const selectMyClaimsPageItemCount = reselect.createSelector(selectState$2, state const selectFetchingMyClaimsPageError = reselect.createSelector(selectState$2, state => state.fetchingClaimListMinePageError); -const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, (myClaimIds, byId, abandoningIds) => { +const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, (myClaimIds, byId, abandoningIds, pendingClaims) => { const claims = []; myClaimIds.forEach(id => { @@ -2404,7 +2425,7 @@ const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaim if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); }); - return [...claims]; + return [...claims, ...pendingClaims]; }); const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp)); @@ -2452,8 +2473,6 @@ const selectMyChannelClaims = reselect.createSelector(selectState$2, selectClaim return claims; }); -const selectMyChannelUrls = reselect.createSelector(selectMyChannelClaims, claims => claims ? claims.map(claim => claim.canonical_url || claim.permanent_url) : undefined); - const selectResolvingUris = reselect.createSelector(selectState$2, state => state.resolvingUris || []); const selectChannelImportPending = reselect.createSelector(selectState$2, state => state.pendingChannelImport); @@ -2857,8 +2876,8 @@ function doSendDraftTransaction(address, amount) { if (balance - amount <= 0) { dispatch(doToast({ - title: __('Insufficient credits'), - message: __('Insufficient credits') + title: 'Insufficient credits', + message: 'Insufficient credits' })); return; } @@ -2873,8 +2892,8 @@ function doSendDraftTransaction(address, amount) { type: SEND_TRANSACTION_COMPLETED }); dispatch(doToast({ - message: __('You sent ${amount} LBC'), - linkText: __('History'), + message: `You sent ${amount} LBC`, + linkText: 'History', linkTarget: '/wallet' })); } else { @@ -2883,7 +2902,7 @@ function doSendDraftTransaction(address, amount) { data: { error: response } }); dispatch(doToast({ - message: __('Transaction failed'), + message: 'Transaction failed', isError: true })); } @@ -2895,7 +2914,7 @@ function doSendDraftTransaction(address, amount) { data: { error: error.message } }); dispatch(doToast({ - message: __('Transaction failed'), + message: 'Transaction failed', isError: true })); }; @@ -2941,7 +2960,7 @@ function doSendTip(params, isSupport, successCallback, errorCallback) { dispatch(doToast({ message: shouldSupport ? __('You deposited %amount% LBC as a support!', { amount: params.amount }) : __('You sent %amount% LBC as a tip, Mahalo!', { amount: params.amount }), linkText: __('History'), - linkTarget: '/wallet' + linkTarget: __('/wallet') })); dispatch({ @@ -3487,7 +3506,7 @@ function doFetchClaimsByChannel(uri, page = 1) { }; } -function doCreateChannel(name, amount, optionalParams, cb) { +function doCreateChannel(name, amount, optionalParams) { return dispatch => { dispatch({ type: CREATE_CHANNEL_STARTED @@ -3532,13 +3551,6 @@ function doCreateChannel(name, amount, optionalParams, cb) { type: CREATE_CHANNEL_COMPLETED, data: { channelClaim } }); - dispatch({ - type: UPDATE_PENDING_CLAIMS, - data: { - claims: [channelClaim] - } - }); - dispatch(doCheckPendingClaims(cb)); return channelClaim; }).catch(error => { dispatch({ @@ -3550,7 +3562,7 @@ function doCreateChannel(name, amount, optionalParams, cb) { }; } -function doUpdateChannel(params, cb) { +function doUpdateChannel(params) { return (dispatch, getState) => { dispatch({ type: UPDATE_CHANNEL_STARTED @@ -3595,15 +3607,7 @@ function doUpdateChannel(params, cb) { type: UPDATE_CHANNEL_COMPLETED, data: { channelClaim } }); - dispatch({ - type: UPDATE_PENDING_CLAIMS, - data: { - claims: [channelClaim] - } - }); - dispatch(doCheckPendingClaims(cb)); - return Boolean(result.outputs[0]); - }).then().catch(error => { + }).catch(error => { dispatch({ type: UPDATE_CHANNEL_FAILED, data: error @@ -3799,46 +3803,6 @@ function doPurchaseList(page = 1, pageSize = PAGE_SIZE) { }; } -const doCheckPendingClaims = onConfirmed => (dispatch, getState) => { - let claimCheckInterval; - - const checkClaimList = () => { - const state = getState(); - const pendingIdSet = new Set(selectPendingIds(state)); - lbryProxy.claim_list({ page: 1, page_size: 10 }).then(result => { - const claims = result.items; - const claimsToConfirm = []; - claims.forEach(claim => { - const { claim_id: claimId } = claim; - if (claim.confirmations > 0 && pendingIdSet.has(claimId)) { - pendingIdSet.delete(claimId); - claimsToConfirm.push(claim); - if (onConfirmed) { - onConfirmed(claim); - } - } - }); - if (claimsToConfirm.length) { - dispatch({ - type: UPDATE_CONFIRMED_CLAIMS, - data: { - claims: claimsToConfirm - } - }); - } - return pendingIdSet.size; - }).then(len => { - if (!len) { - clearInterval(claimCheckInterval); - } - }); - }; - - claimCheckInterval = setInterval(() => { - checkClaimList(); - }, 30000); -}; - const selectState$3 = state => state.fileInfo || {}; const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); @@ -4624,6 +4588,44 @@ const doCheckReflectingFiles = () => (dispatch, getState) => { }, 5000); } }; +const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { + let publishCheckInterval; + + const checkFileList = () => { + const state = getState(); + const pendingById = selectPendingById(state); + lbryProxy.claim_list({ page: 1, page_size: 10 }).then(result => { + const claims = result.items; + const claimsToConfirm = []; + claims.forEach(claim => { + if (claim.confirmations > 0 && pendingById[claim.claim_id]) { + delete pendingById[claim.claim_id]; + claimsToConfirm.push(claim); + if (onConfirmed) { + onConfirmed(claim); + } + } + }); + if (claimsToConfirm.length) { + dispatch({ + type: UPDATE_CONFIRMED_CLAIMS, + data: { + claims: claimsToConfirm + } + }); + } + return Object.keys(pendingById).length; + }).then(len => { + if (!len) { + clearInterval(publishCheckInterval); + } + }); + }; + + publishCheckInterval = setInterval(() => { + checkFileList(); + }, 30000); +}; // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for @@ -5110,16 +5112,6 @@ const doToggleBlockChannel = uri => ({ var _extends$a = 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; }; -/* -new claim = { ...maybeResolvedClaim, ...pendingClaim, meta: maybeResolvedClaim['meta'] } - */ - -function mergeClaims(maybeResolved, pending) { - return _extends$a({}, maybeResolved, pending, { meta: maybeResolved.meta }); -} - -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$3(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 reducers = {}; @@ -5140,7 +5132,7 @@ const defaultState = { fetchingMyPurchasesError: undefined, fetchingMyChannels: false, abandoningById: {}, - pendingIds: [], + pendingById: {}, reflectingById: {}, claimSearchError: false, claimSearchByQuery: {}, @@ -5171,19 +5163,18 @@ function handleClaimAction(state, action) { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - const pendingIds = state.pendingIds; let newResolvingUrls = new Set(state.resolvingUris); Object.entries(resolveInfo).forEach(([url, resolveResponse]) => { // $FlowFixMe const { claimsInChannel, stream, channel } = resolveResponse; + if (claimsInChannel) { + channelClaimCounts[url] = claimsInChannel; + channelClaimCounts[channel.canonical_url] = claimsInChannel; + } if (stream) { - if (pendingIds.includes(stream.claim_id)) { - byId[stream.claim_id] = mergeClaims(stream, byId[stream.claim_id]); - } else { - byId[stream.claim_id] = stream; - } + byId[stream.claim_id] = stream; byUri[url] = stream.claim_id; // If url isn't a canonical_url, make sure that is added too @@ -5195,18 +5186,12 @@ function handleClaimAction(state, action) { newResolvingUrls.delete(stream.permanent_url); } - if (channel && channel.claim_id) { - if (claimsInChannel) { - channelClaimCounts[url] = claimsInChannel; - channelClaimCounts[channel.canonical_url] = claimsInChannel; + if (channel) { + if (!stream) { + byUri[url] = channel.claim_id; } - byUri[url] = channel.claim_id; - if (pendingIds.includes(channel.claim_id)) { - byId[channel.claim_id] = mergeClaims(channel, byId[channel.claim_id]); - } else { - byId[channel.claim_id] = channel; - } + byId[channel.claim_id] = channel; // Also add the permanent_url here until lighthouse returns canonical_url for search results byUri[channel.permanent_url] = channel.claim_id; byUri[channel.canonical_url] = channel.claim_id; @@ -5246,7 +5231,7 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$b({}, handleClaimAction(state, action)); + return _extends$a({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -5261,37 +5246,46 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingIds = state.pendingIds || []; + const pendingById = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); let urlsForCurrentPage = []; - const pendingIdSet = new Set(pendingIds); - claims.forEach(claim => { - const { permanent_url: permanentUri, claim_id: claimId } = claim; + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { - urlsForCurrentPage.push(permanentUri); + urlsForCurrentPage.push(uri); if (claim.confirmations < 1) { - pendingIdSet.add(claimId); - } else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) { - pendingIdSet.delete(claimId); - } - if (pendingIds.includes(claimId)) { - byId[claimId] = mergeClaims(claim, byId[claimId]); + pendingById[claimId] = claim; + delete byId[claimId]; + delete byUri[claimId]; } else { byId[claimId] = claim; + byUri[uri] = claimId; } - byUri[permanentUri] = claimId; myClaimIds.add(claimId); + if (!resolve && pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; + } } }); + // Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0) + if (!resolve) { + Object.values(pendingById) + // $FlowFixMe + .filter(pendingClaim => byId[pendingClaim.claim_id]).forEach(pendingClaim => { + // $FlowFixMe + delete pendingById[pendingClaim.claim_id]; + }); + } + return Object.assign({}, state, { isFetchingClaimListMine: false, myClaims: Array.from(myClaimIds), byId, - pendingIds: Array.from(pendingIdSet), claimsByUri: byUri, + pendingById, myClaimsPageResults: urlsForCurrentPage, myClaimsPageNumber: page, myClaimsPageTotalResults: totalItems @@ -5304,7 +5298,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { const { claims } = action.data; const myClaims = state.myClaims || []; let myClaimIds = new Set(state.myClaims); - const pendingIds = state.pendingIds || []; + const pendingById = Object.assign(state.pendingById); let myChannelClaims; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); @@ -5326,10 +5320,18 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { // $FlowFixMe myChannelClaims.add(claimId); - if (!pendingIds.some(c => c === claimId)) { + if (!byId[claimId]) { byId[claimId] = claim; } + myClaimIds.add(claimId); + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; + } + + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; + } }); } @@ -5339,7 +5341,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { channelClaimCounts, fetchingMyChannels: false, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, - myClaims: myClaimIds ? Array.from(myClaimIds) : null + myClaims: Array.from(myClaimIds) }); }; @@ -5421,31 +5423,19 @@ reducers[ABANDON_CLAIM_STARTED] = (state, action) => { }; reducers[UPDATE_PENDING_CLAIMS] = (state, action) => { - const { claims: pendingClaims } = action.data; + const { claims } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingIds = state.pendingIds; - const pendingIdSet = new Set(pendingIds); + const pendingById = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); - const myChannelClaims = new Set(state.myChannelClaims); // $FlowFixMe - pendingClaims.forEach(claim => { - let newClaim; - const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim; - pendingIdSet.add(claimId); - const oldClaim = byId[claimId]; - if (oldClaim && oldClaim.canonical_url) { - newClaim = mergeClaims(oldClaim, claim); - } else { - newClaim = claim; - } - if (valueType === 'channel') { - myChannelClaims.add(claimId); - } - - if (type && type.match(/claim|update/)) { - byId[claimId] = newClaim; + claims.forEach(claim => { + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; + if (claim.type && claim.type.match(/claim|update/)) { + pendingById[claimId] = claim; + delete byId[claimId]; byUri[uri] = claimId; } myClaimIds.add(claimId); @@ -5453,35 +5443,32 @@ reducers[UPDATE_PENDING_CLAIMS] = (state, action) => { return Object.assign({}, state, { myClaims: Array.from(myClaimIds), byId, - myChannelClaims: Array.from(myChannelClaims), claimsByUri: byUri, - pendingIds: Array.from(pendingIdSet) + pendingById }); }; reducers[UPDATE_CONFIRMED_CLAIMS] = (state, action) => { - const { claims: confirmedClaims } = action.data; + const { claims } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingIds = state.pendingIds; - const pendingIdSet = new Set(pendingIds); + const pendingById = Object.assign({}, state.pendingById); + let myClaimIds = new Set(state.myClaims); - confirmedClaims.forEach(claim => { - const { permanent_url: permanentUri, claim_id: claimId, type } = claim; - let newClaim = claim; - const oldClaim = byId[claimId]; - if (oldClaim && oldClaim.canonical_url) { - newClaim = mergeClaims(oldClaim, claim); - } - if (type && type.match(/claim|update|channel/)) { - byId[claimId] = newClaim; - pendingIdSet.delete(claimId); + claims.forEach(claim => { + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; + if (claim.type && claim.type.match(/claim|update/)) { + delete pendingById[claimId]; + byId[claimId] = claim; } + myClaimIds.add(claimId); }); return Object.assign({}, state, { - pendingIds: Array.from(pendingIdSet), + myClaims: Array.from(myClaimIds), byId, - claimsByUri: byUri + claimsByUri: byUri, + pendingById }); }; @@ -5510,13 +5497,25 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; -reducers[CREATE_CHANNEL_STARTED] = state => _extends$b({}, state, { +reducers[CREATE_CHANNEL_STARTED] = state => _extends$a({}, state, { creatingChannel: true, createChannelError: null }); reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { + const channelClaim = action.data.channelClaim; + const byId = Object.assign({}, state.byId); + const pendingById = Object.assign({}, state.pendingById); + const myChannelClaims = new Set(state.myChannelClaims); + + byId[channelClaim.claim_id] = channelClaim; + pendingById[channelClaim.claim_id] = channelClaim; + myChannelClaims.add(channelClaim.claim_id); + return Object.assign({}, state, { + byId, + pendingById, + myChannelClaims: Array.from(myChannelClaims), creatingChannel: false }); }; @@ -5536,7 +5535,13 @@ reducers[UPDATE_CHANNEL_STARTED] = (state, action) => { }; reducers[UPDATE_CHANNEL_COMPLETED] = (state, action) => { + const channelClaim = action.data.channelClaim; + const byId = Object.assign({}, state.byId); + + byId[channelClaim.claim_id] = channelClaim; + return Object.assign({}, state, { + byId, updateChannelError: '', updatingChannel: false }); @@ -5580,7 +5585,7 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { delete fetchingClaimSearchByQuery[query]; - return Object.assign({}, state, _extends$b({}, handleClaimAction(state, action), { + return Object.assign({}, state, _extends$a({}, handleClaimAction(state, action), { claimSearchByQuery, claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery @@ -5602,22 +5607,22 @@ reducers[CLAIM_SEARCH_FAILED] = (state, action) => { }; reducers[CLAIM_REPOST_STARTED] = state => { - return _extends$b({}, state, { + return _extends$a({}, state, { repostLoading: true, repostError: null }); }; reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { const { originalClaimId, repostClaim } = action.data; - const byId = _extends$b({}, state.byId); - const claimsByUri = _extends$b({}, state.claimsByUri); + const byId = _extends$a({}, state.byId); + const claimsByUri = _extends$a({}, state.claimsByUri); const claimThatWasReposted = byId[originalClaimId]; - const repostStub = _extends$b({}, repostClaim, { reposted_claim: claimThatWasReposted }); + const repostStub = _extends$a({}, repostClaim, { reposted_claim: claimThatWasReposted }); byId[repostStub.claim_id] = repostStub; claimsByUri[repostStub.permanent_url] = repostStub.claim_id; - return _extends$b({}, state, { + return _extends$a({}, state, { byId, claimsByUri, repostLoading: false, @@ -5627,13 +5632,13 @@ reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { reducers[CLAIM_REPOST_FAILED] = (state, action) => { const { error } = action.data; - return _extends$b({}, state, { + return _extends$a({}, state, { repostLoading: false, repostError: error }); }; reducers[CLEAR_REPOST_ERROR] = state => { - return _extends$b({}, state, { + return _extends$a({}, state, { repostError: null }); }; @@ -5644,34 +5649,34 @@ reducers[ADD_FILES_REFLECTING] = (state, action) => { reflectingById[claimId] = { fileListItem: pendingClaim, progress: 0, stalled: false }; - return Object.assign({}, state, _extends$b({}, state, { + return Object.assign({}, state, _extends$a({}, state, { reflectingById: reflectingById })); }; reducers[UPDATE_FILES_REFLECTING] = (state, action) => { const newReflectingById = action.data; - return Object.assign({}, state, _extends$b({}, state, { + return Object.assign({}, state, _extends$a({}, state, { reflectingById: newReflectingById })); }; reducers[TOGGLE_CHECKING_REFLECTING] = (state, action) => { const checkingReflecting = action.data; - return Object.assign({}, state, _extends$b({}, state, { + return Object.assign({}, state, _extends$a({}, state, { checkingReflecting })); }; reducers[TOGGLE_CHECKING_PENDING] = (state, action) => { const checking = action.data; - return Object.assign({}, state, _extends$b({}, state, { + return Object.assign({}, state, _extends$a({}, state, { checkingPending: checking })); }; reducers[PURCHASE_LIST_STARTED] = state => { - return _extends$b({}, state, { + return _extends$a({}, state, { fetchingMyPurchases: true, fetchingMyPurchasesError: null }); @@ -5716,7 +5721,7 @@ reducers[PURCHASE_LIST_COMPLETED] = (state, action) => { reducers[PURCHASE_LIST_FAILED] = (state, action) => { const { error } = action.data; - return _extends$b({}, state, { + return _extends$a({}, state, { fetchingMyPurchases: false, fetchingMyPurchasesError: error }); @@ -5737,7 +5742,7 @@ reducers[PURCHASE_URI_COMPLETED] = (state, action) => { myPurchases.push(uri); - return _extends$b({}, state, { + return _extends$a({}, state, { byId, myPurchases, purchaseUriSuccess: true @@ -5745,13 +5750,13 @@ reducers[PURCHASE_URI_COMPLETED] = (state, action) => { }; reducers[PURCHASE_URI_FAILED] = state => { - return _extends$b({}, state, { + return _extends$a({}, state, { purchaseUriSuccess: false }); }; reducers[CLEAR_PURCHASED_URI_SUCCESS] = state => { - return _extends$b({}, state, { + return _extends$a({}, state, { purchaseUriSuccess: false }); }; @@ -5780,7 +5785,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -var _extends$c = 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; }; +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; }; const defaultState$1 = { commentById: {}, // commentId -> Comment @@ -5791,11 +5796,11 @@ const defaultState$1 = { }; const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$c({}, state, { + [COMMENT_CREATE_STARTED]: (state, action) => _extends$b({}, state, { isLoading: true }), - [COMMENT_CREATE_FAILED]: (state, action) => _extends$c({}, state, { + [COMMENT_CREATE_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }), @@ -5813,14 +5818,14 @@ const commentReducer = handleActions({ newCommentIds.unshift(comment.comment_id); byId[claimId] = newCommentIds; - return _extends$c({}, state, { + return _extends$b({}, state, { commentById, byId, isLoading: false }); }, - [COMMENT_LIST_STARTED]: state => _extends$c({}, state, { isLoading: true }), + [COMMENT_LIST_STARTED]: state => _extends$b({}, state, { isLoading: true }), [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; @@ -5844,7 +5849,7 @@ const commentReducer = handleActions({ byId[claimId] = commentIds; commentsByUri[uri] = claimId; } - return _extends$c({}, state, { + return _extends$b({}, state, { byId, commentById, commentsByUri, @@ -5852,10 +5857,10 @@ const commentReducer = handleActions({ }); }, - [COMMENT_LIST_FAILED]: (state, action) => _extends$c({}, state, { + [COMMENT_LIST_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }), - [COMMENT_ABANDON_STARTED]: (state, action) => _extends$c({}, state, { + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$b({}, state, { isLoading: true }), [COMMENT_ABANDON_COMPLETED]: (state, action) => { @@ -5873,18 +5878,18 @@ const commentReducer = handleActions({ } delete commentById[comment_id]; - return _extends$c({}, state, { + return _extends$b({}, state, { commentById, byId, isLoading: false }); }, // do nothing - [COMMENT_ABANDON_FAILED]: (state, action) => _extends$c({}, state, { + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }), // do nothing - [COMMENT_UPDATE_STARTED]: (state, action) => _extends$c({}, state, { + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$b({}, state, { isLoading: true }), // replace existing comment with comment returned here under its comment_id @@ -5893,29 +5898,29 @@ const commentReducer = handleActions({ const commentById = Object.assign({}, state.commentById); commentById[comment.comment_id] = comment; - return _extends$c({}, state, { + return _extends$b({}, state, { commentById, isLoading: false }); }, // nothing can be done here - [COMMENT_UPDATE_FAILED]: (state, action) => _extends$c({}, state, { + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }), // nothing can really be done here - [COMMENT_HIDE_STARTED]: (state, action) => _extends$c({}, state, { + [COMMENT_HIDE_STARTED]: (state, action) => _extends$b({}, state, { isLoading: true }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$c({}, state, { // todo: add HiddenComments state & create selectors + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$b({}, state, { // todo: add HiddenComments state & create selectors isLoading: false }), // nothing can be done here - [COMMENT_HIDE_FAILED]: (state, action) => _extends$c({}, state, { + [COMMENT_HIDE_FAILED]: (state, action) => _extends$b({}, state, { isLoading: false }) }, defaultState$1); -var _extends$d = 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; }; +var _extends$c = 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; }; const reducers$1 = {}; const defaultState$2 = { @@ -5924,9 +5929,9 @@ const defaultState$2 = { reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$d({}, state, { - positions: _extends$d({}, state.positions, { - [claimId]: _extends$d({}, state.positions[claimId], { + return _extends$c({}, state, { + positions: _extends$c({}, state.positions, { + [claimId]: _extends$c({}, state.positions[claimId], { [outpoint]: position }) }) @@ -6093,7 +6098,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -var _extends$e = 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; }; +var _extends$d = 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; }; const defaultState$4 = { notifications: [], @@ -6108,7 +6113,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$e({}, state, { + return _extends$d({}, state, { toasts: newToasts }); }, @@ -6116,7 +6121,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$e({}, state, { + return _extends$d({}, state, { toasts: newToasts }); }, @@ -6127,7 +6132,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$e({}, state, { + return _extends$d({}, state, { notifications: newNotifications }); }, @@ -6138,7 +6143,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$e({}, state, { + return _extends$d({}, state, { notifications }); }, @@ -6147,7 +6152,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$e({}, state, { + return _extends$d({}, state, { notifications: newNotifications }); }, @@ -6158,7 +6163,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$e({}, state, { + return _extends$d({}, state, { errors: newErrors }); }, @@ -6166,13 +6171,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$e({}, state, { + return _extends$d({}, state, { errors: newErrors }); } }, defaultState$4); -var _extends$f = 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; }; +var _extends$e = 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$4(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; } @@ -6213,20 +6218,20 @@ const defaultState$5 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$f({}, state, data); + return _extends$e({}, state, data); }, - [CLEAR_PUBLISH]: state => _extends$f({}, defaultState$5, { + [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$5, { bid: state.bid, optimize: state.optimize }), - [PUBLISH_START]: state => _extends$f({}, state, { + [PUBLISH_START]: state => _extends$e({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$f({}, state, { + [PUBLISH_FAIL]: state => _extends$e({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$f({}, state, { + [PUBLISH_SUCCESS]: state => _extends$e({}, state, { publishing: false, publishSuccess: true }), @@ -6241,14 +6246,14 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$f({}, defaultState$5, publishData, { + return _extends$e({}, defaultState$5, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$5); -var _extends$g = 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; }; +var _extends$f = 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; }; const defaultState$6 = { isActive: false, // does the user have any typed text in the search input @@ -6270,23 +6275,23 @@ const defaultState$6 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$g({}, state, { + [SEARCH_START]: state => _extends$f({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$g({}, state, { + return _extends$f({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$g({}, state, { + [SEARCH_FAIL]: state => _extends$f({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$g({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$f({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -6304,24 +6309,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$g({}, state, { + return _extends$f({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$g({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$f({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$g({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$f({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$g({}, state, { - suggestions: _extends$g({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$f({}, state, { + suggestions: _extends$f({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -6329,30 +6334,30 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$g({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$f({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$g({}, state, { + [SEARCH_FOCUS]: state => _extends$f({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$g({}, state, { + [SEARCH_BLUR]: state => _extends$f({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$g({}, oldOptions, newOptions); - return _extends$g({}, state, { + const options = _extends$f({}, oldOptions, newOptions); + return _extends$f({}, state, { options }); } }, defaultState$6); -var _extends$h = 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; }; +var _extends$g = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$h({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$g({}, tagsMap, { [tag]: { name: tag } }), {}); } @@ -6375,7 +6380,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$h({}, state, { + return _extends$g({}, state, { followedTags: newFollowedTags }); }, @@ -6384,10 +6389,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$h({}, knownTags); + let newKnownTags = _extends$g({}, knownTags); newKnownTags[name] = { name }; - return _extends$h({}, state, { + return _extends$g({}, state, { knownTags: newKnownTags }); }, @@ -6396,11 +6401,11 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$h({}, knownTags); + let newKnownTags = _extends$g({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$h({}, state, { + return _extends$g({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -6408,15 +6413,15 @@ const tagsReducer = handleActions({ [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; if (Array.isArray(tags)) { - return _extends$h({}, state, { + return _extends$g({}, state, { followedTags: tags }); } - return _extends$h({}, state); + return _extends$g({}, state); } }, defaultState$7); -var _extends$i = 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; }; +var _extends$h = 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; }; const defaultState$8 = { blockedChannels: [] @@ -6440,13 +6445,13 @@ const blockedReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { blocked } = action.data; - return _extends$i({}, state, { + return _extends$h({}, state, { blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } }, defaultState$8); -var _extends$j = 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; }; +var _extends$i = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -6498,40 +6503,40 @@ const defaultState$9 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$j({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$i({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$j({}, state.transactions); + const byId = _extends$i({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$j({}, state, { + return _extends$i({}, state, { transactions: byId, fetchingTransactions: false }); }, [FETCH_TXO_PAGE_STARTED]: state => { - return _extends$j({}, state, { + return _extends$i({}, state, { fetchingTxos: true, fetchingTxosError: undefined }); }, [FETCH_TXO_PAGE_COMPLETED]: (state, action) => { - return _extends$j({}, state, { + return _extends$i({}, state, { txoPage: action.data, fetchingTxos: false }); }, [FETCH_TXO_PAGE_FAILED]: (state, action) => { - return _extends$j({}, state, { + return _extends$i({}, state, { txoPage: {}, fetchingTxos: false, fetchingTxosError: action.data @@ -6539,12 +6544,12 @@ const walletReducer = handleActions({ }, [UPDATE_TXO_FETCH_PARAMS]: (state, action) => { - return _extends$j({}, state, { + return _extends$i({}, state, { txoFetchParams: action.data }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$j({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$i({}, state, { fetchingSupports: true }), @@ -6557,7 +6562,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$j({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$i({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -6566,7 +6571,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$j({}, state, { + return _extends$i({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -6579,20 +6584,20 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$j({}, state, { + return _extends$i({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, [ABANDON_CLAIM_SUPPORT_STARTED]: (state, action) => { - return _extends$j({}, state, { + return _extends$i({}, state, { abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_PREVIEW]: (state, action) => { - return _extends$j({}, state, { + return _extends$i({}, state, { abandonClaimSupportError: undefined }); }, @@ -6603,36 +6608,36 @@ const walletReducer = handleActions({ pendingtxs[claimId] = { txid, type, effective }; - return _extends$j({}, state, { + return _extends$i({}, state, { pendingSupportTransactions: pendingtxs, abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_FAILED]: (state, action) => { - return _extends$j({}, state, { + return _extends$i({}, state, { abandonClaimSupportError: action.data }); }, [PENDING_SUPPORTS_UPDATED]: (state, action) => { - return _extends$j({}, state, { + return _extends$i({}, state, { pendingSupportTransactions: action.data }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$j({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$j({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$i({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$j({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$i({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -6641,32 +6646,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$j({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$i({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$j({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$i({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$j({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$i({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$j({}, state, { draftTransaction: newDraft }); + return _extends$i({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$j({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$i({}, oldDraft, { address: action.data.address }); - return _extends$j({}, state, { draftTransaction: newDraft }); + return _extends$i({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$j({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$i({}, state.draftTransaction, { sending: true }); - return _extends$j({}, state, { draftTransaction: newDraftTransaction }); + return _extends$i({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -6679,114 +6684,114 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$j({}, state, { draftTransaction: newDraftTransaction }); + return _extends$i({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$j({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$i({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$j({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$i({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$j({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$i({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$j({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$i({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$i({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$j({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$i({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$j({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$i({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$j({}, state, { + [WALLET_DECRYPT_START]: state => _extends$i({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$j({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$i({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$j({}, state, { + [WALLET_UNLOCK_START]: state => _extends$i({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$i({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$j({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$i({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$j({}, state, { + [WALLET_LOCK_START]: state => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$j({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$i({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$j({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$i({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$j({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$i({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$j({}, state, { + [WALLET_RESTART]: state => _extends$i({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$j({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$i({}, state, { walletReconnecting: false }) }, defaultState$9); @@ -6804,14 +6809,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$k = 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; }; +var _extends$j = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$k({ + return _extends$j({ id }, params); } @@ -6959,7 +6964,7 @@ exports.doAddTag = doAddTag; exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; -exports.doCheckPendingClaims = doCheckPendingClaims; +exports.doCheckPendingPublishes = doCheckPendingPublishes; exports.doCheckPublishNameAvailability = doCheckPublishNameAvailability; exports.doCheckReflectingFiles = doCheckReflectingFiles; exports.doClaimSearch = doClaimSearch; @@ -7068,6 +7073,7 @@ exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectOmittedCountForChannel = makeSelectOmittedCountForChannel; exports.makeSelectPendingAmountByUri = makeSelectPendingAmountByUri; +exports.makeSelectPendingByUri = makeSelectPendingByUri; exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; @@ -7159,7 +7165,6 @@ exports.selectIsStillEditing = selectIsStillEditing; exports.selectIsWalletReconnecting = selectIsWalletReconnecting; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; -exports.selectMyChannelUrls = selectMyChannelUrls; exports.selectMyClaimForUri = selectMyClaimForUri; exports.selectMyClaimUrisWithoutChannels = selectMyClaimUrisWithoutChannels; exports.selectMyClaims = selectMyClaims; @@ -7172,6 +7177,8 @@ exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; exports.selectMyPurchases = selectMyPurchases; exports.selectMyPurchasesCount = selectMyPurchasesCount; exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount; +exports.selectPendingById = selectPendingById; +exports.selectPendingClaims = selectPendingClaims; exports.selectPendingSupportTransactions = selectPendingSupportTransactions; exports.selectPlayingUri = selectPlayingUri; exports.selectPublishFormValues = selectPublishFormValues; diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index 0b97c0e..c9732bd 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -22,7 +22,7 @@ declare type GenericClaim = { timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed is_channel_signature_valid?: boolean, - is_my_output: boolean, + is_my_output: true, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index 0b97c0e..c9732bd 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -22,7 +22,7 @@ declare type GenericClaim = { timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed is_channel_signature_valid?: boolean, - is_my_output: boolean, + is_my_output: true, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx diff --git a/src/index.js b/src/index.js index dcec873..76f5ed6 100644 --- a/src/index.js +++ b/src/index.js @@ -76,7 +76,6 @@ export { doClearRepostError, doCheckPublishNameAvailability, doPurchaseList, - doCheckPendingClaims, } from 'redux/actions/claims'; export { doClearPurchasedUriSuccess, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -95,6 +94,7 @@ export { doUploadThumbnail, doPrepareEdit, doPublish, + doCheckPendingPublishes, doCheckReflectingFiles, } from 'redux/actions/publish'; @@ -198,6 +198,7 @@ export { makeSelectFirstRecommendedFileForUri, makeSelectChannelForClaimUri, makeSelectClaimIsPending, + makeSelectPendingByUri, makeSelectReflectingClaimForUri, makeSelectClaimsInChannelForCurrentPageState, makeSelectShortUrlForUri, @@ -206,6 +207,7 @@ export { makeSelectSupportsForUri, makeSelectMyPurchasesForPage, makeSelectClaimWasPurchased, + selectPendingById, selectReflectingById, selectClaimsById, selectClaimsByUri, @@ -215,9 +217,9 @@ export { selectMyActiveClaims, selectAllFetchingChannelClaims, selectIsFetchingClaimListMine, + selectPendingClaims, selectMyClaims, selectMyClaimsWithoutChannels, - selectMyChannelUrls, selectMyClaimUrisWithoutChannels, selectAllMyClaimsByOutpoint, selectMyClaimsOutpoints, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 615b7a6..56a4baf 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -9,7 +9,6 @@ import { selectResolvingUris, selectClaimsByUri, selectMyChannelClaims, - selectPendingIds, } from 'redux/selectors/claims'; import { doFetchTxoPage } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; @@ -339,7 +338,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { }; } -export function doCreateChannel(name: string, amount: number, optionalParams: any, cb: any) { +export function doCreateChannel(name: string, amount: number, optionalParams: any) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CREATE_CHANNEL_STARTED, @@ -396,13 +395,6 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an type: ACTIONS.CREATE_CHANNEL_COMPLETED, data: { channelClaim }, }); - dispatch({ - type: ACTIONS.UPDATE_PENDING_CLAIMS, - data: { - claims: [channelClaim], - }, - }); - dispatch(doCheckPendingClaims(cb)); return channelClaim; }) .catch(error => { @@ -416,7 +408,7 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an }; } -export function doUpdateChannel(params: any, cb: any) { +export function doUpdateChannel(params: any) { return (dispatch: Dispatch, getState: GetState) => { dispatch({ type: ACTIONS.UPDATE_CHANNEL_STARTED, @@ -462,16 +454,7 @@ export function doUpdateChannel(params: any, cb: any) { type: ACTIONS.UPDATE_CHANNEL_COMPLETED, data: { channelClaim }, }); - dispatch({ - type: ACTIONS.UPDATE_PENDING_CLAIMS, - data: { - claims: [channelClaim], - }, - }); - dispatch(doCheckPendingClaims(cb)); - return Boolean(result.outputs[0]); }) - .then() .catch(error => { dispatch({ type: ACTIONS.UPDATE_CHANNEL_FAILED, @@ -686,48 +669,3 @@ export function doPurchaseList(page: number = 1, pageSize: number = PAGE_SIZE) { }).then(success, failure); }; } - -export const doCheckPendingClaims = (onConfirmed: Function) => ( - dispatch: Dispatch, - getState: GetState -) => { - let claimCheckInterval; - - const checkClaimList = () => { - const state = getState(); - const pendingIdSet = new Set(selectPendingIds(state)); - Lbry.claim_list({ page: 1, page_size: 10 }) - .then(result => { - const claims = result.items; - const claimsToConfirm = []; - claims.forEach(claim => { - const { claim_id: claimId } = claim; - if (claim.confirmations > 0 && pendingIdSet.has(claimId)) { - pendingIdSet.delete(claimId); - claimsToConfirm.push(claim); - if (onConfirmed) { - onConfirmed(claim); - } - } - }); - if (claimsToConfirm.length) { - dispatch({ - type: ACTIONS.UPDATE_CONFIRMED_CLAIMS, - data: { - claims: claimsToConfirm, - }, - }); - } - return pendingIdSet.size; - }) - .then(len => { - if (!len) { - clearInterval(claimCheckInterval); - } - }); - }; - - claimCheckInterval = setInterval(() => { - checkClaimList(); - }, 30000); -}; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index c977640..23d6d74 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -10,6 +10,7 @@ import { doError } from 'redux/actions/notifications'; import { isClaimNsfw } from 'util/claim'; import { selectMyChannelClaims, + selectPendingById, selectMyClaimsWithoutChannels, selectReflectingById, } from 'redux/selectors/claims'; @@ -426,3 +427,46 @@ export const doCheckReflectingFiles = () => (dispatch: Dispatch, getState: GetSt }, 5000); } }; +export const doCheckPendingPublishes = (onConfirmed: Function) => ( + dispatch: Dispatch, + getState: GetState +) => { + let publishCheckInterval; + + const checkFileList = () => { + const state = getState(); + const pendingById = selectPendingById(state); + Lbry.claim_list({ page: 1, page_size: 10 }) + .then(result => { + const claims = result.items; + const claimsToConfirm = []; + claims.forEach(claim => { + if (claim.confirmations > 0 && pendingById[claim.claim_id]) { + delete pendingById[claim.claim_id]; + claimsToConfirm.push(claim); + if (onConfirmed) { + onConfirmed(claim); + } + } + }); + if (claimsToConfirm.length) { + dispatch({ + type: ACTIONS.UPDATE_CONFIRMED_CLAIMS, + data: { + claims: claimsToConfirm, + }, + }); + } + return Object.keys(pendingById).length; + }) + .then(len => { + if (!len) { + clearInterval(publishCheckInterval); + } + }); + }; + + publishCheckInterval = setInterval(() => { + checkFileList(); + }, 30000); +}; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index f6f2a69..d74ffd1 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -9,7 +9,7 @@ // - Sean import * as ACTIONS from 'constants/action_types'; -import mergeClaim from 'util/merge-claim'; +import { buildURI, parseURI } from 'lbryURI'; type State = { createChannelError: ?string, @@ -17,7 +17,7 @@ type State = { claimsByUri: { [string]: string }, byId: { [string]: Claim }, resolvingUris: Array, - pendingIds: Array, + pendingById: { [string]: Claim }, reflectingById: { [string]: ReflectingUpdate }, myClaims: ?Array, myChannelClaims: ?Array, @@ -75,7 +75,7 @@ const defaultState = { fetchingMyPurchasesError: undefined, fetchingMyChannels: false, abandoningById: {}, - pendingIds: [], + pendingById: {}, reflectingById: {}, claimSearchError: false, claimSearchByQuery: {}, @@ -112,19 +112,18 @@ function handleClaimAction(state: State, action: any): State { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); - const pendingIds = state.pendingIds; let newResolvingUrls = new Set(state.resolvingUris); Object.entries(resolveInfo).forEach(([url: string, resolveResponse: ResolveResponse]) => { // $FlowFixMe const { claimsInChannel, stream, channel } = resolveResponse; + if (claimsInChannel) { + channelClaimCounts[url] = claimsInChannel; + channelClaimCounts[channel.canonical_url] = claimsInChannel; + } if (stream) { - if (pendingIds.includes(stream.claim_id)) { - byId[stream.claim_id] = mergeClaim(stream, byId[stream.claim_id]); - } else { - byId[stream.claim_id] = stream; - } + byId[stream.claim_id] = stream; byUri[url] = stream.claim_id; // If url isn't a canonical_url, make sure that is added too @@ -136,18 +135,12 @@ function handleClaimAction(state: State, action: any): State { newResolvingUrls.delete(stream.permanent_url); } - if (channel && channel.claim_id) { - if (claimsInChannel) { - channelClaimCounts[url] = claimsInChannel; - channelClaimCounts[channel.canonical_url] = claimsInChannel; + if (channel) { + if (!stream) { + byUri[url] = channel.claim_id; } - byUri[url] = channel.claim_id; - if (pendingIds.includes(channel.claim_id)) { - byId[channel.claim_id] = mergeClaim(channel, byId[channel.claim_id]); - } else { - byId[channel.claim_id] = channel; - } + byId[channel.claim_id] = channel; // Also add the permanent_url here until lighthouse returns canonical_url for search results byUri[channel.permanent_url] = channel.claim_id; byUri[channel.canonical_url] = channel.claim_id; @@ -205,37 +198,47 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingIds = state.pendingIds || []; + const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); let urlsForCurrentPage = []; - const pendingIdSet = new Set(pendingIds); - claims.forEach((claim: Claim) => { - const { permanent_url: permanentUri, claim_id: claimId } = claim; + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { - urlsForCurrentPage.push(permanentUri); + urlsForCurrentPage.push(uri); if (claim.confirmations < 1) { - pendingIdSet.add(claimId); - } else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) { - pendingIdSet.delete(claimId); - } - if (pendingIds.includes(claimId)) { - byId[claimId] = mergeClaim(claim, byId[claimId]); + pendingById[claimId] = claim; + delete byId[claimId]; + delete byUri[claimId]; } else { byId[claimId] = claim; + byUri[uri] = claimId; } - byUri[permanentUri] = claimId; myClaimIds.add(claimId); + if (!resolve && pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; + } } }); + // Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0) + if (!resolve) { + Object.values(pendingById) + // $FlowFixMe + .filter(pendingClaim => byId[pendingClaim.claim_id]) + .forEach(pendingClaim => { + // $FlowFixMe + delete pendingById[pendingClaim.claim_id]; + }); + } + return Object.assign({}, state, { isFetchingClaimListMine: false, myClaims: Array.from(myClaimIds), byId, - pendingIds: Array.from(pendingIdSet), claimsByUri: byUri, + pendingById, myClaimsPageResults: urlsForCurrentPage, myClaimsPageNumber: page, myClaimsPageTotalResults: totalItems, @@ -249,7 +252,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St const { claims }: { claims: Array } = action.data; const myClaims = state.myClaims || []; let myClaimIds = new Set(state.myClaims); - const pendingIds = state.pendingIds || []; + const pendingById = Object.assign(state.pendingById); let myChannelClaims; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); @@ -272,10 +275,18 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St // $FlowFixMe myChannelClaims.add(claimId); - if (!pendingIds.some(c => c === claimId)) { + if (!byId[claimId]) { byId[claimId] = claim; } + myClaimIds.add(claimId); + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; + } + + if (pendingById[claimId] && claim.confirmations > 0) { + delete pendingById[claimId]; + } }); } @@ -285,7 +296,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St channelClaimCounts, fetchingMyChannels: false, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, - myClaims: myClaimIds ? Array.from(myClaimIds) : null, + myClaims: Array.from(myClaimIds), }); }; @@ -374,31 +385,19 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State => }; reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => { - const { claims: pendingClaims }: { claims: Array } = action.data; + const { claims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingIds = state.pendingIds; - const pendingIdSet = new Set(pendingIds); + const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); let myClaimIds = new Set(state.myClaims); - const myChannelClaims = new Set(state.myChannelClaims); // $FlowFixMe - pendingClaims.forEach((claim: Claim) => { - let newClaim; - const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim; - pendingIdSet.add(claimId); - const oldClaim = byId[claimId]; - if (oldClaim && oldClaim.canonical_url) { - newClaim = mergeClaim(oldClaim, claim); - } else { - newClaim = claim; - } - if (valueType === 'channel') { - myChannelClaims.add(claimId); - } - - if (type && type.match(/claim|update/)) { - byId[claimId] = newClaim; + claims.forEach((claim: Claim) => { + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; + if (claim.type && claim.type.match(/claim|update/)) { + pendingById[claimId] = claim; + delete byId[claimId]; byUri[uri] = claimId; } myClaimIds.add(claimId); @@ -406,35 +405,32 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => return Object.assign({}, state, { myClaims: Array.from(myClaimIds), byId, - myChannelClaims: Array.from(myChannelClaims), claimsByUri: byUri, - pendingIds: Array.from(pendingIdSet), + pendingById, }); }; reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => { - const { claims: confirmedClaims }: { claims: Array } = action.data; + const { claims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingIds = state.pendingIds; - const pendingIdSet = new Set(pendingIds); + const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); + let myClaimIds = new Set(state.myClaims); - confirmedClaims.forEach((claim: GenericClaim) => { - const { permanent_url: permanentUri, claim_id: claimId, type } = claim; - let newClaim = claim; - const oldClaim = byId[claimId]; - if (oldClaim && oldClaim.canonical_url) { - newClaim = mergeClaim(oldClaim, claim); - } - if (type && type.match(/claim|update|channel/)) { - byId[claimId] = newClaim; - pendingIdSet.delete(claimId); + claims.forEach((claim: GenericClaim) => { + const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); + const { claim_id: claimId } = claim; + if (claim.type && claim.type.match(/claim|update/)) { + delete pendingById[claimId]; + byId[claimId] = claim; } + myClaimIds.add(claimId); }); return Object.assign({}, state, { - pendingIds: Array.from(pendingIdSet), + myClaims: Array.from(myClaimIds), byId, claimsByUri: byUri, + pendingById, }); }; @@ -470,7 +466,19 @@ reducers[ACTIONS.CREATE_CHANNEL_STARTED] = (state: State): State => ({ }); reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { + const channelClaim: ChannelClaim = action.data.channelClaim; + const byId = Object.assign({}, state.byId); + const pendingById = Object.assign({}, state.pendingById); + const myChannelClaims = new Set(state.myChannelClaims); + + byId[channelClaim.claim_id] = channelClaim; + pendingById[channelClaim.claim_id] = channelClaim; + myChannelClaims.add(channelClaim.claim_id); + return Object.assign({}, state, { + byId, + pendingById, + myChannelClaims: Array.from(myChannelClaims), creatingChannel: false, }); }; @@ -490,7 +498,13 @@ reducers[ACTIONS.UPDATE_CHANNEL_STARTED] = (state: State, action: any): State => }; reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { + const channelClaim: ChannelClaim = action.data.channelClaim; + const byId = Object.assign({}, state.byId); + + byId[channelClaim.claim_id] = channelClaim; + return Object.assign({}, state, { + byId, updateChannelError: '', updatingChannel: false, }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index b724567..e2ced6c 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -6,7 +6,7 @@ import { } from 'redux/selectors/search'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { createSelector } from 'reselect'; -import { isClaimNsfw, filterClaims } from 'util/claim'; +import { isClaimNsfw, createNormalizedClaimSearchKey, filterClaims } from 'util/claim'; import { getSearchQueryString } from 'util/query-params'; import { PAGE_SIZE } from 'constants/claim'; @@ -48,9 +48,10 @@ export const selectRepostError = createSelector( ); export const selectClaimsByUri = createSelector( - selectClaimIdsByUri, + selectState, selectClaimsById, - (byUri, byId) => { + (state, byId) => { + const byUri = state.claimsByUri || {}; const claims = {}; Object.keys(byUri).forEach(uri => { @@ -75,25 +76,42 @@ export const selectAllClaimsByChannel = createSelector( state => state.paginatedClaimsByChannel || {} ); -export const selectPendingIds = createSelector( +export const selectPendingById = createSelector( selectState, - state => state.pendingIds || [] + state => state.pendingById || {} +); + +export const selectPendingClaims = createSelector( + selectState, + state => Object.values(state.pendingById || []) ); export const makeSelectClaimIsPending = (uri: string) => createSelector( - selectClaimIdsByUri, - selectPendingIds, - (idsByUri, pendingIds) => { - const claimId = idsByUri[normalizeURI(uri)]; + selectPendingById, + pendingById => { + let claimId; + + try { + const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); + claimId = isChannel ? channelClaimId : streamClaimId; + } catch (e) {} if (claimId) { - return pendingIds.some(i => i === claimId); + return Boolean(pendingById[claimId]); } - return false; } ); +export const makeSelectPendingByUri = (uri: string) => + createSelector( + selectPendingById, + pendingById => { + const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); + const claimId = isChannel ? channelClaimId : streamClaimId; + return pendingById[claimId]; + } + ); export const selectReflectingById = createSelector( selectState, state => state.reflectingById @@ -101,21 +119,30 @@ export const selectReflectingById = createSelector( export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) => createSelector( - selectClaimIdsByUri, - selectClaimsById, - (byUri, byId) => { - let validUri; + selectClaimsByUri, + selectPendingById, + (byUri, pendingById) => { + // Check if a claim is pending first + // It won't be in claimsByUri because resolving it will return nothing + + let valid; let channelClaimId; let streamClaimId; let isChannel; try { ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); - validUri = true; + valid = true; } catch (e) {} - if (validUri && byUri) { - const claimId = uri && byUri[normalizeURI(uri)]; - const claim = byId[claimId]; + if (valid && byUri) { + const claimId = isChannel ? channelClaimId : streamClaimId; + const pendingClaim = pendingById[claimId]; + + if (pendingClaim) { + return pendingClaim; + } + + const claim = byUri[normalizeURI(uri)]; if (claim === undefined || claim === null) { // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) return claim; @@ -429,7 +456,8 @@ export const selectMyClaims = createSelector( selectMyActiveClaims, selectClaimsById, selectAbandoningIds, - (myClaimIds, byId, abandoningIds) => { + selectPendingClaims, + (myClaimIds, byId, abandoningIds, pendingClaims) => { const claims = []; myClaimIds.forEach(id => { @@ -438,7 +466,7 @@ export const selectMyClaims = createSelector( if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); }); - return [...claims]; + return [...claims, ...pendingClaims]; } ); @@ -510,11 +538,6 @@ export const selectMyChannelClaims = createSelector( } ); -export const selectMyChannelUrls = createSelector( - selectMyChannelClaims, - claims => claims ? claims.map(claim => claim.canonical_url || claim.permanent_url) : undefined -); - export const selectResolvingUris = createSelector( selectState, state => state.resolvingUris || [] diff --git a/src/util/merge-claim.js b/src/util/merge-claim.js deleted file mode 100644 index 3ab2976..0000000 --- a/src/util/merge-claim.js +++ /dev/null @@ -1,7 +0,0 @@ -/* -new claim = { ...maybeResolvedClaim, ...pendingClaim, meta: maybeResolvedClaim['meta'] } - */ - -export default function mergeClaims(maybeResolved, pending){ - return { ...maybeResolved, ...pending, meta: maybeResolved.meta }; -} -- 2.45.2 From e9d03635883fbe87f1835fca0bf28b402cca6696 Mon Sep 17 00:00:00 2001 From: jessop Date: Tue, 16 Jun 2020 21:56:51 -0400 Subject: [PATCH 354/371] support pending channels bugfix bugfix2 --- dist/bundle.es.js | 596 +++++++++++++++++----------------- dist/flow-typed/Claim.js | 2 +- flow-typed/Claim.js | 2 +- src/index.js | 6 +- src/redux/actions/claims.js | 66 +++- src/redux/actions/publish.js | 44 --- src/redux/reducers/claims.js | 155 ++++----- src/redux/selectors/claims.js | 75 ++--- src/util/merge-claim.js | 7 + 9 files changed, 465 insertions(+), 488 deletions(-) create mode 100644 src/util/merge-claim.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 171bd30..4792db5 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2180,8 +2180,7 @@ const selectRepostLoading = reselect.createSelector(selectState$2, state => stat const selectRepostError = reselect.createSelector(selectState$2, state => state.repostError); -const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsById, (state, byId) => { - const byUri = state.claimsByUri || {}; +const selectClaimsByUri = reselect.createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => { const claims = {}; Object.keys(byUri).forEach(uri => { @@ -2202,52 +2201,32 @@ const selectClaimsByUri = reselect.createSelector(selectState$2, selectClaimsByI const selectAllClaimsByChannel = reselect.createSelector(selectState$2, state => state.paginatedClaimsByChannel || {}); -const selectPendingById = reselect.createSelector(selectState$2, state => state.pendingById || {}); +const selectPendingIds = reselect.createSelector(selectState$2, state => state.pendingIds || []); -const selectPendingClaims = reselect.createSelector(selectState$2, state => Object.values(state.pendingById || [])); - -const makeSelectClaimIsPending = uri => reselect.createSelector(selectPendingById, pendingById => { - let claimId; - - try { - const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); - claimId = isChannel ? channelClaimId : streamClaimId; - } catch (e) {} +const makeSelectClaimIsPending = uri => reselect.createSelector(selectClaimIdsByUri, selectPendingIds, (idsByUri, pendingIds) => { + const claimId = idsByUri[normalizeURI(uri)]; if (claimId) { - return Boolean(pendingById[claimId]); + return pendingIds.some(i => i === claimId); } + return false; }); -const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById, pendingById => { - const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); - const claimId = isChannel ? channelClaimId : streamClaimId; - return pendingById[claimId]; -}); const selectReflectingById = reselect.createSelector(selectState$2, state => state.reflectingById); -const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => { - // Check if a claim is pending first - // It won't be in claimsByUri because resolving it will return nothing - - let valid; +const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimIdsByUri, selectClaimsById, (byUri, byId) => { + let validUri; let channelClaimId; let streamClaimId; let isChannel; try { ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); - valid = true; + validUri = true; } catch (e) {} - if (valid && byUri) { - const claimId = isChannel ? channelClaimId : streamClaimId; - const pendingClaim = pendingById[claimId]; - - if (pendingClaim) { - return pendingClaim; - } - - const claim = byUri[normalizeURI(uri)]; + if (validUri && byUri) { + const claimId = uri && byUri[normalizeURI(uri)]; + const claim = byId[claimId]; if (claim === undefined || claim === null) { // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) return claim; @@ -2416,7 +2395,7 @@ const selectMyClaimsPageItemCount = reselect.createSelector(selectState$2, state const selectFetchingMyClaimsPageError = reselect.createSelector(selectState$2, state => state.fetchingClaimListMinePageError); -const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, selectPendingClaims, (myClaimIds, byId, abandoningIds, pendingClaims) => { +const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaimsById, selectAbandoningIds, (myClaimIds, byId, abandoningIds) => { const claims = []; myClaimIds.forEach(id => { @@ -2425,7 +2404,7 @@ const selectMyClaims = reselect.createSelector(selectMyActiveClaims, selectClaim if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); }); - return [...claims, ...pendingClaims]; + return [...claims]; }); const selectMyClaimsWithoutChannels = reselect.createSelector(selectMyClaims, myClaims => myClaims.filter(claim => !claim.name.match(/^@/)).sort((a, b) => a.timestamp - b.timestamp)); @@ -2473,6 +2452,8 @@ const selectMyChannelClaims = reselect.createSelector(selectState$2, selectClaim return claims; }); +const selectMyChannelUrls = reselect.createSelector(selectMyChannelClaims, claims => claims ? claims.map(claim => claim.canonical_url || claim.permanent_url) : undefined); + const selectResolvingUris = reselect.createSelector(selectState$2, state => state.resolvingUris || []); const selectChannelImportPending = reselect.createSelector(selectState$2, state => state.pendingChannelImport); @@ -2876,8 +2857,8 @@ function doSendDraftTransaction(address, amount) { if (balance - amount <= 0) { dispatch(doToast({ - title: 'Insufficient credits', - message: 'Insufficient credits' + title: __('Insufficient credits'), + message: __('Insufficient credits') })); return; } @@ -2892,8 +2873,8 @@ function doSendDraftTransaction(address, amount) { type: SEND_TRANSACTION_COMPLETED }); dispatch(doToast({ - message: `You sent ${amount} LBC`, - linkText: 'History', + message: __('You sent ${amount} LBC'), + linkText: __('History'), linkTarget: '/wallet' })); } else { @@ -2902,7 +2883,7 @@ function doSendDraftTransaction(address, amount) { data: { error: response } }); dispatch(doToast({ - message: 'Transaction failed', + message: __('Transaction failed'), isError: true })); } @@ -2914,7 +2895,7 @@ function doSendDraftTransaction(address, amount) { data: { error: error.message } }); dispatch(doToast({ - message: 'Transaction failed', + message: __('Transaction failed'), isError: true })); }; @@ -2960,7 +2941,7 @@ function doSendTip(params, isSupport, successCallback, errorCallback) { dispatch(doToast({ message: shouldSupport ? __('You deposited %amount% LBC as a support!', { amount: params.amount }) : __('You sent %amount% LBC as a tip, Mahalo!', { amount: params.amount }), linkText: __('History'), - linkTarget: __('/wallet') + linkTarget: '/wallet' })); dispatch({ @@ -3506,7 +3487,7 @@ function doFetchClaimsByChannel(uri, page = 1) { }; } -function doCreateChannel(name, amount, optionalParams) { +function doCreateChannel(name, amount, optionalParams, cb) { return dispatch => { dispatch({ type: CREATE_CHANNEL_STARTED @@ -3551,6 +3532,13 @@ function doCreateChannel(name, amount, optionalParams) { type: CREATE_CHANNEL_COMPLETED, data: { channelClaim } }); + dispatch({ + type: UPDATE_PENDING_CLAIMS, + data: { + claims: [channelClaim] + } + }); + dispatch(doCheckPendingClaims(cb)); return channelClaim; }).catch(error => { dispatch({ @@ -3562,7 +3550,7 @@ function doCreateChannel(name, amount, optionalParams) { }; } -function doUpdateChannel(params) { +function doUpdateChannel(params, cb) { return (dispatch, getState) => { dispatch({ type: UPDATE_CHANNEL_STARTED @@ -3607,7 +3595,15 @@ function doUpdateChannel(params) { type: UPDATE_CHANNEL_COMPLETED, data: { channelClaim } }); - }).catch(error => { + dispatch({ + type: UPDATE_PENDING_CLAIMS, + data: { + claims: [channelClaim] + } + }); + dispatch(doCheckPendingClaims(cb)); + return Boolean(result.outputs[0]); + }).then().catch(error => { dispatch({ type: UPDATE_CHANNEL_FAILED, data: error @@ -3803,6 +3799,46 @@ function doPurchaseList(page = 1, pageSize = PAGE_SIZE) { }; } +const doCheckPendingClaims = onConfirmed => (dispatch, getState) => { + let claimCheckInterval; + + const checkClaimList = () => { + const state = getState(); + const pendingIdSet = new Set(selectPendingIds(state)); + lbryProxy.claim_list({ page: 1, page_size: 10 }).then(result => { + const claims = result.items; + const claimsToConfirm = []; + claims.forEach(claim => { + const { claim_id: claimId } = claim; + if (claim.confirmations > 0 && pendingIdSet.has(claimId)) { + pendingIdSet.delete(claimId); + claimsToConfirm.push(claim); + if (onConfirmed) { + onConfirmed(claim); + } + } + }); + if (claimsToConfirm.length) { + dispatch({ + type: UPDATE_CONFIRMED_CLAIMS, + data: { + claims: claimsToConfirm + } + }); + } + return pendingIdSet.size; + }).then(len => { + if (!len) { + clearInterval(claimCheckInterval); + } + }); + }; + + claimCheckInterval = setInterval(() => { + checkClaimList(); + }, 30000); +}; + const selectState$3 = state => state.fileInfo || {}; const selectFileInfosByOutpoint = reselect.createSelector(selectState$3, state => state.byOutpoint || {}); @@ -4588,44 +4624,6 @@ const doCheckReflectingFiles = () => (dispatch, getState) => { }, 5000); } }; -const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => { - let publishCheckInterval; - - const checkFileList = () => { - const state = getState(); - const pendingById = selectPendingById(state); - lbryProxy.claim_list({ page: 1, page_size: 10 }).then(result => { - const claims = result.items; - const claimsToConfirm = []; - claims.forEach(claim => { - if (claim.confirmations > 0 && pendingById[claim.claim_id]) { - delete pendingById[claim.claim_id]; - claimsToConfirm.push(claim); - if (onConfirmed) { - onConfirmed(claim); - } - } - }); - if (claimsToConfirm.length) { - dispatch({ - type: UPDATE_CONFIRMED_CLAIMS, - data: { - claims: claimsToConfirm - } - }); - } - return Object.keys(pendingById).length; - }).then(len => { - if (!len) { - clearInterval(publishCheckInterval); - } - }); - }; - - publishCheckInterval = setInterval(() => { - checkFileList(); - }, 30000); -}; // Returns a function, that, as long as it continues to be invoked, will not // be triggered. The function will be called after it stops being called for @@ -5112,6 +5110,16 @@ const doToggleBlockChannel = uri => ({ var _extends$a = 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; }; +/* +new claim = { ...maybeResolvedClaim, ...pendingClaim, meta: maybeResolvedClaim['meta'] } + */ + +function mergeClaims(maybeResolved, pending) { + return _extends$a({}, maybeResolved, pending, { meta: maybeResolved.meta }); +} + +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$3(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 reducers = {}; @@ -5132,7 +5140,7 @@ const defaultState = { fetchingMyPurchasesError: undefined, fetchingMyChannels: false, abandoningById: {}, - pendingById: {}, + pendingIds: [], reflectingById: {}, claimSearchError: false, claimSearchByQuery: {}, @@ -5163,18 +5171,19 @@ function handleClaimAction(state, action) { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + const pendingIds = state.pendingIds; let newResolvingUrls = new Set(state.resolvingUris); Object.entries(resolveInfo).forEach(([url, resolveResponse]) => { // $FlowFixMe const { claimsInChannel, stream, channel } = resolveResponse; - if (claimsInChannel) { - channelClaimCounts[url] = claimsInChannel; - channelClaimCounts[channel.canonical_url] = claimsInChannel; - } if (stream) { - byId[stream.claim_id] = stream; + if (pendingIds.includes(stream.claim_id)) { + byId[stream.claim_id] = mergeClaims(stream, byId[stream.claim_id]); + } else { + byId[stream.claim_id] = stream; + } byUri[url] = stream.claim_id; // If url isn't a canonical_url, make sure that is added too @@ -5186,12 +5195,17 @@ function handleClaimAction(state, action) { newResolvingUrls.delete(stream.permanent_url); } - if (channel) { - if (!stream) { - byUri[url] = channel.claim_id; + if (channel && channel.claim_id) { + if (claimsInChannel) { + channelClaimCounts[url] = claimsInChannel; + channelClaimCounts[channel.canonical_url] = claimsInChannel; } - byId[channel.claim_id] = channel; + if (pendingIds.includes(channel.claim_id)) { + byId[channel.claim_id] = mergeClaims(channel, byId[channel.claim_id]); + } else { + byId[channel.claim_id] = channel; + } // Also add the permanent_url here until lighthouse returns canonical_url for search results byUri[channel.permanent_url] = channel.claim_id; byUri[channel.canonical_url] = channel.claim_id; @@ -5231,7 +5245,7 @@ reducers[RESOLVE_URIS_STARTED] = (state, action) => { }; reducers[RESOLVE_URIS_COMPLETED] = (state, action) => { - return _extends$a({}, handleClaimAction(state, action)); + return _extends$b({}, handleClaimAction(state, action)); }; reducers[FETCH_CLAIM_LIST_MINE_STARTED] = state => Object.assign({}, state, { @@ -5246,46 +5260,37 @@ reducers[FETCH_CLAIM_LIST_MINE_COMPLETED] = (state, action) => { const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById = Object.assign({}, state.pendingById); + const pendingIds = state.pendingIds || []; let myClaimIds = new Set(state.myClaims); let urlsForCurrentPage = []; + const pendingIdSet = new Set(pendingIds); + claims.forEach(claim => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; + const { permanent_url: permanentUri, claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { - urlsForCurrentPage.push(uri); + urlsForCurrentPage.push(permanentUri); if (claim.confirmations < 1) { - pendingById[claimId] = claim; - delete byId[claimId]; - delete byUri[claimId]; + pendingIdSet.add(claimId); + } else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) { + pendingIdSet.delete(claimId); + } + if (pendingIds.includes(claimId)) { + byId[claimId] = mergeClaims(claim, byId[claimId]); } else { byId[claimId] = claim; - byUri[uri] = claimId; } + byUri[permanentUri] = claimId; myClaimIds.add(claimId); - if (!resolve && pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } } }); - // Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0) - if (!resolve) { - Object.values(pendingById) - // $FlowFixMe - .filter(pendingClaim => byId[pendingClaim.claim_id]).forEach(pendingClaim => { - // $FlowFixMe - delete pendingById[pendingClaim.claim_id]; - }); - } - return Object.assign({}, state, { isFetchingClaimListMine: false, myClaims: Array.from(myClaimIds), byId, + pendingIds: Array.from(pendingIdSet), claimsByUri: byUri, - pendingById, myClaimsPageResults: urlsForCurrentPage, myClaimsPageNumber: page, myClaimsPageTotalResults: totalItems @@ -5298,7 +5303,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { const { claims } = action.data; const myClaims = state.myClaims || []; let myClaimIds = new Set(state.myClaims); - const pendingById = Object.assign(state.pendingById); + const pendingIds = state.pendingIds || []; let myChannelClaims; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); @@ -5320,18 +5325,10 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { // $FlowFixMe myChannelClaims.add(claimId); - if (!byId[claimId]) { + if (!pendingIds.some(c => c === claimId)) { byId[claimId] = claim; } - myClaimIds.add(claimId); - if (pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } - - if (pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } }); } @@ -5341,7 +5338,7 @@ reducers[FETCH_CHANNEL_LIST_COMPLETED] = (state, action) => { channelClaimCounts, fetchingMyChannels: false, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, - myClaims: Array.from(myClaimIds) + myClaims: myClaimIds ? Array.from(myClaimIds) : null }); }; @@ -5423,19 +5420,31 @@ reducers[ABANDON_CLAIM_STARTED] = (state, action) => { }; reducers[UPDATE_PENDING_CLAIMS] = (state, action) => { - const { claims } = action.data; + const { claims: pendingClaims } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById = Object.assign({}, state.pendingById); + const pendingIds = state.pendingIds; + const pendingIdSet = new Set(pendingIds); let myClaimIds = new Set(state.myClaims); + const myChannelClaims = new Set(state.myChannelClaims); // $FlowFixMe - claims.forEach(claim => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; - if (claim.type && claim.type.match(/claim|update/)) { - pendingById[claimId] = claim; - delete byId[claimId]; + pendingClaims.forEach(claim => { + let newClaim; + const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim; + pendingIdSet.add(claimId); + const oldClaim = byId[claimId]; + if (oldClaim && oldClaim.canonical_url) { + newClaim = mergeClaims(oldClaim, claim); + } else { + newClaim = claim; + } + if (valueType === 'channel') { + myChannelClaims.add(claimId); + } + + if (type && type.match(/claim|update/)) { + byId[claimId] = newClaim; byUri[uri] = claimId; } myClaimIds.add(claimId); @@ -5443,32 +5452,35 @@ reducers[UPDATE_PENDING_CLAIMS] = (state, action) => { return Object.assign({}, state, { myClaims: Array.from(myClaimIds), byId, + myChannelClaims: Array.from(myChannelClaims), claimsByUri: byUri, - pendingById + pendingIds: Array.from(pendingIdSet) }); }; reducers[UPDATE_CONFIRMED_CLAIMS] = (state, action) => { - const { claims } = action.data; + const { claims: confirmedClaims } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById = Object.assign({}, state.pendingById); - let myClaimIds = new Set(state.myClaims); + const pendingIds = state.pendingIds; + const pendingIdSet = new Set(pendingIds); - claims.forEach(claim => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; - if (claim.type && claim.type.match(/claim|update/)) { - delete pendingById[claimId]; - byId[claimId] = claim; + confirmedClaims.forEach(claim => { + const { permanent_url: permanentUri, claim_id: claimId, type } = claim; + let newClaim = claim; + const oldClaim = byId[claimId]; + if (oldClaim && oldClaim.canonical_url) { + newClaim = mergeClaims(oldClaim, claim); + } + if (type && type.match(/claim|update|channel/)) { + byId[claimId] = newClaim; + pendingIdSet.delete(claimId); } - myClaimIds.add(claimId); }); return Object.assign({}, state, { - myClaims: Array.from(myClaimIds), + pendingIds: Array.from(pendingIdSet), byId, - claimsByUri: byUri, - pendingById + claimsByUri: byUri }); }; @@ -5497,25 +5509,13 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; -reducers[CREATE_CHANNEL_STARTED] = state => _extends$a({}, state, { +reducers[CREATE_CHANNEL_STARTED] = state => _extends$b({}, state, { creatingChannel: true, createChannelError: null }); reducers[CREATE_CHANNEL_COMPLETED] = (state, action) => { - const channelClaim = action.data.channelClaim; - const byId = Object.assign({}, state.byId); - const pendingById = Object.assign({}, state.pendingById); - const myChannelClaims = new Set(state.myChannelClaims); - - byId[channelClaim.claim_id] = channelClaim; - pendingById[channelClaim.claim_id] = channelClaim; - myChannelClaims.add(channelClaim.claim_id); - return Object.assign({}, state, { - byId, - pendingById, - myChannelClaims: Array.from(myChannelClaims), creatingChannel: false }); }; @@ -5535,13 +5535,7 @@ reducers[UPDATE_CHANNEL_STARTED] = (state, action) => { }; reducers[UPDATE_CHANNEL_COMPLETED] = (state, action) => { - const channelClaim = action.data.channelClaim; - const byId = Object.assign({}, state.byId); - - byId[channelClaim.claim_id] = channelClaim; - return Object.assign({}, state, { - byId, updateChannelError: '', updatingChannel: false }); @@ -5585,7 +5579,7 @@ reducers[CLAIM_SEARCH_COMPLETED] = (state, action) => { delete fetchingClaimSearchByQuery[query]; - return Object.assign({}, state, _extends$a({}, handleClaimAction(state, action), { + return Object.assign({}, state, _extends$b({}, handleClaimAction(state, action), { claimSearchByQuery, claimSearchByQueryLastPageReached, fetchingClaimSearchByQuery @@ -5607,22 +5601,22 @@ reducers[CLAIM_SEARCH_FAILED] = (state, action) => { }; reducers[CLAIM_REPOST_STARTED] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { repostLoading: true, repostError: null }); }; reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { const { originalClaimId, repostClaim } = action.data; - const byId = _extends$a({}, state.byId); - const claimsByUri = _extends$a({}, state.claimsByUri); + const byId = _extends$b({}, state.byId); + const claimsByUri = _extends$b({}, state.claimsByUri); const claimThatWasReposted = byId[originalClaimId]; - const repostStub = _extends$a({}, repostClaim, { reposted_claim: claimThatWasReposted }); + const repostStub = _extends$b({}, repostClaim, { reposted_claim: claimThatWasReposted }); byId[repostStub.claim_id] = repostStub; claimsByUri[repostStub.permanent_url] = repostStub.claim_id; - return _extends$a({}, state, { + return _extends$b({}, state, { byId, claimsByUri, repostLoading: false, @@ -5632,13 +5626,13 @@ reducers[CLAIM_REPOST_COMPLETED] = (state, action) => { reducers[CLAIM_REPOST_FAILED] = (state, action) => { const { error } = action.data; - return _extends$a({}, state, { + return _extends$b({}, state, { repostLoading: false, repostError: error }); }; reducers[CLEAR_REPOST_ERROR] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { repostError: null }); }; @@ -5649,34 +5643,34 @@ reducers[ADD_FILES_REFLECTING] = (state, action) => { reflectingById[claimId] = { fileListItem: pendingClaim, progress: 0, stalled: false }; - return Object.assign({}, state, _extends$a({}, state, { + return Object.assign({}, state, _extends$b({}, state, { reflectingById: reflectingById })); }; reducers[UPDATE_FILES_REFLECTING] = (state, action) => { const newReflectingById = action.data; - return Object.assign({}, state, _extends$a({}, state, { + return Object.assign({}, state, _extends$b({}, state, { reflectingById: newReflectingById })); }; reducers[TOGGLE_CHECKING_REFLECTING] = (state, action) => { const checkingReflecting = action.data; - return Object.assign({}, state, _extends$a({}, state, { + return Object.assign({}, state, _extends$b({}, state, { checkingReflecting })); }; reducers[TOGGLE_CHECKING_PENDING] = (state, action) => { const checking = action.data; - return Object.assign({}, state, _extends$a({}, state, { + return Object.assign({}, state, _extends$b({}, state, { checkingPending: checking })); }; reducers[PURCHASE_LIST_STARTED] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { fetchingMyPurchases: true, fetchingMyPurchasesError: null }); @@ -5721,7 +5715,7 @@ reducers[PURCHASE_LIST_COMPLETED] = (state, action) => { reducers[PURCHASE_LIST_FAILED] = (state, action) => { const { error } = action.data; - return _extends$a({}, state, { + return _extends$b({}, state, { fetchingMyPurchases: false, fetchingMyPurchasesError: error }); @@ -5742,7 +5736,7 @@ reducers[PURCHASE_URI_COMPLETED] = (state, action) => { myPurchases.push(uri); - return _extends$a({}, state, { + return _extends$b({}, state, { byId, myPurchases, purchaseUriSuccess: true @@ -5750,13 +5744,13 @@ reducers[PURCHASE_URI_COMPLETED] = (state, action) => { }; reducers[PURCHASE_URI_FAILED] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { purchaseUriSuccess: false }); }; reducers[CLEAR_PURCHASED_URI_SUCCESS] = state => { - return _extends$a({}, state, { + return _extends$b({}, state, { purchaseUriSuccess: false }); }; @@ -5785,7 +5779,7 @@ const handleActions = (actionMap, defaultState) => (state = defaultState, action return state; }; -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; }; +var _extends$c = 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; }; const defaultState$1 = { commentById: {}, // commentId -> Comment @@ -5796,11 +5790,11 @@ const defaultState$1 = { }; const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$b({}, state, { + [COMMENT_CREATE_STARTED]: (state, action) => _extends$c({}, state, { isLoading: true }), - [COMMENT_CREATE_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_CREATE_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }), @@ -5818,14 +5812,14 @@ const commentReducer = handleActions({ newCommentIds.unshift(comment.comment_id); byId[claimId] = newCommentIds; - return _extends$b({}, state, { + return _extends$c({}, state, { commentById, byId, isLoading: false }); }, - [COMMENT_LIST_STARTED]: state => _extends$b({}, state, { isLoading: true }), + [COMMENT_LIST_STARTED]: state => _extends$c({}, state, { isLoading: true }), [COMMENT_LIST_COMPLETED]: (state, action) => { const { comments, claimId, uri } = action.data; @@ -5849,7 +5843,7 @@ const commentReducer = handleActions({ byId[claimId] = commentIds; commentsByUri[uri] = claimId; } - return _extends$b({}, state, { + return _extends$c({}, state, { byId, commentById, commentsByUri, @@ -5857,10 +5851,10 @@ const commentReducer = handleActions({ }); }, - [COMMENT_LIST_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_LIST_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }), - [COMMENT_ABANDON_STARTED]: (state, action) => _extends$b({}, state, { + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$c({}, state, { isLoading: true }), [COMMENT_ABANDON_COMPLETED]: (state, action) => { @@ -5878,18 +5872,18 @@ const commentReducer = handleActions({ } delete commentById[comment_id]; - return _extends$b({}, state, { + return _extends$c({}, state, { commentById, byId, isLoading: false }); }, // do nothing - [COMMENT_ABANDON_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }), // do nothing - [COMMENT_UPDATE_STARTED]: (state, action) => _extends$b({}, state, { + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$c({}, state, { isLoading: true }), // replace existing comment with comment returned here under its comment_id @@ -5898,29 +5892,29 @@ const commentReducer = handleActions({ const commentById = Object.assign({}, state.commentById); commentById[comment.comment_id] = comment; - return _extends$b({}, state, { + return _extends$c({}, state, { commentById, isLoading: false }); }, // nothing can be done here - [COMMENT_UPDATE_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }), // nothing can really be done here - [COMMENT_HIDE_STARTED]: (state, action) => _extends$b({}, state, { + [COMMENT_HIDE_STARTED]: (state, action) => _extends$c({}, state, { isLoading: true }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$b({}, state, { // todo: add HiddenComments state & create selectors + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$c({}, state, { // todo: add HiddenComments state & create selectors isLoading: false }), // nothing can be done here - [COMMENT_HIDE_FAILED]: (state, action) => _extends$b({}, state, { + [COMMENT_HIDE_FAILED]: (state, action) => _extends$c({}, state, { isLoading: false }) }, defaultState$1); -var _extends$c = 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; }; +var _extends$d = 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; }; const reducers$1 = {}; const defaultState$2 = { @@ -5929,9 +5923,9 @@ const defaultState$2 = { reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$c({}, state, { - positions: _extends$c({}, state.positions, { - [claimId]: _extends$c({}, state.positions[claimId], { + return _extends$d({}, state, { + positions: _extends$d({}, state.positions, { + [claimId]: _extends$d({}, state.positions[claimId], { [outpoint]: position }) }) @@ -6098,7 +6092,7 @@ function fileInfoReducer(state = defaultState$3, action) { return state; } -var _extends$d = 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; }; +var _extends$e = 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; }; const defaultState$4 = { notifications: [], @@ -6113,7 +6107,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$d({}, state, { + return _extends$e({}, state, { toasts: newToasts }); }, @@ -6121,7 +6115,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$d({}, state, { + return _extends$e({}, state, { toasts: newToasts }); }, @@ -6132,7 +6126,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications: newNotifications }); }, @@ -6143,7 +6137,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications }); }, @@ -6152,7 +6146,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications: newNotifications }); }, @@ -6163,7 +6157,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$d({}, state, { + return _extends$e({}, state, { errors: newErrors }); }, @@ -6171,13 +6165,13 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$d({}, state, { + return _extends$e({}, state, { errors: newErrors }); } }, defaultState$4); -var _extends$e = 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; }; +var _extends$f = 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$4(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; } @@ -6218,20 +6212,20 @@ const defaultState$5 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$e({}, state, data); + return _extends$f({}, state, data); }, - [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$5, { + [CLEAR_PUBLISH]: state => _extends$f({}, defaultState$5, { bid: state.bid, optimize: state.optimize }), - [PUBLISH_START]: state => _extends$e({}, state, { + [PUBLISH_START]: state => _extends$f({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$e({}, state, { + [PUBLISH_FAIL]: state => _extends$f({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$e({}, state, { + [PUBLISH_SUCCESS]: state => _extends$f({}, state, { publishing: false, publishSuccess: true }), @@ -6246,14 +6240,14 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$e({}, defaultState$5, publishData, { + return _extends$f({}, defaultState$5, publishData, { editingURI: uri, uri: shortUri }); } }, defaultState$5); -var _extends$f = 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; }; +var _extends$g = 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; }; const defaultState$6 = { isActive: false, // does the user have any typed text in the search input @@ -6275,23 +6269,23 @@ const defaultState$6 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$f({}, state, { + [SEARCH_START]: state => _extends$g({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$f({}, state, { + return _extends$g({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$f({}, state, { + [SEARCH_FAIL]: state => _extends$g({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$f({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$g({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -6309,24 +6303,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$f({}, state, { + return _extends$g({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$f({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$g({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$f({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$g({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$f({}, state, { - suggestions: _extends$f({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$g({}, state, { + suggestions: _extends$g({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -6334,30 +6328,30 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$f({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$g({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$f({}, state, { + [SEARCH_FOCUS]: state => _extends$g({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$f({}, state, { + [SEARCH_BLUR]: state => _extends$g({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$f({}, oldOptions, newOptions); - return _extends$f({}, state, { + const options = _extends$g({}, oldOptions, newOptions); + return _extends$g({}, state, { options }); } }, defaultState$6); -var _extends$g = 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; }; +var _extends$h = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$g({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$h({}, tagsMap, { [tag]: { name: tag } }), {}); } @@ -6380,7 +6374,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$g({}, state, { + return _extends$h({}, state, { followedTags: newFollowedTags }); }, @@ -6389,10 +6383,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$g({}, knownTags); + let newKnownTags = _extends$h({}, knownTags); newKnownTags[name] = { name }; - return _extends$g({}, state, { + return _extends$h({}, state, { knownTags: newKnownTags }); }, @@ -6401,11 +6395,11 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$g({}, knownTags); + let newKnownTags = _extends$h({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$g({}, state, { + return _extends$h({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -6413,15 +6407,15 @@ const tagsReducer = handleActions({ [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; if (Array.isArray(tags)) { - return _extends$g({}, state, { + return _extends$h({}, state, { followedTags: tags }); } - return _extends$g({}, state); + return _extends$h({}, state); } }, defaultState$7); -var _extends$h = 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; }; +var _extends$i = 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; }; const defaultState$8 = { blockedChannels: [] @@ -6445,13 +6439,13 @@ const blockedReducer = handleActions({ }, [USER_STATE_POPULATE]: (state, action) => { const { blocked } = action.data; - return _extends$h({}, state, { + return _extends$i({}, state, { blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels }); } }, defaultState$8); -var _extends$i = 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; }; +var _extends$j = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -6503,40 +6497,40 @@ const defaultState$9 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$i({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$j({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$i({}, state.transactions); + const byId = _extends$j({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$i({}, state, { + return _extends$j({}, state, { transactions: byId, fetchingTransactions: false }); }, [FETCH_TXO_PAGE_STARTED]: state => { - return _extends$i({}, state, { + return _extends$j({}, state, { fetchingTxos: true, fetchingTxosError: undefined }); }, [FETCH_TXO_PAGE_COMPLETED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { txoPage: action.data, fetchingTxos: false }); }, [FETCH_TXO_PAGE_FAILED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { txoPage: {}, fetchingTxos: false, fetchingTxosError: action.data @@ -6544,12 +6538,12 @@ const walletReducer = handleActions({ }, [UPDATE_TXO_FETCH_PARAMS]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { txoFetchParams: action.data }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$i({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$j({}, state, { fetchingSupports: true }), @@ -6562,7 +6556,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$i({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$j({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -6571,7 +6565,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$i({}, state, { + return _extends$j({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -6584,20 +6578,20 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$i({}, state, { + return _extends$j({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, [ABANDON_CLAIM_SUPPORT_STARTED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_PREVIEW]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: undefined }); }, @@ -6608,36 +6602,36 @@ const walletReducer = handleActions({ pendingtxs[claimId] = { txid, type, effective }; - return _extends$i({}, state, { + return _extends$j({}, state, { pendingSupportTransactions: pendingtxs, abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_FAILED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: action.data }); }, [PENDING_SUPPORTS_UPDATED]: (state, action) => { - return _extends$i({}, state, { + return _extends$j({}, state, { pendingSupportTransactions: action.data }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$i({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$j({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$i({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$j({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$i({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$j({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -6646,32 +6640,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$i({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$j({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$i({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$j({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$i({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$j({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$i({}, state, { draftTransaction: newDraft }); + return _extends$j({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$i({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$j({}, oldDraft, { address: action.data.address }); - return _extends$i({}, state, { draftTransaction: newDraft }); + return _extends$j({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$i({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$j({}, state.draftTransaction, { sending: true }); - return _extends$i({}, state, { draftTransaction: newDraftTransaction }); + return _extends$j({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -6684,114 +6678,114 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$i({}, state, { draftTransaction: newDraftTransaction }); + return _extends$j({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$i({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$j({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$i({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$j({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$i({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$j({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$i({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$j({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$j({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$i({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$j({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$j({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$i({}, state, { + [WALLET_DECRYPT_START]: state => _extends$j({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$j({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$i({}, state, { + [WALLET_UNLOCK_START]: state => _extends$j({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$j({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$j({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$i({}, state, { + [WALLET_LOCK_START]: state => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$i({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$i({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$i({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$j({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$i({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$j({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$i({}, state, { + [WALLET_RESTART]: state => _extends$j({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$i({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$j({}, state, { walletReconnecting: false }) }, defaultState$9); @@ -6809,14 +6803,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$j = 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; }; +var _extends$k = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$j({ + return _extends$k({ id }, params); } @@ -6964,7 +6958,7 @@ exports.doAddTag = doAddTag; exports.doBalanceSubscribe = doBalanceSubscribe; exports.doBlurSearchInput = doBlurSearchInput; exports.doCheckAddressIsMine = doCheckAddressIsMine; -exports.doCheckPendingPublishes = doCheckPendingPublishes; +exports.doCheckPendingClaims = doCheckPendingClaims; exports.doCheckPublishNameAvailability = doCheckPublishNameAvailability; exports.doCheckReflectingFiles = doCheckReflectingFiles; exports.doClaimSearch = doClaimSearch; @@ -7073,7 +7067,6 @@ exports.makeSelectNsfwCountForChannel = makeSelectNsfwCountForChannel; exports.makeSelectNsfwCountFromUris = makeSelectNsfwCountFromUris; exports.makeSelectOmittedCountForChannel = makeSelectOmittedCountForChannel; exports.makeSelectPendingAmountByUri = makeSelectPendingAmountByUri; -exports.makeSelectPendingByUri = makeSelectPendingByUri; exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri; exports.makeSelectPublishFormValue = makeSelectPublishFormValue; exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions; @@ -7165,6 +7158,7 @@ exports.selectIsStillEditing = selectIsStillEditing; exports.selectIsWalletReconnecting = selectIsWalletReconnecting; exports.selectMyActiveClaims = selectMyActiveClaims; exports.selectMyChannelClaims = selectMyChannelClaims; +exports.selectMyChannelUrls = selectMyChannelUrls; exports.selectMyClaimForUri = selectMyClaimForUri; exports.selectMyClaimUrisWithoutChannels = selectMyClaimUrisWithoutChannels; exports.selectMyClaims = selectMyClaims; @@ -7177,8 +7171,6 @@ exports.selectMyClaimsWithoutChannels = selectMyClaimsWithoutChannels; exports.selectMyPurchases = selectMyPurchases; exports.selectMyPurchasesCount = selectMyPurchasesCount; exports.selectMyStreamUrlsCount = selectMyStreamUrlsCount; -exports.selectPendingById = selectPendingById; -exports.selectPendingClaims = selectPendingClaims; exports.selectPendingSupportTransactions = selectPendingSupportTransactions; exports.selectPlayingUri = selectPlayingUri; exports.selectPublishFormValues = selectPublishFormValues; diff --git a/dist/flow-typed/Claim.js b/dist/flow-typed/Claim.js index c9732bd..0b97c0e 100644 --- a/dist/flow-typed/Claim.js +++ b/dist/flow-typed/Claim.js @@ -22,7 +22,7 @@ declare type GenericClaim = { timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed is_channel_signature_valid?: boolean, - is_my_output: true, + is_my_output: boolean, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx diff --git a/flow-typed/Claim.js b/flow-typed/Claim.js index c9732bd..0b97c0e 100644 --- a/flow-typed/Claim.js +++ b/flow-typed/Claim.js @@ -22,7 +22,7 @@ declare type GenericClaim = { timestamp?: number, // date of last transaction height: number, // block height the tx was confirmed is_channel_signature_valid?: boolean, - is_my_output: true, + is_my_output: boolean, name: string, normalized_name: string, // `name` normalized via unicode NFD spec, nout: number, // index number for an output of a tx diff --git a/src/index.js b/src/index.js index 76f5ed6..dcec873 100644 --- a/src/index.js +++ b/src/index.js @@ -76,6 +76,7 @@ export { doClearRepostError, doCheckPublishNameAvailability, doPurchaseList, + doCheckPendingClaims, } from 'redux/actions/claims'; export { doClearPurchasedUriSuccess, doPurchaseUri, doFileGet } from 'redux/actions/file'; @@ -94,7 +95,6 @@ export { doUploadThumbnail, doPrepareEdit, doPublish, - doCheckPendingPublishes, doCheckReflectingFiles, } from 'redux/actions/publish'; @@ -198,7 +198,6 @@ export { makeSelectFirstRecommendedFileForUri, makeSelectChannelForClaimUri, makeSelectClaimIsPending, - makeSelectPendingByUri, makeSelectReflectingClaimForUri, makeSelectClaimsInChannelForCurrentPageState, makeSelectShortUrlForUri, @@ -207,7 +206,6 @@ export { makeSelectSupportsForUri, makeSelectMyPurchasesForPage, makeSelectClaimWasPurchased, - selectPendingById, selectReflectingById, selectClaimsById, selectClaimsByUri, @@ -217,9 +215,9 @@ export { selectMyActiveClaims, selectAllFetchingChannelClaims, selectIsFetchingClaimListMine, - selectPendingClaims, selectMyClaims, selectMyClaimsWithoutChannels, + selectMyChannelUrls, selectMyClaimUrisWithoutChannels, selectAllMyClaimsByOutpoint, selectMyClaimsOutpoints, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 56a4baf..615b7a6 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -9,6 +9,7 @@ import { selectResolvingUris, selectClaimsByUri, selectMyChannelClaims, + selectPendingIds, } from 'redux/selectors/claims'; import { doFetchTxoPage } from 'redux/actions/wallet'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; @@ -338,7 +339,7 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { }; } -export function doCreateChannel(name: string, amount: number, optionalParams: any) { +export function doCreateChannel(name: string, amount: number, optionalParams: any, cb: any) { return (dispatch: Dispatch) => { dispatch({ type: ACTIONS.CREATE_CHANNEL_STARTED, @@ -395,6 +396,13 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an type: ACTIONS.CREATE_CHANNEL_COMPLETED, data: { channelClaim }, }); + dispatch({ + type: ACTIONS.UPDATE_PENDING_CLAIMS, + data: { + claims: [channelClaim], + }, + }); + dispatch(doCheckPendingClaims(cb)); return channelClaim; }) .catch(error => { @@ -408,7 +416,7 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an }; } -export function doUpdateChannel(params: any) { +export function doUpdateChannel(params: any, cb: any) { return (dispatch: Dispatch, getState: GetState) => { dispatch({ type: ACTIONS.UPDATE_CHANNEL_STARTED, @@ -454,7 +462,16 @@ export function doUpdateChannel(params: any) { type: ACTIONS.UPDATE_CHANNEL_COMPLETED, data: { channelClaim }, }); + dispatch({ + type: ACTIONS.UPDATE_PENDING_CLAIMS, + data: { + claims: [channelClaim], + }, + }); + dispatch(doCheckPendingClaims(cb)); + return Boolean(result.outputs[0]); }) + .then() .catch(error => { dispatch({ type: ACTIONS.UPDATE_CHANNEL_FAILED, @@ -669,3 +686,48 @@ export function doPurchaseList(page: number = 1, pageSize: number = PAGE_SIZE) { }).then(success, failure); }; } + +export const doCheckPendingClaims = (onConfirmed: Function) => ( + dispatch: Dispatch, + getState: GetState +) => { + let claimCheckInterval; + + const checkClaimList = () => { + const state = getState(); + const pendingIdSet = new Set(selectPendingIds(state)); + Lbry.claim_list({ page: 1, page_size: 10 }) + .then(result => { + const claims = result.items; + const claimsToConfirm = []; + claims.forEach(claim => { + const { claim_id: claimId } = claim; + if (claim.confirmations > 0 && pendingIdSet.has(claimId)) { + pendingIdSet.delete(claimId); + claimsToConfirm.push(claim); + if (onConfirmed) { + onConfirmed(claim); + } + } + }); + if (claimsToConfirm.length) { + dispatch({ + type: ACTIONS.UPDATE_CONFIRMED_CLAIMS, + data: { + claims: claimsToConfirm, + }, + }); + } + return pendingIdSet.size; + }) + .then(len => { + if (!len) { + clearInterval(claimCheckInterval); + } + }); + }; + + claimCheckInterval = setInterval(() => { + checkClaimList(); + }, 30000); +}; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 23d6d74..c977640 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -10,7 +10,6 @@ import { doError } from 'redux/actions/notifications'; import { isClaimNsfw } from 'util/claim'; import { selectMyChannelClaims, - selectPendingById, selectMyClaimsWithoutChannels, selectReflectingById, } from 'redux/selectors/claims'; @@ -427,46 +426,3 @@ export const doCheckReflectingFiles = () => (dispatch: Dispatch, getState: GetSt }, 5000); } }; -export const doCheckPendingPublishes = (onConfirmed: Function) => ( - dispatch: Dispatch, - getState: GetState -) => { - let publishCheckInterval; - - const checkFileList = () => { - const state = getState(); - const pendingById = selectPendingById(state); - Lbry.claim_list({ page: 1, page_size: 10 }) - .then(result => { - const claims = result.items; - const claimsToConfirm = []; - claims.forEach(claim => { - if (claim.confirmations > 0 && pendingById[claim.claim_id]) { - delete pendingById[claim.claim_id]; - claimsToConfirm.push(claim); - if (onConfirmed) { - onConfirmed(claim); - } - } - }); - if (claimsToConfirm.length) { - dispatch({ - type: ACTIONS.UPDATE_CONFIRMED_CLAIMS, - data: { - claims: claimsToConfirm, - }, - }); - } - return Object.keys(pendingById).length; - }) - .then(len => { - if (!len) { - clearInterval(publishCheckInterval); - } - }); - }; - - publishCheckInterval = setInterval(() => { - checkFileList(); - }, 30000); -}; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index d74ffd1..13a747e 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -9,7 +9,7 @@ // - Sean import * as ACTIONS from 'constants/action_types'; -import { buildURI, parseURI } from 'lbryURI'; +import mergeClaim from 'util/merge-claim'; type State = { createChannelError: ?string, @@ -17,7 +17,7 @@ type State = { claimsByUri: { [string]: string }, byId: { [string]: Claim }, resolvingUris: Array, - pendingById: { [string]: Claim }, + pendingIds: Array, reflectingById: { [string]: ReflectingUpdate }, myClaims: ?Array, myChannelClaims: ?Array, @@ -75,7 +75,7 @@ const defaultState = { fetchingMyPurchasesError: undefined, fetchingMyChannels: false, abandoningById: {}, - pendingById: {}, + pendingIds: [], reflectingById: {}, claimSearchError: false, claimSearchByQuery: {}, @@ -112,18 +112,19 @@ function handleClaimAction(state: State, action: any): State { const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); + const pendingIds = state.pendingIds; let newResolvingUrls = new Set(state.resolvingUris); Object.entries(resolveInfo).forEach(([url: string, resolveResponse: ResolveResponse]) => { // $FlowFixMe const { claimsInChannel, stream, channel } = resolveResponse; - if (claimsInChannel) { - channelClaimCounts[url] = claimsInChannel; - channelClaimCounts[channel.canonical_url] = claimsInChannel; - } if (stream) { - byId[stream.claim_id] = stream; + if (pendingIds.includes(stream.claim_id)) { + byId[stream.claim_id] = mergeClaim(stream, byId[stream.claim_id]); + } else { + byId[stream.claim_id] = stream; + } byUri[url] = stream.claim_id; // If url isn't a canonical_url, make sure that is added too @@ -135,12 +136,17 @@ function handleClaimAction(state: State, action: any): State { newResolvingUrls.delete(stream.permanent_url); } - if (channel) { - if (!stream) { - byUri[url] = channel.claim_id; + if (channel && channel.claim_id) { + if (claimsInChannel) { + channelClaimCounts[url] = claimsInChannel; + channelClaimCounts[channel.canonical_url] = claimsInChannel; } - byId[channel.claim_id] = channel; + if (pendingIds.includes(channel.claim_id)) { + byId[channel.claim_id] = mergeClaim(channel, byId[channel.claim_id]); + } else { + byId[channel.claim_id] = channel; + } // Also add the permanent_url here until lighthouse returns canonical_url for search results byUri[channel.permanent_url] = channel.claim_id; byUri[channel.canonical_url] = channel.claim_id; @@ -198,47 +204,37 @@ reducers[ACTIONS.FETCH_CLAIM_LIST_MINE_COMPLETED] = (state: State, action: any): const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); + const pendingIds = state.pendingIds || []; let myClaimIds = new Set(state.myClaims); let urlsForCurrentPage = []; + const pendingIdSet = new Set(pendingIds); + claims.forEach((claim: Claim) => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; + const { permanent_url: permanentUri, claim_id: claimId } = claim; if (claim.type && claim.type.match(/claim|update/)) { - urlsForCurrentPage.push(uri); + urlsForCurrentPage.push(permanentUri); if (claim.confirmations < 1) { - pendingById[claimId] = claim; - delete byId[claimId]; - delete byUri[claimId]; + pendingIdSet.add(claimId); + } else if (!resolve && pendingIdSet.has(claimId) && claim.confirmations > 0) { + pendingIdSet.delete(claimId); + } + if (pendingIds.includes(claimId)) { + byId[claimId] = mergeClaim(claim, byId[claimId]); } else { byId[claimId] = claim; - byUri[uri] = claimId; } + byUri[permanentUri] = claimId; myClaimIds.add(claimId); - if (!resolve && pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } } }); - // Remove old pending publishes if resolve if false (resolve=true means confirmations on updates are not 0) - if (!resolve) { - Object.values(pendingById) - // $FlowFixMe - .filter(pendingClaim => byId[pendingClaim.claim_id]) - .forEach(pendingClaim => { - // $FlowFixMe - delete pendingById[pendingClaim.claim_id]; - }); - } - return Object.assign({}, state, { isFetchingClaimListMine: false, myClaims: Array.from(myClaimIds), byId, + pendingIds: Array.from(pendingIdSet), claimsByUri: byUri, - pendingById, myClaimsPageResults: urlsForCurrentPage, myClaimsPageNumber: page, myClaimsPageTotalResults: totalItems, @@ -252,7 +248,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St const { claims }: { claims: Array } = action.data; const myClaims = state.myClaims || []; let myClaimIds = new Set(state.myClaims); - const pendingById = Object.assign(state.pendingById); + const pendingIds = state.pendingIds || []; let myChannelClaims; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); @@ -275,18 +271,10 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St // $FlowFixMe myChannelClaims.add(claimId); - if (!byId[claimId]) { + if (!pendingIds.some(c => c === claimId)) { byId[claimId] = claim; } - myClaimIds.add(claimId); - if (pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } - - if (pendingById[claimId] && claim.confirmations > 0) { - delete pendingById[claimId]; - } }); } @@ -296,7 +284,7 @@ reducers[ACTIONS.FETCH_CHANNEL_LIST_COMPLETED] = (state: State, action: any): St channelClaimCounts, fetchingMyChannels: false, myChannelClaims: myChannelClaims ? Array.from(myChannelClaims) : null, - myClaims: Array.from(myClaimIds), + myClaims: myClaimIds ? Array.from(myClaimIds) : null, }); }; @@ -385,19 +373,31 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State => }; reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => { - const { claims }: { claims: Array } = action.data; + const { claims: pendingClaims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); + const pendingIds = state.pendingIds; + const pendingIdSet = new Set(pendingIds); let myClaimIds = new Set(state.myClaims); + const myChannelClaims = new Set(state.myChannelClaims); // $FlowFixMe - claims.forEach((claim: Claim) => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; - if (claim.type && claim.type.match(/claim|update/)) { - pendingById[claimId] = claim; - delete byId[claimId]; + pendingClaims.forEach((claim: Claim) => { + let newClaim; + const { permanent_url: uri, claim_id: claimId, type, value_type: valueType } = claim; + pendingIdSet.add(claimId); + const oldClaim = byId[claimId]; + if (oldClaim && oldClaim.canonical_url) { + newClaim = mergeClaim(oldClaim, claim); + } else { + newClaim = claim; + } + if (valueType === 'channel') { + myChannelClaims.add(claimId); + } + + if (type && type.match(/claim|update/)) { + byId[claimId] = newClaim; byUri[uri] = claimId; } myClaimIds.add(claimId); @@ -405,32 +405,35 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => return Object.assign({}, state, { myClaims: Array.from(myClaimIds), byId, + myChannelClaims: Array.from(myChannelClaims), claimsByUri: byUri, - pendingById, + pendingIds: Array.from(pendingIdSet), }); }; reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => { - const { claims }: { claims: Array } = action.data; + const { claims: confirmedClaims }: { claims: Array } = action.data; const byId = Object.assign({}, state.byId); const byUri = Object.assign({}, state.claimsByUri); - const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById); - let myClaimIds = new Set(state.myClaims); + const pendingIds = state.pendingIds; + const pendingIdSet = new Set(pendingIds); - claims.forEach((claim: GenericClaim) => { - const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id }); - const { claim_id: claimId } = claim; - if (claim.type && claim.type.match(/claim|update/)) { - delete pendingById[claimId]; - byId[claimId] = claim; + confirmedClaims.forEach((claim: GenericClaim) => { + const { permanent_url: permanentUri, claim_id: claimId, type } = claim; + let newClaim = claim; + const oldClaim = byId[claimId]; + if (oldClaim && oldClaim.canonical_url) { + newClaim = mergeClaim(oldClaim, claim); + } + if (type && type.match(/claim|update|channel/)) { + byId[claimId] = newClaim; + pendingIdSet.delete(claimId); } - myClaimIds.add(claimId); }); return Object.assign({}, state, { - myClaims: Array.from(myClaimIds), + pendingIds: Array.from(pendingIdSet), byId, claimsByUri: byUri, - pendingById, }); }; @@ -466,19 +469,7 @@ reducers[ACTIONS.CREATE_CHANNEL_STARTED] = (state: State): State => ({ }); reducers[ACTIONS.CREATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { - const channelClaim: ChannelClaim = action.data.channelClaim; - const byId = Object.assign({}, state.byId); - const pendingById = Object.assign({}, state.pendingById); - const myChannelClaims = new Set(state.myChannelClaims); - - byId[channelClaim.claim_id] = channelClaim; - pendingById[channelClaim.claim_id] = channelClaim; - myChannelClaims.add(channelClaim.claim_id); - return Object.assign({}, state, { - byId, - pendingById, - myChannelClaims: Array.from(myChannelClaims), creatingChannel: false, }); }; @@ -498,13 +489,7 @@ reducers[ACTIONS.UPDATE_CHANNEL_STARTED] = (state: State, action: any): State => }; reducers[ACTIONS.UPDATE_CHANNEL_COMPLETED] = (state: State, action: any): State => { - const channelClaim: ChannelClaim = action.data.channelClaim; - const byId = Object.assign({}, state.byId); - - byId[channelClaim.claim_id] = channelClaim; - return Object.assign({}, state, { - byId, updateChannelError: '', updatingChannel: false, }); diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index e2ced6c..b724567 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -6,7 +6,7 @@ import { } from 'redux/selectors/search'; import { selectSupportsByOutpoint } from 'redux/selectors/wallet'; import { createSelector } from 'reselect'; -import { isClaimNsfw, createNormalizedClaimSearchKey, filterClaims } from 'util/claim'; +import { isClaimNsfw, filterClaims } from 'util/claim'; import { getSearchQueryString } from 'util/query-params'; import { PAGE_SIZE } from 'constants/claim'; @@ -48,10 +48,9 @@ export const selectRepostError = createSelector( ); export const selectClaimsByUri = createSelector( - selectState, + selectClaimIdsByUri, selectClaimsById, - (state, byId) => { - const byUri = state.claimsByUri || {}; + (byUri, byId) => { const claims = {}; Object.keys(byUri).forEach(uri => { @@ -76,42 +75,25 @@ export const selectAllClaimsByChannel = createSelector( state => state.paginatedClaimsByChannel || {} ); -export const selectPendingById = createSelector( +export const selectPendingIds = createSelector( selectState, - state => state.pendingById || {} -); - -export const selectPendingClaims = createSelector( - selectState, - state => Object.values(state.pendingById || []) + state => state.pendingIds || [] ); export const makeSelectClaimIsPending = (uri: string) => createSelector( - selectPendingById, - pendingById => { - let claimId; - - try { - const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); - claimId = isChannel ? channelClaimId : streamClaimId; - } catch (e) {} + selectClaimIdsByUri, + selectPendingIds, + (idsByUri, pendingIds) => { + const claimId = idsByUri[normalizeURI(uri)]; if (claimId) { - return Boolean(pendingById[claimId]); + return pendingIds.some(i => i === claimId); } + return false; } ); -export const makeSelectPendingByUri = (uri: string) => - createSelector( - selectPendingById, - pendingById => { - const { isChannel, channelClaimId, streamClaimId } = parseURI(uri); - const claimId = isChannel ? channelClaimId : streamClaimId; - return pendingById[claimId]; - } - ); export const selectReflectingById = createSelector( selectState, state => state.reflectingById @@ -119,30 +101,21 @@ export const selectReflectingById = createSelector( export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) => createSelector( - selectClaimsByUri, - selectPendingById, - (byUri, pendingById) => { - // Check if a claim is pending first - // It won't be in claimsByUri because resolving it will return nothing - - let valid; + selectClaimIdsByUri, + selectClaimsById, + (byUri, byId) => { + let validUri; let channelClaimId; let streamClaimId; let isChannel; try { ({ isChannel, channelClaimId, streamClaimId } = parseURI(uri)); - valid = true; + validUri = true; } catch (e) {} - if (valid && byUri) { - const claimId = isChannel ? channelClaimId : streamClaimId; - const pendingClaim = pendingById[claimId]; - - if (pendingClaim) { - return pendingClaim; - } - - const claim = byUri[normalizeURI(uri)]; + if (validUri && byUri) { + const claimId = uri && byUri[normalizeURI(uri)]; + const claim = byId[claimId]; if (claim === undefined || claim === null) { // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) return claim; @@ -456,8 +429,7 @@ export const selectMyClaims = createSelector( selectMyActiveClaims, selectClaimsById, selectAbandoningIds, - selectPendingClaims, - (myClaimIds, byId, abandoningIds, pendingClaims) => { + (myClaimIds, byId, abandoningIds) => { const claims = []; myClaimIds.forEach(id => { @@ -466,7 +438,7 @@ export const selectMyClaims = createSelector( if (claim && abandoningIds.indexOf(id) === -1) claims.push(claim); }); - return [...claims, ...pendingClaims]; + return [...claims]; } ); @@ -538,6 +510,11 @@ export const selectMyChannelClaims = createSelector( } ); +export const selectMyChannelUrls = createSelector( + selectMyChannelClaims, + claims => claims ? claims.map(claim => claim.canonical_url || claim.permanent_url) : undefined +); + export const selectResolvingUris = createSelector( selectState, state => state.resolvingUris || [] diff --git a/src/util/merge-claim.js b/src/util/merge-claim.js new file mode 100644 index 0000000..3ab2976 --- /dev/null +++ b/src/util/merge-claim.js @@ -0,0 +1,7 @@ +/* +new claim = { ...maybeResolvedClaim, ...pendingClaim, meta: maybeResolvedClaim['meta'] } + */ + +export default function mergeClaims(maybeResolved, pending){ + return { ...maybeResolved, ...pending, meta: maybeResolved.meta }; +} -- 2.45.2 From 0ecf719daa6781e82488b91157a97784de1f14f8 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 22 Jun 2020 14:37:37 -0400 Subject: [PATCH 355/371] handle resolving vanity channel urls --- dist/bundle.es.js | 5 +++++ src/redux/reducers/claims.js | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 4792db5..430b1ae 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5168,6 +5168,7 @@ function handleClaimAction(state, action) { const { resolveInfo } = action.data; + const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); @@ -5196,6 +5197,10 @@ function handleClaimAction(state, action) { } if (channel && channel.claim_id) { + if (!stream) { + byUri[url] = channel.claim_id; + } + if (claimsInChannel) { channelClaimCounts[url] = claimsInChannel; channelClaimCounts[channel.canonical_url] = claimsInChannel; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 13a747e..061e555 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -109,6 +109,7 @@ function handleClaimAction(state: State, action: any): State { claimsInChannel: ?number, }, } = action.data; + const byUri = Object.assign({}, state.claimsByUri); const byId = Object.assign({}, state.byId); const channelClaimCounts = Object.assign({}, state.channelClaimCounts); @@ -137,6 +138,10 @@ function handleClaimAction(state: State, action: any): State { } if (channel && channel.claim_id) { + if (!stream) { + byUri[url] = channel.claim_id; + } + if (claimsInChannel) { channelClaimCounts[url] = claimsInChannel; channelClaimCounts[channel.canonical_url] = claimsInChannel; -- 2.45.2 From 5ac2065b6188e213c40eecd8149bc7b5b89e6eeb Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 23 Jun 2020 11:15:17 -0400 Subject: [PATCH 356/371] fix selector to properly return null for abandoned claims --- dist/bundle.es.js | 9 ++++++--- src/redux/selectors/claims.js | 11 +++++++---- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 430b1ae..ee5209b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2227,9 +2227,12 @@ const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelec if (validUri && byUri) { const claimId = uri && byUri[normalizeURI(uri)]; const claim = byId[claimId]; - if (claim === undefined || claim === null) { - // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) - return claim; + + // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) + if (claimId === null) { + return null; + } else if (claimId === undefined) { + return undefined; } const repostedClaim = claim.reposted_claim; diff --git a/src/redux/selectors/claims.js b/src/redux/selectors/claims.js index b724567..eadd945 100644 --- a/src/redux/selectors/claims.js +++ b/src/redux/selectors/claims.js @@ -116,9 +116,12 @@ export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) if (validUri && byUri) { const claimId = uri && byUri[normalizeURI(uri)]; const claim = byId[claimId]; - if (claim === undefined || claim === null) { - // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) - return claim; + + // Make sure to return the claim as is so apps can check if it's been resolved before (null) or still needs to be resolved (undefined) + if (claimId === null) { + return null; + } else if (claimId === undefined) { + return undefined; } const repostedClaim = claim.reposted_claim; @@ -512,7 +515,7 @@ export const selectMyChannelClaims = createSelector( export const selectMyChannelUrls = createSelector( selectMyChannelClaims, - claims => claims ? claims.map(claim => claim.canonical_url || claim.permanent_url) : undefined + claims => (claims ? claims.map(claim => claim.canonical_url || claim.permanent_url) : undefined) ); export const selectResolvingUris = createSelector( -- 2.45.2 From e4c05cebe97b278eca0f7e1c24fa0c210132abd2 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 23 Jun 2020 14:48:30 -0400 Subject: [PATCH 357/371] remove comment/blocked code --- dist/bundle.es.js | 738 ++++++-------------------------- flow-typed/Blocklist.js | 10 - flow-typed/Comment.js | 23 - src/constants/action_types.js | 20 - src/index.js | 20 - src/redux/actions/blocked.js | 9 - src/redux/actions/comments.js | 225 ---------- src/redux/reducers/blocked.js | 41 -- src/redux/reducers/comments.js | 153 ------- src/redux/selectors/blocked.js | 22 - src/redux/selectors/comments.js | 71 --- 11 files changed, 129 insertions(+), 1203 deletions(-) delete mode 100644 flow-typed/Blocklist.js delete mode 100644 flow-typed/Comment.js delete mode 100644 src/redux/actions/blocked.js delete mode 100644 src/redux/actions/comments.js delete mode 100644 src/redux/reducers/blocked.js delete mode 100644 src/redux/reducers/comments.js delete mode 100644 src/redux/selectors/blocked.js delete mode 100644 src/redux/selectors/comments.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ee5209b..a136b70 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -154,23 +154,6 @@ const PURCHASE_LIST_STARTED = 'PURCHASE_LIST_STARTED'; const PURCHASE_LIST_COMPLETED = 'PURCHASE_LIST_COMPLETED'; const PURCHASE_LIST_FAILED = 'PURCHASE_LIST_FAILED'; -// Comments -const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; -const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED'; -const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED'; -const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; -const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; -const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; -const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; -const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; -const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; -const COMMENT_UPDATE_STARTED = 'COMMENT_UPDATE_STARTED'; -const COMMENT_UPDATE_COMPLETED = 'COMMENT_UPDATE_COMPLETED'; -const COMMENT_UPDATE_FAILED = 'COMMENT_UPDATE_FAILED'; -const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; -const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; -const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; - // Files const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; @@ -306,9 +289,6 @@ const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; const TAG_ADD = 'TAG_ADD'; const TAG_DELETE = 'TAG_DELETE'; -// Blocked Channels -const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; - // Sync const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; @@ -437,21 +417,6 @@ var action_types = /*#__PURE__*/Object.freeze({ PURCHASE_LIST_STARTED: PURCHASE_LIST_STARTED, PURCHASE_LIST_COMPLETED: PURCHASE_LIST_COMPLETED, PURCHASE_LIST_FAILED: PURCHASE_LIST_FAILED, - COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, - COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, - COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, - COMMENT_CREATE_STARTED: COMMENT_CREATE_STARTED, - COMMENT_CREATE_COMPLETED: COMMENT_CREATE_COMPLETED, - COMMENT_CREATE_FAILED: COMMENT_CREATE_FAILED, - COMMENT_ABANDON_STARTED: COMMENT_ABANDON_STARTED, - COMMENT_ABANDON_COMPLETED: COMMENT_ABANDON_COMPLETED, - COMMENT_ABANDON_FAILED: COMMENT_ABANDON_FAILED, - COMMENT_UPDATE_STARTED: COMMENT_UPDATE_STARTED, - COMMENT_UPDATE_COMPLETED: COMMENT_UPDATE_COMPLETED, - COMMENT_UPDATE_FAILED: COMMENT_UPDATE_FAILED, - COMMENT_HIDE_STARTED: COMMENT_HIDE_STARTED, - COMMENT_HIDE_COMPLETED: COMMENT_HIDE_COMPLETED, - COMMENT_HIDE_FAILED: COMMENT_HIDE_FAILED, FILE_LIST_STARTED: FILE_LIST_STARTED, FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, @@ -564,7 +529,6 @@ var action_types = /*#__PURE__*/Object.freeze({ TOGGLE_TAG_FOLLOW: TOGGLE_TAG_FOLLOW, TAG_ADD: TAG_ADD, TAG_DELETE: TAG_DELETE, - TOGGLE_BLOCK_CHANNEL: TOGGLE_BLOCK_CHANNEL, USER_STATE_POPULATE: USER_STATE_POPULATE }); @@ -4910,207 +4874,6 @@ const doDeleteTag = name => ({ } }); -// - -function doCommentList(uri, page = 1, pageSize = 99999) { - return (dispatch, getState) => { - const state = getState(); - const claim = selectClaimsByUri(state)[uri]; - const claimId = claim ? claim.claim_id : null; - - dispatch({ - type: COMMENT_LIST_STARTED - }); - lbryProxy.comment_list({ - claim_id: claimId, - page, - page_size: pageSize - }).then(result => { - const { items: comments } = result; - dispatch({ - type: COMMENT_LIST_COMPLETED, - data: { - comments, - claimId: claimId, - uri: uri - } - }); - }).catch(error => { - console.log(error); - dispatch({ - type: COMMENT_LIST_FAILED, - data: error - }); - }); - }; -} - -function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { - return (dispatch, getState) => { - const state = getState(); - dispatch({ - type: COMMENT_CREATE_STARTED - }); - - const myChannels = selectMyChannelClaims(state); - const namedChannelClaim = myChannels && myChannels.find(myChannel => myChannel.name === channel); - const channel_id = namedChannelClaim.claim_id; - - if (channel_id == null) { - dispatch({ - type: COMMENT_CREATE_FAILED, - data: {} - }); - dispatch(doToast({ - message: 'Channel cannot be anonymous, please select a channel and try again.', - isError: true - })); - return; - } - - return lbryProxy.comment_create({ - comment: comment, - claim_id: claim_id, - channel_id: channel_id, - parent_id: parent_id - }).then(result => { - dispatch({ - type: COMMENT_CREATE_COMPLETED, - data: { - comment: result, - claimId: claim_id - } - }); - }).catch(error => { - dispatch({ - type: COMMENT_CREATE_FAILED, - data: error - }); - dispatch(doToast({ - message: 'Unable to create comment, please try again later.', - isError: true - })); - }); - }; -} - -function doCommentHide(comment_id) { - return dispatch => { - dispatch({ - type: COMMENT_HIDE_STARTED - }); - return lbryProxy.comment_hide({ - comment_ids: [comment_id] - }).then(result => { - dispatch({ - type: COMMENT_HIDE_COMPLETED, - data: result - }); - }).catch(error => { - dispatch({ - type: COMMENT_HIDE_FAILED, - data: error - }); - dispatch(doToast({ - message: 'Unable to hide this comment, please try again later.', - isError: true - })); - }); - }; -} - -function doCommentAbandon(comment_id) { - return dispatch => { - dispatch({ - type: COMMENT_ABANDON_STARTED - }); - return lbryProxy.comment_abandon({ - comment_id: comment_id - }).then(result => { - // Comment may not be deleted if the signing channel can't be signed. - // This will happen if the channel was recently created or abandoned. - if (result.abandoned) { - dispatch({ - type: COMMENT_ABANDON_COMPLETED, - data: { - comment_id: comment_id - } - }); - } else { - dispatch({ - type: COMMENT_ABANDON_FAILED - }); - dispatch(doToast({ - message: 'Your channel is still being setup, try again in a few moments.', - isError: true - })); - } - }).catch(error => { - dispatch({ - type: COMMENT_ABANDON_FAILED, - data: error - }); - dispatch(doToast({ - message: 'Unable to delete this comment, please try again later.', - isError: true - })); - }); - }; -} - -function doCommentUpdate(comment_id, comment) { - // if they provided an empty string, they must have wanted to abandon - if (comment === '') { - return doCommentAbandon(comment_id); - } else { - return dispatch => { - dispatch({ - type: COMMENT_UPDATE_STARTED - }); - return lbryProxy.comment_update({ - comment_id: comment_id, - comment: comment - }).then(result => { - if (result != null) { - dispatch({ - type: COMMENT_UPDATE_COMPLETED, - data: { - comment: result - } - }); - } else { - // the result will return null - dispatch({ - type: COMMENT_UPDATE_FAILED - }); - dispatch(doToast({ - message: 'Your channel is still being setup, try again in a few moments.', - isError: true - })); - } - }).catch(error => { - dispatch({ - type: COMMENT_UPDATE_FAILED, - data: error - }); - dispatch(doToast({ - message: 'Unable to edit this comment, please try again later.', - isError: true - })); - }); - }; - } -} - -// - -const doToggleBlockChannel = uri => ({ - type: TOGGLE_BLOCK_CHANNEL, - data: { - uri - } -}); - var _extends$a = 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; }; /* @@ -5769,185 +5532,32 @@ function claimsReducer(state = defaultState, action) { return state; } -// util for creating reducers -// based off of redux-actions -// https://redux-actions.js.org/docs/api/handleAction.html#handleactions - -// eslint-disable-next-line import/prefer-default-export -const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { - const handler = actionMap[action.type]; - - if (handler) { - const newState = handler(state, action); - return Object.assign({}, state, newState); - } - - // just return the original state if no handler - // returning a copy here breaks redux-persist - return state; -}; - var _extends$c = 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; }; -const defaultState$1 = { - commentById: {}, // commentId -> Comment - byId: {}, // ClaimID -> list of comments - commentsByUri: {}, // URI -> claimId - isLoading: false, - myComments: undefined -}; - -const commentReducer = handleActions({ - [COMMENT_CREATE_STARTED]: (state, action) => _extends$c({}, state, { - isLoading: true - }), - - [COMMENT_CREATE_FAILED]: (state, action) => _extends$c({}, state, { - isLoading: false - }), - - [COMMENT_CREATE_COMPLETED]: (state, action) => { - const { comment, claimId } = action.data; - const commentById = Object.assign({}, state.commentById); - const byId = Object.assign({}, state.byId); - const comments = byId[claimId]; - const newCommentIds = comments.slice(); - - // add the comment by its ID - commentById[comment.comment_id] = comment; - - // push the comment_id to the top of ID list - newCommentIds.unshift(comment.comment_id); - byId[claimId] = newCommentIds; - - return _extends$c({}, state, { - commentById, - byId, - isLoading: false - }); - }, - - [COMMENT_LIST_STARTED]: state => _extends$c({}, state, { isLoading: true }), - - [COMMENT_LIST_COMPLETED]: (state, action) => { - const { comments, claimId, uri } = action.data; - - const commentById = Object.assign({}, state.commentById); - const byId = Object.assign({}, state.byId); - const commentsByUri = Object.assign({}, state.commentsByUri); - - if (comments) { - // we use an Array to preserve order of listing - // in reality this doesn't matter and we can just - // sort comments by their timestamp - const commentIds = Array(comments.length); - - // map the comment_ids to the new comments - for (let i = 0; i < comments.length; i++) { - commentIds[i] = comments[i].comment_id; - commentById[commentIds[i]] = comments[i]; - } - - byId[claimId] = commentIds; - commentsByUri[uri] = claimId; - } - return _extends$c({}, state, { - byId, - commentById, - commentsByUri, - isLoading: false - }); - }, - - [COMMENT_LIST_FAILED]: (state, action) => _extends$c({}, state, { - isLoading: false - }), - [COMMENT_ABANDON_STARTED]: (state, action) => _extends$c({}, state, { - isLoading: true - }), - [COMMENT_ABANDON_COMPLETED]: (state, action) => { - const { comment_id } = action.data; - const commentById = Object.assign({}, state.commentById); - const byId = Object.assign({}, state.byId); - - // to remove the comment and its references - const claimId = commentById[comment_id].claim_id; - for (let i = 0; i < byId[claimId].length; i++) { - if (byId[claimId][i] === comment_id) { - byId[claimId].splice(i, 1); - break; - } - } - delete commentById[comment_id]; - - return _extends$c({}, state, { - commentById, - byId, - isLoading: false - }); - }, - // do nothing - [COMMENT_ABANDON_FAILED]: (state, action) => _extends$c({}, state, { - isLoading: false - }), - // do nothing - [COMMENT_UPDATE_STARTED]: (state, action) => _extends$c({}, state, { - isLoading: true - }), - // replace existing comment with comment returned here under its comment_id - [COMMENT_UPDATE_COMPLETED]: (state, action) => { - const { comment } = action.data; - const commentById = Object.assign({}, state.commentById); - commentById[comment.comment_id] = comment; - - return _extends$c({}, state, { - commentById, - isLoading: false - }); - }, - // nothing can be done here - [COMMENT_UPDATE_FAILED]: (state, action) => _extends$c({}, state, { - isLoading: false - }), - // nothing can really be done here - [COMMENT_HIDE_STARTED]: (state, action) => _extends$c({}, state, { - isLoading: true - }), - [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$c({}, state, { // todo: add HiddenComments state & create selectors - isLoading: false - }), - // nothing can be done here - [COMMENT_HIDE_FAILED]: (state, action) => _extends$c({}, state, { - isLoading: false - }) -}, defaultState$1); - -var _extends$d = 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; }; - const reducers$1 = {}; -const defaultState$2 = { +const defaultState$1 = { positions: {} }; reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$d({}, state, { - positions: _extends$d({}, state.positions, { - [claimId]: _extends$d({}, state.positions[claimId], { + return _extends$c({}, state, { + positions: _extends$c({}, state.positions, { + [claimId]: _extends$c({}, state.positions[claimId], { [outpoint]: position }) }) }); }; -function contentReducer(state = defaultState$2, action) { +function contentReducer(state = defaultState$1, action) { const handler = reducers$1[action.type]; if (handler) return handler(state, action); return state; } const reducers$2 = {}; -const defaultState$3 = { +const defaultState$2 = { fileListPublishedSort: DATE_NEW, fileListDownloadedSort: DATE_NEW }; @@ -6094,15 +5704,33 @@ reducers$2[SET_FILE_LIST_SORT] = (state, action) => { }); }; -function fileInfoReducer(state = defaultState$3, action) { +function fileInfoReducer(state = defaultState$2, action) { const handler = reducers$2[action.type]; if (handler) return handler(state, action); return state; } -var _extends$e = 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; }; +// util for creating reducers +// based off of redux-actions +// https://redux-actions.js.org/docs/api/handleAction.html#handleactions -const defaultState$4 = { +// eslint-disable-next-line import/prefer-default-export +const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { + const handler = actionMap[action.type]; + + if (handler) { + const newState = handler(state, action); + return Object.assign({}, state, newState); + } + + // just return the original state if no handler + // returning a copy here breaks redux-persist + return state; +}; + +var _extends$d = 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; }; + +const defaultState$3 = { notifications: [], toasts: [], errors: [] @@ -6115,7 +5743,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$e({}, state, { + return _extends$d({}, state, { toasts: newToasts }); }, @@ -6123,7 +5751,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$e({}, state, { + return _extends$d({}, state, { toasts: newToasts }); }, @@ -6134,7 +5762,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$e({}, state, { + return _extends$d({}, state, { notifications: newNotifications }); }, @@ -6145,7 +5773,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$e({}, state, { + return _extends$d({}, state, { notifications }); }, @@ -6154,7 +5782,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$e({}, state, { + return _extends$d({}, state, { notifications: newNotifications }); }, @@ -6165,7 +5793,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$e({}, state, { + return _extends$d({}, state, { errors: newErrors }); }, @@ -6173,17 +5801,17 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$e({}, state, { + return _extends$d({}, state, { errors: newErrors }); } -}, defaultState$4); +}, defaultState$3); -var _extends$f = 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; }; +var _extends$e = 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$4(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$5 = { +const defaultState$4 = { editingURI: undefined, filePath: undefined, fileDur: 0, @@ -6220,20 +5848,20 @@ const defaultState$5 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$f({}, state, data); + return _extends$e({}, state, data); }, - [CLEAR_PUBLISH]: state => _extends$f({}, defaultState$5, { + [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$4, { bid: state.bid, optimize: state.optimize }), - [PUBLISH_START]: state => _extends$f({}, state, { + [PUBLISH_START]: state => _extends$e({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$f({}, state, { + [PUBLISH_FAIL]: state => _extends$e({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$f({}, state, { + [PUBLISH_SUCCESS]: state => _extends$e({}, state, { publishing: false, publishSuccess: true }), @@ -6248,16 +5876,16 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$f({}, defaultState$5, publishData, { + return _extends$e({}, defaultState$4, publishData, { editingURI: uri, uri: shortUri }); } -}, defaultState$5); +}, defaultState$4); -var _extends$g = 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; }; +var _extends$f = 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; }; -const defaultState$6 = { +const defaultState$5 = { 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 @@ -6277,23 +5905,23 @@ const defaultState$6 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$g({}, state, { + [SEARCH_START]: state => _extends$f({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$g({}, state, { + return _extends$f({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$g({}, state, { + [SEARCH_FAIL]: state => _extends$f({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$g({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$f({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -6311,24 +5939,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$g({}, state, { + return _extends$f({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$g({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$f({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$g({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$f({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$g({}, state, { - suggestions: _extends$g({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$f({}, state, { + suggestions: _extends$f({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -6336,35 +5964,35 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$g({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$f({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$g({}, state, { + [SEARCH_FOCUS]: state => _extends$f({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$g({}, state, { + [SEARCH_BLUR]: state => _extends$f({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$g({}, oldOptions, newOptions); - return _extends$g({}, state, { + const options = _extends$f({}, oldOptions, newOptions); + return _extends$f({}, state, { options }); } -}, defaultState$6); +}, defaultState$5); -var _extends$h = 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; }; +var _extends$g = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$h({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$g({}, tagsMap, { [tag]: { name: tag } }), {}); } -const defaultState$7 = { +const defaultState$6 = { followedTags: [], knownTags: getDefaultKnownTags() }; @@ -6382,7 +6010,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$h({}, state, { + return _extends$g({}, state, { followedTags: newFollowedTags }); }, @@ -6391,10 +6019,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$h({}, knownTags); + let newKnownTags = _extends$g({}, knownTags); newKnownTags[name] = { name }; - return _extends$h({}, state, { + return _extends$g({}, state, { knownTags: newKnownTags }); }, @@ -6403,11 +6031,11 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$h({}, knownTags); + let newKnownTags = _extends$g({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$h({}, state, { + return _extends$g({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -6415,45 +6043,15 @@ const tagsReducer = handleActions({ [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; if (Array.isArray(tags)) { - return _extends$h({}, state, { + return _extends$g({}, state, { followedTags: tags }); } - return _extends$h({}, state); + return _extends$g({}, state); } -}, defaultState$7); +}, defaultState$6); -var _extends$i = 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; }; - -const defaultState$8 = { - blockedChannels: [] -}; - -const blockedReducer = handleActions({ - [TOGGLE_BLOCK_CHANNEL]: (state, action) => { - const { blockedChannels } = state; - const { uri } = action.data; - let newBlockedChannels = blockedChannels.slice(); - - if (newBlockedChannels.includes(uri)) { - newBlockedChannels = newBlockedChannels.filter(id => id !== uri); - } else { - newBlockedChannels.push(uri); - } - - return { - blockedChannels: newBlockedChannels - }; - }, - [USER_STATE_POPULATE]: (state, action) => { - const { blocked } = action.data; - return _extends$i({}, state, { - blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels - }); - } -}, defaultState$8); - -var _extends$j = 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; }; +var _extends$h = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -6464,7 +6062,7 @@ const buildDraftTransaction = () => ({ // See details in https://github.com/lbryio/lbry/issues/1307 -const defaultState$9 = { +const defaultState$7 = { balance: undefined, totalBalance: undefined, reservedBalance: undefined, @@ -6505,40 +6103,40 @@ const defaultState$9 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$j({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$h({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$j({}, state.transactions); + const byId = _extends$h({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$j({}, state, { + return _extends$h({}, state, { transactions: byId, fetchingTransactions: false }); }, [FETCH_TXO_PAGE_STARTED]: state => { - return _extends$j({}, state, { + return _extends$h({}, state, { fetchingTxos: true, fetchingTxosError: undefined }); }, [FETCH_TXO_PAGE_COMPLETED]: (state, action) => { - return _extends$j({}, state, { + return _extends$h({}, state, { txoPage: action.data, fetchingTxos: false }); }, [FETCH_TXO_PAGE_FAILED]: (state, action) => { - return _extends$j({}, state, { + return _extends$h({}, state, { txoPage: {}, fetchingTxos: false, fetchingTxosError: action.data @@ -6546,12 +6144,12 @@ const walletReducer = handleActions({ }, [UPDATE_TXO_FETCH_PARAMS]: (state, action) => { - return _extends$j({}, state, { + return _extends$h({}, state, { txoFetchParams: action.data }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$j({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$h({}, state, { fetchingSupports: true }), @@ -6564,7 +6162,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$j({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$h({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -6573,7 +6171,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$j({}, state, { + return _extends$h({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -6586,20 +6184,20 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$j({}, state, { + return _extends$h({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, [ABANDON_CLAIM_SUPPORT_STARTED]: (state, action) => { - return _extends$j({}, state, { + return _extends$h({}, state, { abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_PREVIEW]: (state, action) => { - return _extends$j({}, state, { + return _extends$h({}, state, { abandonClaimSupportError: undefined }); }, @@ -6610,36 +6208,36 @@ const walletReducer = handleActions({ pendingtxs[claimId] = { txid, type, effective }; - return _extends$j({}, state, { + return _extends$h({}, state, { pendingSupportTransactions: pendingtxs, abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_FAILED]: (state, action) => { - return _extends$j({}, state, { + return _extends$h({}, state, { abandonClaimSupportError: action.data }); }, [PENDING_SUPPORTS_UPDATED]: (state, action) => { - return _extends$j({}, state, { + return _extends$h({}, state, { pendingSupportTransactions: action.data }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$j({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$h({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$j({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$h({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$j({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$h({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -6648,32 +6246,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$j({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$h({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$j({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$h({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$j({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$h({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$j({}, state, { draftTransaction: newDraft }); + return _extends$h({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$j({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$h({}, oldDraft, { address: action.data.address }); - return _extends$j({}, state, { draftTransaction: newDraft }); + return _extends$h({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$j({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$h({}, state.draftTransaction, { sending: true }); - return _extends$j({}, state, { draftTransaction: newDraftTransaction }); + return _extends$h({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -6686,117 +6284,117 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$j({}, state, { draftTransaction: newDraftTransaction }); + return _extends$h({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$j({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$h({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$j({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$h({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$j({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$h({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$j({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$h({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$h({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$j({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$h({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$j({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$h({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$j({}, state, { + [WALLET_DECRYPT_START]: state => _extends$h({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$j({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$h({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$j({}, state, { + [WALLET_UNLOCK_START]: state => _extends$h({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$h({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$j({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$h({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$j({}, state, { + [WALLET_LOCK_START]: state => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$j({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$j({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$h({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$j({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$h({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$j({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$h({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$j({}, state, { + [WALLET_RESTART]: state => _extends$h({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$j({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$h({}, state, { walletReconnecting: false }) -}, defaultState$9); +}, defaultState$7); // @@ -6811,14 +6409,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$k = 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; }; +var _extends$i = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$k({ + return _extends$i({ id }, params); } @@ -6839,64 +6437,11 @@ const selectError = reselect.createSelector(selectState$6, state => { // -const selectState$7 = state => state.comments || {}; +const selectState$7 = state => state.tags || {}; -const selectCommentsById = reselect.createSelector(selectState$7, state => state.commentById || {}); +const selectKnownTagsByName = reselect.createSelector(selectState$7, state => state.knownTags); -const selectIsFetchingComments = reselect.createSelector(selectState$7, state => state.isLoading); - -const selectCommentsByClaimId = reselect.createSelector(selectState$7, selectCommentsById, (state, byId) => { - const byClaimId = state.byId || {}; - const comments = {}; - - // replace every comment_id in the list with the actual comment object - Object.keys(byClaimId).forEach(claimId => { - const commentIds = byClaimId[claimId]; - - comments[claimId] = Array(commentIds === null ? 0 : commentIds.length); - for (let i = 0; i < commentIds.length; i++) { - comments[claimId][i] = byId[commentIds[i]]; - } - }); - - return comments; -}); - -// previously this used a mapping from claimId -> Array -/* export const selectCommentsById = createSelector( - selectState, - state => state.byId || {} -); */ -const selectCommentsByUri = reselect.createSelector(selectState$7, state => { - const byUri = state.commentsByUri || {}; - const comments = {}; - Object.keys(byUri).forEach(uri => { - const claimId = byUri[uri]; - if (claimId === null) { - comments[uri] = null; - } else { - comments[uri] = claimId; - } - }); - - return comments; -}); - -const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsByClaimId, selectCommentsByUri, (byClaimId, byUri) => { - const claimId = byUri[uri]; - return byClaimId && byClaimId[claimId]; -}); - -// todo: allow SDK to retrieve user comments through comment_list -// todo: implement selectors for selecting comments owned by user - -// - -const selectState$8 = state => state.tags || {}; - -const selectKnownTagsByName = reselect.createSelector(selectState$8, state => state.knownTags); - -const selectFollowedTagsList = reselect.createSelector(selectState$8, state => state.followedTags.filter(tag => typeof tag === 'string')); +const selectFollowedTagsList = reselect.createSelector(selectState$7, state => state.followedTags.filter(tag => typeof tag === 'string')); const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag.toLowerCase() })).sort((a, b) => a.name.localeCompare(b.name))); @@ -6917,18 +6462,6 @@ const makeSelectIsFollowingTag = tag => reselect.createSelector(selectFollowedTa return followedTags.some(followedTag => followedTag.name === tag.toLowerCase()); }); -// - -const selectState$9 = state => state.blocked || {}; - -const selectBlockedChannels = reselect.createSelector(selectState$9, state => state.blockedChannels); - -const selectBlockedChannelsCount = reselect.createSelector(selectBlockedChannels, state => state.length); - -const selectChannelIsBlocked = uri => reselect.createSelector(selectBlockedChannels, state => { - return state.includes(uri); -}); - exports.ABANDON_STATES = abandon_states; exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; @@ -6951,11 +6484,9 @@ exports.TXO_LIST = txo_list; exports.TX_LIST = transaction_list; exports.apiCall = apiCall; exports.batchActions = batchActions; -exports.blockedReducer = blockedReducer; exports.buildSharedStateMiddleware = buildSharedStateMiddleware; exports.buildURI = buildURI; exports.claimsReducer = claimsReducer; -exports.commentReducer = commentReducer; exports.contentReducer = contentReducer; exports.convertToShareLink = convertToShareLink; exports.createNormalizedClaimSearchKey = createNormalizedClaimSearchKey; @@ -6974,11 +6505,6 @@ exports.doClearPublish = doClearPublish; exports.doClearPurchasedUriSuccess = doClearPurchasedUriSuccess; exports.doClearRepostError = doClearRepostError; exports.doClearSupport = doClearSupport; -exports.doCommentAbandon = doCommentAbandon; -exports.doCommentCreate = doCommentCreate; -exports.doCommentHide = doCommentHide; -exports.doCommentList = doCommentList; -exports.doCommentUpdate = doCommentUpdate; exports.doCreateChannel = doCreateChannel; exports.doDeleteTag = doDeleteTag; exports.doDismissError = doDismissError; @@ -7017,7 +6543,6 @@ exports.doSetFileListSort = doSetFileListSort; exports.doSetTransactionListFilter = doSetTransactionListFilter; exports.doSupportAbandonForClaim = doSupportAbandonForClaim; exports.doToast = doToast; -exports.doToggleBlockChannel = doToggleBlockChannel; exports.doToggleTagFollow = doToggleTagFollow; exports.doUpdateBalance = doUpdateBalance; exports.doUpdateBlockHeight = doUpdateBlockHeight; @@ -7049,7 +6574,6 @@ exports.makeSelectClaimIsPending = makeSelectClaimIsPending; exports.makeSelectClaimWasPurchased = makeSelectClaimWasPurchased; exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannelForCurrentPageState; exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; -exports.makeSelectCommentsForUri = makeSelectCommentsForUri; exports.makeSelectContentPositionForUri = makeSelectContentPositionForUri; exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; exports.makeSelectCoverForUri = makeSelectCoverForUri; @@ -7112,12 +6636,9 @@ exports.selectAllClaimsByChannel = selectAllClaimsByChannel; exports.selectAllFetchingChannelClaims = selectAllFetchingChannelClaims; exports.selectAllMyClaimsByOutpoint = selectAllMyClaimsByOutpoint; exports.selectBalance = selectBalance; -exports.selectBlockedChannels = selectBlockedChannels; -exports.selectBlockedChannelsCount = selectBlockedChannelsCount; exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; exports.selectChannelImportPending = selectChannelImportPending; -exports.selectChannelIsBlocked = selectChannelIsBlocked; exports.selectClaimIdsByUri = selectClaimIdsByUri; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; @@ -7153,7 +6674,6 @@ exports.selectFollowedTagsList = selectFollowedTagsList; exports.selectGettingNewAddress = selectGettingNewAddress; exports.selectHasTransactions = selectHasTransactions; exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; -exports.selectIsFetchingComments = selectIsFetchingComments; exports.selectIsFetchingFileList = selectIsFetchingFileList; exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileListDownloadedOrPublished; exports.selectIsFetchingMyPurchases = selectIsFetchingMyPurchases; diff --git a/flow-typed/Blocklist.js b/flow-typed/Blocklist.js deleted file mode 100644 index 454a714..0000000 --- a/flow-typed/Blocklist.js +++ /dev/null @@ -1,10 +0,0 @@ -declare type BlocklistState = { - blockedChannels: Array -}; - -declare type BlocklistAction = { - type: string, - data: { - uri: string, - }, -}; diff --git a/flow-typed/Comment.js b/flow-typed/Comment.js deleted file mode 100644 index 64ea974..0000000 --- a/flow-typed/Comment.js +++ /dev/null @@ -1,23 +0,0 @@ -declare type Comment = { - comment: string, // comment body - comment_id: string, // sha256 digest - claim_id: string, // id linking to the claim this comment - timestamp: number, // integer representing unix-time - is_hidden: boolean, // claim owner may enable/disable this - channel_id?: string, // claimId of channel signing this comment - channel_name?: string, // name of channel claim - channel_url?: string, // full lbry url to signing channel - signature?: string, // signature of comment by originating channel - signing_ts?: string, // timestamp used when signing this comment - is_channel_signature_valid?: boolean, // whether or not the signature could be validated - parent_id?: number, // comment_id of comment this is in reply to -}; - -// todo: relate individual comments to their commentId -declare type CommentsState = { - commentsByUri: { [string]: string }, - byId: { [string]: Array }, - commentById: { [string]: Comment }, - isLoading: boolean, - myComments: ?Set, -}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index b14cfb8..3525f4d 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -131,23 +131,6 @@ export const PURCHASE_LIST_STARTED = 'PURCHASE_LIST_STARTED'; export const PURCHASE_LIST_COMPLETED = 'PURCHASE_LIST_COMPLETED'; export const PURCHASE_LIST_FAILED = 'PURCHASE_LIST_FAILED'; -// Comments -export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; -export const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED'; -export const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED'; -export const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; -export const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; -export const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; -export const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; -export const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; -export const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; -export const COMMENT_UPDATE_STARTED = 'COMMENT_UPDATE_STARTED'; -export const COMMENT_UPDATE_COMPLETED = 'COMMENT_UPDATE_COMPLETED'; -export const COMMENT_UPDATE_FAILED = 'COMMENT_UPDATE_FAILED'; -export const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; -export const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; -export const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; - // Files export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; export const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; @@ -283,8 +266,5 @@ export const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; export const TAG_ADD = 'TAG_ADD'; export const TAG_DELETE = 'TAG_DELETE'; -// Blocked Channels -export const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; - // Sync export const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; diff --git a/src/index.js b/src/index.js index dcec873..d28f38f 100644 --- a/src/index.js +++ b/src/index.js @@ -135,16 +135,6 @@ export { export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; -export { - doCommentList, - doCommentCreate, - doCommentAbandon, - doCommentHide, - doCommentUpdate, -} from 'redux/actions/comments'; - -export { doToggleBlockChannel } from 'redux/actions/blocked'; - export { doPopulateSharedUserState, doPreferenceGet, doPreferenceSet } from 'redux/actions/sync'; // utils @@ -155,14 +145,12 @@ export { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; // reducers export { claimsReducer } from 'redux/reducers/claims'; -export { commentReducer } from 'redux/reducers/comments'; export { contentReducer } from 'redux/reducers/content'; export { fileInfoReducer } from 'redux/reducers/file_info'; export { notificationsReducer } from 'redux/reducers/notifications'; export { publishReducer } from 'redux/reducers/publish'; export { searchReducer } from 'redux/reducers/search'; export { tagsReducer } from 'redux/reducers/tags'; -export { blockedReducer } from 'redux/reducers/blocked'; export { walletReducer } from 'redux/reducers/wallet'; // selectors @@ -252,8 +240,6 @@ export { selectPurchaseUriSuccess, } from 'redux/selectors/claims'; -export { makeSelectCommentsForUri, selectIsFetchingComments } from 'redux/selectors/comments'; - export { makeSelectFileInfoForUri, makeSelectDownloadingForUri, @@ -361,9 +347,3 @@ export { selectUnfollowedTags, makeSelectIsFollowingTag, } from 'redux/selectors/tags'; - -export { - selectBlockedChannels, - selectChannelIsBlocked, - selectBlockedChannelsCount, -} from 'redux/selectors/blocked'; diff --git a/src/redux/actions/blocked.js b/src/redux/actions/blocked.js deleted file mode 100644 index 1e96563..0000000 --- a/src/redux/actions/blocked.js +++ /dev/null @@ -1,9 +0,0 @@ -// @flow -import * as ACTIONS from 'constants/action_types'; - -export const doToggleBlockChannel = (uri: string) => ({ - type: ACTIONS.TOGGLE_BLOCK_CHANNEL, - data: { - uri, - }, -}); diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js deleted file mode 100644 index 22b38e4..0000000 --- a/src/redux/actions/comments.js +++ /dev/null @@ -1,225 +0,0 @@ -// @flow -import * as ACTIONS from 'constants/action_types'; -import Lbry from 'lbry'; -import { selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims'; -import { doToast } from 'redux/actions/notifications'; - -export function doCommentList(uri: string, page: number = 1, pageSize: number = 99999) { - return (dispatch: Dispatch, getState: GetState) => { - const state = getState(); - const claim = selectClaimsByUri(state)[uri]; - const claimId = claim ? claim.claim_id : null; - - dispatch({ - type: ACTIONS.COMMENT_LIST_STARTED, - }); - Lbry.comment_list({ - claim_id: claimId, - page, - page_size: pageSize, - }) - .then((result: CommentListResponse) => { - const { items: comments } = result; - dispatch({ - type: ACTIONS.COMMENT_LIST_COMPLETED, - data: { - comments, - claimId: claimId, - uri: uri, - }, - }); - }) - .catch(error => { - console.log(error); - dispatch({ - type: ACTIONS.COMMENT_LIST_FAILED, - data: error, - }); - }); - }; -} - -export function doCommentCreate( - comment: string = '', - claim_id: string = '', - channel: string, - parent_id?: string -) { - return (dispatch: Dispatch, getState: GetState) => { - const state = getState(); - dispatch({ - type: ACTIONS.COMMENT_CREATE_STARTED, - }); - - const myChannels = selectMyChannelClaims(state); - const namedChannelClaim = - myChannels && myChannels.find(myChannel => myChannel.name === channel); - const channel_id = namedChannelClaim.claim_id; - - if (channel_id == null) { - dispatch({ - type: ACTIONS.COMMENT_CREATE_FAILED, - data: {}, - }); - dispatch( - doToast({ - message: 'Channel cannot be anonymous, please select a channel and try again.', - isError: true, - }) - ); - return; - } - - return Lbry.comment_create({ - comment: comment, - claim_id: claim_id, - channel_id: channel_id, - parent_id: parent_id, - }) - .then((result: CommentCreateResponse) => { - dispatch({ - type: ACTIONS.COMMENT_CREATE_COMPLETED, - data: { - comment: result, - claimId: claim_id, - }, - }); - }) - .catch(error => { - dispatch({ - type: ACTIONS.COMMENT_CREATE_FAILED, - data: error, - }); - dispatch( - doToast({ - message: 'Unable to create comment, please try again later.', - isError: true, - }) - ); - }); - }; -} - -export function doCommentHide(comment_id: string) { - return (dispatch: Dispatch) => { - dispatch({ - type: ACTIONS.COMMENT_HIDE_STARTED, - }); - return Lbry.comment_hide({ - comment_ids: [comment_id], - }) - .then((result: CommentHideResponse) => { - dispatch({ - type: ACTIONS.COMMENT_HIDE_COMPLETED, - data: result, - }); - }) - .catch(error => { - dispatch({ - type: ACTIONS.COMMENT_HIDE_FAILED, - data: error, - }); - dispatch( - doToast({ - message: 'Unable to hide this comment, please try again later.', - isError: true, - }) - ); - }); - }; -} - -export function doCommentAbandon(comment_id: string) { - return (dispatch: Dispatch) => { - dispatch({ - type: ACTIONS.COMMENT_ABANDON_STARTED, - }); - return Lbry.comment_abandon({ - comment_id: comment_id, - }) - .then((result: CommentAbandonResponse) => { - // Comment may not be deleted if the signing channel can't be signed. - // This will happen if the channel was recently created or abandoned. - if (result.abandoned) { - dispatch({ - type: ACTIONS.COMMENT_ABANDON_COMPLETED, - data: { - comment_id: comment_id, - }, - }); - } else { - dispatch({ - type: ACTIONS.COMMENT_ABANDON_FAILED, - }); - dispatch( - doToast({ - message: 'Your channel is still being setup, try again in a few moments.', - isError: true, - }) - ); - } - }) - .catch(error => { - dispatch({ - type: ACTIONS.COMMENT_ABANDON_FAILED, - data: error, - }); - dispatch( - doToast({ - message: 'Unable to delete this comment, please try again later.', - isError: true, - }) - ); - }); - }; -} - -export function doCommentUpdate(comment_id: string, comment: string) { - // if they provided an empty string, they must have wanted to abandon - if (comment === '') { - return doCommentAbandon(comment_id); - } else { - return (dispatch: Dispatch) => { - dispatch({ - type: ACTIONS.COMMENT_UPDATE_STARTED, - }); - return Lbry.comment_update({ - comment_id: comment_id, - comment: comment, - }) - .then((result: CommentUpdateResponse) => { - if (result != null) { - dispatch({ - type: ACTIONS.COMMENT_UPDATE_COMPLETED, - data: { - comment: result, - }, - }); - } else { - // the result will return null - dispatch({ - type: ACTIONS.COMMENT_UPDATE_FAILED, - }); - dispatch( - doToast({ - message: 'Your channel is still being setup, try again in a few moments.', - isError: true, - }) - ); - } - }) - .catch(error => { - dispatch({ - type: ACTIONS.COMMENT_UPDATE_FAILED, - data: error, - }); - dispatch( - doToast({ - message: 'Unable to edit this comment, please try again later.', - isError: true, - }) - ); - }); - }; - } -} diff --git a/src/redux/reducers/blocked.js b/src/redux/reducers/blocked.js deleted file mode 100644 index c688936..0000000 --- a/src/redux/reducers/blocked.js +++ /dev/null @@ -1,41 +0,0 @@ -// @flow -import * as ACTIONS from 'constants/action_types'; -import { handleActions } from 'util/redux-utils'; - -const defaultState: BlocklistState = { - blockedChannels: [], -}; - -export const blockedReducer = handleActions( - { - [ACTIONS.TOGGLE_BLOCK_CHANNEL]: ( - state: BlocklistState, - action: BlocklistAction - ): BlocklistState => { - const { blockedChannels } = state; - const { uri } = action.data; - let newBlockedChannels = blockedChannels.slice(); - - if (newBlockedChannels.includes(uri)) { - newBlockedChannels = newBlockedChannels.filter(id => id !== uri); - } else { - newBlockedChannels.push(uri); - } - - return { - blockedChannels: newBlockedChannels, - }; - }, - [ACTIONS.USER_STATE_POPULATE]: ( - state: BlocklistState, - action: { data: { blocked: ?Array } } - ) => { - const { blocked } = action.data; - return { - ...state, - blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels, - }; - }, - }, - defaultState -); diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js deleted file mode 100644 index 46d08d8..0000000 --- a/src/redux/reducers/comments.js +++ /dev/null @@ -1,153 +0,0 @@ -// @flow -import * as ACTIONS from 'constants/action_types'; -import { handleActions } from 'util/redux-utils'; - -const defaultState: CommentsState = { - commentById: {}, // commentId -> Comment - byId: {}, // ClaimID -> list of comments - commentsByUri: {}, // URI -> claimId - isLoading: false, - myComments: undefined, -}; - -export const commentReducer = handleActions( - { - [ACTIONS.COMMENT_CREATE_STARTED]: (state: CommentsState, action: any): CommentsState => ({ - ...state, - isLoading: true, - }), - - [ACTIONS.COMMENT_CREATE_FAILED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: false, - }), - - [ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => { - const { comment, claimId }: { comment: Comment, claimId: string } = action.data; - const commentById = Object.assign({}, state.commentById); - const byId = Object.assign({}, state.byId); - const comments = byId[claimId]; - const newCommentIds = comments.slice(); - - // add the comment by its ID - commentById[comment.comment_id] = comment; - - // push the comment_id to the top of ID list - newCommentIds.unshift(comment.comment_id); - byId[claimId] = newCommentIds; - - return { - ...state, - commentById, - byId, - isLoading: false, - }; - }, - - [ACTIONS.COMMENT_LIST_STARTED]: state => ({ ...state, isLoading: true }), - - [ACTIONS.COMMENT_LIST_COMPLETED]: (state: CommentsState, action: any) => { - const { comments, claimId, uri } = action.data; - - const commentById = Object.assign({}, state.commentById); - const byId = Object.assign({}, state.byId); - const commentsByUri = Object.assign({}, state.commentsByUri); - - if (comments) { - // we use an Array to preserve order of listing - // in reality this doesn't matter and we can just - // sort comments by their timestamp - const commentIds = Array(comments.length); - - // map the comment_ids to the new comments - for (let i = 0; i < comments.length; i++) { - commentIds[i] = comments[i].comment_id; - commentById[commentIds[i]] = comments[i]; - } - - byId[claimId] = commentIds; - commentsByUri[uri] = claimId; - } - return { - ...state, - byId, - commentById, - commentsByUri, - isLoading: false, - }; - }, - - [ACTIONS.COMMENT_LIST_FAILED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: false, - }), - [ACTIONS.COMMENT_ABANDON_STARTED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: true, - }), - [ACTIONS.COMMENT_ABANDON_COMPLETED]: (state: CommentsState, action: any) => { - const { comment_id } = action.data; - const commentById = Object.assign({}, state.commentById); - const byId = Object.assign({}, state.byId); - - // to remove the comment and its references - const claimId = commentById[comment_id].claim_id; - for (let i = 0; i < byId[claimId].length; i++) { - if (byId[claimId][i] === comment_id) { - byId[claimId].splice(i, 1); - break; - } - } - delete commentById[comment_id]; - - return { - ...state, - commentById, - byId, - isLoading: false, - }; - }, - // do nothing - [ACTIONS.COMMENT_ABANDON_FAILED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: false, - }), - // do nothing - [ACTIONS.COMMENT_UPDATE_STARTED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: true, - }), - // replace existing comment with comment returned here under its comment_id - [ACTIONS.COMMENT_UPDATE_COMPLETED]: (state: CommentsState, action: any) => { - const { comment } = action.data; - const commentById = Object.assign({}, state.commentById); - commentById[comment.comment_id] = comment; - - return { - ...state, - commentById, - isLoading: false, - }; - }, - // nothing can be done here - [ACTIONS.COMMENT_UPDATE_FAILED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: false, - }), - // nothing can really be done here - [ACTIONS.COMMENT_HIDE_STARTED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: true, - }), - [ACTIONS.COMMENT_HIDE_COMPLETED]: (state: CommentsState, action: any) => ({ - ...state, // todo: add HiddenComments state & create selectors - isLoading: false, - }), - // nothing can be done here - [ACTIONS.COMMENT_HIDE_FAILED]: (state: CommentsState, action: any) => ({ - ...state, - isLoading: false, - }), - }, - defaultState -); diff --git a/src/redux/selectors/blocked.js b/src/redux/selectors/blocked.js deleted file mode 100644 index 424ea89..0000000 --- a/src/redux/selectors/blocked.js +++ /dev/null @@ -1,22 +0,0 @@ -// @flow -import { createSelector } from 'reselect'; - -const selectState = (state: { blocked: BlocklistState }) => state.blocked || {}; - -export const selectBlockedChannels = createSelector( - selectState, - (state: BlocklistState) => state.blockedChannels -); - -export const selectBlockedChannelsCount = createSelector( - selectBlockedChannels, - (state: Array) => state.length -); - -export const selectChannelIsBlocked = (uri: string) => - createSelector( - selectBlockedChannels, - (state: Array) => { - return state.includes(uri); - } - ); diff --git a/src/redux/selectors/comments.js b/src/redux/selectors/comments.js deleted file mode 100644 index d8033ff..0000000 --- a/src/redux/selectors/comments.js +++ /dev/null @@ -1,71 +0,0 @@ -// @flow -import { createSelector } from 'reselect'; - -const selectState = state => state.comments || {}; - -export const selectCommentsById = createSelector( - selectState, - state => state.commentById || {} -); - -export const selectIsFetchingComments = createSelector( - selectState, - state => state.isLoading -); - -export const selectCommentsByClaimId = createSelector( - selectState, - selectCommentsById, - (state, byId) => { - const byClaimId = state.byId || {}; - const comments = {}; - - // replace every comment_id in the list with the actual comment object - Object.keys(byClaimId).forEach(claimId => { - const commentIds = byClaimId[claimId]; - - comments[claimId] = Array(commentIds === null ? 0 : commentIds.length); - for (let i = 0; i < commentIds.length; i++) { - comments[claimId][i] = byId[commentIds[i]]; - } - }); - - return comments; - } -); - -// previously this used a mapping from claimId -> Array -/* export const selectCommentsById = createSelector( - selectState, - state => state.byId || {} -); */ -export const selectCommentsByUri = createSelector( - selectState, - state => { - const byUri = state.commentsByUri || {}; - const comments = {}; - Object.keys(byUri).forEach(uri => { - const claimId = byUri[uri]; - if (claimId === null) { - comments[uri] = null; - } else { - comments[uri] = claimId; - } - }); - - return comments; - } -); - -export const makeSelectCommentsForUri = (uri: string) => - createSelector( - selectCommentsByClaimId, - selectCommentsByUri, - (byClaimId, byUri) => { - const claimId = byUri[uri]; - return byClaimId && byClaimId[claimId]; - } - ); - -// todo: allow SDK to retrieve user comments through comment_list -// todo: implement selectors for selecting comments owned by user -- 2.45.2 From fc217d58d7c5a7cdf5b963b58b065d9af81d19ff Mon Sep 17 00:00:00 2001 From: infiinte-persistence Date: Wed, 24 Jun 2020 13:31:09 +0800 Subject: [PATCH 358/371] Fix unresolved "You sent ${amount} LBC" ## Fixes: [lbry-desktop] #-4429: Unresolved string: "You sent ${amount} LBC" ## Changes: Corrected error in commit c9492522. --- src/redux/actions/wallet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redux/actions/wallet.js b/src/redux/actions/wallet.js index a554590..949ada5 100644 --- a/src/redux/actions/wallet.js +++ b/src/redux/actions/wallet.js @@ -187,7 +187,7 @@ export function doSendDraftTransaction(address, amount) { }); dispatch( doToast({ - message: __('You sent ${amount} LBC'), + message: __(`You sent ${amount} LBC`), linkText: __('History'), linkTarget: '/wallet', }) -- 2.45.2 From ebf0d49fb0f3e321658bf3e822fe8ba034583866 Mon Sep 17 00:00:00 2001 From: Baltazar Gomez Date: Fri, 26 Jun 2020 23:29:00 -0500 Subject: [PATCH 359/371] add file text to publish state --- src/redux/reducers/publish.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js index ae7313d..4c94168 100644 --- a/src/redux/reducers/publish.js +++ b/src/redux/reducers/publish.js @@ -7,6 +7,7 @@ import { CHANNEL_ANONYMOUS } from 'constants/claim'; type PublishState = { editingURI: ?string, + fileText: ?string, filePath: ?string, contentIsFree: boolean, fileDur: number, @@ -36,6 +37,7 @@ type PublishState = { const defaultState: PublishState = { editingURI: undefined, + fileText: '', filePath: undefined, fileDur: 0, fileSize: 0, -- 2.45.2 From cca78e9341f5e3049776bdd6f2cb32907ada96f6 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 29 Jun 2020 17:02:19 -0400 Subject: [PATCH 360/371] Revert "remove comment/blocked code" This reverts commit e4c05cebe97b278eca0f7e1c24fa0c210132abd2. --- dist/bundle.es.js | 738 ++++++++++++++++++++++++++------ flow-typed/Blocklist.js | 10 + flow-typed/Comment.js | 23 + src/constants/action_types.js | 20 + src/index.js | 20 + src/redux/actions/blocked.js | 9 + src/redux/actions/comments.js | 225 ++++++++++ src/redux/reducers/blocked.js | 41 ++ src/redux/reducers/comments.js | 153 +++++++ src/redux/selectors/blocked.js | 22 + src/redux/selectors/comments.js | 71 +++ 11 files changed, 1203 insertions(+), 129 deletions(-) create mode 100644 flow-typed/Blocklist.js create mode 100644 flow-typed/Comment.js create mode 100644 src/redux/actions/blocked.js create mode 100644 src/redux/actions/comments.js create mode 100644 src/redux/reducers/blocked.js create mode 100644 src/redux/reducers/comments.js create mode 100644 src/redux/selectors/blocked.js create mode 100644 src/redux/selectors/comments.js diff --git a/dist/bundle.es.js b/dist/bundle.es.js index a136b70..ee5209b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -154,6 +154,23 @@ const PURCHASE_LIST_STARTED = 'PURCHASE_LIST_STARTED'; const PURCHASE_LIST_COMPLETED = 'PURCHASE_LIST_COMPLETED'; const PURCHASE_LIST_FAILED = 'PURCHASE_LIST_FAILED'; +// Comments +const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; +const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED'; +const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED'; +const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; +const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; +const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; +const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; +const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; +const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; +const COMMENT_UPDATE_STARTED = 'COMMENT_UPDATE_STARTED'; +const COMMENT_UPDATE_COMPLETED = 'COMMENT_UPDATE_COMPLETED'; +const COMMENT_UPDATE_FAILED = 'COMMENT_UPDATE_FAILED'; +const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; +const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; +const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; + // Files const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; @@ -289,6 +306,9 @@ const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; const TAG_ADD = 'TAG_ADD'; const TAG_DELETE = 'TAG_DELETE'; +// Blocked Channels +const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; + // Sync const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; @@ -417,6 +437,21 @@ var action_types = /*#__PURE__*/Object.freeze({ PURCHASE_LIST_STARTED: PURCHASE_LIST_STARTED, PURCHASE_LIST_COMPLETED: PURCHASE_LIST_COMPLETED, PURCHASE_LIST_FAILED: PURCHASE_LIST_FAILED, + COMMENT_LIST_STARTED: COMMENT_LIST_STARTED, + COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED, + COMMENT_LIST_FAILED: COMMENT_LIST_FAILED, + COMMENT_CREATE_STARTED: COMMENT_CREATE_STARTED, + COMMENT_CREATE_COMPLETED: COMMENT_CREATE_COMPLETED, + COMMENT_CREATE_FAILED: COMMENT_CREATE_FAILED, + COMMENT_ABANDON_STARTED: COMMENT_ABANDON_STARTED, + COMMENT_ABANDON_COMPLETED: COMMENT_ABANDON_COMPLETED, + COMMENT_ABANDON_FAILED: COMMENT_ABANDON_FAILED, + COMMENT_UPDATE_STARTED: COMMENT_UPDATE_STARTED, + COMMENT_UPDATE_COMPLETED: COMMENT_UPDATE_COMPLETED, + COMMENT_UPDATE_FAILED: COMMENT_UPDATE_FAILED, + COMMENT_HIDE_STARTED: COMMENT_HIDE_STARTED, + COMMENT_HIDE_COMPLETED: COMMENT_HIDE_COMPLETED, + COMMENT_HIDE_FAILED: COMMENT_HIDE_FAILED, FILE_LIST_STARTED: FILE_LIST_STARTED, FILE_LIST_SUCCEEDED: FILE_LIST_SUCCEEDED, FETCH_FILE_INFO_STARTED: FETCH_FILE_INFO_STARTED, @@ -529,6 +564,7 @@ var action_types = /*#__PURE__*/Object.freeze({ TOGGLE_TAG_FOLLOW: TOGGLE_TAG_FOLLOW, TAG_ADD: TAG_ADD, TAG_DELETE: TAG_DELETE, + TOGGLE_BLOCK_CHANNEL: TOGGLE_BLOCK_CHANNEL, USER_STATE_POPULATE: USER_STATE_POPULATE }); @@ -4874,6 +4910,207 @@ const doDeleteTag = name => ({ } }); +// + +function doCommentList(uri, page = 1, pageSize = 99999) { + return (dispatch, getState) => { + const state = getState(); + const claim = selectClaimsByUri(state)[uri]; + const claimId = claim ? claim.claim_id : null; + + dispatch({ + type: COMMENT_LIST_STARTED + }); + lbryProxy.comment_list({ + claim_id: claimId, + page, + page_size: pageSize + }).then(result => { + const { items: comments } = result; + dispatch({ + type: COMMENT_LIST_COMPLETED, + data: { + comments, + claimId: claimId, + uri: uri + } + }); + }).catch(error => { + console.log(error); + dispatch({ + type: COMMENT_LIST_FAILED, + data: error + }); + }); + }; +} + +function doCommentCreate(comment = '', claim_id = '', channel, parent_id) { + return (dispatch, getState) => { + const state = getState(); + dispatch({ + type: COMMENT_CREATE_STARTED + }); + + const myChannels = selectMyChannelClaims(state); + const namedChannelClaim = myChannels && myChannels.find(myChannel => myChannel.name === channel); + const channel_id = namedChannelClaim.claim_id; + + if (channel_id == null) { + dispatch({ + type: COMMENT_CREATE_FAILED, + data: {} + }); + dispatch(doToast({ + message: 'Channel cannot be anonymous, please select a channel and try again.', + isError: true + })); + return; + } + + return lbryProxy.comment_create({ + comment: comment, + claim_id: claim_id, + channel_id: channel_id, + parent_id: parent_id + }).then(result => { + dispatch({ + type: COMMENT_CREATE_COMPLETED, + data: { + comment: result, + claimId: claim_id + } + }); + }).catch(error => { + dispatch({ + type: COMMENT_CREATE_FAILED, + data: error + }); + dispatch(doToast({ + message: 'Unable to create comment, please try again later.', + isError: true + })); + }); + }; +} + +function doCommentHide(comment_id) { + return dispatch => { + dispatch({ + type: COMMENT_HIDE_STARTED + }); + return lbryProxy.comment_hide({ + comment_ids: [comment_id] + }).then(result => { + dispatch({ + type: COMMENT_HIDE_COMPLETED, + data: result + }); + }).catch(error => { + dispatch({ + type: COMMENT_HIDE_FAILED, + data: error + }); + dispatch(doToast({ + message: 'Unable to hide this comment, please try again later.', + isError: true + })); + }); + }; +} + +function doCommentAbandon(comment_id) { + return dispatch => { + dispatch({ + type: COMMENT_ABANDON_STARTED + }); + return lbryProxy.comment_abandon({ + comment_id: comment_id + }).then(result => { + // Comment may not be deleted if the signing channel can't be signed. + // This will happen if the channel was recently created or abandoned. + if (result.abandoned) { + dispatch({ + type: COMMENT_ABANDON_COMPLETED, + data: { + comment_id: comment_id + } + }); + } else { + dispatch({ + type: COMMENT_ABANDON_FAILED + }); + dispatch(doToast({ + message: 'Your channel is still being setup, try again in a few moments.', + isError: true + })); + } + }).catch(error => { + dispatch({ + type: COMMENT_ABANDON_FAILED, + data: error + }); + dispatch(doToast({ + message: 'Unable to delete this comment, please try again later.', + isError: true + })); + }); + }; +} + +function doCommentUpdate(comment_id, comment) { + // if they provided an empty string, they must have wanted to abandon + if (comment === '') { + return doCommentAbandon(comment_id); + } else { + return dispatch => { + dispatch({ + type: COMMENT_UPDATE_STARTED + }); + return lbryProxy.comment_update({ + comment_id: comment_id, + comment: comment + }).then(result => { + if (result != null) { + dispatch({ + type: COMMENT_UPDATE_COMPLETED, + data: { + comment: result + } + }); + } else { + // the result will return null + dispatch({ + type: COMMENT_UPDATE_FAILED + }); + dispatch(doToast({ + message: 'Your channel is still being setup, try again in a few moments.', + isError: true + })); + } + }).catch(error => { + dispatch({ + type: COMMENT_UPDATE_FAILED, + data: error + }); + dispatch(doToast({ + message: 'Unable to edit this comment, please try again later.', + isError: true + })); + }); + }; + } +} + +// + +const doToggleBlockChannel = uri => ({ + type: TOGGLE_BLOCK_CHANNEL, + data: { + uri + } +}); + var _extends$a = 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; }; /* @@ -5532,32 +5769,185 @@ function claimsReducer(state = defaultState, action) { return state; } +// util for creating reducers +// based off of redux-actions +// https://redux-actions.js.org/docs/api/handleAction.html#handleactions + +// eslint-disable-next-line import/prefer-default-export +const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { + const handler = actionMap[action.type]; + + if (handler) { + const newState = handler(state, action); + return Object.assign({}, state, newState); + } + + // just return the original state if no handler + // returning a copy here breaks redux-persist + return state; +}; + var _extends$c = 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; }; -const reducers$1 = {}; const defaultState$1 = { + commentById: {}, // commentId -> Comment + byId: {}, // ClaimID -> list of comments + commentsByUri: {}, // URI -> claimId + isLoading: false, + myComments: undefined +}; + +const commentReducer = handleActions({ + [COMMENT_CREATE_STARTED]: (state, action) => _extends$c({}, state, { + isLoading: true + }), + + [COMMENT_CREATE_FAILED]: (state, action) => _extends$c({}, state, { + isLoading: false + }), + + [COMMENT_CREATE_COMPLETED]: (state, action) => { + const { comment, claimId } = action.data; + const commentById = Object.assign({}, state.commentById); + const byId = Object.assign({}, state.byId); + const comments = byId[claimId]; + const newCommentIds = comments.slice(); + + // add the comment by its ID + commentById[comment.comment_id] = comment; + + // push the comment_id to the top of ID list + newCommentIds.unshift(comment.comment_id); + byId[claimId] = newCommentIds; + + return _extends$c({}, state, { + commentById, + byId, + isLoading: false + }); + }, + + [COMMENT_LIST_STARTED]: state => _extends$c({}, state, { isLoading: true }), + + [COMMENT_LIST_COMPLETED]: (state, action) => { + const { comments, claimId, uri } = action.data; + + const commentById = Object.assign({}, state.commentById); + const byId = Object.assign({}, state.byId); + const commentsByUri = Object.assign({}, state.commentsByUri); + + if (comments) { + // we use an Array to preserve order of listing + // in reality this doesn't matter and we can just + // sort comments by their timestamp + const commentIds = Array(comments.length); + + // map the comment_ids to the new comments + for (let i = 0; i < comments.length; i++) { + commentIds[i] = comments[i].comment_id; + commentById[commentIds[i]] = comments[i]; + } + + byId[claimId] = commentIds; + commentsByUri[uri] = claimId; + } + return _extends$c({}, state, { + byId, + commentById, + commentsByUri, + isLoading: false + }); + }, + + [COMMENT_LIST_FAILED]: (state, action) => _extends$c({}, state, { + isLoading: false + }), + [COMMENT_ABANDON_STARTED]: (state, action) => _extends$c({}, state, { + isLoading: true + }), + [COMMENT_ABANDON_COMPLETED]: (state, action) => { + const { comment_id } = action.data; + const commentById = Object.assign({}, state.commentById); + const byId = Object.assign({}, state.byId); + + // to remove the comment and its references + const claimId = commentById[comment_id].claim_id; + for (let i = 0; i < byId[claimId].length; i++) { + if (byId[claimId][i] === comment_id) { + byId[claimId].splice(i, 1); + break; + } + } + delete commentById[comment_id]; + + return _extends$c({}, state, { + commentById, + byId, + isLoading: false + }); + }, + // do nothing + [COMMENT_ABANDON_FAILED]: (state, action) => _extends$c({}, state, { + isLoading: false + }), + // do nothing + [COMMENT_UPDATE_STARTED]: (state, action) => _extends$c({}, state, { + isLoading: true + }), + // replace existing comment with comment returned here under its comment_id + [COMMENT_UPDATE_COMPLETED]: (state, action) => { + const { comment } = action.data; + const commentById = Object.assign({}, state.commentById); + commentById[comment.comment_id] = comment; + + return _extends$c({}, state, { + commentById, + isLoading: false + }); + }, + // nothing can be done here + [COMMENT_UPDATE_FAILED]: (state, action) => _extends$c({}, state, { + isLoading: false + }), + // nothing can really be done here + [COMMENT_HIDE_STARTED]: (state, action) => _extends$c({}, state, { + isLoading: true + }), + [COMMENT_HIDE_COMPLETED]: (state, action) => _extends$c({}, state, { // todo: add HiddenComments state & create selectors + isLoading: false + }), + // nothing can be done here + [COMMENT_HIDE_FAILED]: (state, action) => _extends$c({}, state, { + isLoading: false + }) +}, defaultState$1); + +var _extends$d = 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; }; + +const reducers$1 = {}; +const defaultState$2 = { positions: {} }; reducers$1[SET_CONTENT_POSITION] = (state, action) => { const { claimId, outpoint, position } = action.data; - return _extends$c({}, state, { - positions: _extends$c({}, state.positions, { - [claimId]: _extends$c({}, state.positions[claimId], { + return _extends$d({}, state, { + positions: _extends$d({}, state.positions, { + [claimId]: _extends$d({}, state.positions[claimId], { [outpoint]: position }) }) }); }; -function contentReducer(state = defaultState$1, action) { +function contentReducer(state = defaultState$2, action) { const handler = reducers$1[action.type]; if (handler) return handler(state, action); return state; } const reducers$2 = {}; -const defaultState$2 = { +const defaultState$3 = { fileListPublishedSort: DATE_NEW, fileListDownloadedSort: DATE_NEW }; @@ -5704,33 +6094,15 @@ reducers$2[SET_FILE_LIST_SORT] = (state, action) => { }); }; -function fileInfoReducer(state = defaultState$2, action) { +function fileInfoReducer(state = defaultState$3, action) { const handler = reducers$2[action.type]; if (handler) return handler(state, action); return state; } -// util for creating reducers -// based off of redux-actions -// https://redux-actions.js.org/docs/api/handleAction.html#handleactions +var _extends$e = 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; }; -// eslint-disable-next-line import/prefer-default-export -const handleActions = (actionMap, defaultState) => (state = defaultState, action) => { - const handler = actionMap[action.type]; - - if (handler) { - const newState = handler(state, action); - return Object.assign({}, state, newState); - } - - // just return the original state if no handler - // returning a copy here breaks redux-persist - return state; -}; - -var _extends$d = 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; }; - -const defaultState$3 = { +const defaultState$4 = { notifications: [], toasts: [], errors: [] @@ -5743,7 +6115,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.push(toast); - return _extends$d({}, state, { + return _extends$e({}, state, { toasts: newToasts }); }, @@ -5751,7 +6123,7 @@ const notificationsReducer = handleActions({ const newToasts = state.toasts.slice(); newToasts.shift(); - return _extends$d({}, state, { + return _extends$e({}, state, { toasts: newToasts }); }, @@ -5762,7 +6134,7 @@ const notificationsReducer = handleActions({ const newNotifications = state.notifications.slice(); newNotifications.push(notification); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications: newNotifications }); }, @@ -5773,7 +6145,7 @@ const notificationsReducer = handleActions({ notifications = notifications.map(pastNotification => pastNotification.id === notification.id ? notification : pastNotification); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications }); }, @@ -5782,7 +6154,7 @@ const notificationsReducer = handleActions({ let newNotifications = state.notifications.slice(); newNotifications = newNotifications.filter(notification => notification.id !== id); - return _extends$d({}, state, { + return _extends$e({}, state, { notifications: newNotifications }); }, @@ -5793,7 +6165,7 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.push(error); - return _extends$d({}, state, { + return _extends$e({}, state, { errors: newErrors }); }, @@ -5801,17 +6173,17 @@ const notificationsReducer = handleActions({ const newErrors = state.errors.slice(); newErrors.shift(); - return _extends$d({}, state, { + return _extends$e({}, state, { errors: newErrors }); } -}, defaultState$3); +}, defaultState$4); -var _extends$e = 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; }; +var _extends$f = 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$4(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$4 = { +const defaultState$5 = { editingURI: undefined, filePath: undefined, fileDur: 0, @@ -5848,20 +6220,20 @@ const defaultState$4 = { const publishReducer = handleActions({ [UPDATE_PUBLISH_FORM]: (state, action) => { const { data } = action; - return _extends$e({}, state, data); + return _extends$f({}, state, data); }, - [CLEAR_PUBLISH]: state => _extends$e({}, defaultState$4, { + [CLEAR_PUBLISH]: state => _extends$f({}, defaultState$5, { bid: state.bid, optimize: state.optimize }), - [PUBLISH_START]: state => _extends$e({}, state, { + [PUBLISH_START]: state => _extends$f({}, state, { publishing: true, publishSuccess: false }), - [PUBLISH_FAIL]: state => _extends$e({}, state, { + [PUBLISH_FAIL]: state => _extends$f({}, state, { publishing: false }), - [PUBLISH_SUCCESS]: state => _extends$e({}, state, { + [PUBLISH_SUCCESS]: state => _extends$f({}, state, { publishing: false, publishSuccess: true }), @@ -5876,16 +6248,16 @@ const publishReducer = handleActions({ streamName: name }); - return _extends$e({}, defaultState$4, publishData, { + return _extends$f({}, defaultState$5, publishData, { editingURI: uri, uri: shortUri }); } -}, defaultState$4); +}, defaultState$5); -var _extends$f = 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; }; +var _extends$g = 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; }; -const defaultState$5 = { +const defaultState$6 = { 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 @@ -5905,23 +6277,23 @@ const defaultState$5 = { }; const searchReducer = handleActions({ - [SEARCH_START]: state => _extends$f({}, state, { + [SEARCH_START]: state => _extends$g({}, state, { searching: true }), [SEARCH_SUCCESS]: (state, action) => { const { query, uris } = action.data; - return _extends$f({}, state, { + return _extends$g({}, state, { searching: false, urisByQuery: Object.assign({}, state.urisByQuery, { [query]: uris }) }); }, - [SEARCH_FAIL]: state => _extends$f({}, state, { + [SEARCH_FAIL]: state => _extends$g({}, state, { searching: false }), - [RESOLVED_SEARCH_START]: state => _extends$f({}, state, { + [RESOLVED_SEARCH_START]: state => _extends$g({}, state, { searching: true }), [RESOLVED_SEARCH_SUCCESS]: (state, action) => { @@ -5939,24 +6311,24 @@ const searchReducer = handleActions({ // the returned number of urls is less than the page size, so we're on the last page resolvedResultsByQueryLastPageReached[query] = results.length < pageSize; - return _extends$f({}, state, { + return _extends$g({}, state, { searching: false, resolvedResultsByQuery, resolvedResultsByQueryLastPageReached }); }, - [RESOLVED_SEARCH_FAIL]: state => _extends$f({}, state, { + [RESOLVED_SEARCH_FAIL]: state => _extends$g({}, state, { searching: false }), - [UPDATE_SEARCH_QUERY]: (state, action) => _extends$f({}, state, { + [UPDATE_SEARCH_QUERY]: (state, action) => _extends$g({}, state, { searchQuery: action.data.query, isActive: true }), - [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$f({}, state, { - suggestions: _extends$f({}, state.suggestions, { + [UPDATE_SEARCH_SUGGESTIONS]: (state, action) => _extends$g({}, state, { + suggestions: _extends$g({}, state.suggestions, { [action.data.query]: action.data.suggestions }) }), @@ -5964,35 +6336,35 @@ const searchReducer = handleActions({ // sets isActive to false so the uri will be populated correctly if the // user is on a file page. The search query will still be present on any // other page - [DISMISS_NOTIFICATION]: state => _extends$f({}, state, { + [DISMISS_NOTIFICATION]: state => _extends$g({}, state, { isActive: false }), - [SEARCH_FOCUS]: state => _extends$f({}, state, { + [SEARCH_FOCUS]: state => _extends$g({}, state, { focused: true }), - [SEARCH_BLUR]: state => _extends$f({}, state, { + [SEARCH_BLUR]: state => _extends$g({}, state, { focused: false }), [UPDATE_SEARCH_OPTIONS]: (state, action) => { const { options: oldOptions } = state; const newOptions = action.data; - const options = _extends$f({}, oldOptions, newOptions); - return _extends$f({}, state, { + const options = _extends$g({}, oldOptions, newOptions); + return _extends$g({}, state, { options }); } -}, defaultState$5); +}, defaultState$6); -var _extends$g = 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; }; +var _extends$h = 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 getDefaultKnownTags() { - return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$g({}, tagsMap, { + return DEFAULT_FOLLOWED_TAGS.concat(DEFAULT_KNOWN_TAGS).reduce((tagsMap, tag) => _extends$h({}, tagsMap, { [tag]: { name: tag } }), {}); } -const defaultState$6 = { +const defaultState$7 = { followedTags: [], knownTags: getDefaultKnownTags() }; @@ -6010,7 +6382,7 @@ const tagsReducer = handleActions({ newFollowedTags.push(name); } - return _extends$g({}, state, { + return _extends$h({}, state, { followedTags: newFollowedTags }); }, @@ -6019,10 +6391,10 @@ const tagsReducer = handleActions({ const { knownTags } = state; const { name } = action.data; - let newKnownTags = _extends$g({}, knownTags); + let newKnownTags = _extends$h({}, knownTags); newKnownTags[name] = { name }; - return _extends$g({}, state, { + return _extends$h({}, state, { knownTags: newKnownTags }); }, @@ -6031,11 +6403,11 @@ const tagsReducer = handleActions({ const { knownTags, followedTags } = state; const { name } = action.data; - let newKnownTags = _extends$g({}, knownTags); + let newKnownTags = _extends$h({}, knownTags); delete newKnownTags[name]; const newFollowedTags = followedTags.filter(tag => tag !== name); - return _extends$g({}, state, { + return _extends$h({}, state, { knownTags: newKnownTags, followedTags: newFollowedTags }); @@ -6043,15 +6415,45 @@ const tagsReducer = handleActions({ [USER_STATE_POPULATE]: (state, action) => { const { tags } = action.data; if (Array.isArray(tags)) { - return _extends$g({}, state, { + return _extends$h({}, state, { followedTags: tags }); } - return _extends$g({}, state); + return _extends$h({}, state); } -}, defaultState$6); +}, defaultState$7); -var _extends$h = 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; }; +var _extends$i = 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; }; + +const defaultState$8 = { + blockedChannels: [] +}; + +const blockedReducer = handleActions({ + [TOGGLE_BLOCK_CHANNEL]: (state, action) => { + const { blockedChannels } = state; + const { uri } = action.data; + let newBlockedChannels = blockedChannels.slice(); + + if (newBlockedChannels.includes(uri)) { + newBlockedChannels = newBlockedChannels.filter(id => id !== uri); + } else { + newBlockedChannels.push(uri); + } + + return { + blockedChannels: newBlockedChannels + }; + }, + [USER_STATE_POPULATE]: (state, action) => { + const { blocked } = action.data; + return _extends$i({}, state, { + blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels + }); + } +}, defaultState$8); + +var _extends$j = 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; }; const buildDraftTransaction = () => ({ amount: undefined, @@ -6062,7 +6464,7 @@ const buildDraftTransaction = () => ({ // See details in https://github.com/lbryio/lbry/issues/1307 -const defaultState$7 = { +const defaultState$9 = { balance: undefined, totalBalance: undefined, reservedBalance: undefined, @@ -6103,40 +6505,40 @@ const defaultState$7 = { }; const walletReducer = handleActions({ - [FETCH_TRANSACTIONS_STARTED]: state => _extends$h({}, state, { + [FETCH_TRANSACTIONS_STARTED]: state => _extends$j({}, state, { fetchingTransactions: true }), [FETCH_TRANSACTIONS_COMPLETED]: (state, action) => { - const byId = _extends$h({}, state.transactions); + const byId = _extends$j({}, state.transactions); const { transactions } = action.data; transactions.forEach(transaction => { byId[transaction.txid] = transaction; }); - return _extends$h({}, state, { + return _extends$j({}, state, { transactions: byId, fetchingTransactions: false }); }, [FETCH_TXO_PAGE_STARTED]: state => { - return _extends$h({}, state, { + return _extends$j({}, state, { fetchingTxos: true, fetchingTxosError: undefined }); }, [FETCH_TXO_PAGE_COMPLETED]: (state, action) => { - return _extends$h({}, state, { + return _extends$j({}, state, { txoPage: action.data, fetchingTxos: false }); }, [FETCH_TXO_PAGE_FAILED]: (state, action) => { - return _extends$h({}, state, { + return _extends$j({}, state, { txoPage: {}, fetchingTxos: false, fetchingTxosError: action.data @@ -6144,12 +6546,12 @@ const walletReducer = handleActions({ }, [UPDATE_TXO_FETCH_PARAMS]: (state, action) => { - return _extends$h({}, state, { + return _extends$j({}, state, { txoFetchParams: action.data }); }, - [FETCH_SUPPORTS_STARTED]: state => _extends$h({}, state, { + [FETCH_SUPPORTS_STARTED]: state => _extends$j({}, state, { fetchingSupports: true }), @@ -6162,7 +6564,7 @@ const walletReducer = handleActions({ byOutpoint[`${txid}:${nout}`] = transaction; }); - return _extends$h({}, state, { supports: byOutpoint, fetchingSupports: false }); + return _extends$j({}, state, { supports: byOutpoint, fetchingSupports: false }); }, [ABANDON_SUPPORT_STARTED]: (state, action) => { @@ -6171,7 +6573,7 @@ const walletReducer = handleActions({ currentlyAbandoning[outpoint] = true; - return _extends$h({}, state, { + return _extends$j({}, state, { abandoningSupportsByOutpoint: currentlyAbandoning }); }, @@ -6184,20 +6586,20 @@ const walletReducer = handleActions({ delete currentlyAbandoning[outpoint]; delete byOutpoint[outpoint]; - return _extends$h({}, state, { + return _extends$j({}, state, { supports: byOutpoint, abandoningSupportsById: currentlyAbandoning }); }, [ABANDON_CLAIM_SUPPORT_STARTED]: (state, action) => { - return _extends$h({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_PREVIEW]: (state, action) => { - return _extends$h({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: undefined }); }, @@ -6208,36 +6610,36 @@ const walletReducer = handleActions({ pendingtxs[claimId] = { txid, type, effective }; - return _extends$h({}, state, { + return _extends$j({}, state, { pendingSupportTransactions: pendingtxs, abandonClaimSupportError: undefined }); }, [ABANDON_CLAIM_SUPPORT_FAILED]: (state, action) => { - return _extends$h({}, state, { + return _extends$j({}, state, { abandonClaimSupportError: action.data }); }, [PENDING_SUPPORTS_UPDATED]: (state, action) => { - return _extends$h({}, state, { + return _extends$j({}, state, { pendingSupportTransactions: action.data }); }, - [GET_NEW_ADDRESS_STARTED]: state => _extends$h({}, state, { + [GET_NEW_ADDRESS_STARTED]: state => _extends$j({}, state, { gettingNewAddress: true }), [GET_NEW_ADDRESS_COMPLETED]: (state, action) => { const { address } = action.data; - return _extends$h({}, state, { gettingNewAddress: false, receiveAddress: address }); + return _extends$j({}, state, { gettingNewAddress: false, receiveAddress: address }); }, - [UPDATE_BALANCE]: (state, action) => _extends$h({}, state, { + [UPDATE_BALANCE]: (state, action) => _extends$j({}, state, { totalBalance: action.data.totalBalance, balance: action.data.balance, reservedBalance: action.data.reservedBalance, @@ -6246,32 +6648,32 @@ const walletReducer = handleActions({ tipsBalance: action.data.tipsBalance }), - [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$h({}, state, { + [CHECK_ADDRESS_IS_MINE_STARTED]: state => _extends$j({}, state, { checkingAddressOwnership: true }), - [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$h({}, state, { + [CHECK_ADDRESS_IS_MINE_COMPLETED]: state => _extends$j({}, state, { checkingAddressOwnership: false }), [SET_DRAFT_TRANSACTION_AMOUNT]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$h({}, oldDraft, { amount: parseFloat(action.data.amount) }); + const newDraft = _extends$j({}, oldDraft, { amount: parseFloat(action.data.amount) }); - return _extends$h({}, state, { draftTransaction: newDraft }); + return _extends$j({}, state, { draftTransaction: newDraft }); }, [SET_DRAFT_TRANSACTION_ADDRESS]: (state, action) => { const oldDraft = state.draftTransaction; - const newDraft = _extends$h({}, oldDraft, { address: action.data.address }); + const newDraft = _extends$j({}, oldDraft, { address: action.data.address }); - return _extends$h({}, state, { draftTransaction: newDraft }); + return _extends$j({}, state, { draftTransaction: newDraft }); }, [SEND_TRANSACTION_STARTED]: state => { - const newDraftTransaction = _extends$h({}, state.draftTransaction, { sending: true }); + const newDraftTransaction = _extends$j({}, state.draftTransaction, { sending: true }); - return _extends$h({}, state, { draftTransaction: newDraftTransaction }); + return _extends$j({}, state, { draftTransaction: newDraftTransaction }); }, [SEND_TRANSACTION_COMPLETED]: state => Object.assign({}, state, { @@ -6284,117 +6686,117 @@ const walletReducer = handleActions({ error: action.data.error }); - return _extends$h({}, state, { draftTransaction: newDraftTransaction }); + return _extends$j({}, state, { draftTransaction: newDraftTransaction }); }, - [SUPPORT_TRANSACTION_STARTED]: state => _extends$h({}, state, { + [SUPPORT_TRANSACTION_STARTED]: state => _extends$j({}, state, { sendingSupport: true }), - [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$h({}, state, { + [SUPPORT_TRANSACTION_COMPLETED]: state => _extends$j({}, state, { sendingSupport: false }), - [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$h({}, state, { + [SUPPORT_TRANSACTION_FAILED]: (state, action) => _extends$j({}, state, { error: action.data.error, sendingSupport: false }), - [CLEAR_SUPPORT_TRANSACTION]: state => _extends$h({}, state, { + [CLEAR_SUPPORT_TRANSACTION]: state => _extends$j({}, state, { sendingSupport: false }), - [WALLET_STATUS_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_STATUS_COMPLETED]: (state, action) => _extends$j({}, state, { walletIsEncrypted: action.result }), - [WALLET_ENCRYPT_START]: state => _extends$h({}, state, { + [WALLET_ENCRYPT_START]: state => _extends$j({}, state, { walletEncryptPending: true, walletEncryptSucceded: null, walletEncryptResult: null }), - [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_ENCRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { walletEncryptPending: false, walletEncryptSucceded: true, walletEncryptResult: action.result }), - [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_ENCRYPT_FAILED]: (state, action) => _extends$j({}, state, { walletEncryptPending: false, walletEncryptSucceded: false, walletEncryptResult: action.result }), - [WALLET_DECRYPT_START]: state => _extends$h({}, state, { + [WALLET_DECRYPT_START]: state => _extends$j({}, state, { walletDecryptPending: true, walletDecryptSucceded: null, walletDecryptResult: null }), - [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_DECRYPT_COMPLETED]: (state, action) => _extends$j({}, state, { walletDecryptPending: false, walletDecryptSucceded: true, walletDecryptResult: action.result }), - [WALLET_DECRYPT_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_DECRYPT_FAILED]: (state, action) => _extends$j({}, state, { walletDecryptPending: false, walletDecryptSucceded: false, walletDecryptResult: action.result }), - [WALLET_UNLOCK_START]: state => _extends$h({}, state, { + [WALLET_UNLOCK_START]: state => _extends$j({}, state, { walletUnlockPending: true, walletUnlockSucceded: null, walletUnlockResult: null }), - [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_UNLOCK_COMPLETED]: (state, action) => _extends$j({}, state, { walletUnlockPending: false, walletUnlockSucceded: true, walletUnlockResult: action.result }), - [WALLET_UNLOCK_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_UNLOCK_FAILED]: (state, action) => _extends$j({}, state, { walletUnlockPending: false, walletUnlockSucceded: false, walletUnlockResult: action.result }), - [WALLET_LOCK_START]: state => _extends$h({}, state, { + [WALLET_LOCK_START]: state => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: null, walletLockResult: null }), - [WALLET_LOCK_COMPLETED]: (state, action) => _extends$h({}, state, { + [WALLET_LOCK_COMPLETED]: (state, action) => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: true, walletLockResult: action.result }), - [WALLET_LOCK_FAILED]: (state, action) => _extends$h({}, state, { + [WALLET_LOCK_FAILED]: (state, action) => _extends$j({}, state, { walletLockPending: false, walletLockSucceded: false, walletLockResult: action.result }), - [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$h({}, state, { + [SET_TRANSACTION_LIST_FILTER]: (state, action) => _extends$j({}, state, { transactionListFilter: action.data }), - [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$h({}, state, { + [UPDATE_CURRENT_HEIGHT]: (state, action) => _extends$j({}, state, { latestBlock: action.data }), - [WALLET_RESTART]: state => _extends$h({}, state, { + [WALLET_RESTART]: state => _extends$j({}, state, { walletReconnecting: true }), - [WALLET_RESTART_COMPLETED]: state => _extends$h({}, state, { + [WALLET_RESTART_COMPLETED]: state => _extends$j({}, state, { walletReconnecting: false }) -}, defaultState$7); +}, defaultState$9); // @@ -6409,14 +6811,14 @@ const makeSelectContentPositionForUri = uri => reselect.createSelector(selectSta return state.positions[id] ? state.positions[id][outpoint] : null; }); -var _extends$i = 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; }; +var _extends$k = 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; }; const selectState$6 = state => state.notifications || {}; const selectToast = reselect.createSelector(selectState$6, state => { if (state.toasts.length) { const { id, params } = state.toasts[0]; - return _extends$i({ + return _extends$k({ id }, params); } @@ -6437,11 +6839,64 @@ const selectError = reselect.createSelector(selectState$6, state => { // -const selectState$7 = state => state.tags || {}; +const selectState$7 = state => state.comments || {}; -const selectKnownTagsByName = reselect.createSelector(selectState$7, state => state.knownTags); +const selectCommentsById = reselect.createSelector(selectState$7, state => state.commentById || {}); -const selectFollowedTagsList = reselect.createSelector(selectState$7, state => state.followedTags.filter(tag => typeof tag === 'string')); +const selectIsFetchingComments = reselect.createSelector(selectState$7, state => state.isLoading); + +const selectCommentsByClaimId = reselect.createSelector(selectState$7, selectCommentsById, (state, byId) => { + const byClaimId = state.byId || {}; + const comments = {}; + + // replace every comment_id in the list with the actual comment object + Object.keys(byClaimId).forEach(claimId => { + const commentIds = byClaimId[claimId]; + + comments[claimId] = Array(commentIds === null ? 0 : commentIds.length); + for (let i = 0; i < commentIds.length; i++) { + comments[claimId][i] = byId[commentIds[i]]; + } + }); + + return comments; +}); + +// previously this used a mapping from claimId -> Array +/* export const selectCommentsById = createSelector( + selectState, + state => state.byId || {} +); */ +const selectCommentsByUri = reselect.createSelector(selectState$7, state => { + const byUri = state.commentsByUri || {}; + const comments = {}; + Object.keys(byUri).forEach(uri => { + const claimId = byUri[uri]; + if (claimId === null) { + comments[uri] = null; + } else { + comments[uri] = claimId; + } + }); + + return comments; +}); + +const makeSelectCommentsForUri = uri => reselect.createSelector(selectCommentsByClaimId, selectCommentsByUri, (byClaimId, byUri) => { + const claimId = byUri[uri]; + return byClaimId && byClaimId[claimId]; +}); + +// todo: allow SDK to retrieve user comments through comment_list +// todo: implement selectors for selecting comments owned by user + +// + +const selectState$8 = state => state.tags || {}; + +const selectKnownTagsByName = reselect.createSelector(selectState$8, state => state.knownTags); + +const selectFollowedTagsList = reselect.createSelector(selectState$8, state => state.followedTags.filter(tag => typeof tag === 'string')); const selectFollowedTags = reselect.createSelector(selectFollowedTagsList, followedTags => followedTags.map(tag => ({ name: tag.toLowerCase() })).sort((a, b) => a.name.localeCompare(b.name))); @@ -6462,6 +6917,18 @@ const makeSelectIsFollowingTag = tag => reselect.createSelector(selectFollowedTa return followedTags.some(followedTag => followedTag.name === tag.toLowerCase()); }); +// + +const selectState$9 = state => state.blocked || {}; + +const selectBlockedChannels = reselect.createSelector(selectState$9, state => state.blockedChannels); + +const selectBlockedChannelsCount = reselect.createSelector(selectBlockedChannels, state => state.length); + +const selectChannelIsBlocked = uri => reselect.createSelector(selectBlockedChannels, state => { + return state.includes(uri); +}); + exports.ABANDON_STATES = abandon_states; exports.ACTIONS = action_types; exports.CLAIM_VALUES = claim; @@ -6484,9 +6951,11 @@ exports.TXO_LIST = txo_list; exports.TX_LIST = transaction_list; exports.apiCall = apiCall; exports.batchActions = batchActions; +exports.blockedReducer = blockedReducer; exports.buildSharedStateMiddleware = buildSharedStateMiddleware; exports.buildURI = buildURI; exports.claimsReducer = claimsReducer; +exports.commentReducer = commentReducer; exports.contentReducer = contentReducer; exports.convertToShareLink = convertToShareLink; exports.createNormalizedClaimSearchKey = createNormalizedClaimSearchKey; @@ -6505,6 +6974,11 @@ exports.doClearPublish = doClearPublish; exports.doClearPurchasedUriSuccess = doClearPurchasedUriSuccess; exports.doClearRepostError = doClearRepostError; exports.doClearSupport = doClearSupport; +exports.doCommentAbandon = doCommentAbandon; +exports.doCommentCreate = doCommentCreate; +exports.doCommentHide = doCommentHide; +exports.doCommentList = doCommentList; +exports.doCommentUpdate = doCommentUpdate; exports.doCreateChannel = doCreateChannel; exports.doDeleteTag = doDeleteTag; exports.doDismissError = doDismissError; @@ -6543,6 +7017,7 @@ exports.doSetFileListSort = doSetFileListSort; exports.doSetTransactionListFilter = doSetTransactionListFilter; exports.doSupportAbandonForClaim = doSupportAbandonForClaim; exports.doToast = doToast; +exports.doToggleBlockChannel = doToggleBlockChannel; exports.doToggleTagFollow = doToggleTagFollow; exports.doUpdateBalance = doUpdateBalance; exports.doUpdateBlockHeight = doUpdateBlockHeight; @@ -6574,6 +7049,7 @@ exports.makeSelectClaimIsPending = makeSelectClaimIsPending; exports.makeSelectClaimWasPurchased = makeSelectClaimWasPurchased; exports.makeSelectClaimsInChannelForCurrentPageState = makeSelectClaimsInChannelForCurrentPageState; exports.makeSelectClaimsInChannelForPage = makeSelectClaimsInChannelForPage; +exports.makeSelectCommentsForUri = makeSelectCommentsForUri; exports.makeSelectContentPositionForUri = makeSelectContentPositionForUri; exports.makeSelectContentTypeForUri = makeSelectContentTypeForUri; exports.makeSelectCoverForUri = makeSelectCoverForUri; @@ -6636,9 +7112,12 @@ exports.selectAllClaimsByChannel = selectAllClaimsByChannel; exports.selectAllFetchingChannelClaims = selectAllFetchingChannelClaims; exports.selectAllMyClaimsByOutpoint = selectAllMyClaimsByOutpoint; exports.selectBalance = selectBalance; +exports.selectBlockedChannels = selectBlockedChannels; +exports.selectBlockedChannelsCount = selectBlockedChannelsCount; exports.selectBlocks = selectBlocks; exports.selectChannelClaimCounts = selectChannelClaimCounts; exports.selectChannelImportPending = selectChannelImportPending; +exports.selectChannelIsBlocked = selectChannelIsBlocked; exports.selectClaimIdsByUri = selectClaimIdsByUri; exports.selectClaimSearchByQuery = selectClaimSearchByQuery; exports.selectClaimSearchByQueryLastPageReached = selectClaimSearchByQueryLastPageReached; @@ -6674,6 +7153,7 @@ exports.selectFollowedTagsList = selectFollowedTagsList; exports.selectGettingNewAddress = selectGettingNewAddress; exports.selectHasTransactions = selectHasTransactions; exports.selectIsFetchingClaimListMine = selectIsFetchingClaimListMine; +exports.selectIsFetchingComments = selectIsFetchingComments; exports.selectIsFetchingFileList = selectIsFetchingFileList; exports.selectIsFetchingFileListDownloadedOrPublished = selectIsFetchingFileListDownloadedOrPublished; exports.selectIsFetchingMyPurchases = selectIsFetchingMyPurchases; diff --git a/flow-typed/Blocklist.js b/flow-typed/Blocklist.js new file mode 100644 index 0000000..454a714 --- /dev/null +++ b/flow-typed/Blocklist.js @@ -0,0 +1,10 @@ +declare type BlocklistState = { + blockedChannels: Array +}; + +declare type BlocklistAction = { + type: string, + data: { + uri: string, + }, +}; diff --git a/flow-typed/Comment.js b/flow-typed/Comment.js new file mode 100644 index 0000000..64ea974 --- /dev/null +++ b/flow-typed/Comment.js @@ -0,0 +1,23 @@ +declare type Comment = { + comment: string, // comment body + comment_id: string, // sha256 digest + claim_id: string, // id linking to the claim this comment + timestamp: number, // integer representing unix-time + is_hidden: boolean, // claim owner may enable/disable this + channel_id?: string, // claimId of channel signing this comment + channel_name?: string, // name of channel claim + channel_url?: string, // full lbry url to signing channel + signature?: string, // signature of comment by originating channel + signing_ts?: string, // timestamp used when signing this comment + is_channel_signature_valid?: boolean, // whether or not the signature could be validated + parent_id?: number, // comment_id of comment this is in reply to +}; + +// todo: relate individual comments to their commentId +declare type CommentsState = { + commentsByUri: { [string]: string }, + byId: { [string]: Array }, + commentById: { [string]: Comment }, + isLoading: boolean, + myComments: ?Set, +}; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index 3525f4d..b14cfb8 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -131,6 +131,23 @@ export const PURCHASE_LIST_STARTED = 'PURCHASE_LIST_STARTED'; export const PURCHASE_LIST_COMPLETED = 'PURCHASE_LIST_COMPLETED'; export const PURCHASE_LIST_FAILED = 'PURCHASE_LIST_FAILED'; +// Comments +export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED'; +export const COMMENT_LIST_COMPLETED = 'COMMENT_LIST_COMPLETED'; +export const COMMENT_LIST_FAILED = 'COMMENT_LIST_FAILED'; +export const COMMENT_CREATE_STARTED = 'COMMENT_CREATE_STARTED'; +export const COMMENT_CREATE_COMPLETED = 'COMMENT_CREATE_COMPLETED'; +export const COMMENT_CREATE_FAILED = 'COMMENT_CREATE_FAILED'; +export const COMMENT_ABANDON_STARTED = 'COMMENT_ABANDON_STARTED'; +export const COMMENT_ABANDON_COMPLETED = 'COMMENT_ABANDON_COMPLETED'; +export const COMMENT_ABANDON_FAILED = 'COMMENT_ABANDON_FAILED'; +export const COMMENT_UPDATE_STARTED = 'COMMENT_UPDATE_STARTED'; +export const COMMENT_UPDATE_COMPLETED = 'COMMENT_UPDATE_COMPLETED'; +export const COMMENT_UPDATE_FAILED = 'COMMENT_UPDATE_FAILED'; +export const COMMENT_HIDE_STARTED = 'COMMENT_HIDE_STARTED'; +export const COMMENT_HIDE_COMPLETED = 'COMMENT_HIDE_COMPLETED'; +export const COMMENT_HIDE_FAILED = 'COMMENT_HIDE_FAILED'; + // Files export const FILE_LIST_STARTED = 'FILE_LIST_STARTED'; export const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; @@ -266,5 +283,8 @@ export const TOGGLE_TAG_FOLLOW = 'TOGGLE_TAG_FOLLOW'; export const TAG_ADD = 'TAG_ADD'; export const TAG_DELETE = 'TAG_DELETE'; +// Blocked Channels +export const TOGGLE_BLOCK_CHANNEL = 'TOGGLE_BLOCK_CHANNEL'; + // Sync export const USER_STATE_POPULATE = 'USER_STATE_POPULATE'; diff --git a/src/index.js b/src/index.js index d28f38f..dcec873 100644 --- a/src/index.js +++ b/src/index.js @@ -135,6 +135,16 @@ export { export { doToggleTagFollow, doAddTag, doDeleteTag } from 'redux/actions/tags'; +export { + doCommentList, + doCommentCreate, + doCommentAbandon, + doCommentHide, + doCommentUpdate, +} from 'redux/actions/comments'; + +export { doToggleBlockChannel } from 'redux/actions/blocked'; + export { doPopulateSharedUserState, doPreferenceGet, doPreferenceSet } from 'redux/actions/sync'; // utils @@ -145,12 +155,14 @@ export { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; // reducers export { claimsReducer } from 'redux/reducers/claims'; +export { commentReducer } from 'redux/reducers/comments'; export { contentReducer } from 'redux/reducers/content'; export { fileInfoReducer } from 'redux/reducers/file_info'; export { notificationsReducer } from 'redux/reducers/notifications'; export { publishReducer } from 'redux/reducers/publish'; export { searchReducer } from 'redux/reducers/search'; export { tagsReducer } from 'redux/reducers/tags'; +export { blockedReducer } from 'redux/reducers/blocked'; export { walletReducer } from 'redux/reducers/wallet'; // selectors @@ -240,6 +252,8 @@ export { selectPurchaseUriSuccess, } from 'redux/selectors/claims'; +export { makeSelectCommentsForUri, selectIsFetchingComments } from 'redux/selectors/comments'; + export { makeSelectFileInfoForUri, makeSelectDownloadingForUri, @@ -347,3 +361,9 @@ export { selectUnfollowedTags, makeSelectIsFollowingTag, } from 'redux/selectors/tags'; + +export { + selectBlockedChannels, + selectChannelIsBlocked, + selectBlockedChannelsCount, +} from 'redux/selectors/blocked'; diff --git a/src/redux/actions/blocked.js b/src/redux/actions/blocked.js new file mode 100644 index 0000000..1e96563 --- /dev/null +++ b/src/redux/actions/blocked.js @@ -0,0 +1,9 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; + +export const doToggleBlockChannel = (uri: string) => ({ + type: ACTIONS.TOGGLE_BLOCK_CHANNEL, + data: { + uri, + }, +}); diff --git a/src/redux/actions/comments.js b/src/redux/actions/comments.js new file mode 100644 index 0000000..22b38e4 --- /dev/null +++ b/src/redux/actions/comments.js @@ -0,0 +1,225 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; +import Lbry from 'lbry'; +import { selectClaimsByUri, selectMyChannelClaims } from 'redux/selectors/claims'; +import { doToast } from 'redux/actions/notifications'; + +export function doCommentList(uri: string, page: number = 1, pageSize: number = 99999) { + return (dispatch: Dispatch, getState: GetState) => { + const state = getState(); + const claim = selectClaimsByUri(state)[uri]; + const claimId = claim ? claim.claim_id : null; + + dispatch({ + type: ACTIONS.COMMENT_LIST_STARTED, + }); + Lbry.comment_list({ + claim_id: claimId, + page, + page_size: pageSize, + }) + .then((result: CommentListResponse) => { + const { items: comments } = result; + dispatch({ + type: ACTIONS.COMMENT_LIST_COMPLETED, + data: { + comments, + claimId: claimId, + uri: uri, + }, + }); + }) + .catch(error => { + console.log(error); + dispatch({ + type: ACTIONS.COMMENT_LIST_FAILED, + data: error, + }); + }); + }; +} + +export function doCommentCreate( + comment: string = '', + claim_id: string = '', + channel: string, + parent_id?: string +) { + return (dispatch: Dispatch, getState: GetState) => { + const state = getState(); + dispatch({ + type: ACTIONS.COMMENT_CREATE_STARTED, + }); + + const myChannels = selectMyChannelClaims(state); + const namedChannelClaim = + myChannels && myChannels.find(myChannel => myChannel.name === channel); + const channel_id = namedChannelClaim.claim_id; + + if (channel_id == null) { + dispatch({ + type: ACTIONS.COMMENT_CREATE_FAILED, + data: {}, + }); + dispatch( + doToast({ + message: 'Channel cannot be anonymous, please select a channel and try again.', + isError: true, + }) + ); + return; + } + + return Lbry.comment_create({ + comment: comment, + claim_id: claim_id, + channel_id: channel_id, + parent_id: parent_id, + }) + .then((result: CommentCreateResponse) => { + dispatch({ + type: ACTIONS.COMMENT_CREATE_COMPLETED, + data: { + comment: result, + claimId: claim_id, + }, + }); + }) + .catch(error => { + dispatch({ + type: ACTIONS.COMMENT_CREATE_FAILED, + data: error, + }); + dispatch( + doToast({ + message: 'Unable to create comment, please try again later.', + isError: true, + }) + ); + }); + }; +} + +export function doCommentHide(comment_id: string) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.COMMENT_HIDE_STARTED, + }); + return Lbry.comment_hide({ + comment_ids: [comment_id], + }) + .then((result: CommentHideResponse) => { + dispatch({ + type: ACTIONS.COMMENT_HIDE_COMPLETED, + data: result, + }); + }) + .catch(error => { + dispatch({ + type: ACTIONS.COMMENT_HIDE_FAILED, + data: error, + }); + dispatch( + doToast({ + message: 'Unable to hide this comment, please try again later.', + isError: true, + }) + ); + }); + }; +} + +export function doCommentAbandon(comment_id: string) { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_STARTED, + }); + return Lbry.comment_abandon({ + comment_id: comment_id, + }) + .then((result: CommentAbandonResponse) => { + // Comment may not be deleted if the signing channel can't be signed. + // This will happen if the channel was recently created or abandoned. + if (result.abandoned) { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_COMPLETED, + data: { + comment_id: comment_id, + }, + }); + } else { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_FAILED, + }); + dispatch( + doToast({ + message: 'Your channel is still being setup, try again in a few moments.', + isError: true, + }) + ); + } + }) + .catch(error => { + dispatch({ + type: ACTIONS.COMMENT_ABANDON_FAILED, + data: error, + }); + dispatch( + doToast({ + message: 'Unable to delete this comment, please try again later.', + isError: true, + }) + ); + }); + }; +} + +export function doCommentUpdate(comment_id: string, comment: string) { + // if they provided an empty string, they must have wanted to abandon + if (comment === '') { + return doCommentAbandon(comment_id); + } else { + return (dispatch: Dispatch) => { + dispatch({ + type: ACTIONS.COMMENT_UPDATE_STARTED, + }); + return Lbry.comment_update({ + comment_id: comment_id, + comment: comment, + }) + .then((result: CommentUpdateResponse) => { + if (result != null) { + dispatch({ + type: ACTIONS.COMMENT_UPDATE_COMPLETED, + data: { + comment: result, + }, + }); + } else { + // the result will return null + dispatch({ + type: ACTIONS.COMMENT_UPDATE_FAILED, + }); + dispatch( + doToast({ + message: 'Your channel is still being setup, try again in a few moments.', + isError: true, + }) + ); + } + }) + .catch(error => { + dispatch({ + type: ACTIONS.COMMENT_UPDATE_FAILED, + data: error, + }); + dispatch( + doToast({ + message: 'Unable to edit this comment, please try again later.', + isError: true, + }) + ); + }); + }; + } +} diff --git a/src/redux/reducers/blocked.js b/src/redux/reducers/blocked.js new file mode 100644 index 0000000..c688936 --- /dev/null +++ b/src/redux/reducers/blocked.js @@ -0,0 +1,41 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; +import { handleActions } from 'util/redux-utils'; + +const defaultState: BlocklistState = { + blockedChannels: [], +}; + +export const blockedReducer = handleActions( + { + [ACTIONS.TOGGLE_BLOCK_CHANNEL]: ( + state: BlocklistState, + action: BlocklistAction + ): BlocklistState => { + const { blockedChannels } = state; + const { uri } = action.data; + let newBlockedChannels = blockedChannels.slice(); + + if (newBlockedChannels.includes(uri)) { + newBlockedChannels = newBlockedChannels.filter(id => id !== uri); + } else { + newBlockedChannels.push(uri); + } + + return { + blockedChannels: newBlockedChannels, + }; + }, + [ACTIONS.USER_STATE_POPULATE]: ( + state: BlocklistState, + action: { data: { blocked: ?Array } } + ) => { + const { blocked } = action.data; + return { + ...state, + blockedChannels: blocked && blocked.length ? blocked : state.blockedChannels, + }; + }, + }, + defaultState +); diff --git a/src/redux/reducers/comments.js b/src/redux/reducers/comments.js new file mode 100644 index 0000000..46d08d8 --- /dev/null +++ b/src/redux/reducers/comments.js @@ -0,0 +1,153 @@ +// @flow +import * as ACTIONS from 'constants/action_types'; +import { handleActions } from 'util/redux-utils'; + +const defaultState: CommentsState = { + commentById: {}, // commentId -> Comment + byId: {}, // ClaimID -> list of comments + commentsByUri: {}, // URI -> claimId + isLoading: false, + myComments: undefined, +}; + +export const commentReducer = handleActions( + { + [ACTIONS.COMMENT_CREATE_STARTED]: (state: CommentsState, action: any): CommentsState => ({ + ...state, + isLoading: true, + }), + + [ACTIONS.COMMENT_CREATE_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + + [ACTIONS.COMMENT_CREATE_COMPLETED]: (state: CommentsState, action: any): CommentsState => { + const { comment, claimId }: { comment: Comment, claimId: string } = action.data; + const commentById = Object.assign({}, state.commentById); + const byId = Object.assign({}, state.byId); + const comments = byId[claimId]; + const newCommentIds = comments.slice(); + + // add the comment by its ID + commentById[comment.comment_id] = comment; + + // push the comment_id to the top of ID list + newCommentIds.unshift(comment.comment_id); + byId[claimId] = newCommentIds; + + return { + ...state, + commentById, + byId, + isLoading: false, + }; + }, + + [ACTIONS.COMMENT_LIST_STARTED]: state => ({ ...state, isLoading: true }), + + [ACTIONS.COMMENT_LIST_COMPLETED]: (state: CommentsState, action: any) => { + const { comments, claimId, uri } = action.data; + + const commentById = Object.assign({}, state.commentById); + const byId = Object.assign({}, state.byId); + const commentsByUri = Object.assign({}, state.commentsByUri); + + if (comments) { + // we use an Array to preserve order of listing + // in reality this doesn't matter and we can just + // sort comments by their timestamp + const commentIds = Array(comments.length); + + // map the comment_ids to the new comments + for (let i = 0; i < comments.length; i++) { + commentIds[i] = comments[i].comment_id; + commentById[commentIds[i]] = comments[i]; + } + + byId[claimId] = commentIds; + commentsByUri[uri] = claimId; + } + return { + ...state, + byId, + commentById, + commentsByUri, + isLoading: false, + }; + }, + + [ACTIONS.COMMENT_LIST_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + [ACTIONS.COMMENT_ABANDON_STARTED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: true, + }), + [ACTIONS.COMMENT_ABANDON_COMPLETED]: (state: CommentsState, action: any) => { + const { comment_id } = action.data; + const commentById = Object.assign({}, state.commentById); + const byId = Object.assign({}, state.byId); + + // to remove the comment and its references + const claimId = commentById[comment_id].claim_id; + for (let i = 0; i < byId[claimId].length; i++) { + if (byId[claimId][i] === comment_id) { + byId[claimId].splice(i, 1); + break; + } + } + delete commentById[comment_id]; + + return { + ...state, + commentById, + byId, + isLoading: false, + }; + }, + // do nothing + [ACTIONS.COMMENT_ABANDON_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + // do nothing + [ACTIONS.COMMENT_UPDATE_STARTED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: true, + }), + // replace existing comment with comment returned here under its comment_id + [ACTIONS.COMMENT_UPDATE_COMPLETED]: (state: CommentsState, action: any) => { + const { comment } = action.data; + const commentById = Object.assign({}, state.commentById); + commentById[comment.comment_id] = comment; + + return { + ...state, + commentById, + isLoading: false, + }; + }, + // nothing can be done here + [ACTIONS.COMMENT_UPDATE_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + // nothing can really be done here + [ACTIONS.COMMENT_HIDE_STARTED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: true, + }), + [ACTIONS.COMMENT_HIDE_COMPLETED]: (state: CommentsState, action: any) => ({ + ...state, // todo: add HiddenComments state & create selectors + isLoading: false, + }), + // nothing can be done here + [ACTIONS.COMMENT_HIDE_FAILED]: (state: CommentsState, action: any) => ({ + ...state, + isLoading: false, + }), + }, + defaultState +); diff --git a/src/redux/selectors/blocked.js b/src/redux/selectors/blocked.js new file mode 100644 index 0000000..424ea89 --- /dev/null +++ b/src/redux/selectors/blocked.js @@ -0,0 +1,22 @@ +// @flow +import { createSelector } from 'reselect'; + +const selectState = (state: { blocked: BlocklistState }) => state.blocked || {}; + +export const selectBlockedChannels = createSelector( + selectState, + (state: BlocklistState) => state.blockedChannels +); + +export const selectBlockedChannelsCount = createSelector( + selectBlockedChannels, + (state: Array) => state.length +); + +export const selectChannelIsBlocked = (uri: string) => + createSelector( + selectBlockedChannels, + (state: Array) => { + return state.includes(uri); + } + ); diff --git a/src/redux/selectors/comments.js b/src/redux/selectors/comments.js new file mode 100644 index 0000000..d8033ff --- /dev/null +++ b/src/redux/selectors/comments.js @@ -0,0 +1,71 @@ +// @flow +import { createSelector } from 'reselect'; + +const selectState = state => state.comments || {}; + +export const selectCommentsById = createSelector( + selectState, + state => state.commentById || {} +); + +export const selectIsFetchingComments = createSelector( + selectState, + state => state.isLoading +); + +export const selectCommentsByClaimId = createSelector( + selectState, + selectCommentsById, + (state, byId) => { + const byClaimId = state.byId || {}; + const comments = {}; + + // replace every comment_id in the list with the actual comment object + Object.keys(byClaimId).forEach(claimId => { + const commentIds = byClaimId[claimId]; + + comments[claimId] = Array(commentIds === null ? 0 : commentIds.length); + for (let i = 0; i < commentIds.length; i++) { + comments[claimId][i] = byId[commentIds[i]]; + } + }); + + return comments; + } +); + +// previously this used a mapping from claimId -> Array +/* export const selectCommentsById = createSelector( + selectState, + state => state.byId || {} +); */ +export const selectCommentsByUri = createSelector( + selectState, + state => { + const byUri = state.commentsByUri || {}; + const comments = {}; + Object.keys(byUri).forEach(uri => { + const claimId = byUri[uri]; + if (claimId === null) { + comments[uri] = null; + } else { + comments[uri] = claimId; + } + }); + + return comments; + } +); + +export const makeSelectCommentsForUri = (uri: string) => + createSelector( + selectCommentsByClaimId, + selectCommentsByUri, + (byClaimId, byUri) => { + const claimId = byUri[uri]; + return byClaimId && byClaimId[claimId]; + } + ); + +// todo: allow SDK to retrieve user comments through comment_list +// todo: implement selectors for selecting comments owned by user -- 2.45.2 From cf0b135a15fb759a2bf328b069968f0e84e16e22 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 29 Jun 2020 17:02:39 -0400 Subject: [PATCH 361/371] update build --- dist/bundle.es.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index ee5209b..dee7cab 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -2876,7 +2876,7 @@ function doSendDraftTransaction(address, amount) { type: SEND_TRANSACTION_COMPLETED }); dispatch(doToast({ - message: __('You sent ${amount} LBC'), + message: __(`You sent ${amount} LBC`), linkText: __('History'), linkTarget: '/wallet' })); -- 2.45.2 From 85f0f574bd082ca5d0b87dcba11863fb3f050555 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Mon, 29 Jun 2020 17:43:49 -0400 Subject: [PATCH 362/371] update build --- dist/bundle.es.js | 1 + 1 file changed, 1 insertion(+) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index dee7cab..742564d 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -6185,6 +6185,7 @@ function _objectWithoutProperties$4(obj, keys) { var target = {}; for (var i in const defaultState$5 = { editingURI: undefined, + fileText: '', filePath: undefined, fileDur: 0, fileSize: 0, -- 2.45.2 From c0bfa4d32005266d41df18a19c93914c426a8067 Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 2 Jul 2020 12:50:54 -0400 Subject: [PATCH 363/371] prevent delete from byUri when pending --- dist/bundle.es.js | 2 +- src/redux/reducers/claims.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 742564d..434826f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -5222,7 +5222,7 @@ function handleClaimAction(state, action) { } newResolvingUrls.delete(url); - if (!stream && !channel) { + if (!stream && !channel && !pendingIds.includes(byUri[url])) { byUri[url] = null; } }); diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index 061e555..b00b2e7 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -160,7 +160,7 @@ function handleClaimAction(state: State, action: any): State { } newResolvingUrls.delete(url); - if (!stream && !channel) { + if (!stream && !channel && !pendingIds.includes(byUri[url])) { byUri[url] = null; } }); -- 2.45.2 From 906199d866a187015668a27363f010828c15979a Mon Sep 17 00:00:00 2001 From: jessop Date: Thu, 2 Jul 2020 18:03:55 -0400 Subject: [PATCH 364/371] provide for clearing channel errors --- dist/bundle.es.js | 15 ++++++++++++++- src/constants/action_types.js | 1 + src/index.js | 1 + src/redux/actions/claims.js | 7 ++++++- src/redux/reducers/claims.js | 8 +++++++- 5 files changed, 29 insertions(+), 3 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 434826f..186b0a0 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -142,6 +142,7 @@ const CLAIM_REPOST_STARTED = 'CLAIM_REPOST_STARTED'; const CLAIM_REPOST_COMPLETED = 'CLAIM_REPOST_COMPLETED'; const CLAIM_REPOST_FAILED = 'CLAIM_REPOST_FAILED'; const CLEAR_REPOST_ERROR = 'CLEAR_REPOST_ERROR'; +const CLEAR_CHANNEL_ERRORS = 'CLEAR_CHANNEL_ERRORS'; const CHECK_PUBLISH_NAME_STARTED = 'CHECK_PUBLISH_NAME_STARTED'; const CHECK_PUBLISH_NAME_COMPLETED = 'CHECK_PUBLISH_NAME_COMPLETED'; const UPDATE_PENDING_CLAIMS = 'UPDATE_PENDING_CLAIMS'; @@ -426,6 +427,7 @@ var action_types = /*#__PURE__*/Object.freeze({ CLAIM_REPOST_COMPLETED: CLAIM_REPOST_COMPLETED, CLAIM_REPOST_FAILED: CLAIM_REPOST_FAILED, CLEAR_REPOST_ERROR: CLEAR_REPOST_ERROR, + CLEAR_CHANNEL_ERRORS: CLEAR_CHANNEL_ERRORS, CHECK_PUBLISH_NAME_STARTED: CHECK_PUBLISH_NAME_STARTED, CHECK_PUBLISH_NAME_COMPLETED: CHECK_PUBLISH_NAME_COMPLETED, UPDATE_PENDING_CLAIMS: UPDATE_PENDING_CLAIMS, @@ -3490,6 +3492,12 @@ function doFetchClaimsByChannel(uri, page = 1) { }; } +function doClearChannelErrors() { + return { + type: CLEAR_CHANNEL_ERRORS + }; +} + function doCreateChannel(name, amount, optionalParams, cb) { return dispatch => { dispatch({ @@ -3548,7 +3556,6 @@ function doCreateChannel(name, amount, optionalParams, cb) { type: CREATE_CHANNEL_FAILED, data: error.message }); - return error; }); }; } @@ -5517,6 +5524,11 @@ reducers[ABANDON_CLAIM_SUCCEEDED] = (state, action) => { }); }; +reducers[CLEAR_CHANNEL_ERRORS] = state => _extends$b({}, state, { + createChannelError: null, + updateChannelError: null +}); + reducers[CREATE_CHANNEL_STARTED] = state => _extends$b({}, state, { creatingChannel: true, createChannelError: null @@ -6971,6 +6983,7 @@ exports.doCheckPendingClaims = doCheckPendingClaims; exports.doCheckPublishNameAvailability = doCheckPublishNameAvailability; exports.doCheckReflectingFiles = doCheckReflectingFiles; exports.doClaimSearch = doClaimSearch; +exports.doClearChannelErrors = doClearChannelErrors; exports.doClearPublish = doClearPublish; exports.doClearPurchasedUriSuccess = doClearPurchasedUriSuccess; exports.doClearRepostError = doClearRepostError; diff --git a/src/constants/action_types.js b/src/constants/action_types.js index b14cfb8..87e4295 100644 --- a/src/constants/action_types.js +++ b/src/constants/action_types.js @@ -119,6 +119,7 @@ export const CLAIM_REPOST_STARTED = 'CLAIM_REPOST_STARTED'; export const CLAIM_REPOST_COMPLETED = 'CLAIM_REPOST_COMPLETED'; export const CLAIM_REPOST_FAILED = 'CLAIM_REPOST_FAILED'; export const CLEAR_REPOST_ERROR = 'CLEAR_REPOST_ERROR'; +export const CLEAR_CHANNEL_ERRORS = 'CLEAR_CHANNEL_ERRORS'; export const CHECK_PUBLISH_NAME_STARTED = 'CHECK_PUBLISH_NAME_STARTED'; export const CHECK_PUBLISH_NAME_COMPLETED = 'CHECK_PUBLISH_NAME_COMPLETED'; export const UPDATE_PENDING_CLAIMS = 'UPDATE_PENDING_CLAIMS'; diff --git a/src/index.js b/src/index.js index dcec873..ad996b7 100644 --- a/src/index.js +++ b/src/index.js @@ -74,6 +74,7 @@ export { doImportChannel, doRepost, doClearRepostError, + doClearChannelErrors, doCheckPublishNameAvailability, doPurchaseList, doCheckPendingClaims, diff --git a/src/redux/actions/claims.js b/src/redux/actions/claims.js index 615b7a6..d74cb32 100644 --- a/src/redux/actions/claims.js +++ b/src/redux/actions/claims.js @@ -339,6 +339,12 @@ export function doFetchClaimsByChannel(uri: string, page: number = 1) { }; } +export function doClearChannelErrors() { + return { + type: ACTIONS.CLEAR_CHANNEL_ERRORS, + }; +} + export function doCreateChannel(name: string, amount: number, optionalParams: any, cb: any) { return (dispatch: Dispatch) => { dispatch({ @@ -410,7 +416,6 @@ export function doCreateChannel(name: string, amount: number, optionalParams: an type: ACTIONS.CREATE_CHANNEL_FAILED, data: error.message, }); - return error; }) ); }; diff --git a/src/redux/reducers/claims.js b/src/redux/reducers/claims.js index b00b2e7..1de07d5 100644 --- a/src/redux/reducers/claims.js +++ b/src/redux/reducers/claims.js @@ -42,7 +42,7 @@ type State = { [number]: Array, }, }, - updateChannelError: string, + updateChannelError: ?string, updatingChannel: boolean, pendingChannelImport: string | boolean, repostLoading: boolean, @@ -467,6 +467,12 @@ reducers[ACTIONS.ABANDON_CLAIM_SUCCEEDED] = (state: State, action: any): State = }); }; +reducers[ACTIONS.CLEAR_CHANNEL_ERRORS] = (state: State): State => ({ + ...state, + createChannelError: null, + updateChannelError: null, +}); + reducers[ACTIONS.CREATE_CHANNEL_STARTED] = (state: State): State => ({ ...state, creatingChannel: true, -- 2.45.2 From 0f80568acd7c1378199a18296534a90133c916f7 Mon Sep 17 00:00:00 2001 From: Mark Beamer Jr Date: Mon, 9 Mar 2020 22:10:30 -0400 Subject: [PATCH 365/371] Initial LBRY First To Allow publishing to youtube channels. --- .flowconfig | 1 + dist/bundle.es.js | 169 +++++++++++++++++++++++++++++++++- dist/flow-typed/LbryFirst.js | 99 ++++++++++++++++++++ flow-typed/LbryFirst.js | 99 ++++++++++++++++++++ src/index.js | 2 + src/lbry-first.js | 168 +++++++++++++++++++++++++++++++++ src/redux/actions/publish.js | 12 ++- src/redux/reducers/publish.js | 2 + 8 files changed, 547 insertions(+), 5 deletions(-) create mode 100644 dist/flow-typed/LbryFirst.js create mode 100644 flow-typed/LbryFirst.js create mode 100644 src/lbry-first.js diff --git a/.flowconfig b/.flowconfig index 64516a4..bcc0450 100644 --- a/.flowconfig +++ b/.flowconfig @@ -12,4 +12,5 @@ module.name_mapper='^redux\(.*\)$' -> '/src/redux\1' module.name_mapper='^util\(.*\)$' -> '/src/util\1' module.name_mapper='^constants\(.*\)$' -> '/src/constants\1' module.name_mapper='^lbry\(.*\)$' -> '/src/lbry\1' +module.name_mapper='^lbry-first\(.*\)$' -> '/src/lbry-first\1' module.name_mapper='^lbryURI\(.*\)$' -> '/src/lbryURI\1' diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 186b0a0..2ee2b36 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1219,6 +1219,161 @@ const lbryProxy = new Proxy(Lbry, { // +const CHECK_LBRYFIRST_STARTED_TRY_NUMBER = 200; +// +// Basic LBRYFIRST connection config +// Offers a proxy to call LBRYFIRST methods + +// +const LbryFirst = { + isConnected: false, + connectPromise: null, + lbryFirstConnectionString: 'http://localhost:1337/rpc', + apiRequestHeaders: { 'Content-Type': 'application/json' }, + + // Allow overriding lbryFirst connection string (e.g. to `/api/proxy` for lbryweb) + setLbryFirstConnectionString: value => { + LbryFirst.lbryFirstConnectionString = value; + }, + + setApiHeader: (key, value) => { + LbryFirst.apiRequestHeaders = Object.assign(LbryFirst.apiRequestHeaders, { [key]: value }); + }, + + unsetApiHeader: key => { + Object.keys(LbryFirst.apiRequestHeaders).includes(key) && delete LbryFirst.apiRequestHeaders['key']; + }, + // Allow overriding Lbry methods + overrides: {}, + setOverride: (methodName, newMethod) => { + LbryFirst.overrides[methodName] = newMethod; + }, + getApiRequestHeaders: () => LbryFirst.apiRequestHeaders, + + // + // LbryFirst Methods + // + status: (params = {}) => lbryFirstCallWithResult('status', params), + stop: () => lbryFirstCallWithResult('stop', {}), + version: () => lbryFirstCallWithResult('version', {}), + + // Upload to youtube + upload: (params = {}) => { + // Only upload when originally publishing for now + if (!params.file_path) { + return {}; + } + const uploadParams = {}; + uploadParams.Title = params.title; + uploadParams.Description = params.description; + uploadParams.FilePath = params.file_path; + uploadParams.Category = ''; + uploadParams.Keywords = ''; + return lbryFirstCallWithResult('youtube.Upload', uploadParams); + }, + + hasYTAuth: () => { + const emptyParams = {}; + return lbryFirstCallWithResult('youtube.HasAuth', emptyParams); + }, + + ytSignup: () => { + const emptyParams = {}; + return lbryFirstCallWithResult('youtube.Signup', emptyParams); + }, + + // Connect to lbry-first + connect: () => { + if (LbryFirst.connectPromise === null) { + LbryFirst.connectPromise = new Promise((resolve, reject) => { + let tryNum = 0; + // Check every half second to see if the lbryFirst is accepting connections + function checkLbryFirstStarted() { + tryNum += 1; + LbryFirst.status().then(resolve).catch(() => { + if (tryNum <= CHECK_LBRYFIRST_STARTED_TRY_NUMBER) { + setTimeout(checkLbryFirstStarted, tryNum < 50 ? 400 : 1000); + } else { + reject(new Error('Unable to connect to LBRY')); + } + }); + } + + checkLbryFirstStarted(); + }); + } + + // Flow thinks this could be empty, but it will always return a promise + // $FlowFixMe + return LbryFirst.connectPromise; + } +}; + +function checkAndParse$1(response) { + if (response.status >= 200 && response.status < 300) { + return response.json(); + } + return response.json().then(json => { + let error; + if (json.error) { + const errorMessage = typeof json.error === 'object' ? json.error.message : json.error; + error = new Error(errorMessage); + } else { + error = new Error('Protocol error with unknown response signature'); + } + return Promise.reject(error); + }); +} + +function apiCall$1(method, params, resolve, reject) { + const counter = new Date().getTime(); + params = [params]; + const options = { + method: 'POST', + headers: LbryFirst.apiRequestHeaders, + body: JSON.stringify({ + jsonrpc: '2.0', + method, + params, + id: counter + }) + }; + + return fetch(LbryFirst.lbryFirstConnectionString, options).then(checkAndParse$1).then(response => { + const error = response.error || response.result && response.result.error; + + if (error) { + return reject(error); + } + return resolve(response.result); + }).catch(reject); +} + +function lbryFirstCallWithResult(name, params = {}) { + console.log(`LbryFirst: calling ${name}`); + return new Promise((resolve, reject) => { + apiCall$1(name, params, result => { + resolve(result); + }, reject); + }); +} + +// This is only for a fallback +// If there is a LbryFirst method that is being called by an app, it should be added to /flow-typed/LbryFirst.js +const lbryFirstProxy = new Proxy(LbryFirst, { + get(target, name) { + if (name in target) { + return target[name]; + } + + return (params = {}) => new Promise((resolve, reject) => { + apiCall$1(name, params, resolve, reject); + }); + } +}); + +// + const DEFAULT_SEARCH_RESULT_FROM = 0; const DEFAULT_SEARCH_SIZE = 20; @@ -4469,6 +4624,7 @@ const doPublish = (success, fail) => (dispatch, getState) => { language, license, licenseUrl, + useLBRYUploader, licenseType, otherLicenseDescription, thumbnail, @@ -4554,8 +4710,13 @@ const doPublish = (success, fail) => (dispatch, getState) => { // Only pass file on new uploads, not metadata only edits. // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; - - return lbryProxy.publish(publishPayload).then(success, fail); + // if (useLBRYUploader) return LbryFirst.upload(publishPayload); + return lbryProxy.publish(publishPayload).then(response => { + if (!useLBRYUploader) { + return success(response); + } + return lbryFirstProxy.upload(publishPayload).then(success(response), success(response)); + }, fail); }; // Calls file_list until any reflecting files are done @@ -6227,7 +6388,8 @@ const defaultState$5 = { publishing: false, publishSuccess: false, publishError: undefined, - optimize: false + optimize: false, + useLBRYUploader: false }; const publishReducer = handleActions({ @@ -6950,6 +7112,7 @@ exports.DEFAULT_FOLLOWED_TAGS = DEFAULT_FOLLOWED_TAGS; exports.DEFAULT_KNOWN_TAGS = DEFAULT_KNOWN_TAGS; exports.LICENSES = licenses; exports.Lbry = lbryProxy; +exports.LbryFirst = lbryFirstProxy; exports.MATURE_TAGS = MATURE_TAGS; exports.PAGES = pages; exports.SEARCH_OPTIONS = SEARCH_OPTIONS; diff --git a/dist/flow-typed/LbryFirst.js b/dist/flow-typed/LbryFirst.js new file mode 100644 index 0000000..3cad4dc --- /dev/null +++ b/dist/flow-typed/LbryFirst.js @@ -0,0 +1,99 @@ +// @flow +declare type StatusResponse = { + Version: string, + Message: string, + Running: boolean, + Commit: string, +}; + +declare type VersionResponse = { + build: string, + lbrynet_version: string, + os_release: string, + os_system: string, + platform: string, + processor: string, + python_version: string, +}; +/* SAMPLE UPLOAD RESPONSE (FULL) +"Video": { + "etag": "\"Dn5xIderbhAnUk5TAW0qkFFir0M/xlGLrlTox7VFTRcR8F77RbKtaU4\"", + "id": "8InjtdvVmwE", + "kind": "youtube#video", + "snippet": { + "categoryId": "22", + "channelId": "UCXiVsGTU88fJjheB2rqF0rA", + "channelTitle": "Mark Beamer", + "liveBroadcastContent": "none", + "localized": { + "title": "my title" + }, + "publishedAt": "2020-05-05T04:17:53.000Z", + "thumbnails": { + "default": { + "height": 90, + "url": "https://i9.ytimg.com/vi/8InjtdvVmwE/default.jpg?sqp=CMTQw_UF&rs=AOn4CLB6dlhZMSMrazDlWRsitPgCsn8fVw", + "width": 120 + }, + "high": { + "height": 360, + "url": "https://i9.ytimg.com/vi/8InjtdvVmwE/hqdefault.jpg?sqp=CMTQw_UF&rs=AOn4CLB-Je_7l6qvASRAR_bSGWZHaXaJWQ", + "width": 480 + }, + "medium": { + "height": 180, + "url": "https://i9.ytimg.com/vi/8InjtdvVmwE/mqdefault.jpg?sqp=CMTQw_UF&rs=AOn4CLCvSnDLqVznRNMKuvJ_0misY_chPQ", + "width": 320 + } + }, + "title": "my title" + }, + "status": { + "embeddable": true, + "license": "youtube", + "privacyStatus": "private", + "publicStatsViewable": true, + "uploadStatus": "uploaded" + } + } + */ +declare type UploadResponse = { + Video: { + id: string, + snippet: { + channelId: string, + }, + status: { + uploadStatus: string, + }, + }, +}; + +declare type HasYTAuthResponse = { + HashAuth: boolean, +} + +declare type YTSignupResponse = {} + +// +// Types used in the generic LbryFirst object that is exported +// +declare type LbryFirstTypes = { + isConnected: boolean, + connectPromise: ?Promise, + connect: () => void, + lbryFirstConnectionString: string, + apiRequestHeaders: { [key: string]: string }, + setApiHeader: (string, string) => void, + unsetApiHeader: string => void, + overrides: { [string]: ?Function }, + setOverride: (string, Function) => void, + + // LbryFirst Methods + stop: () => Promise, + status: () => Promise, + version: () => Promise, + upload: (params: {}) => Promise, + hasYTAuth: () =>Promise, + ytSignup: () =>Promise, +}; diff --git a/flow-typed/LbryFirst.js b/flow-typed/LbryFirst.js new file mode 100644 index 0000000..3cad4dc --- /dev/null +++ b/flow-typed/LbryFirst.js @@ -0,0 +1,99 @@ +// @flow +declare type StatusResponse = { + Version: string, + Message: string, + Running: boolean, + Commit: string, +}; + +declare type VersionResponse = { + build: string, + lbrynet_version: string, + os_release: string, + os_system: string, + platform: string, + processor: string, + python_version: string, +}; +/* SAMPLE UPLOAD RESPONSE (FULL) +"Video": { + "etag": "\"Dn5xIderbhAnUk5TAW0qkFFir0M/xlGLrlTox7VFTRcR8F77RbKtaU4\"", + "id": "8InjtdvVmwE", + "kind": "youtube#video", + "snippet": { + "categoryId": "22", + "channelId": "UCXiVsGTU88fJjheB2rqF0rA", + "channelTitle": "Mark Beamer", + "liveBroadcastContent": "none", + "localized": { + "title": "my title" + }, + "publishedAt": "2020-05-05T04:17:53.000Z", + "thumbnails": { + "default": { + "height": 90, + "url": "https://i9.ytimg.com/vi/8InjtdvVmwE/default.jpg?sqp=CMTQw_UF&rs=AOn4CLB6dlhZMSMrazDlWRsitPgCsn8fVw", + "width": 120 + }, + "high": { + "height": 360, + "url": "https://i9.ytimg.com/vi/8InjtdvVmwE/hqdefault.jpg?sqp=CMTQw_UF&rs=AOn4CLB-Je_7l6qvASRAR_bSGWZHaXaJWQ", + "width": 480 + }, + "medium": { + "height": 180, + "url": "https://i9.ytimg.com/vi/8InjtdvVmwE/mqdefault.jpg?sqp=CMTQw_UF&rs=AOn4CLCvSnDLqVznRNMKuvJ_0misY_chPQ", + "width": 320 + } + }, + "title": "my title" + }, + "status": { + "embeddable": true, + "license": "youtube", + "privacyStatus": "private", + "publicStatsViewable": true, + "uploadStatus": "uploaded" + } + } + */ +declare type UploadResponse = { + Video: { + id: string, + snippet: { + channelId: string, + }, + status: { + uploadStatus: string, + }, + }, +}; + +declare type HasYTAuthResponse = { + HashAuth: boolean, +} + +declare type YTSignupResponse = {} + +// +// Types used in the generic LbryFirst object that is exported +// +declare type LbryFirstTypes = { + isConnected: boolean, + connectPromise: ?Promise, + connect: () => void, + lbryFirstConnectionString: string, + apiRequestHeaders: { [key: string]: string }, + setApiHeader: (string, string) => void, + unsetApiHeader: string => void, + overrides: { [string]: ?Function }, + setOverride: (string, Function) => void, + + // LbryFirst Methods + stop: () => Promise, + status: () => Promise, + version: () => Promise, + upload: (params: {}) => Promise, + hasYTAuth: () =>Promise, + ytSignup: () =>Promise, +}; diff --git a/src/index.js b/src/index.js index ad996b7..e994dae 100644 --- a/src/index.js +++ b/src/index.js @@ -15,6 +15,7 @@ import * as SHARED_PREFERENCES from 'constants/shared_preferences'; import { SEARCH_TYPES, SEARCH_OPTIONS } from 'constants/search'; import { DEFAULT_KNOWN_TAGS, DEFAULT_FOLLOWED_TAGS, MATURE_TAGS } from 'constants/tags'; import Lbry, { apiCall } from 'lbry'; +import LbryFirst from 'lbry-first'; import { selectState as selectSearchState } from 'redux/selectors/search'; // constants @@ -42,6 +43,7 @@ export { // common export { Lbry, apiCall }; +export { LbryFirst }; export { regexInvalidURI, regexAddress, diff --git a/src/lbry-first.js b/src/lbry-first.js new file mode 100644 index 0000000..0a467d6 --- /dev/null +++ b/src/lbry-first.js @@ -0,0 +1,168 @@ +// @flow +import 'proxy-polyfill'; + +const CHECK_LBRYFIRST_STARTED_TRY_NUMBER = 200; +// +// Basic LBRYFIRST connection config +// Offers a proxy to call LBRYFIRST methods + +// +const LbryFirst: LbryFirstTypes = { + isConnected: false, + connectPromise: null, + lbryFirstConnectionString: 'http://localhost:1337/rpc', + apiRequestHeaders: { 'Content-Type': 'application/json' }, + + // Allow overriding lbryFirst connection string (e.g. to `/api/proxy` for lbryweb) + setLbryFirstConnectionString: (value: string) => { + LbryFirst.lbryFirstConnectionString = value; + }, + + setApiHeader: (key: string, value: string) => { + LbryFirst.apiRequestHeaders = Object.assign(LbryFirst.apiRequestHeaders, { [key]: value }); + }, + + unsetApiHeader: key => { + Object.keys(LbryFirst.apiRequestHeaders).includes(key) && delete LbryFirst.apiRequestHeaders['key']; + }, + // Allow overriding Lbry methods + overrides: {}, + setOverride: (methodName, newMethod) => { + LbryFirst.overrides[methodName] = newMethod; + }, + getApiRequestHeaders: () => LbryFirst.apiRequestHeaders, + + // + // LbryFirst Methods + // + status: (params = {}) => lbryFirstCallWithResult('status', params), + stop: () => lbryFirstCallWithResult('stop', {}), + version: () => lbryFirstCallWithResult('version', {}), + + // Upload to youtube + upload: (params = {}) => { + // Only upload when originally publishing for now + if (!params.file_path) { + return {}; + } + const uploadParams = {}; + uploadParams.Title = params.title; + uploadParams.Description = params.description; + uploadParams.FilePath = params.file_path; + uploadParams.Category = ''; + uploadParams.Keywords = ''; + return lbryFirstCallWithResult('youtube.Upload', uploadParams); + }, + + hasYTAuth: () => { + const emptyParams = {}; + return lbryFirstCallWithResult('youtube.HasAuth', emptyParams); + }, + + ytSignup: () => { + const emptyParams = {}; + return lbryFirstCallWithResult('youtube.Signup', emptyParams); + }, + + // Connect to lbry-first + connect: () => { + if (LbryFirst.connectPromise === null) { + LbryFirst.connectPromise = new Promise((resolve, reject) => { + let tryNum = 0; + // Check every half second to see if the lbryFirst is accepting connections + function checkLbryFirstStarted() { + tryNum += 1; + LbryFirst.status() + .then(resolve) + .catch(() => { + if (tryNum <= CHECK_LBRYFIRST_STARTED_TRY_NUMBER) { + setTimeout(checkLbryFirstStarted, tryNum < 50 ? 400 : 1000); + } else { + reject(new Error('Unable to connect to LBRY')); + } + }); + } + + checkLbryFirstStarted(); + }); + } + + // Flow thinks this could be empty, but it will always return a promise + // $FlowFixMe + return LbryFirst.connectPromise; + }, +}; + +function checkAndParse(response) { + if (response.status >= 200 && response.status < 300) { + return response.json(); + } + return response.json().then(json => { + let error; + if (json.error) { + const errorMessage = typeof json.error === 'object' ? json.error.message : json.error; + error = new Error(errorMessage); + } else { + error = new Error('Protocol error with unknown response signature'); + } + return Promise.reject(error); + }); +} + +export function apiCall(method: string, params: ?{}, resolve: Function, reject: Function) { + const counter = new Date().getTime(); + params = [params]; + const options = { + method: 'POST', + headers: LbryFirst.apiRequestHeaders, + body: JSON.stringify({ + jsonrpc: '2.0', + method, + params, + id: counter, + }), + }; + + return fetch(LbryFirst.lbryFirstConnectionString, options) + .then(checkAndParse) + .then(response => { + const error = response.error || (response.result && response.result.error); + + if (error) { + return reject(error); + } + return resolve(response.result); + }) + .catch(reject); +} + +function lbryFirstCallWithResult(name: string, params: ?{} = {}) { + console.log(`LbryFirst: calling ${name}`); + return new Promise((resolve, reject) => { + apiCall( + name, + params, + result => { + resolve(result); + }, + reject + ); + }); +} + +// This is only for a fallback +// If there is a LbryFirst method that is being called by an app, it should be added to /flow-typed/LbryFirst.js +const lbryFirstProxy = new Proxy(LbryFirst, { + get(target: LbryFirstTypes, name: string) { + if (name in target) { + return target[name]; + } + + return (params = {}) => + new Promise((resolve, reject) => { + apiCall(name, params, resolve, reject); + }); + }, +}); + +export default lbryFirstProxy; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index c977640..6d56e1f 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -4,6 +4,7 @@ import { SPEECH_STATUS, SPEECH_PUBLISH } from 'constants/speech_urls'; import * as ACTIONS from 'constants/action_types'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import Lbry from 'lbry'; +import LbryFirst from 'lbry-first'; import { batchActions } from 'util/batch-actions'; import { creditsToString } from 'util/format-credits'; import { doError } from 'redux/actions/notifications'; @@ -245,6 +246,7 @@ export const doPublish = (success: Function, fail: Function) => ( language, license, licenseUrl, + useLBRYUploader, licenseType, otherLicenseDescription, thumbnail, @@ -350,8 +352,14 @@ export const doPublish = (success: Function, fail: Function) => ( // Only pass file on new uploads, not metadata only edits. // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; - - return Lbry.publish(publishPayload).then(success, fail); + // if (useLBRYUploader) return LbryFirst.upload(publishPayload); + return Lbry.publish(publishPayload) + .then((response) => { + if (!useLBRYUploader) { + return success(response); + } + return LbryFirst.upload(publishPayload).then(success(response), success(response)); + }, fail); }; // Calls file_list until any reflecting files are done diff --git a/src/redux/reducers/publish.js b/src/redux/reducers/publish.js index 4c94168..2104675 100644 --- a/src/redux/reducers/publish.js +++ b/src/redux/reducers/publish.js @@ -33,6 +33,7 @@ type PublishState = { licenseUrl: string, tags: Array, optimize: boolean, + useLBRYUploader: boolean, }; const defaultState: PublishState = { @@ -68,6 +69,7 @@ const defaultState: PublishState = { publishSuccess: false, publishError: undefined, optimize: false, + useLBRYUploader: false, }; export const publishReducer = handleActions( -- 2.45.2 From 1523bbd33fa215bedebc15bbf2b71a3f7c837a5b Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Tue, 7 Jul 2020 18:06:59 -0400 Subject: [PATCH 366/371] add 'lbry-first' tag to lbry-first publishes --- dist/bundle.es.js | 24 +++++++++++++++--------- flow-typed/LbryFirst.js | 10 +++++----- src/lbry-first.js | 33 +++++++++++++++++++++------------ src/redux/actions/publish.js | 19 +++++++++++-------- 4 files changed, 52 insertions(+), 34 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2ee2b36..2f9771f 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1261,14 +1261,17 @@ const LbryFirst = { upload: (params = {}) => { // Only upload when originally publishing for now if (!params.file_path) { - return {}; + return new Promise(); } - const uploadParams = {}; - uploadParams.Title = params.title; - uploadParams.Description = params.description; - uploadParams.FilePath = params.file_path; - uploadParams.Category = ''; - uploadParams.Keywords = ''; + + const uploadParams = { + Title: params.title, + Description: params.description, + FilePath: params.file_path, + Category: '', + Keywords: '' + }; + return lbryFirstCallWithResult('youtube.Upload', uploadParams); }, @@ -1350,7 +1353,6 @@ function apiCall$1(method, params, resolve, reject) { } function lbryFirstCallWithResult(name, params = {}) { - console.log(`LbryFirst: calling ${name}`); return new Promise((resolve, reject) => { apiCall$1(name, params, result => { resolve(result); @@ -4681,6 +4683,10 @@ const doPublish = (success, fail) => (dispatch, getState) => { publishPayload.thumbnail_url = thumbnail; } + if (useLBRYUploader) { + publishPayload.tags.push('lbry-first'); + } + // Set release time to curret date. On edits, keep original release/transaction time as release_time if (myClaimForUriEditing && myClaimForUriEditing.value.release_time) { publishPayload.release_time = Number(myClaimForUri.value.release_time); @@ -4710,7 +4716,7 @@ const doPublish = (success, fail) => (dispatch, getState) => { // Only pass file on new uploads, not metadata only edits. // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; - // if (useLBRYUploader) return LbryFirst.upload(publishPayload); + return lbryProxy.publish(publishPayload).then(response => { if (!useLBRYUploader) { return success(response); diff --git a/flow-typed/LbryFirst.js b/flow-typed/LbryFirst.js index 3cad4dc..850fa88 100644 --- a/flow-typed/LbryFirst.js +++ b/flow-typed/LbryFirst.js @@ -71,9 +71,9 @@ declare type UploadResponse = { declare type HasYTAuthResponse = { HashAuth: boolean, -} +}; -declare type YTSignupResponse = {} +declare type YTSignupResponse = {}; // // Types used in the generic LbryFirst object that is exported @@ -93,7 +93,7 @@ declare type LbryFirstTypes = { stop: () => Promise, status: () => Promise, version: () => Promise, - upload: (params: {}) => Promise, - hasYTAuth: () =>Promise, - ytSignup: () =>Promise, + upload: any => Promise, + hasYTAuth: () => Promise, + ytSignup: () => Promise, }; diff --git a/src/lbry-first.js b/src/lbry-first.js index 0a467d6..d0e9f3b 100644 --- a/src/lbry-first.js +++ b/src/lbry-first.js @@ -23,7 +23,8 @@ const LbryFirst: LbryFirstTypes = { }, unsetApiHeader: key => { - Object.keys(LbryFirst.apiRequestHeaders).includes(key) && delete LbryFirst.apiRequestHeaders['key']; + Object.keys(LbryFirst.apiRequestHeaders).includes(key) && + delete LbryFirst.apiRequestHeaders['key']; }, // Allow overriding Lbry methods overrides: {}, @@ -40,17 +41,26 @@ const LbryFirst: LbryFirstTypes = { version: () => lbryFirstCallWithResult('version', {}), // Upload to youtube - upload: (params = {}) => { + upload: (params: { title: string, description: string, file_path: ?string } = {}) => { // Only upload when originally publishing for now if (!params.file_path) { - return {}; + return Promise.resolve(); } - const uploadParams = {}; - uploadParams.Title = params.title; - uploadParams.Description = params.description; - uploadParams.FilePath = params.file_path; - uploadParams.Category = ''; - uploadParams.Keywords = ''; + + const uploadParams: { + Title: string, + Description: string, + FilePath: string, + Category: string, + Keywords: string, + } = { + Title: params.title, + Description: params.description, + FilePath: params.file_path, + Category: '', + Keywords: '', + }; + return lbryFirstCallWithResult('youtube.Upload', uploadParams); }, @@ -111,14 +121,14 @@ function checkAndParse(response) { export function apiCall(method: string, params: ?{}, resolve: Function, reject: Function) { const counter = new Date().getTime(); - params = [params]; + const paramsArray = [params]; const options = { method: 'POST', headers: LbryFirst.apiRequestHeaders, body: JSON.stringify({ jsonrpc: '2.0', method, - params, + params: paramsArray, id: counter, }), }; @@ -137,7 +147,6 @@ export function apiCall(method: string, params: ?{}, resolve: Function, reject: } function lbryFirstCallWithResult(name: string, params: ?{} = {}) { - console.log(`LbryFirst: calling ${name}`); return new Promise((resolve, reject) => { apiCall( name, diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 6d56e1f..b5364e5 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -323,6 +323,10 @@ export const doPublish = (success: Function, fail: Function) => ( publishPayload.thumbnail_url = thumbnail; } + if (useLBRYUploader) { + publishPayload.tags.push('lbry-first'); + } + // Set release time to curret date. On edits, keep original release/transaction time as release_time if (myClaimForUriEditing && myClaimForUriEditing.value.release_time) { publishPayload.release_time = Number(myClaimForUri.value.release_time); @@ -352,14 +356,13 @@ export const doPublish = (success: Function, fail: Function) => ( // Only pass file on new uploads, not metadata only edits. // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; - // if (useLBRYUploader) return LbryFirst.upload(publishPayload); - return Lbry.publish(publishPayload) - .then((response) => { - if (!useLBRYUploader) { - return success(response); - } - return LbryFirst.upload(publishPayload).then(success(response), success(response)); - }, fail); + + return Lbry.publish(publishPayload).then(response => { + if (!useLBRYUploader) { + return success(response); + } + return LbryFirst.upload(publishPayload).then(success(response), success(response)); + }, fail); }; // Calls file_list until any reflecting files are done -- 2.45.2 From 31647e4ee7371ca05a9fa13b3ac3f5b4a794383d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Wed, 8 Jul 2020 01:40:43 -0400 Subject: [PATCH 367/371] add back 'remove' function --- dist/bundle.es.js | 11 ++++++++--- dist/flow-typed/LbryFirst.js | 10 +++++----- src/lbry-first.js | 5 +++++ 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 2f9771f..1002bcd 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1261,7 +1261,7 @@ const LbryFirst = { upload: (params = {}) => { // Only upload when originally publishing for now if (!params.file_path) { - return new Promise(); + return Promise.resolve(); } const uploadParams = { @@ -1285,6 +1285,11 @@ const LbryFirst = { return lbryFirstCallWithResult('youtube.Signup', emptyParams); }, + remove: () => { + const emptyParams = {}; + return lbryFirstCallWithResult('youtube.Remove', emptyParams); + }, + // Connect to lbry-first connect: () => { if (LbryFirst.connectPromise === null) { @@ -1330,14 +1335,14 @@ function checkAndParse$1(response) { function apiCall$1(method, params, resolve, reject) { const counter = new Date().getTime(); - params = [params]; + const paramsArray = [params]; const options = { method: 'POST', headers: LbryFirst.apiRequestHeaders, body: JSON.stringify({ jsonrpc: '2.0', method, - params, + params: paramsArray, id: counter }) }; diff --git a/dist/flow-typed/LbryFirst.js b/dist/flow-typed/LbryFirst.js index 3cad4dc..850fa88 100644 --- a/dist/flow-typed/LbryFirst.js +++ b/dist/flow-typed/LbryFirst.js @@ -71,9 +71,9 @@ declare type UploadResponse = { declare type HasYTAuthResponse = { HashAuth: boolean, -} +}; -declare type YTSignupResponse = {} +declare type YTSignupResponse = {}; // // Types used in the generic LbryFirst object that is exported @@ -93,7 +93,7 @@ declare type LbryFirstTypes = { stop: () => Promise, status: () => Promise, version: () => Promise, - upload: (params: {}) => Promise, - hasYTAuth: () =>Promise, - ytSignup: () =>Promise, + upload: any => Promise, + hasYTAuth: () => Promise, + ytSignup: () => Promise, }; diff --git a/src/lbry-first.js b/src/lbry-first.js index d0e9f3b..8b2deb7 100644 --- a/src/lbry-first.js +++ b/src/lbry-first.js @@ -74,6 +74,11 @@ const LbryFirst: LbryFirstTypes = { return lbryFirstCallWithResult('youtube.Signup', emptyParams); }, + remove: () => { + const emptyParams = {}; + return lbryFirstCallWithResult('youtube.Remove', emptyParams); + }, + // Connect to lbry-first connect: () => { if (LbryFirst.connectPromise === null) { -- 2.45.2 From e6d89b06909b7f3a280e25625669f64ce06f340d Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Thu, 9 Jul 2020 10:51:50 -0400 Subject: [PATCH 368/371] send lbryfirst error to desktop for handling --- dist/bundle.es.js | 8 +++++++- src/redux/actions/publish.js | 10 +++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1002bcd..1258f92 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4726,7 +4726,13 @@ const doPublish = (success, fail) => (dispatch, getState) => { if (!useLBRYUploader) { return success(response); } - return lbryFirstProxy.upload(publishPayload).then(success(response), success(response)); + + return lbryFirstProxy.upload(publishPayload).then(() => { + // Return original publish response so app treats it like a normal publish + return success(response); + }).catch(error => { + return success(response, error); + }); }, fail); }; diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index b5364e5..88652d2 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -361,7 +361,15 @@ export const doPublish = (success: Function, fail: Function) => ( if (!useLBRYUploader) { return success(response); } - return LbryFirst.upload(publishPayload).then(success(response), success(response)); + + return LbryFirst.upload(publishPayload) + .then(() => { + // Return original publish response so app treats it like a normal publish + return success(response); + }) + .catch(error => { + return success(response, error); + }); }, fail); }; -- 2.45.2 From 85077f6f00fa76ddfc261beeb62b9706a2bbf25e Mon Sep 17 00:00:00 2001 From: infiinte-persistence Date: Fri, 10 Jul 2020 18:16:09 +0800 Subject: [PATCH 369/371] Publish: Handle reflecting-state not updated correctly. Fixes 4385 (lbry-desktop) `Don't show upload progress if no file exists (shows 0% progress)` An undefined result exception was causing the reflecting-state update code to be missed, so Desktop still thinks the item is still reflecting and continues to show the "Uploading(0%)" status. --- dist/bundle.es.js | 28 +++++++++++++++------------- src/redux/actions/publish.js | 28 +++++++++++++++------------- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 1258f92..0b56a63 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4758,19 +4758,21 @@ const doCheckReflectingFiles = () => (dispatch, getState) => { Promise.all(promises).then(function (results) { results.forEach(function (res) { - const fileListItem = res.items[0]; - const fileClaimId = fileListItem.claim_id; - const { - is_fully_reflected: done, - uploading_to_reflector: uploading, - reflector_progress: progress - } = fileListItem; - if (uploading) { - newReflectingById[fileClaimId] = { - fileListItem: fileListItem, - progress, - stalled: !done && !uploading - }; + if (res.items[0]) { + const fileListItem = res.items[0]; + const fileClaimId = fileListItem.claim_id; + const { + is_fully_reflected: done, + uploading_to_reflector: uploading, + reflector_progress: progress + } = fileListItem; + if (uploading) { + newReflectingById[fileClaimId] = { + fileListItem: fileListItem, + progress, + stalled: !done && !uploading + }; + } } }); }).then(function () { diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 88652d2..40af286 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -395,19 +395,21 @@ export const doCheckReflectingFiles = () => (dispatch: Dispatch, getState: GetSt Promise.all(promises) .then(results => { results.forEach(res => { - const fileListItem = res.items[0]; - const fileClaimId = fileListItem.claim_id; - const { - is_fully_reflected: done, - uploading_to_reflector: uploading, - reflector_progress: progress, - } = fileListItem; - if (uploading) { - newReflectingById[fileClaimId] = { - fileListItem: fileListItem, - progress, - stalled: !done && !uploading, - }; + if (res.items[0]) { + const fileListItem = res.items[0]; + const fileClaimId = fileListItem.claim_id; + const { + is_fully_reflected: done, + uploading_to_reflector: uploading, + reflector_progress: progress, + } = fileListItem; + if (uploading) { + newReflectingById[fileClaimId] = { + fileListItem: fileListItem, + progress, + stalled: !done && !uploading, + }; + } } }); }) -- 2.45.2 From c29123e815bf9b4b8d0c06f49f6aa4d1f583f5c8 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 10 Jul 2020 12:36:30 -0400 Subject: [PATCH 370/371] pass authToken to youtube.HasAuth --- dist/bundle.es.js | 7 ++++--- dist/flow-typed/LbryFirst.js | 2 +- flow-typed/LbryFirst.js | 2 +- src/lbry-first.js | 7 ++++--- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 0b56a63..9a3f93b 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -1275,9 +1275,10 @@ const LbryFirst = { return lbryFirstCallWithResult('youtube.Upload', uploadParams); }, - hasYTAuth: () => { - const emptyParams = {}; - return lbryFirstCallWithResult('youtube.HasAuth', emptyParams); + hasYTAuth: token => { + const hasYTAuthParams = {}; + hasYTAuthParams.AuthToken = token; + return lbryFirstCallWithResult('youtube.HasAuth', hasYTAuthParams); }, ytSignup: () => { diff --git a/dist/flow-typed/LbryFirst.js b/dist/flow-typed/LbryFirst.js index 850fa88..b068f5f 100644 --- a/dist/flow-typed/LbryFirst.js +++ b/dist/flow-typed/LbryFirst.js @@ -94,6 +94,6 @@ declare type LbryFirstTypes = { status: () => Promise, version: () => Promise, upload: any => Promise, - hasYTAuth: () => Promise, + hasYTAuth: string => Promise, ytSignup: () => Promise, }; diff --git a/flow-typed/LbryFirst.js b/flow-typed/LbryFirst.js index 850fa88..b068f5f 100644 --- a/flow-typed/LbryFirst.js +++ b/flow-typed/LbryFirst.js @@ -94,6 +94,6 @@ declare type LbryFirstTypes = { status: () => Promise, version: () => Promise, upload: any => Promise, - hasYTAuth: () => Promise, + hasYTAuth: string => Promise, ytSignup: () => Promise, }; diff --git a/src/lbry-first.js b/src/lbry-first.js index 8b2deb7..4dcb39e 100644 --- a/src/lbry-first.js +++ b/src/lbry-first.js @@ -64,9 +64,10 @@ const LbryFirst: LbryFirstTypes = { return lbryFirstCallWithResult('youtube.Upload', uploadParams); }, - hasYTAuth: () => { - const emptyParams = {}; - return lbryFirstCallWithResult('youtube.HasAuth', emptyParams); + hasYTAuth: (token: string) => { + const hasYTAuthParams = {}; + hasYTAuthParams.AuthToken = token; + return lbryFirstCallWithResult('youtube.HasAuth', hasYTAuthParams); }, ytSignup: () => { -- 2.45.2 From a1673ebfa933c0e921a23a1877d22e21c2bff8f9 Mon Sep 17 00:00:00 2001 From: Sean Yesmunt Date: Fri, 10 Jul 2020 13:39:55 -0400 Subject: [PATCH 371/371] add permanent_url to lbryFirst publish payload --- dist/bundle.es.js | 3 +++ src/redux/actions/publish.js | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/dist/bundle.es.js b/dist/bundle.es.js index 9a3f93b..17e89d9 100644 --- a/dist/bundle.es.js +++ b/dist/bundle.es.js @@ -4728,6 +4728,9 @@ const doPublish = (success, fail) => (dispatch, getState) => { return success(response); } + // $FlowFixMe + publishPayload.permanent_url = response.outputs[0].permanent_url; + return lbryFirstProxy.upload(publishPayload).then(() => { // Return original publish response so app treats it like a normal publish return success(response); diff --git a/src/redux/actions/publish.js b/src/redux/actions/publish.js index 40af286..8c52098 100644 --- a/src/redux/actions/publish.js +++ b/src/redux/actions/publish.js @@ -357,11 +357,14 @@ export const doPublish = (success: Function, fail: Function) => ( // The sdk will figure it out if (filePath) publishPayload.file_path = filePath; - return Lbry.publish(publishPayload).then(response => { + return Lbry.publish(publishPayload).then((response: PublishResponse) => { if (!useLBRYUploader) { return success(response); } + // $FlowFixMe + publishPayload.permanent_url = response.outputs[0].permanent_url; + return LbryFirst.upload(publishPayload) .then(() => { // Return original publish response so app treats it like a normal publish -- 2.45.2