File info fix #735
8 changed files with 166 additions and 112 deletions
|
@ -13,6 +13,7 @@ Web UI version numbers should always match the corresponding version of LBRY App
|
|||
|
||||
### Changed
|
||||
* Moved all redux code into /redux folder
|
||||
* Lots of changes in selectors, reducers and actions for deprecating `outpoints` and using `sd_hash` in `file_list` API call(#693$)
|
||||
*
|
||||
|
||||
### Fixed
|
||||
|
@ -24,7 +25,7 @@ Web UI version numbers should always match the corresponding version of LBRY App
|
|||
*
|
||||
|
||||
### Deprecated
|
||||
*
|
||||
* Use of `outpoints` in `file_list` API call. `sd_hash` has to be used instead.(#693)
|
||||
*
|
||||
|
||||
### Removed
|
||||
|
|
|
@ -250,8 +250,14 @@ lbry.getAppVersionInfo = function() {
|
|||
*/
|
||||
lbry.file_list = function(params = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const { name, channel_name, outpoint } = params;
|
||||
const { name, channel_name, outpoint, sd_hash } = params;
|
||||
|
||||
/**
|
||||
* sd_hash is now used as a param to the API call
|
||||
* see https://github.com/lbryio/lbry-app/issues/693 for reference
|
||||
* rest all of the functionality remains the same and it is still based on outpoints
|
||||
*/
|
||||
const newParams = { sd_hash, full_status: params.full_status };
|
||||
/**
|
||||
* If we're searching by outpoint, check first to see if there's a matching pending publish.
|
||||
* Pending publishes use their own faux outpoints that are always unique, so we don't need
|
||||
|
@ -267,7 +273,7 @@ lbry.file_list = function(params = {}) {
|
|||
|
||||
apiCall(
|
||||
"file_list",
|
||||
params,
|
||||
newParams,
|
||||
fileInfos => {
|
||||
removePendingPublishIfNeeded({ name, channel_name, outpoint });
|
||||
|
||||
|
|
|
@ -13,10 +13,14 @@ class FileListDownloaded extends React.PureComponent {
|
|||
|
||||
render() {
|
||||
const { fileInfos, isFetching, navigate } = this.props;
|
||||
|
||||
const filteredFileInfos = fileInfos.filter(
|
||||
fileInfo => fileInfo.outpoint !== null
|
||||
);
|
||||
let content;
|
||||
if (fileInfos && fileInfos.length > 0) {
|
||||
content = <FileList fileInfos={fileInfos} fetching={isFetching} />;
|
||||
if (filteredFileInfos && filteredFileInfos.length > 0) {
|
||||
content = (
|
||||
<FileList fileInfos={filteredFileInfos} fetching={isFetching} />
|
||||
);
|
||||
} else {
|
||||
if (isFetching) {
|
||||
content = <BusyMessage message={__("Loading")} />;
|
||||
|
|
|
@ -7,7 +7,7 @@ import { makeSelectClientSetting } from "redux/selectors/settings";
|
|||
import { selectBalance, selectTransactionItems } from "redux/selectors/wallet";
|
||||
import {
|
||||
makeSelectFileInfoForUri,
|
||||
selectDownloadingByOutpoint,
|
||||
selectDownloadingBySdHash,
|
||||
} from "redux/selectors/file_info";
|
||||
import { selectResolvingUris } from "redux/selectors/content";
|
||||
import { makeSelectCostInfoForUri } from "redux/selectors/cost_info";
|
||||
|
@ -138,12 +138,13 @@ export function doFetchRewardedContent() {
|
|||
};
|
||||
}
|
||||
|
||||
export function doUpdateLoadStatus(uri, outpoint) {
|
||||
export function doUpdateLoadStatus(uri, outpoint, sd_hash) {
|
||||
return function(dispatch, getState) {
|
||||
const state = getState();
|
||||
|
||||
lbry
|
||||
.file_list({
|
||||
sd_hash: sd_hash,
|
||||
outpoint: outpoint,
|
||||
full_status: true,
|
||||
})
|
||||
|
@ -151,7 +152,7 @@ export function doUpdateLoadStatus(uri, outpoint) {
|
|||
if (!fileInfo || fileInfo.written_bytes == 0) {
|
||||
// download hasn't started yet
|
||||
setTimeout(() => {
|
||||
dispatch(doUpdateLoadStatus(uri, outpoint));
|
||||
dispatch(doUpdateLoadStatus(uri, outpoint, sd_hash));
|
||||
}, DOWNLOAD_POLL_INTERVAL);
|
||||
} else if (fileInfo.completed) {
|
||||
// TODO this isn't going to get called if they reload the client before
|
||||
|
@ -160,8 +161,8 @@ export function doUpdateLoadStatus(uri, outpoint) {
|
|||
type: types.DOWNLOADING_COMPLETED,
|
||||
data: {
|
||||
uri,
|
||||
outpoint,
|
||||
fileInfo,
|
||||
sd_hash,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -187,9 +188,9 @@ export function doUpdateLoadStatus(uri, outpoint) {
|
|||
type: types.DOWNLOADING_PROGRESSED,
|
||||
data: {
|
||||
uri,
|
||||
outpoint,
|
||||
fileInfo,
|
||||
progress,
|
||||
sd_hash,
|
||||
},
|
||||
});
|
||||
|
||||
|
@ -197,14 +198,14 @@ export function doUpdateLoadStatus(uri, outpoint) {
|
|||
setProgressBar(totalProgress);
|
||||
|
||||
setTimeout(() => {
|
||||
dispatch(doUpdateLoadStatus(uri, outpoint));
|
||||
dispatch(doUpdateLoadStatus(uri, outpoint, sd_hash));
|
||||
}, DOWNLOAD_POLL_INTERVAL);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export function doStartDownload(uri, outpoint) {
|
||||
export function doStartDownload(uri, outpoint, sd_hash) {
|
||||
return function(dispatch, getState) {
|
||||
const state = getState();
|
||||
|
||||
|
@ -212,21 +213,23 @@ export function doStartDownload(uri, outpoint) {
|
|||
throw new Error("outpoint is required to begin a download");
|
||||
}
|
||||
|
||||
const { downloadingByOutpoint = {} } = state.fileInfo;
|
||||
const { downloadingBySdHash = {} } = state.fileInfo;
|
||||
|
||||
if (downloadingByOutpoint[outpoint]) return;
|
||||
if (downloadingBySdHash[sd_hash]) return;
|
||||
|
||||
lbry.file_list({ outpoint, full_status: true }).then(([fileInfo]) => {
|
||||
lbry
|
||||
.file_list({ sd_hash, outpoint, full_status: true })
|
||||
.then(([fileInfo]) => {
|
||||
dispatch({
|
||||
type: types.DOWNLOADING_STARTED,
|
||||
data: {
|
||||
uri,
|
||||
outpoint,
|
||||
fileInfo,
|
||||
sd_hash,
|
||||
},
|
||||
});
|
||||
|
||||
dispatch(doUpdateLoadStatus(uri, outpoint));
|
||||
dispatch(doUpdateLoadStatus(uri, outpoint, sd_hash));
|
||||
});
|
||||
};
|
||||
}
|
||||
|
@ -235,7 +238,7 @@ export function doDownloadFile(uri, streamInfo) {
|
|||
return function(dispatch, getState) {
|
||||
const state = getState();
|
||||
|
||||
dispatch(doStartDownload(uri, streamInfo.outpoint));
|
||||
dispatch(doStartDownload(uri, streamInfo.outpoint, streamInfo.sd_hash));
|
||||
|
||||
lbryio
|
||||
.call("file", "view", {
|
||||
|
@ -296,9 +299,9 @@ export function doPurchaseUri(uri) {
|
|||
const state = getState();
|
||||
const balance = selectBalance(state);
|
||||
const fileInfo = makeSelectFileInfoForUri(uri)(state);
|
||||
const downloadingByOutpoint = selectDownloadingByOutpoint(state);
|
||||
const downloadingBySdHash = selectDownloadingBySdHash(state);
|
||||
const alreadyDownloading =
|
||||
fileInfo && !!downloadingByOutpoint[fileInfo.outpoint];
|
||||
fileInfo && !!downloadingBySdHash[fileInfo.sd_hash];
|
||||
|
||||
function attemptPlay(cost, instantPurchaseMax = null) {
|
||||
if (cost > 0 && (!instantPurchaseMax || cost > instantPurchaseMax)) {
|
||||
|
|
|
@ -8,9 +8,10 @@ import {
|
|||
} from "redux/selectors/claims";
|
||||
import {
|
||||
selectIsFetchingFileList,
|
||||
selectFileInfosByOutpoint,
|
||||
selectUrisLoading,
|
||||
selectFileInfosBySdHash,
|
||||
selectFetchingSdHash,
|
||||
selectTotalDownloadProgress,
|
||||
selectSdHashesByOutpoint,
|
||||
} from "redux/selectors/file_info";
|
||||
import { doCloseModal } from "redux/actions/app";
|
||||
import { doNavigate, doHistoryBack } from "redux/actions/navigation";
|
||||
|
@ -23,24 +24,24 @@ export function doFetchFileInfo(uri) {
|
|||
return function(dispatch, getState) {
|
||||
const state = getState();
|
||||
const claim = selectClaimsByUri(state)[uri];
|
||||
const outpoint = claim ? `${claim.txid}:${claim.nout}` : null;
|
||||
const alreadyFetching = !!selectUrisLoading(state)[uri];
|
||||
const sd_hash = claim.value.stream.source.source;
|
||||
const alreadyFetching = !!selectFetchingSdHash(state)[sd_hash];
|
||||
|
||||
if (!alreadyFetching) {
|
||||
dispatch({
|
||||
type: types.FETCH_FILE_INFO_STARTED,
|
||||
data: {
|
||||
outpoint,
|
||||
sd_hash,
|
||||
},
|
||||
});
|
||||
|
||||
lbry
|
||||
.file_list({ outpoint: outpoint, full_status: true })
|
||||
.file_list({ sd_hash: sd_hash, full_status: true })
|
||||
.then(fileInfos => {
|
||||
dispatch({
|
||||
type: types.FETCH_FILE_INFO_COMPLETED,
|
||||
data: {
|
||||
outpoint,
|
||||
sd_hash,
|
||||
fileInfo: fileInfos && fileInfos.length ? fileInfos[0] : null,
|
||||
},
|
||||
});
|
||||
|
@ -89,6 +90,7 @@ export function doOpenFileInFolder(path) {
|
|||
export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) {
|
||||
return function(dispatch, getState) {
|
||||
const state = getState();
|
||||
const sdHash = selectSdHashesByOutpoint(state)[outpoint];
|
||||
|
||||
lbry.file_delete({
|
||||
outpoint: outpoint,
|
||||
|
@ -98,8 +100,8 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) {
|
|||
// If the file is for a claim we published then also abandom the claim
|
||||
const myClaimsOutpoints = selectMyClaimsOutpoints(state);
|
||||
if (abandonClaim && myClaimsOutpoints.indexOf(outpoint) !== -1) {
|
||||
const byOutpoint = selectFileInfosByOutpoint(state);
|
||||
const fileInfo = byOutpoint[outpoint];
|
||||
const bySdHash = selectFileInfosBySdHash(state);
|
||||
const fileInfo = bySdHash[sd_hash];
|
||||
|
||||
if (fileInfo) {
|
||||
txid = fileInfo.outpoint.slice(0, -2);
|
||||
|
@ -112,7 +114,7 @@ export function doDeleteFile(outpoint, deleteFromComputer, abandonClaim) {
|
|||
dispatch({
|
||||
type: types.FILE_DELETE,
|
||||
data: {
|
||||
outpoint,
|
||||
sdHash,
|
||||
},
|
||||
});
|
||||
|
||||
|
|
|
@ -12,27 +12,27 @@ reducers[types.FILE_LIST_STARTED] = function(state, action) {
|
|||
|
||||
reducers[types.FILE_LIST_SUCCEEDED] = function(state, action) {
|
||||
const { fileInfos } = action.data;
|
||||
const newByOutpoint = Object.assign({}, state.byOutpoint);
|
||||
const pendingByOutpoint = Object.assign({}, state.pendingByOutpoint);
|
||||
const newBySdHash = Object.assign({}, state.bySdHash);
|
||||
const pendingBySdHash = Object.assign({}, state.pendingBySdHash);
|
||||
|
||||
fileInfos.forEach(fileInfo => {
|
||||
const { outpoint } = fileInfo;
|
||||
const { sd_hash } = fileInfo;
|
||||
|
||||
if (outpoint) newByOutpoint[fileInfo.outpoint] = fileInfo;
|
||||
if (sd_hash) newBySdHash[fileInfo.sd_hash] = fileInfo;
|
||||
});
|
||||
|
||||
return Object.assign({}, state, {
|
||||
isFetchingFileList: false,
|
||||
byOutpoint: newByOutpoint,
|
||||
pendingByOutpoint,
|
||||
bySdHash: newBySdHash,
|
||||
pendingBySdHash,
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.FETCH_FILE_INFO_STARTED] = function(state, action) {
|
||||
const { outpoint } = action.data;
|
||||
const { sd_hash } = action.data;
|
||||
const newFetching = Object.assign({}, state.fetching);
|
||||
|
||||
newFetching[outpoint] = true;
|
||||
newFetching[sd_hash] = true;
|
||||
|
||||
return Object.assign({}, state, {
|
||||
fetching: newFetching,
|
||||
|
@ -40,80 +40,80 @@ reducers[types.FETCH_FILE_INFO_STARTED] = function(state, action) {
|
|||
};
|
||||
|
||||
reducers[types.FETCH_FILE_INFO_COMPLETED] = function(state, action) {
|
||||
const { fileInfo, outpoint } = action.data;
|
||||
const { fileInfo, sd_hash } = action.data;
|
||||
|
||||
const newByOutpoint = Object.assign({}, state.byOutpoint);
|
||||
const newBySdHash = Object.assign({}, state.bySdHash);
|
||||
const newFetching = Object.assign({}, state.fetching);
|
||||
|
||||
newByOutpoint[outpoint] = fileInfo;
|
||||
delete newFetching[outpoint];
|
||||
newBySdHash[sd_hash] = fileInfo;
|
||||
delete newFetching[sd_hash];
|
||||
|
||||
return Object.assign({}, state, {
|
||||
byOutpoint: newByOutpoint,
|
||||
bySdHash: newBySdHash,
|
||||
fetching: newFetching,
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.DOWNLOADING_STARTED] = function(state, action) {
|
||||
const { uri, outpoint, fileInfo } = action.data;
|
||||
const { uri, sd_hash, fileInfo } = action.data;
|
||||
|
||||
const newByOutpoint = Object.assign({}, state.byOutpoint);
|
||||
const newDownloading = Object.assign({}, state.downloadingByOutpoint);
|
||||
const newBySdHash = Object.assign({}, state.bySdHash);
|
||||
const newDownloading = Object.assign({}, state.downloadingBySdHash);
|
||||
const newLoading = Object.assign({}, state.urisLoading);
|
||||
|
||||
newDownloading[outpoint] = true;
|
||||
newByOutpoint[outpoint] = fileInfo;
|
||||
newDownloading[sd_hash] = true;
|
||||
newBySdHash[sd_hash] = fileInfo;
|
||||
delete newLoading[uri];
|
||||
|
||||
return Object.assign({}, state, {
|
||||
downloadingByOutpoint: newDownloading,
|
||||
downloadingBySdHash: newDownloading,
|
||||
urisLoading: newLoading,
|
||||
byOutpoint: newByOutpoint,
|
||||
bySdHash: newBySdHash,
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.DOWNLOADING_PROGRESSED] = function(state, action) {
|
||||
const { uri, outpoint, fileInfo } = action.data;
|
||||
const { uri, sd_hash, fileInfo } = action.data;
|
||||
|
||||
const newByOutpoint = Object.assign({}, state.byOutpoint);
|
||||
const newDownloading = Object.assign({}, state.downloadingByOutpoint);
|
||||
const newBySdHash = Object.assign({}, state.bySdHash);
|
||||
const newDownloading = Object.assign({}, state.downloadingBySdHash);
|
||||
|
||||
newByOutpoint[outpoint] = fileInfo;
|
||||
newDownloading[outpoint] = true;
|
||||
newBySdHash[sd_hash] = fileInfo;
|
||||
newDownloading[sd_hash] = true;
|
||||
|
||||
return Object.assign({}, state, {
|
||||
byOutpoint: newByOutpoint,
|
||||
downloadingByOutpoint: newDownloading,
|
||||
bySdHash: newBySdHash,
|
||||
downloadingBySdHash: newDownloading,
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.DOWNLOADING_COMPLETED] = function(state, action) {
|
||||
const { uri, outpoint, fileInfo } = action.data;
|
||||
const { uri, sd_hash, fileInfo } = action.data;
|
||||
|
||||
const newByOutpoint = Object.assign({}, state.byOutpoint);
|
||||
const newDownloading = Object.assign({}, state.downloadingByOutpoint);
|
||||
const newBySdHash = Object.assign({}, state.bySdHash);
|
||||
const newDownloading = Object.assign({}, state.downloadingBySdHash);
|
||||
|
||||
newByOutpoint[outpoint] = fileInfo;
|
||||
delete newDownloading[outpoint];
|
||||
newBySdHash[sd_hash] = fileInfo;
|
||||
delete newDownloading[sd_hash];
|
||||
|
||||
return Object.assign({}, state, {
|
||||
byOutpoint: newByOutpoint,
|
||||
downloadingByOutpoint: newDownloading,
|
||||
bySdHash: newBySdHash,
|
||||
downloadingBySdHash: newDownloading,
|
||||
});
|
||||
};
|
||||
|
||||
reducers[types.FILE_DELETE] = function(state, action) {
|
||||
const { outpoint } = action.data;
|
||||
const { sd_hash } = action.data;
|
||||
|
||||
const newByOutpoint = Object.assign({}, state.byOutpoint);
|
||||
const downloadingByOutpoint = Object.assign({}, state.downloadingByOutpoint);
|
||||
const newBySdHash = Object.assign({}, state.bySdHash);
|
||||
const downloadingBySdHash = Object.assign({}, state.downloadingBySdHash);
|
||||
|
||||
delete newByOutpoint[outpoint];
|
||||
delete downloadingByOutpoint[outpoint];
|
||||
delete newBySdHash[sd_hash];
|
||||
delete downloadingBySdHash[sd_hash];
|
||||
|
||||
return Object.assign({}, state, {
|
||||
byOutpoint: newByOutpoint,
|
||||
downloadingByOutpoint,
|
||||
bySdHash: newBySdHash,
|
||||
downloadingBySdHash,
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -189,6 +189,20 @@ export const selectMyClaimsOutpoints = createSelector(
|
|||
}
|
||||
);
|
||||
|
||||
export const selectMyClaimSdHashesByOutpoint = createSelector(
|
||||
selectMyClaims,
|
||||
myClaims => {
|
||||
const sdHashByOutpoint = {};
|
||||
|
||||
myClaims.forEach(claim => {
|
||||
sdHashByOutpoint[`${claim.txid}:${claim.nout}`] =
|
||||
claim.value.stream.source.source;
|
||||
});
|
||||
|
||||
return sdHashByOutpoint;
|
||||
}
|
||||
);
|
||||
|
||||
export const selectFetchingMyChannels = createSelector(
|
||||
_selectState,
|
||||
state => !!state.fetchingMyChannels
|
||||
|
|
|
@ -4,14 +4,14 @@ import {
|
|||
selectClaimsByUri,
|
||||
selectIsFetchingClaimListMine,
|
||||
selectMyClaims,
|
||||
selectMyClaimsOutpoints,
|
||||
selectMyClaimSdHashesByOutpoint,
|
||||
} from "redux/selectors/claims";
|
||||
|
||||
export const _selectState = state => state.fileInfo || {};
|
||||
|
||||
export const selectFileInfosByOutpoint = createSelector(
|
||||
export const selectFileInfosBySdHash = createSelector(
|
||||
_selectState,
|
||||
state => state.byOutpoint || {}
|
||||
state => state.bySdHash || {}
|
||||
);
|
||||
|
||||
export const selectIsFetchingFileList = createSelector(
|
||||
|
@ -29,28 +29,32 @@ export const selectIsFetchingFileListDownloadedOrPublished = createSelector(
|
|||
export const makeSelectFileInfoForUri = uri => {
|
||||
return createSelector(
|
||||
selectClaimsByUri,
|
||||
selectFileInfosByOutpoint,
|
||||
(claims, byOutpoint) => {
|
||||
const claim = claims[uri],
|
||||
outpoint = claim ? `${claim.txid}:${claim.nout}` : undefined;
|
||||
selectFileInfosBySdHash,
|
||||
(claims, bySdHash) => {
|
||||
const claim = claims[uri];
|
||||
let sd_hash = undefined;
|
||||
|
||||
return outpoint ? byOutpoint[outpoint] : undefined;
|
||||
if (claim && !claim.name.startsWith("@")) {
|
||||
sd_hash = claim ? claim.value.stream.source.source : undefined;
|
||||
}
|
||||
|
||||
return sd_hash ? bySdHash[sd_hash] : undefined;
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export const selectDownloadingByOutpoint = createSelector(
|
||||
export const selectDownloadingBySdHash = createSelector(
|
||||
_selectState,
|
||||
state => state.downloadingByOutpoint || {}
|
||||
state => state.downloadingBySdHash || {}
|
||||
);
|
||||
|
||||
export const makeSelectDownloadingForUri = uri => {
|
||||
return createSelector(
|
||||
selectDownloadingByOutpoint,
|
||||
selectDownloadingBySdHash,
|
||||
makeSelectFileInfoForUri(uri),
|
||||
(byOutpoint, fileInfo) => {
|
||||
(bySdHash, fileInfo) => {
|
||||
if (!fileInfo) return false;
|
||||
return byOutpoint[fileInfo.outpoint];
|
||||
return bySdHash[fileInfo.sd_hash];
|
||||
}
|
||||
);
|
||||
};
|
||||
|
@ -64,16 +68,21 @@ export const makeSelectLoadingForUri = uri => {
|
|||
return createSelector(selectUrisLoading, byUri => byUri && byUri[uri]);
|
||||
};
|
||||
|
||||
export const selectFetchingSdHash = createSelector(
|
||||
_selectState,
|
||||
state => state.fetching || {}
|
||||
);
|
||||
|
||||
export const selectFileInfosPendingPublish = createSelector(
|
||||
_selectState,
|
||||
state => Object.values(state.pendingByOutpoint || {})
|
||||
state => Object.values(state.pendingBySdHash || {})
|
||||
);
|
||||
|
||||
export const selectFileInfosDownloaded = createSelector(
|
||||
selectFileInfosByOutpoint,
|
||||
selectFileInfosBySdHash,
|
||||
selectMyClaims,
|
||||
(byOutpoint, myClaims) => {
|
||||
return Object.values(byOutpoint).filter(fileInfo => {
|
||||
(bySdHash, myClaims) => {
|
||||
return Object.values(bySdHash).filter(fileInfo => {
|
||||
const myClaimIds = myClaims.map(claim => claim.claim_id);
|
||||
|
||||
return (
|
||||
|
@ -86,15 +95,17 @@ export const selectFileInfosDownloaded = createSelector(
|
|||
);
|
||||
|
||||
export const selectFileInfosPublished = createSelector(
|
||||
selectFileInfosByOutpoint,
|
||||
selectMyClaimsOutpoints,
|
||||
selectFileInfosBySdHash,
|
||||
selectMyClaimSdHashesByOutpoint,
|
||||
selectFileInfosPendingPublish,
|
||||
(byOutpoint, outpoints, pendingPublish) => {
|
||||
(bySdHash, sdHashesByOutpoint, pendingPublish) => {
|
||||
const fileInfos = [];
|
||||
outpoints.forEach(outpoint => {
|
||||
const fileInfo = byOutpoint[outpoint];
|
||||
|
||||
Object.keys(sdHashesByOutpoint).forEach(outpoint => {
|
||||
const fileInfo = bySdHash[sdHashesByOutpoint[outpoint]];
|
||||
if (fileInfo) fileInfos.push(fileInfo);
|
||||
});
|
||||
|
||||
return [...fileInfos, ...pendingPublish];
|
||||
}
|
||||
);
|
||||
|
@ -110,16 +121,16 @@ export const selectFileInfosPublished = createSelector(
|
|||
|
||||
export const selectFileInfosByUri = createSelector(
|
||||
selectClaimsByUri,
|
||||
selectFileInfosByOutpoint,
|
||||
(claimsByUri, byOutpoint) => {
|
||||
selectFileInfosBySdHash,
|
||||
(claimsByUri, bySdHash) => {
|
||||
const fileInfos = {};
|
||||
const uris = Object.keys(claimsByUri);
|
||||
|
||||
uris.forEach(uri => {
|
||||
const claim = claimsByUri[uri];
|
||||
if (claim) {
|
||||
const outpoint = `${claim.txid}:${claim.nout}`;
|
||||
const fileInfo = byOutpoint[outpoint];
|
||||
const sd_hash = claim.value.stream.source.source;
|
||||
const fileInfo = bySdHash[sd_hash];
|
||||
|
||||
if (fileInfo) fileInfos[uri] = fileInfo;
|
||||
}
|
||||
|
@ -129,14 +140,14 @@ export const selectFileInfosByUri = createSelector(
|
|||
);
|
||||
|
||||
export const selectDownloadingFileInfos = createSelector(
|
||||
selectDownloadingByOutpoint,
|
||||
selectFileInfosByOutpoint,
|
||||
(downloadingByOutpoint, fileInfosByOutpoint) => {
|
||||
const outpoints = Object.keys(downloadingByOutpoint);
|
||||
selectDownloadingBySdHash,
|
||||
selectFileInfosBySdHash,
|
||||
(downloadingBySdHash, fileInfosBySdHash) => {
|
||||
const sdHashes = Object.keys(downloadingBySdHash);
|
||||
const fileInfos = [];
|
||||
|
||||
outpoints.forEach(outpoint => {
|
||||
const fileInfo = fileInfosByOutpoint[outpoint];
|
||||
sdHashes.forEach(sdHash => {
|
||||
const fileInfo = fileInfosBySdHash[sdHash];
|
||||
|
||||
if (fileInfo) fileInfos.push(fileInfo);
|
||||
});
|
||||
|
@ -160,3 +171,16 @@ export const selectTotalDownloadProgress = createSelector(
|
|||
else return -1;
|
||||
}
|
||||
);
|
||||
|
||||
export const selectSdHashesByOutpoint = createSelector(
|
||||
selectFileInfosBySdHash,
|
||||
fileInfos => {
|
||||
const sdHashesByOutpoint = {};
|
||||
|
||||
Object.keys(fileInfos).forEach(fileInfo => {
|
||||
sdHashesByOutpoint[fileInfo.outpoint] = fileInfo.sd_hash;
|
||||
});
|
||||
|
||||
return sdHashesByOutpoint;
|
||||
}
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue