add purchase_list
This commit is contained in:
parent
259317250a
commit
278e12dcbe
13 changed files with 421 additions and 34 deletions
171
dist/bundle.es.js
vendored
171
dist/bundle.es.js
vendored
|
@ -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;
|
||||
|
|
18
dist/flow-typed/Claim.js
vendored
18
dist/flow-typed/Claim.js
vendored
|
@ -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',
|
||||
};
|
||||
|
|
17
dist/flow-typed/Lbry.js
vendored
17
dist/flow-typed/Lbry.js
vendored
|
@ -214,6 +214,22 @@ declare type StreamRepostOptions = {
|
|||
|
||||
declare type StreamRepostResponse = GenericTxResponse;
|
||||
|
||||
declare type PurchaseListResponse = {
|
||||
items: Array<PurchaseReceipt & { claim: StreamClaim }>,
|
||||
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<SupportListResponse>,
|
||||
support_abandon: (params: {}) => Promise<SupportAbandonResponse>,
|
||||
stream_repost: (params: StreamRepostOptions) => Promise<StreamRepostResponse>,
|
||||
purchase_list: (params: PurchaseListOptions) => Promise<PurchaseListResponse>,
|
||||
|
||||
// File fetching and manipulation
|
||||
file_list: (params: {}) => Promise<FileListResponse>,
|
||||
|
|
18
flow-typed/Claim.js
vendored
18
flow-typed/Claim.js
vendored
|
@ -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',
|
||||
};
|
||||
|
|
17
flow-typed/Lbry.js
vendored
17
flow-typed/Lbry.js
vendored
|
@ -214,6 +214,22 @@ declare type StreamRepostOptions = {
|
|||
|
||||
declare type StreamRepostResponse = GenericTxResponse;
|
||||
|
||||
declare type PurchaseListResponse = {
|
||||
items: Array<PurchaseReceipt & { claim: StreamClaim }>,
|
||||
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<SupportListResponse>,
|
||||
support_abandon: (params: {}) => Promise<SupportAbandonResponse>,
|
||||
stream_repost: (params: StreamRepostOptions) => Promise<StreamRepostResponse>,
|
||||
purchase_list: (params: PurchaseListOptions) => Promise<PurchaseListResponse>,
|
||||
|
||||
// File fetching and manipulation
|
||||
file_list: (params: {}) => Promise<FileListResponse>,
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -35,7 +35,9 @@ export function doResolveUris(uris: Array<string>, 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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -25,6 +25,11 @@ type State = {
|
|||
fetchingChannelClaims: { [string]: number },
|
||||
fetchingMyChannels: boolean,
|
||||
fetchingClaimSearchByQuery: { [string]: boolean },
|
||||
myPurchases: ?Array<string>,
|
||||
myPurchasesPageNumber: ?number,
|
||||
myPurchasesPageTotalResults: ?number,
|
||||
fetchingMyPurchases: boolean,
|
||||
fetchingMyPurchasesError: ?string,
|
||||
claimSearchByQuery: { [string]: Array<string> },
|
||||
claimSearchByQueryLastPageReached: { [string]: Array<boolean> },
|
||||
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);
|
||||
|
|
|
@ -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<string>, 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
)
|
||||
: [];
|
||||
}
|
||||
);
|
||||
|
|
|
@ -51,3 +51,20 @@ export function concatClaims(
|
|||
|
||||
return claims;
|
||||
}
|
||||
|
||||
export function filterClaims(claims: Array<Claim>, query: ?string): Array<Claim> {
|
||||
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;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue