track reflecting files #310

Merged
jessopb merged 1 commit from feat-trackReflectingFiles into master 2020-05-08 21:07:59 +02:00
10 changed files with 289 additions and 9 deletions

133
dist/bundle.es.js vendored
View file

@ -145,6 +145,10 @@ const CHECK_PUBLISH_NAME_STARTED = 'CHECK_PUBLISH_NAME_STARTED';
const CHECK_PUBLISH_NAME_COMPLETED = 'CHECK_PUBLISH_NAME_COMPLETED';
const UPDATE_PENDING_CLAIMS = 'UPDATE_PENDING_CLAIMS';
const UPDATE_CONFIRMED_CLAIMS = 'UPDATE_CONFIRMED_CLAIMS';
const ADD_FILES_REFLECTING = 'ADD_FILES_REFLECTING';
const UPDATE_FILES_REFLECTING = 'UPDATE_FILES_REFLECTING';
const TOGGLE_CHECKING_REFLECTING = 'TOGGLE_CHECKING_REFLECTING';
const TOGGLE_CHECKING_PENDING = 'TOGGLE_CHECKING_PENDING';
// Comments
const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED';
@ -421,6 +425,10 @@ var action_types = /*#__PURE__*/Object.freeze({
CHECK_PUBLISH_NAME_COMPLETED: CHECK_PUBLISH_NAME_COMPLETED,
UPDATE_PENDING_CLAIMS: UPDATE_PENDING_CLAIMS,
UPDATE_CONFIRMED_CLAIMS: UPDATE_CONFIRMED_CLAIMS,
ADD_FILES_REFLECTING: ADD_FILES_REFLECTING,
UPDATE_FILES_REFLECTING: UPDATE_FILES_REFLECTING,
TOGGLE_CHECKING_REFLECTING: TOGGLE_CHECKING_REFLECTING,
TOGGLE_CHECKING_PENDING: TOGGLE_CHECKING_PENDING,
COMMENT_LIST_STARTED: COMMENT_LIST_STARTED,
COMMENT_LIST_COMPLETED: COMMENT_LIST_COMPLETED,
COMMENT_LIST_FAILED: COMMENT_LIST_FAILED,
@ -2184,6 +2192,7 @@ const makeSelectPendingByUri = uri => reselect.createSelector(selectPendingById,
const claimId = isChannel ? channelClaimId : streamClaimId;
return pendingById[claimId];
});
const selectReflectingById = reselect.createSelector(selectState$2, state => state.reflectingById);
const makeSelectClaimForUri = (uri, returnRepost = true) => reselect.createSelector(selectClaimsByUri, selectPendingById, (byUri, pendingById) => {
// Check if a claim is pending first
@ -2546,6 +2555,11 @@ const selectUpdatingChannel = reselect.createSelector(selectState$2, state => st
const selectUpdateChannelError = reselect.createSelector(selectState$2, state => state.updateChannelError);
const makeSelectReflectingClaimForUri = uri => reselect.createSelector(makeSelectClaimForUri(uri), selectReflectingById, (claim, reflectingById) => {
const claimId = claim && claim.claimId;
return reflectingById[claimId];
});
const makeSelectMyStreamUrlsForPage = (page = 1) => reselect.createSelector(selectMyClaimUrisWithoutChannels, urls => {
const start = (Number(page) - 1) * Number(PAGE_SIZE);
const end = Number(page) * Number(PAGE_SIZE);
@ -4114,6 +4128,8 @@ const selectTakeOverAmount = reselect.createSelector(selectState$5, selectMyClai
var _extends$7 = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
function _asyncToGenerator(fn) { return function () { var gen = fn.apply(this, arguments); return new Promise(function (resolve, reject) { function step(key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { return Promise.resolve(value).then(function (value) { step("next", value); }, function (err) { step("throw", err); }); } } return step("next"); }); }; }
const doResetThumbnailStatus = () => dispatch => {
dispatch({
type: UPDATE_PUBLISH_FORM,
@ -4400,7 +4416,82 @@ const doPublish = (success, fail) => (dispatch, getState) => {
return lbryProxy.publish(publishPayload).then(success, fail);
};
// Calls claim_list_mine until any pending publishes are confirmed
// Calls file_list until any reflecting files are done
const doCheckReflectingFiles = () => (dispatch, getState) => {
const state = getState();
const { checkingReflector } = state.claims;
let reflectorCheckInterval;
const checkFileList = (() => {
var _ref = _asyncToGenerator(function* () {
const state = getState();
const reflectingById = selectReflectingById(state);
const ids = Object.keys(reflectingById);
const newReflectingById = {};
const promises = [];
// TODO: just use file_list({claim_id: Array<claimId>})
if (Object.keys(reflectingById).length) {
ids.forEach(function (claimId) {
promises.push(lbryProxy.file_list({ claim_id: claimId }));
});
Promise.all(promises).then(function (results) {
results.forEach(function (res) {
const fileListItem = res.items[0];
const fileClaimId = fileListItem.claim_id;
const {
is_fully_reflected: done,
uploading_to_reflector: uploading,
reflector_progress: progress
} = fileListItem;
if (uploading) {
newReflectingById[fileClaimId] = {
fileListItem: fileListItem,
progress,
stalled: !done && !uploading
};
}
});
}).then(function () {
dispatch({
type: UPDATE_FILES_REFLECTING,
data: newReflectingById
});
if (!Object.keys(newReflectingById).length) {
dispatch({
type: TOGGLE_CHECKING_REFLECTING,
data: false
});
clearInterval(reflectorCheckInterval);
}
});
} else {
dispatch({
type: TOGGLE_CHECKING_REFLECTING,
data: false
});
clearInterval(reflectorCheckInterval);
}
});
return function checkFileList() {
return _ref.apply(this, arguments);
};
})();
// do it once...
checkFileList();
// then start the interval if it's not already started
if (!checkingReflector) {
dispatch({
type: TOGGLE_CHECKING_REFLECTING,
data: true
});
reflectorCheckInterval = setInterval(() => {
checkFileList();
}, 5000);
}
};
const doCheckPendingPublishes = onConfirmed => (dispatch, getState) => {
let publishCheckInterval;
@ -4940,6 +5031,7 @@ const defaultState = {
fetchingMyChannels: false,
abandoningById: {},
pendingById: {},
reflectingById: {},
claimSearchError: false,
claimSearchByQuery: {},
claimSearchByQueryLastPageReached: {},
@ -4956,7 +5048,9 @@ const defaultState = {
myClaimsPageNumber: undefined,
myClaimsPageTotalResults: undefined,
isFetchingClaimListMine: false,
isCheckingNameForPublish: false
isCheckingNameForPublish: false,
checkingPending: false,
checkingReflecting: false
};
function handleClaimAction(state, action) {
@ -5438,6 +5532,38 @@ reducers[CLEAR_REPOST_ERROR] = state => {
repostError: null
});
};
reducers[ADD_FILES_REFLECTING] = (state, action) => {
const pendingClaim = action.data;
const { reflectingById } = state;
const claimId = pendingClaim && pendingClaim.claim_id;
reflectingById[claimId] = { fileListItem: pendingClaim, progress: 0, stalled: false };
return Object.assign({}, state, _extends$9({}, state, {
reflectingById: reflectingById
}));
};
reducers[UPDATE_FILES_REFLECTING] = (state, action) => {
const newReflectingById = action.data;
return Object.assign({}, state, _extends$9({}, state, {
reflectingById: newReflectingById
}));
};
reducers[TOGGLE_CHECKING_REFLECTING] = (state, action) => {
const checkingReflecting = action.data;
return Object.assign({}, state, _extends$9({}, state, {
checkingReflecting
}));
};
reducers[TOGGLE_CHECKING_PENDING] = (state, action) => {
const checking = action.data;
return Object.assign({}, state, _extends$9({}, state, {
checkingPending: checking
}));
};
function claimsReducer(state = defaultState, action) {
const handler = reducers[action.type];
@ -6715,6 +6841,7 @@ exports.doBlurSearchInput = doBlurSearchInput;
exports.doCheckAddressIsMine = doCheckAddressIsMine;
exports.doCheckPendingPublishes = doCheckPendingPublishes;
exports.doCheckPublishNameAvailability = doCheckPublishNameAvailability;
exports.doCheckReflectingFiles = doCheckReflectingFiles;
exports.doClaimSearch = doClaimSearch;
exports.doClearPublish = doClearPublish;
exports.doClearRepostError = doClearRepostError;
@ -6824,6 +6951,7 @@ exports.makeSelectPermanentUrlForUri = makeSelectPermanentUrlForUri;
exports.makeSelectPublishFormValue = makeSelectPublishFormValue;
exports.makeSelectQueryWithOptions = makeSelectQueryWithOptions;
exports.makeSelectRecommendedContentForUri = makeSelectRecommendedContentForUri;
exports.makeSelectReflectingClaimForUri = makeSelectReflectingClaimForUri;
exports.makeSelectResolvedRecommendedContentForUri = makeSelectResolvedRecommendedContentForUri;
exports.makeSelectResolvedSearchResults = makeSelectResolvedSearchResults;
exports.makeSelectResolvedSearchResultsLastPageReached = makeSelectResolvedSearchResultsLastPageReached;
@ -6928,6 +7056,7 @@ exports.selectPurchaseUriErrorMessage = selectPurchaseUriErrorMessage;
exports.selectPurchasedUris = selectPurchasedUris;
exports.selectReceiveAddress = selectReceiveAddress;
exports.selectRecentTransactions = selectRecentTransactions;
exports.selectReflectingById = selectReflectingById;
exports.selectRepostError = selectRepostError;
exports.selectRepostLoading = selectRepostLoading;
exports.selectReservedBalance = selectReservedBalance;

View file

@ -20,6 +20,7 @@ declare type FileListItem = {
outpoint: string,
points_paid: number,
protobuf: string,
reflector_progress: number,
sd_hash: string,
status: string,
stopped: false,
@ -29,10 +30,12 @@ declare type FileListItem = {
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,
};

5
dist/flow-typed/Reflector.js vendored Normal file
View file

@ -0,0 +1,5 @@
declare type ReflectingUpdate = {
fileListItem: FileListItem,
progress: number | boolean,
stalled: boolean,
};

3
flow-typed/File.js vendored
View file

@ -20,6 +20,7 @@ declare type FileListItem = {
outpoint: string,
points_paid: number,
protobuf: string,
reflector_progress: number,
sd_hash: string,
status: string,
stopped: false,
@ -29,10 +30,12 @@ declare type FileListItem = {
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,
};

5
flow-typed/Reflector.js vendored Normal file
View file

@ -0,0 +1,5 @@
declare type ReflectingUpdate = {
fileListItem: FileListItem,
progress: number | boolean,
stalled: boolean,
};

View file

@ -122,6 +122,10 @@ export const CHECK_PUBLISH_NAME_STARTED = 'CHECK_PUBLISH_NAME_STARTED';
export const CHECK_PUBLISH_NAME_COMPLETED = 'CHECK_PUBLISH_NAME_COMPLETED';
export const UPDATE_PENDING_CLAIMS = 'UPDATE_PENDING_CLAIMS';
export const UPDATE_CONFIRMED_CLAIMS = 'UPDATE_CONFIRMED_CLAIMS';
export const ADD_FILES_REFLECTING = 'ADD_FILES_REFLECTING';
export const UPDATE_FILES_REFLECTING = 'UPDATE_FILES_REFLECTING';
export const TOGGLE_CHECKING_REFLECTING = 'TOGGLE_CHECKING_REFLECTING';
export const TOGGLE_CHECKING_PENDING = 'TOGGLE_CHECKING_PENDING';
// Comments
export const COMMENT_LIST_STARTED = 'COMMENT_LIST_STARTED';

View file

@ -94,6 +94,7 @@ export {
doPrepareEdit,
doPublish,
doCheckPendingPublishes,
doCheckReflectingFiles,
} from 'redux/actions/publish';
export {
@ -206,12 +207,14 @@ export {
makeSelectChannelForClaimUri,
makeSelectClaimIsPending,
makeSelectPendingByUri,
makeSelectReflectingClaimForUri,
makeSelectClaimsInChannelForCurrentPageState,
makeSelectShortUrlForUri,
makeSelectCanonicalUrlForUri,
makeSelectPermanentUrlForUri,
makeSelectSupportsForUri,
selectPendingById,
selectReflectingById,
selectClaimsById,
selectClaimsByUri,
selectAllClaimsByChannel,

View file

@ -12,6 +12,7 @@ import {
selectMyChannelClaims,
selectPendingById,
selectMyClaimsWithoutChannels,
selectReflectingById,
} from 'redux/selectors/claims';
import { selectPublishFormValues, selectMyClaimForUri } from 'redux/selectors/publish';
@ -354,7 +355,78 @@ export const doPublish = (success: Function, fail: Function) => (
return Lbry.publish(publishPayload).then(success, fail);
};
// Calls claim_list_mine until any pending publishes are confirmed
// Calls file_list until any reflecting files are done
export const doCheckReflectingFiles = () => (dispatch: Dispatch, getState: GetState) => {
const state = getState();
const { checkingReflector } = state.claims;
let reflectorCheckInterval;
const checkFileList = async() => {
const state = getState();
const reflectingById = selectReflectingById(state);
const ids = Object.keys(reflectingById);
const newReflectingById = {};
const promises = [];
// TODO: just use file_list({claim_id: Array<claimId>})
if (Object.keys(reflectingById).length) {
ids.forEach(claimId => {
promises.push(Lbry.file_list({ claim_id: claimId }));
});
Promise.all(promises)
.then(results => {
results.forEach(res => {
const fileListItem = res.items[0];
const fileClaimId = fileListItem.claim_id;
const {
is_fully_reflected: done,
uploading_to_reflector: uploading,
reflector_progress: progress,
} = fileListItem;
if (uploading) {
newReflectingById[fileClaimId] = {
fileListItem: fileListItem,
progress,
stalled: !done && !uploading,
};
}
});
})
.then(() => {
dispatch({
type: ACTIONS.UPDATE_FILES_REFLECTING,
data: newReflectingById,
});
if (!Object.keys(newReflectingById).length) {
dispatch({
type: ACTIONS.TOGGLE_CHECKING_REFLECTING,
data: false,
});
clearInterval(reflectorCheckInterval);
}
});
} else {
dispatch({
type: ACTIONS.TOGGLE_CHECKING_REFLECTING,
data: false,
});
clearInterval(reflectorCheckInterval);
}
};
// do it once...
checkFileList();
// then start the interval if it's not already started
if (!checkingReflector) {
dispatch({
type: ACTIONS.TOGGLE_CHECKING_REFLECTING,
data: true,
});
reflectorCheckInterval = setInterval(() => {
checkFileList();
}, 5000);
}
};
export const doCheckPendingPublishes = (onConfirmed: Function) => (
dispatch: Dispatch,
getState: GetState
@ -387,7 +459,7 @@ export const doCheckPendingPublishes = (onConfirmed: Function) => (
}
return Object.keys(pendingById).length;
})
.then((len) => {
.then(len => {
if (!len) {
clearInterval(publishCheckInterval);
}

View file

@ -18,6 +18,7 @@ type State = {
byId: { [string]: Claim },
resolvingUris: Array<string>,
pendingById: { [string]: Claim },
reflectingById: { [string]: ReflectingUpdate },
myClaims: ?Array<string>,
myChannelClaims: ?Array<string>,
abandoningById: { [string]: boolean },
@ -46,6 +47,8 @@ type State = {
myClaimsPageTotalResults: ?number,
isFetchingClaimListMine: boolean,
isCheckingNameForPublish: boolean,
checkingPending: boolean,
checkingReflecting: boolean,
};
const reducers = {};
@ -63,6 +66,7 @@ const defaultState = {
fetchingMyChannels: false,
abandoningById: {},
pendingById: {},
reflectingById: {},
claimSearchError: false,
claimSearchByQuery: {},
claimSearchByQueryLastPageReached: {},
@ -80,6 +84,8 @@ const defaultState = {
myClaimsPageTotalResults: undefined,
isFetchingClaimListMine: false,
isCheckingNameForPublish: false,
checkingPending: false,
checkingReflecting: false,
};
function handleClaimAction(state: State, action: any): State {
@ -362,7 +368,7 @@ reducers[ACTIONS.ABANDON_CLAIM_STARTED] = (state: State, action: any): State =>
};
reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State => {
const { claims }: { claims: Array<GenericClaim> } = action.data;
const { claims }: { claims: Array<Claim> } = action.data;
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById);
@ -387,13 +393,13 @@ reducers[ACTIONS.UPDATE_PENDING_CLAIMS] = (state: State, action: any): State =>
};
reducers[ACTIONS.UPDATE_CONFIRMED_CLAIMS] = (state: State, action: any): State => {
const { claims }: { claims: Array<GenericClaim> } = action.data;
const { claims }: { claims: Array<Claim> } = action.data;
const byId = Object.assign({}, state.byId);
const byUri = Object.assign({}, state.claimsByUri);
const pendingById: { [string]: Claim } = Object.assign({}, state.pendingById);
let myClaimIds = new Set(state.myClaims);
claims.forEach((claim: Claim) => {
claims.forEach((claim: GenericClaim) => {
const uri = buildURI({ streamName: claim.name, streamClaimId: claim.claim_id });
const { claim_id: claimId } = claim;
if (claim.type && claim.type.match(/claim|update/)) {
@ -594,6 +600,42 @@ reducers[ACTIONS.CLEAR_REPOST_ERROR] = (state: State): State => {
repostError: null,
};
};
reducers[ACTIONS.ADD_FILES_REFLECTING] = (state: State, action): State => {
const pendingClaim = action.data;
const { reflectingById } = state;
const claimId = pendingClaim && pendingClaim.claim_id;
reflectingById[claimId] = { fileListItem: pendingClaim, progress: 0, stalled: false };
return Object.assign({}, state, {
...state,
reflectingById: reflectingById,
});
};
reducers[ACTIONS.UPDATE_FILES_REFLECTING] = (state: State, action): State => {
const newReflectingById = action.data;
return Object.assign({}, state, {
...state,
reflectingById: newReflectingById,
});
};
reducers[ACTIONS.TOGGLE_CHECKING_REFLECTING] = (state: State, action): State => {
const checkingReflecting = action.data;
return Object.assign({}, state, {
...state,
checkingReflecting,
});
};
reducers[ACTIONS.TOGGLE_CHECKING_PENDING] = (state: State, action): State => {
const checking = action.data;
return Object.assign({}, state, {
...state,
checkingPending: checking,
});
};
export function claimsReducer(state: State = defaultState, action: any) {
const handler = reducers[action.type];

View file

@ -111,6 +111,10 @@ export const makeSelectPendingByUri = (uri: string) =>
return pendingById[claimId];
}
);
export const selectReflectingById = createSelector(
selectState,
state => state.reflectingById
);
export const makeSelectClaimForUri = (uri: string, returnRepost: boolean = true) =>
createSelector(
@ -314,8 +318,8 @@ export const makeSelectDateForUri = (uri: string) =>
(claim.value.release_time
? claim.value.release_time * 1000
: claim.meta && claim.meta.creation_timestamp
? claim.meta.creation_timestamp * 1000
: null);
? claim.meta.creation_timestamp * 1000
: null);
if (!timestamp) {
return undefined;
}
@ -717,6 +721,16 @@ export const selectUpdateChannelError = createSelector(
state => state.updateChannelError
);
export const makeSelectReflectingClaimForUri = (uri: string) =>
createSelector(
makeSelectClaimForUri(uri),
selectReflectingById,
(claim, reflectingById) => {
const claimId = claim && claim.claimId;
return reflectingById[claimId];
}
);
export const makeSelectMyStreamUrlsForPage = (page: number = 1) =>
createSelector(
selectMyClaimUrisWithoutChannels,