move file actions from lbry-redux

This commit is contained in:
zeppi 2021-10-05 16:57:47 -04:00 committed by jessopb
parent 4bc4a965d9
commit b44be39252
7 changed files with 231 additions and 15 deletions

78
flow-typed/File.js vendored Normal file
View file

@ -0,0 +1,78 @@
// @flow
declare type FileListItem = {
metadata: StreamMetadata,
added_on: number,
blobs_completed: number,
blobs_in_stream: number,
blobs_remaining: number,
channel_claim_id: string,
channel_name: string,
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,
key: string,
mime_type: string,
nout: number,
outpoint: string,
points_paid: number,
protobuf: string,
reflector_progress: number,
sd_hash: string,
status: string,
stopped: false,
stream_hash: string,
stream_name: string,
streaming_url: string,
suggested_file_name: string,
total_bytes: number,
total_bytes_lower_bound: number,
is_fully_reflected: boolean,
// TODO: sdk plans to change `tx`
// It isn't currently used by the apps
tx: {},
txid: string,
uploading_to_reflector: boolean,
written_bytes: number,
};
declare type FileState = {
failedPurchaseUris: Array<string>,
purchasedUris: Array<string>,
};
declare type PurchaseUriCompleted = {
type: ACTIONS.PURCHASE_URI_COMPLETED,
data: {
uri: string,
streamingUrl: string,
},
};
declare type PurchaseUriFailed = {
type: ACTIONS.PURCHASE_URI_FAILED,
data: {
uri: string,
error: any,
},
};
declare type PurchaseUriStarted = {
type: ACTIONS.PURCHASE_URI_STARTED,
data: {
uri: string,
streamingUrl: string,
},
};
declare type DeletePurchasedUri = {
type: ACTIONS.CLEAR_PURCHASED_URI_SUCCESS,
data: {
uri: string,
},
};

View file

