Merge pull request #315 from lbryio/paid
This commit is contained in:
commit
6c494eaf80
13 changed files with 299 additions and 391 deletions
412
dist/bundle.es.js
vendored
412
dist/bundle.es.js
vendored
File diff suppressed because one or more lines are too long
4
dist/flow-typed/File.js
vendored
4
dist/flow-typed/File.js
vendored
|
@ -11,6 +11,8 @@ declare type FileListItem = {
|
|||
claim_id: string,
|
||||
claim_name: string,
|
||||
completed: false,
|
||||
content_fee?: { txid: string },
|
||||
purchase_receipt?: { txid: string, amount: string },
|
||||
download_directory: string,
|
||||
download_path: string,
|
||||
file_name: string,
|
||||
|
@ -69,7 +71,7 @@ declare type PurchaseUriStarted = {
|
|||
};
|
||||
|
||||
declare type DeletePurchasedUri = {
|
||||
type: ACTIONS.DELETE_PURCHASED_URI,
|
||||
type: ACTIONS.CLEAR_PURCHASED_URI_SUCCESS,
|
||||
data: {
|
||||
uri: string,
|
||||
},
|
||||
|
|
4
flow-typed/File.js
vendored
4
flow-typed/File.js
vendored
|
@ -11,6 +11,8 @@ declare type FileListItem = {
|
|||
claim_id: string,
|
||||
claim_name: string,
|
||||
completed: false,
|
||||
content_fee?: { txid: string },
|
||||
purchase_receipt?: { txid: string, amount: string },
|
||||
download_directory: string,
|
||||
download_path: string,
|
||||
file_name: string,
|
||||
|
@ -69,7 +71,7 @@ declare type PurchaseUriStarted = {
|
|||
};
|
||||
|
||||
declare type DeletePurchasedUri = {
|
||||
type: ACTIONS.DELETE_PURCHASED_URI,
|
||||
type: ACTIONS.CLEAR_PURCHASED_URI_SUCCESS,
|
||||
data: {
|
||||
uri: string,
|
||||
},
|
||||
|
|
|
@ -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';
|
||||
|
|
|
@ -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',
|
||||
|
|
13
src/index.js
13
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,
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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<string>, 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,
|
||||
|
|
|
@ -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,16 +39,17 @@ 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.purchase_receipt || streamInfo.content_fee) {
|
||||
dispatch({
|
||||
type: ACTIONS.PURCHASE_URI_COMPLETED,
|
||||
data: { uri, purchaseReceipt: streamInfo.purchase_receipt || streamInfo.content_fee },
|
||||
});
|
||||
}
|
||||
dispatch({
|
||||
type: ACTIONS.FETCH_FILE_INFO_COMPLETED,
|
||||
data: {
|
||||
fileInfo: streamInfo,
|
||||
outpoint: streamInfo.outpoint,
|
||||
outpoint: outpoint,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -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({
|
||||
|
@ -120,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,
|
||||
};
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ type State = {
|
|||
fetchingChannelClaims: { [string]: number },
|
||||
fetchingMyChannels: boolean,
|
||||
fetchingClaimSearchByQuery: { [string]: boolean },
|
||||
purchaseUriSuccess: boolean,
|
||||
myPurchases: ?Array<string>,
|
||||
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,44 @@ 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,
|
||||
};
|
||||
};
|
||||
|
||||
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);
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
@ -255,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);
|
||||
|
@ -400,7 +410,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;
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -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<string> = createSelector(
|
||||
selectState,
|
||||
state => state.failedPurchaseUris
|
||||
);
|
||||
|
||||
export const selectPurchasedUris: (state: State) => Array<string> = 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;
|
||||
}
|
||||
);
|
|
@ -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;
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Add table
Reference in a new issue