fix merge conflict
This commit is contained in:
commit
3eaa27ef29
21 changed files with 625 additions and 465 deletions
738
dist/bundle.es.js
vendored
738
dist/bundle.es.js
vendored
File diff suppressed because it is too large
Load diff
5
dist/flow-typed/File.js
vendored
5
dist/flow-typed/File.js
vendored
|
@ -38,7 +38,6 @@ declare type FileListItem = {
|
|||
declare type FileState = {
|
||||
failedPurchaseUris: Array<string>,
|
||||
purchasedUris: Array<string>,
|
||||
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,
|
||||
},
|
||||
};
|
||||
|
|
2
dist/flow-typed/Lbry.js
vendored
2
dist/flow-typed/Lbry.js
vendored
|
@ -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,
|
||||
|
|
4
dist/flow-typed/mime.js
vendored
Normal file
4
dist/flow-typed/mime.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
// @flow
|
||||
declare module 'mime' {
|
||||
declare module.exports: any;
|
||||
}
|
5
flow-typed/File.js
vendored
5
flow-typed/File.js
vendored
|
@ -38,7 +38,6 @@ declare type FileListItem = {
|
|||
declare type FileState = {
|
||||
failedPurchaseUris: Array<string>,
|
||||
purchasedUris: Array<string>,
|
||||
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,
|
||||
},
|
||||
};
|
||||
|
|
2
flow-typed/Lbry.js
vendored
2
flow-typed/Lbry.js
vendored
|
@ -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,
|
||||
|
|
4
flow-typed/mime.js
vendored
Normal file
4
flow-typed/mime.js
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
// @flow
|
||||
declare module 'mime' {
|
||||
declare module.exports: any;
|
||||
}
|
|
@ -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"
|
||||
|
|
|
@ -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';
|
||||
|
@ -127,9 +128,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';
|
||||
|
|
|
@ -140,7 +140,6 @@ export { selectToast, selectError } from 'redux/selectors/notifications';
|
|||
export {
|
||||
selectFailedPurchaseUris,
|
||||
selectPurchasedUris,
|
||||
selectPurchasedStreamingUrls,
|
||||
selectPurchaseUriErrorMessage,
|
||||
selectLastPurchasedUri,
|
||||
makeSelectStreamingUrlForUri,
|
||||
|
@ -173,6 +172,7 @@ export {
|
|||
makeSelectPendingByUri,
|
||||
makeSelectClaimsInChannelForCurrentPageState,
|
||||
makeSelectShortUrlForUri,
|
||||
makeSelectSupportsForUri,
|
||||
selectPendingById,
|
||||
selectClaimsById,
|
||||
selectClaimsByUri,
|
||||
|
@ -218,6 +218,11 @@ export {
|
|||
selectFileListDownloadedSort,
|
||||
selectFileListPublishedSort,
|
||||
selectDownloadedUris,
|
||||
makeSelectMediaTypeForUri,
|
||||
makeSelectUriIsStreamable,
|
||||
makeSelectDownloadPathForUri,
|
||||
makeSelectFileNameForUri,
|
||||
makeSelectFilePartlyDownloaded,
|
||||
} from 'redux/selectors/file_info';
|
||||
|
||||
export {
|
||||
|
@ -246,6 +251,7 @@ export {
|
|||
selectTotalBalance,
|
||||
selectTransactionsById,
|
||||
selectSupportsByOutpoint,
|
||||
selectTotalSupports,
|
||||
selectTransactionItems,
|
||||
selectRecentTransactions,
|
||||
selectHasTransactions,
|
||||
|
|
52
src/lbry.js
52
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,40 @@ 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
|
||||
return /^[^/]+/.exec(contentType)[0];
|
||||
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];
|
||||
}
|
||||
}
|
||||
|
||||
return 'unknown';
|
||||
},
|
||||
|
||||
|
|
|
@ -5,57 +5,70 @@ 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) {
|
||||
return (dispatch: Dispatch) => {
|
||||
export function doFileGet(uri: string, saveFile: boolean = true, onSuccess?: GetResponse => any) {
|
||||
return (dispatch: Dispatch, getState: () => any) => {
|
||||
const state = getState();
|
||||
const { nout, txid } = makeSelectClaimForUri(uri)(state);
|
||||
const outpoint = `${txid}:${nout}`;
|
||||
|
||||
dispatch({
|
||||
type: ACTIONS.LOADING_FILE_STARTED,
|
||||
type: ACTIONS.FETCH_FILE_INFO_STARTED,
|
||||
data: {
|
||||
uri,
|
||||
outpoint,
|
||||
},
|
||||
});
|
||||
|
||||
// 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({
|
||||
type: ACTIONS.LOADING_FILE_FAILED,
|
||||
data: { uri },
|
||||
});
|
||||
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 }));
|
||||
} else {
|
||||
// purchase was completed successfully
|
||||
const { streaming_url: streamingUrl } = streamInfo;
|
||||
dispatch({
|
||||
type: ACTIONS.PURCHASE_URI_COMPLETED,
|
||||
data: { uri, streamingUrl: !saveFile && streamingUrl ? streamingUrl : null },
|
||||
data: { uri },
|
||||
});
|
||||
dispatch({
|
||||
type: ACTIONS.FETCH_FILE_INFO_COMPLETED,
|
||||
data: {
|
||||
fileInfo: streamInfo,
|
||||
outpoint: streamInfo.outpoint,
|
||||
},
|
||||
});
|
||||
|
||||
if (onSuccess) {
|
||||
onSuccess(streamInfo);
|
||||
}
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
dispatch({
|
||||
type: ACTIONS.LOADING_FILE_FAILED,
|
||||
data: { uri },
|
||||
});
|
||||
dispatch({
|
||||
type: ACTIONS.PURCHASE_URI_FAILED,
|
||||
data: { uri },
|
||||
});
|
||||
|
||||
dispatch({
|
||||
type: ACTIONS.FETCH_FILE_INFO_FAILED,
|
||||
data: { outpoint },
|
||||
});
|
||||
|
||||
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,
|
||||
})
|
||||
);
|
||||
|
@ -63,7 +76,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,
|
||||
|
@ -77,7 +95,7 @@ export function doPurchaseUri(uri: string, costInfo: { cost: number }, saveFile:
|
|||
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}` },
|
||||
|
@ -98,7 +116,7 @@ export function doPurchaseUri(uri: string, costInfo: { cost: number }, saveFile:
|
|||
return;
|
||||
}
|
||||
|
||||
dispatch(doFileGet(uri, saveFile));
|
||||
dispatch(doFileGet(uri, saveFile, onSuccess));
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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 });
|
||||
};
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
@ -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<Claim> = 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);
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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: '',
|
||||
};
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
});
|
||||
};
|
||||
|
@ -91,7 +98,7 @@ 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];
|
||||
|
@ -131,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',
|
||||
|
|
|
@ -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';
|
||||
|
@ -536,3 +537,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;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
// @flow
|
||||
import { createSelector } from 'reselect';
|
||||
import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
|
||||
|
||||
type State = { file: FileState };
|
||||
|
||||
|
@ -20,19 +21,16 @@ export const selectPurchasedUris: (state: State) => Array<string> = createSelect
|
|||
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) => {}) =>
|
||||
export const makeSelectStreamingUrlForUri = (uri: string) =>
|
||||
createSelector(
|
||||
selectPurchasedStreamingUrls,
|
||||
streamingUrls => streamingUrls && streamingUrls[uri]
|
||||
makeSelectFileInfoForUri(uri),
|
||||
fileInfo => {
|
||||
return fileInfo && fileInfo.streaming_url;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -3,9 +3,12 @@ import {
|
|||
selectIsFetchingClaimListMine,
|
||||
selectMyClaims,
|
||||
selectClaimsById,
|
||||
makeSelectContentTypeForUri,
|
||||
makeSelectClaimForUri,
|
||||
} from 'redux/selectors/claims';
|
||||
import { createSelector } from 'reselect';
|
||||
import { buildURI } from 'lbryURI';
|
||||
import Lbry from 'lbry';
|
||||
|
||||
export const selectState = state => state.fileInfo || {};
|
||||
|
||||
|
@ -53,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(
|
||||
|
@ -72,7 +85,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)
|
||||
);
|
||||
})
|
||||
);
|
||||
|
@ -238,3 +251,54 @@ export const selectDownloadedUris = createSelector(
|
|||
.reverse()
|
||||
.map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`)
|
||||
);
|
||||
|
||||
export const makeSelectMediaTypeForUri = uri =>
|
||||
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 =>
|
||||
createSelector(
|
||||
makeSelectMediaTypeForUri(uri),
|
||||
mediaType => {
|
||||
const isStreamable = ['audio', 'video', 'image'].indexOf(mediaType) !== -1;
|
||||
return isStreamable;
|
||||
}
|
||||
);
|
||||
|
||||
export const makeSelectDownloadPathForUri = uri =>
|
||||
createSelector(
|
||||
makeSelectFileInfoForUri(uri),
|
||||
fileInfo => {
|
||||
return fileInfo && fileInfo.download_path;
|
||||
}
|
||||
);
|
||||
|
||||
export const makeSelectFilePartlyDownloaded = uri =>
|
||||
createSelector(
|
||||
makeSelectFileInfoForUri(uri),
|
||||
fileInfo => {
|
||||
if (!fileInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return fileInfo.written_bytes > 0 || fileInfo.blobs_completed > 0;
|
||||
}
|
||||
);
|
||||
|
||||
export const makeSelectFileNameForUri = uri =>
|
||||
createSelector(
|
||||
makeSelectFileInfoForUri(uri),
|
||||
fileInfo => {
|
||||
return fileInfo && fileInfo.file_name;
|
||||
}
|
||||
);
|
||||
|
|
|
@ -90,6 +90,20 @@ export const selectSupportsByOutpoint = createSelector(
|
|||
state => state.supports || {}
|
||||
);
|
||||
|
||||
export const selectTotalSupports = createSelector(
|
||||
selectSupportsByOutpoint,
|
||||
byOutpoint => {
|
||||
let total = parseFloat("0.0");
|
||||
|
||||
Object.values(byOutpoint).forEach(support => {
|
||||
const { amount } = support;
|
||||
total = amount ? total + parseFloat(amount) : total;
|
||||
});
|
||||
|
||||
return total;
|
||||
}
|
||||
);
|
||||
|
||||
export const selectTransactionItems = createSelector(
|
||||
selectTransactionsById,
|
||||
byId => {
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in a new issue