@ -6,7 +6,6 @@ import {
makeSelectClaimIsMine, makeSelectClaimIsMine,
makeSelectClaimIsPending, makeSelectClaimIsPending,
makeSelectClaimIsNsfw, makeSelectClaimIsNsfw,
doFileGet,
makeSelectReflectingClaimForUri, makeSelectReflectingClaimForUri,
makeSelectClaimWasPurchased, makeSelectClaimWasPurchased,
makeSelectStreamingUrlForUri, makeSelectStreamingUrlForUri,
@ -25,7 +24,7 @@ import { selectShowMatureContent } from 'redux/selectors/settings';
import { makeSelectHasVisitedUri } from 'redux/selectors/content'; import { makeSelectHasVisitedUri } from 'redux/selectors/content';
import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions'; import { makeSelectIsSubscribed } from 'redux/selectors/subscriptions';
import { selectModerationBlockList } from 'redux/selectors/comments'; import { selectModerationBlockList } from 'redux/selectors/comments';
import { doFileGet } from 'redux/actions/file';
import ClaimPreview from './view'; import ClaimPreview from './view';
import formatMediaDuration from 'util/formatMediaDuration'; import formatMediaDuration from 'util/formatMediaDuration';

View file

@ -5,7 +5,6 @@ import {
makeSelectIsUriResolving, makeSelectIsUriResolving,
makeSelectThumbnailForUri, makeSelectThumbnailForUri,
makeSelectTitleForUri, makeSelectTitleForUri,
doFileGet,
makeSelectChannelForClaimUri, makeSelectChannelForClaimUri,
makeSelectClaimIsNsfw, makeSelectClaimIsNsfw,
makeSelectClaimIsStreamPlaceholder, makeSelectClaimIsStreamPlaceholder,
@ -14,6 +13,7 @@ import {
import { selectMutedChannels } from 'redux/selectors/blocked'; import { selectMutedChannels } from 'redux/selectors/blocked';
import { makeSelectViewCountForUri, selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc'; import { makeSelectViewCountForUri, selectBlackListedOutpoints, selectFilteredOutpoints } from 'lbryinc';
import { makeSelectIsActiveLivestream } from 'redux/selectors/livestream'; import { makeSelectIsActiveLivestream } from 'redux/selectors/livestream';
import { doFileGet } from 'redux/actions/file';
import { selectShowMatureContent } from 'redux/selectors/settings'; import { selectShowMatureContent } from 'redux/selectors/settings';
import ClaimPreviewTile from './view'; import ClaimPreviewTile from './view';
import formatMediaDuration from 'util/formatMediaDuration'; import formatMediaDuration from 'util/formatMediaDuration';

View file

@ -1,10 +1,12 @@
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { selectSubscriptions } from 'redux/selectors/subscriptions'; import { selectSubscriptions } from 'redux/selectors/subscriptions';
import { selectPurchaseUriSuccess, doClearPurchasedUriSuccess } from 'lbry-redux'; import { selectPurchaseUriSuccess } from 'lbry-redux';
import { selectFollowedTags } from 'redux/selectors/tags'; import { selectFollowedTags } from 'redux/selectors/tags';
import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user'; import { selectUserVerifiedEmail, selectUser } from 'redux/selectors/user';
import { selectHomepageData, selectLanguage } from 'redux/selectors/settings'; import { selectHomepageData, selectLanguage } from 'redux/selectors/settings';
import { doSignOut } from 'redux/actions/app'; import { doSignOut } from 'redux/actions/app';
import { doClearPurchasedUriSuccess } from 'redux/actions/file';
import { selectUnseenNotificationCount } from 'redux/selectors/notifications'; import { selectUnseenNotificationCount } from 'redux/selectors/notifications';
import SideNavigation from './view'; import SideNavigation from './view';

View file

@ -120,6 +120,13 @@ export const PLAY_VIDEO_STARTED = 'PLAY_VIDEO_STARTED';
export const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED'; export const FETCH_AVAILABILITY_STARTED = 'FETCH_AVAILABILITY_STARTED';
export const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED'; export const FETCH_AVAILABILITY_COMPLETED = 'FETCH_AVAILABILITY_COMPLETED';
export const FILE_DELETE = 'FILE_DELETE'; export const FILE_DELETE = 'FILE_DELETE';
export const FETCH_FILE_INFO_FAILED = 'FETCH_FILE_INFO_FAILED';
export const DOWNLOADING_CANCELED = 'DOWNLOADING_CANCELED';
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 CLEAR_PURCHASED_URI_SUCCESS = 'CLEAR_PURCHASED_URI_SUCCESS';
// Search // Search
export const SEARCH_START = 'SEARCH_START'; export const SEARCH_START = 'SEARCH_START';

View file

@ -10,7 +10,6 @@ import {
SETTINGS, SETTINGS,
makeSelectFileInfoForUri, makeSelectFileInfoForUri,
selectFileInfosByOutpoint, selectFileInfosByOutpoint,
doPurchaseUri,
makeSelectUriIsStreamable, makeSelectUriIsStreamable,
selectDownloadingByOutpoint, selectDownloadingByOutpoint,
makeSelectClaimForUri, makeSelectClaimForUri,
@ -19,6 +18,7 @@ import {
doToast, doToast,
makeSelectUrlsForCollectionId, makeSelectUrlsForCollectionId,
} from 'lbry-redux'; } from 'lbry-redux';
import { doPurchaseUri } from 'redux/actions/file';
import { makeSelectCostInfoForUri, Lbryio } from 'lbryinc'; import { makeSelectCostInfoForUri, Lbryio } from 'lbryinc';
import { makeSelectClientSetting, selectosNotificationsEnabled, selectDaemonSettings } from 'redux/selectors/settings'; import { makeSelectClientSetting, selectosNotificationsEnabled, selectDaemonSettings } from 'redux/selectors/settings';
@ -117,8 +117,8 @@ export function doSetPlayingUri({
uri: ?string, uri: ?string,
source?: string, source?: string,
commentId?: string, commentId?: string,
pathname: string, pathname?: string,
collectionId: string, collectionId?: string,
}) { }) {
return (dispatch: Dispatch) => { return (dispatch: Dispatch) => {
dispatch({ dispatch({
@ -140,7 +140,7 @@ export function doPurchaseUriWrapper(uri: string, cost: number, saveFile: boolea
} }
} }
dispatch(doPurchaseUri(uri, { costInfo: cost }, saveFile, onSuccess)); dispatch(doPurchaseUri(uri, { cost }, saveFile, onSuccess));
}; };
} }

View file

@ -1,3 +1,4 @@
// @flow
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
// @if TARGET='app' // @if TARGET='app'
import { shell } from 'electron'; import { shell } from 'electron';
@ -7,22 +8,28 @@ import {
batchActions, batchActions,
doAbandonClaim, doAbandonClaim,
makeSelectFileInfoForUri, makeSelectFileInfoForUri,
selectDownloadingByOutpoint,
makeSelectStreamingUrlForUri,
makeSelectClaimForUri, makeSelectClaimForUri,
selectBalance,
ABANDON_STATES, ABANDON_STATES,
} from 'lbry-redux'; } from 'lbry-redux';
import { doHideModal } from 'redux/actions/app'; import { doHideModal } from 'redux/actions/app';
import { goBack } from 'connected-react-router'; import { goBack } from 'connected-react-router';
import { doSetPlayingUri } from 'redux/actions/content'; import { doSetPlayingUri } from 'redux/actions/content';
import { selectPlayingUri } from 'redux/selectors/content'; import { selectPlayingUri } from 'redux/selectors/content';
import { doToast } from 'redux/actions/notifications';
type Dispatch = (action: any) => any;
type GetState = () => { file: FileState };
export function doOpenFileInFolder(path) { export function doOpenFileInFolder(path: string) {
return () => { return () => {
shell.showItemInFolder(path); shell.showItemInFolder(path);
}; };
} }
export function doOpenFileInShell(path) { export function doOpenFileInShell(path: string) {
return (dispatch) => { return (dispatch: Dispatch) => {
const success = shell.openPath(path); const success = shell.openPath(path);
if (!success) { if (!success) {
dispatch(doOpenFileInFolder(path)); dispatch(doOpenFileInFolder(path));
@ -30,8 +37,8 @@ export function doOpenFileInShell(path) {
}; };
} }
export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim, cb) { export function doDeleteFile(outpoint: string, deleteFromComputer?: boolean, abandonClaim?: boolean, cb: any) {
return (dispatch) => { return (dispatch: Dispatch) => {
if (abandonClaim) { if (abandonClaim) {
const [txid, nout] = outpoint.split(':'); const [txid, nout] = outpoint.split(':');
dispatch(doAbandonClaim(txid, Number(nout), cb)); dispatch(doAbandonClaim(txid, Number(nout), cb));
@ -53,8 +60,13 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim, cb) {
}; };
} }
export function doDeleteFileAndMaybeGoBack(uri, deleteFromComputer, abandonClaim, doGoBack) { export function doDeleteFileAndMaybeGoBack(
return (dispatch, getState) => { uri: string,
deleteFromComputer?: boolean,
abandonClaim?: boolean,
doGoBack: (any) => void
) {
return (dispatch: Dispatch, getState: GetState) => {
const state = getState(); const state = getState();
const playingUri = selectPlayingUri(state); const playingUri = selectPlayingUri(state);
const { outpoint } = makeSelectFileInfoForUri(uri)(state) || ''; const { outpoint } = makeSelectFileInfoForUri(uri)(state) || '';
@ -88,3 +100,121 @@ export function doDeleteFileAndMaybeGoBack(uri, deleteFromComputer, abandonClaim
dispatch(batchActions(...actions)); dispatch(batchActions(...actions));
}; };
} }
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.FETCH_FILE_INFO_STARTED,
data: {
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' || streamInfo.error === 'Timeout';
if (timeout) {
dispatch({
type: ACTIONS.FETCH_FILE_INFO_FAILED,
data: { outpoint },
});
dispatch(doToast({ message: `File timeout for uri ${uri}`, isError: true }));
} else {
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: outpoint,
},
});
if (onSuccess) {
onSuccess(streamInfo);
}
}
})
.catch((error) => {
dispatch({
type: ACTIONS.PURCHASE_URI_FAILED,
data: { uri, error },
});
dispatch({
type: ACTIONS.FETCH_FILE_INFO_FAILED,
data: { outpoint },
});
dispatch(
doToast({
message: `Failed to view ${uri}, please try again. If this problem persists, visit https://lbry.com/faq/support for support.`,
isError: 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,
data: { uri },
});
const state = getState();
const balance = selectBalance(state);
const fileInfo = makeSelectFileInfoForUri(uri)(state);
const downloadingByOutpoint = selectDownloadingByOutpoint(state);
const alreadyDownloading = fileInfo && !!downloadingByOutpoint[fileInfo.outpoint];
const alreadyStreaming = makeSelectStreamingUrlForUri(uri)(state);
if (!saveFile && (alreadyDownloading || alreadyStreaming)) {
dispatch({
type: ACTIONS.PURCHASE_URI_FAILED,
data: { uri, error: `Already fetching uri: ${uri}` },
});
if (onSuccess) {
onSuccess(fileInfo);
}
return;
}
const { cost } = costInfo;
if (parseFloat(cost) > balance) {
dispatch({
type: ACTIONS.PURCHASE_URI_FAILED,
data: { uri, error: 'Insufficient credits' },
});
Promise.resolve();
return;
}
dispatch(doFileGet(uri, saveFile, onSuccess));
};
}
export function doClearPurchasedUriSuccess() {
return {
type: ACTIONS.CLEAR_PURCHASED_URI_SUCCESS,
};
}