fix merge conflict

This commit is contained in:
Akinwale Ariwodola 2019-08-16 15:54:01 +01:00
commit 3eaa27ef29
21 changed files with 625 additions and 465 deletions

738
dist/bundle.es.js vendored

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,6 @@ declare type FileListItem = {
declare type FileState = { declare type FileState = {
failedPurchaseUris: Array<string>, failedPurchaseUris: Array<string>,
purchasedUris: Array<string>, purchasedUris: Array<string>,
purchasedStreamingUrls: {},
}; };
declare type PurchaseUriCompleted = { declare type PurchaseUriCompleted = {
@ -53,7 +52,7 @@ declare type PurchaseUriFailed = {
type: ACTIONS.PURCHASE_URI_FAILED, type: ACTIONS.PURCHASE_URI_FAILED,
data: { data: {
uri: string, uri: string,
error: any error: any,
}, },
}; };
@ -68,6 +67,6 @@ declare type PurchaseUriStarted = {
declare type DeletePurchasedUri = { declare type DeletePurchasedUri = {
type: ACTIONS.DELETE_PURCHASED_URI, type: ACTIONS.DELETE_PURCHASED_URI,
data: { data: {
uri: string uri: string,
}, },
}; };

View file

@ -68,7 +68,7 @@ declare type ResolveResponse = {
[string]: Claim | { error?: {} }, [string]: Claim | { error?: {} },
}; };
declare type GetResponse = FileListItem; declare type GetResponse = FileListItem & { error?: string };
declare type GenericTxResponse = { declare type GenericTxResponse = {
height: number, height: number,

4
dist/flow-typed/mime.js vendored Normal file
View file

@ -0,0 +1,4 @@
// @flow
declare module 'mime' {
declare module.exports: any;
}

5
flow-typed/File.js vendored
View file

@ -38,7 +38,6 @@ declare type FileListItem = {
declare type FileState = { declare type FileState = {
failedPurchaseUris: Array<string>, failedPurchaseUris: Array<string>,
purchasedUris: Array<string>, purchasedUris: Array<string>,
purchasedStreamingUrls: {},
}; };
declare type PurchaseUriCompleted = { declare type PurchaseUriCompleted = {
@ -53,7 +52,7 @@ declare type PurchaseUriFailed = {
type: ACTIONS.PURCHASE_URI_FAILED, type: ACTIONS.PURCHASE_URI_FAILED,
data: { data: {
uri: string, uri: string,
error: any error: any,
}, },
}; };
@ -68,6 +67,6 @@ declare type PurchaseUriStarted = {
declare type DeletePurchasedUri = { declare type DeletePurchasedUri = {
type: ACTIONS.DELETE_PURCHASED_URI, type: ACTIONS.DELETE_PURCHASED_URI,
data: { data: {
uri: string uri: string,
}, },
}; };

2
flow-typed/Lbry.js vendored
View file

@ -68,7 +68,7 @@ declare type ResolveResponse = {
[string]: Claim | { error?: {} }, [string]: Claim | { error?: {} },
}; };
declare type GetResponse = FileListItem; declare type GetResponse = FileListItem & { error?: string };
declare type GenericTxResponse = { declare type GenericTxResponse = {
height: number, height: number,

4
flow-typed/mime.js vendored Normal file
View file

@ -0,0 +1,4 @@
// @flow
declare module 'mime' {
declare module.exports: any;
}

View file

@ -28,6 +28,7 @@
"format": "prettier 'src/**/*.{js,json}' --write" "format": "prettier 'src/**/*.{js,json}' --write"
}, },
"dependencies": { "dependencies": {
"mime": "^2.4.4",
"proxy-polyfill": "0.1.6", "proxy-polyfill": "0.1.6",
"reselect": "^3.0.0", "reselect": "^3.0.0",
"uuid": "^3.3.2" "uuid": "^3.3.2"

View file

@ -111,6 +111,7 @@ export const FILE_LIST_STARTED = 'FILE_LIST_STARTED';
export const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED'; export const FILE_LIST_SUCCEEDED = 'FILE_LIST_SUCCEEDED';
export const FETCH_FILE_INFO_STARTED = 'FETCH_FILE_INFO_STARTED'; 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_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_STARTED = 'LOADING_VIDEO_STARTED';
export const LOADING_VIDEO_COMPLETED = 'LOADING_VIDEO_COMPLETED'; export const LOADING_VIDEO_COMPLETED = 'LOADING_VIDEO_COMPLETED';
export const LOADING_VIDEO_FAILED = 'LOADING_VIDEO_FAILED'; 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_COMPLETED = 'PURCHASE_URI_COMPLETED';
export const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED'; export const PURCHASE_URI_FAILED = 'PURCHASE_URI_FAILED';
export const DELETE_PURCHASED_URI = 'DELETE_PURCHASED_URI'; 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 // Search
export const SEARCH_START = 'SEARCH_START'; export const SEARCH_START = 'SEARCH_START';

View file

@ -140,7 +140,6 @@ export { selectToast, selectError } from 'redux/selectors/notifications';
export { export {
selectFailedPurchaseUris, selectFailedPurchaseUris,
selectPurchasedUris, selectPurchasedUris,
selectPurchasedStreamingUrls,
selectPurchaseUriErrorMessage, selectPurchaseUriErrorMessage,
selectLastPurchasedUri, selectLastPurchasedUri,
makeSelectStreamingUrlForUri, makeSelectStreamingUrlForUri,
@ -173,6 +172,7 @@ export {
makeSelectPendingByUri, makeSelectPendingByUri,
makeSelectClaimsInChannelForCurrentPageState, makeSelectClaimsInChannelForCurrentPageState,
makeSelectShortUrlForUri, makeSelectShortUrlForUri,
makeSelectSupportsForUri,
selectPendingById, selectPendingById,
selectClaimsById, selectClaimsById,
selectClaimsByUri, selectClaimsByUri,
@ -218,6 +218,11 @@ export {
selectFileListDownloadedSort, selectFileListDownloadedSort,
selectFileListPublishedSort, selectFileListPublishedSort,
selectDownloadedUris, selectDownloadedUris,
makeSelectMediaTypeForUri,
makeSelectUriIsStreamable,
makeSelectDownloadPathForUri,
makeSelectFileNameForUri,
makeSelectFilePartlyDownloaded,
} from 'redux/selectors/file_info'; } from 'redux/selectors/file_info';
export { export {
@ -246,6 +251,7 @@ export {
selectTotalBalance, selectTotalBalance,
selectTransactionsById, selectTransactionsById,
selectSupportsByOutpoint, selectSupportsByOutpoint,
selectTotalSupports,
selectTransactionItems, selectTransactionItems,
selectRecentTransactions, selectRecentTransactions,
selectHasTransactions, selectHasTransactions,

View file

@ -1,5 +1,6 @@
// @flow // @flow
import 'proxy-polyfill'; import 'proxy-polyfill';
import mime from 'mime';
const CHECK_DAEMON_STARTED_TRY_NUMBER = 200; 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 // 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) => { getMediaType: (contentType?: string, fileName: ?string) => {
if (extname) { const formats = [
const formats = [ [/\.(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'],
[/^(mp4|m4v|webm|flv|f4v|ogv)$/i, 'video'], [/\.(mp3|m4a|aac|wav|flac|ogg|opus)$/i, 'audio'],
[/^(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'],
[/^(html|htm|xml|pdf|odf|doc|docx|md|markdown|txt|epub|org)$/i, 'document'], [/\.(json|csv|txt|log|md|markdown|docx|pdf|xml|yml|yaml)$/i, 'document'],
[/^(stl|obj|fbx|gcode)$/i, '3D-file'], [/\.(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 res = formats.reduce((ret, testpair) => {
switch (testpair[0].test(ret)) { const [regex, mediaType] = testpair;
case true:
return testpair[1]; return regex.test(ret) ? mediaType : ret;
default: }, testString);
return ret;
} if (res !== testString) return res;
}, extname);
return res === extname ? 'unknown' : res;
} else if (contentType) {
// $FlowFixMe
return /^[^/]+/.exec(contentType)[0];
} }
// Get mediaType from contentType
if (contentType) {
const matches = /^[^/]+/.exec(contentType);
if (matches) {
return matches[0];
}
}
return 'unknown'; return 'unknown';
}, },

View file

@ -5,57 +5,70 @@ import { doToast } from 'redux/actions/notifications';
import { selectBalance } from 'redux/selectors/wallet'; import { selectBalance } from 'redux/selectors/wallet';
import { makeSelectFileInfoForUri, selectDownloadingByOutpoint } from 'redux/selectors/file_info'; import { makeSelectFileInfoForUri, selectDownloadingByOutpoint } from 'redux/selectors/file_info';
import { makeSelectStreamingUrlForUri } from 'redux/selectors/file'; import { makeSelectStreamingUrlForUri } from 'redux/selectors/file';
import { makeSelectClaimForUri } from 'redux/selectors/claims';
type Dispatch = (action: any) => any; type Dispatch = (action: any) => any;
type GetState = () => { file: FileState }; 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) => { return (dispatch: Dispatch, getState: () => any) => {
const state = getState();
const { nout, txid } = makeSelectClaimForUri(uri)(state);
const outpoint = `${txid}:${nout}`;
dispatch({ dispatch({
type: ACTIONS.LOADING_FILE_STARTED, type: ACTIONS.FETCH_FILE_INFO_STARTED,
data: { data: {
uri, outpoint,
}, },
}); });
// set save_file argument to True to save the file (old behaviour) // set save_file argument to True to save the file (old behaviour)
Lbry.get({ uri, save_file: saveFile }) Lbry.get({ uri, save_file: saveFile })
.then((streamInfo: GetResponse) => { .then((streamInfo: GetResponse) => {
const timeout = streamInfo === null || typeof streamInfo !== 'object'; const timeout =
streamInfo === null || typeof streamInfo !== 'object' || streamInfo.error === 'Timeout';
if (timeout) { if (timeout) {
dispatch({ dispatch({
type: ACTIONS.LOADING_FILE_FAILED, type: ACTIONS.FETCH_FILE_INFO_FAILED,
data: { uri }, data: { outpoint },
});
dispatch({
type: ACTIONS.PURCHASE_URI_FAILED,
data: { uri },
}); });
dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true })); dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true }));
} else { } else {
// purchase was completed successfully // purchase was completed successfully
const { streaming_url: streamingUrl } = streamInfo;
dispatch({ dispatch({
type: ACTIONS.PURCHASE_URI_COMPLETED, 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(() => { .catch(() => {
dispatch({
type: ACTIONS.LOADING_FILE_FAILED,
data: { uri },
});
dispatch({ dispatch({
type: ACTIONS.PURCHASE_URI_FAILED, type: ACTIONS.PURCHASE_URI_FAILED,
data: { uri }, data: { uri },
}); });
dispatch({
type: ACTIONS.FETCH_FILE_INFO_FAILED,
data: { outpoint },
});
dispatch( dispatch(
doToast({ 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, 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) => { return (dispatch: Dispatch, getState: GetState) => {
dispatch({ dispatch({
type: ACTIONS.PURCHASE_URI_STARTED, 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 alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint];
const alreadyStreaming = makeSelectStreamingUrlForUri(uri)(state); const alreadyStreaming = makeSelectStreamingUrlForUri(uri)(state);
if (alreadyDownloading || alreadyStreaming) { if (!saveFile && (alreadyDownloading || alreadyStreaming)) {
dispatch({ dispatch({
type: ACTIONS.PURCHASE_URI_FAILED, type: ACTIONS.PURCHASE_URI_FAILED,
data: { uri, error: `Already fetching uri: ${uri}` }, data: { uri, error: `Already fetching uri: ${uri}` },
@ -98,7 +116,7 @@ export function doPurchaseUri(uri: string, costInfo: { cost: number }, saveFile:
return; return;
} }
dispatch(doFileGet(uri, saveFile)); dispatch(doFileGet(uri, saveFile, onSuccess));
}; };
} }

View file

@ -172,7 +172,7 @@ export const doUploadThumbnail = (
export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem, fs: any) => ( export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileListItem, fs: any) => (
dispatch: Dispatch dispatch: Dispatch
) => { ) => {
const { name, amount, value } = claim; const { name, amount, value = {} } = claim;
const channelName = const channelName =
(claim && claim.signing_channel && claim.signing_channel.normalized_name) || null; (claim && claim.signing_channel && claim.signing_channel.normalized_name) || null;
const { const {
@ -189,6 +189,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
license_url: licenseUrl, license_url: licenseUrl,
thumbnail, thumbnail,
title, title,
tags,
} = value; } = value;
const publishData: UpdatePublishFormData = { const publishData: UpdatePublishFormData = {
@ -205,6 +206,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
uploadThumbnailStatus: thumbnail ? THUMBNAIL_STATUSES.MANUAL : undefined, uploadThumbnailStatus: thumbnail ? THUMBNAIL_STATUSES.MANUAL : undefined,
licenseUrl, licenseUrl,
nsfw: isClaimNsfw(claim), nsfw: isClaimNsfw(claim),
tags: tags ? tags.map(tag => ({ name: tag })) : [],
}; };
// Make sure custom licenses are mapped properly // Make sure custom licenses are mapped properly
@ -226,15 +228,6 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
publishData['channel'] = channelName; 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 }); dispatch({ type: ACTIONS.DO_PREPARE_EDIT, data: publishData });
}; };

View file

@ -10,8 +10,8 @@ export function doUpdateBalance() {
const { const {
wallet: { balance: balanceInStore }, wallet: { balance: balanceInStore },
} = getState(); } = getState();
Lbry.account_balance().then(balanceAsString => { Lbry.account_balance().then(({ available }) => {
const balance = parseFloat(balanceAsString); const balance = parseFloat(available);
if (balanceInStore !== balance) { if (balanceInStore !== balance) {
dispatch({ dispatch({
type: ACTIONS.UPDATE_BALANCE, 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) => { return (dispatch, getState) => {
const state = getState(); const state = getState();
const balance = selectBalance(state); 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) { if (balance - amount <= 0) {
dispatch( dispatch(
@ -230,7 +230,7 @@ export function doSendTip(amount, claimId, successCallback, errorCallback) {
const success = () => { const success = () => {
dispatch( dispatch(
doToast({ doToast({
message: isSupport message: shouldSupport
? __(`You deposited ${amount} LBC as a support!`) ? __(`You deposited ${amount} LBC as a support!`)
: __(`You sent ${amount} LBC as a tip, Mahalo!`), : __(`You sent ${amount} LBC as a tip, Mahalo!`),
linkText: __('History'), linkText: __('History'),
@ -274,7 +274,7 @@ export function doSendTip(amount, claimId, successCallback, errorCallback) {
Lbry.support_create({ Lbry.support_create({
claim_id: claimId, claim_id: claimId,
amount: creditsToString(amount), amount: creditsToString(amount),
tip: isSupport ? false : true, tip: !shouldSupport,
}).then(success, error); }).then(success, error);
}; };
} }

View file

@ -5,7 +5,6 @@ const reducers = {};
const defaultState = { const defaultState = {
failedPurchaseUris: [], failedPurchaseUris: [],
purchasedUris: [], purchasedUris: [],
purchasedStreamingUrls: {},
purchaseUriErrorMessage: '', purchaseUriErrorMessage: '',
}; };
@ -30,10 +29,9 @@ reducers[ACTIONS.PURCHASE_URI_COMPLETED] = (
state: FileState, state: FileState,
action: PurchaseUriCompleted action: PurchaseUriCompleted
): FileState => { ): FileState => {
const { uri, streamingUrl } = action.data; const { uri } = action.data;
const newPurchasedUris = state.purchasedUris.slice(); const newPurchasedUris = state.purchasedUris.slice();
const newFailedPurchaseUris = state.failedPurchaseUris.slice(); const newFailedPurchaseUris = state.failedPurchaseUris.slice();
const newPurchasedStreamingUrls = Object.assign({}, state.purchasedStreamingUrls);
if (!newPurchasedUris.includes(uri)) { if (!newPurchasedUris.includes(uri)) {
newPurchasedUris.push(uri); newPurchasedUris.push(uri);
@ -41,15 +39,11 @@ reducers[ACTIONS.PURCHASE_URI_COMPLETED] = (
if (newFailedPurchaseUris.includes(uri)) { if (newFailedPurchaseUris.includes(uri)) {
newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1); newFailedPurchaseUris.splice(newFailedPurchaseUris.indexOf(uri), 1);
} }
if (streamingUrl) {
newPurchasedStreamingUrls[uri] = streamingUrl;
}
return { return {
...state, ...state,
failedPurchaseUris: newFailedPurchaseUris, failedPurchaseUris: newFailedPurchaseUris,
purchasedUris: newPurchasedUris, purchasedUris: newPurchasedUris,
purchasedStreamingUrls: newPurchasedStreamingUrls,
purchaseUriErrorMessage: '', purchaseUriErrorMessage: '',
}; };
}; };

View file

@ -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) => { reducers[ACTIONS.DOWNLOADING_STARTED] = (state, action) => {
const { uri, outpoint, fileInfo } = action.data; const { uri, outpoint, fileInfo } = action.data;
const newByOutpoint = Object.assign({}, state.byOutpoint); const newByOutpoint = Object.assign({}, state.byOutpoint);
const newDownloading = Object.assign({}, state.downloadingByOutpoint); const newDownloading = Object.assign({}, state.downloadingByOutpoint);
const newLoading = Object.assign({}, state.urisLoading);
newDownloading[outpoint] = true; newDownloading[outpoint] = true;
newByOutpoint[outpoint] = fileInfo; newByOutpoint[outpoint] = fileInfo;
delete newLoading[uri];
return Object.assign({}, state, { return Object.assign({}, state, {
downloadingByOutpoint: newDownloading, downloadingByOutpoint: newDownloading,
urisLoading: newLoading,
byOutpoint: newByOutpoint, byOutpoint: newByOutpoint,
}); });
}; };
@ -91,7 +98,7 @@ reducers[ACTIONS.DOWNLOADING_PROGRESSED] = (state, action) => {
}; };
reducers[ACTIONS.DOWNLOADING_CANCELED] = (state, action) => { reducers[ACTIONS.DOWNLOADING_CANCELED] = (state, action) => {
const { outpoint } = action.data; const { uri, outpoint } = action.data;
const newDownloading = Object.assign({}, state.downloadingByOutpoint); const newDownloading = Object.assign({}, state.downloadingByOutpoint);
delete newDownloading[outpoint]; 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) => { reducers[ACTIONS.SET_FILE_LIST_SORT] = (state, action) => {
const pageSortStates = { const pageSortStates = {
[PAGES.PUBLISHED]: 'fileListPublishedSort', [PAGES.PUBLISHED]: 'fileListPublishedSort',

View file

@ -1,6 +1,7 @@
// @flow // @flow
import { normalizeURI, buildURI, parseURI } from 'lbryURI'; import { normalizeURI, buildURI, parseURI } from 'lbryURI';
import { selectSearchUrisByQuery } from 'redux/selectors/search'; import { selectSearchUrisByQuery } from 'redux/selectors/search';
import { selectSupportsByOutpoint } from 'redux/selectors/wallet';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim'; import { isClaimNsfw, createNormalizedClaimSearchKey } from 'util/claim';
import { getSearchQueryString } from 'util/query-params'; import { getSearchQueryString } from 'util/query-params';
@ -536,3 +537,24 @@ export const makeSelectShortUrlForUri = (uri: string) =>
makeSelectClaimForUri(uri), makeSelectClaimForUri(uri),
claim => claim && claim.short_url 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;
}
);

View file

@ -1,5 +1,6 @@
// @flow // @flow
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { makeSelectFileInfoForUri } from 'redux/selectors/file_info';
type State = { file: FileState }; type State = { file: FileState };
@ -20,19 +21,16 @@ export const selectPurchasedUris: (state: State) => Array<string> = createSelect
state => state.purchasedUris state => state.purchasedUris
); );
export const selectPurchasedStreamingUrls: (state: State) => {} = createSelector(
selectState,
state => state.purchasedStreamingUrls
);
export const selectLastPurchasedUri: (state: State) => string = createSelector( export const selectLastPurchasedUri: (state: State) => string = createSelector(
selectState, selectState,
state => state =>
state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null state.purchasedUris.length > 0 ? state.purchasedUris[state.purchasedUris.length - 1] : null
); );
export const makeSelectStreamingUrlForUri = (uri: string): ((state: State) => {}) => export const makeSelectStreamingUrlForUri = (uri: string) =>
createSelector( createSelector(
selectPurchasedStreamingUrls, makeSelectFileInfoForUri(uri),
streamingUrls => streamingUrls && streamingUrls[uri] fileInfo => {
return fileInfo && fileInfo.streaming_url;
}
); );

View file

@ -3,9 +3,12 @@ import {
selectIsFetchingClaimListMine, selectIsFetchingClaimListMine,
selectMyClaims, selectMyClaims,
selectClaimsById, selectClaimsById,
makeSelectContentTypeForUri,
makeSelectClaimForUri,
} from 'redux/selectors/claims'; } from 'redux/selectors/claims';
import { createSelector } from 'reselect'; import { createSelector } from 'reselect';
import { buildURI } from 'lbryURI'; import { buildURI } from 'lbryURI';
import Lbry from 'lbry';
export const selectState = state => state.fileInfo || {}; export const selectState = state => state.fileInfo || {};
@ -53,13 +56,23 @@ export const makeSelectDownloadingForUri = uri =>
export const selectUrisLoading = createSelector( export const selectUrisLoading = createSelector(
selectState, selectState,
state => state.urisLoading || {} state => state.fetching || {}
); );
export const makeSelectLoadingForUri = uri => export const makeSelectLoadingForUri = uri =>
createSelector( createSelector(
selectUrisLoading, 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( export const selectFileInfosDownloaded = createSelector(
@ -72,7 +85,7 @@ export const selectFileInfosDownloaded = createSelector(
return ( return (
fileInfo && fileInfo &&
myClaimIds.indexOf(fileInfo.claim_id) === -1 && 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() .reverse()
.map(claim => `lbry://${claim.claim_name}#${claim.claim_id}`) .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;
}
);

View file

@ -90,6 +90,20 @@ export const selectSupportsByOutpoint = createSelector(
state => state.supports || {} 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( export const selectTransactionItems = createSelector(
selectTransactionsById, selectTransactionsById,
byId => { byId => {

View file

@ -3523,6 +3523,11 @@ mime-types@^2.1.12, mime-types@~2.1.17:
dependencies: dependencies:
mime-db "~1.33.0" 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: mimic-fn@^1.0.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"