Temp revert to allow putting back the commits

This reverts commit 157b50c58e.
This commit is contained in:
infinite-persistence 2021-12-08 09:15:48 +08:00
parent fcf19a07e8
commit 994d9c6027
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
13 changed files with 58 additions and 286 deletions

View file

@ -62,8 +62,7 @@ declare type FileUploadSdkParams = {
remote_url?: string, remote_url?: string,
thumbnail_url?: string, thumbnail_url?: string,
title?: string, title?: string,
// Temporary values; remove when passing to SDK // Temporary values
guid: string,
uploadUrl?: string, uploadUrl?: string,
}; };

View file

@ -1307,8 +1307,6 @@
"Uploading...": "Uploading...", "Uploading...": "Uploading...",
"Creating...": "Creating...", "Creating...": "Creating...",
"Stopped. Duplicate session detected.": "Stopped. Duplicate session detected.", "Stopped. Duplicate session detected.": "Stopped. Duplicate session detected.",
"File being uploaded in another tab or window.": "File being uploaded in another tab or window.",
"There are pending uploads.": "There are pending uploads.",
"Use a URL": "Use a URL", "Use a URL": "Use a URL",
"Edit Cover Image": "Edit Cover Image", "Edit Cover Image": "Edit Cover Image",
"Cover Image": "Cover Image", "Cover Image": "Cover Image",

View file

@ -2,7 +2,6 @@
import * as PAGES from 'constants/pages'; import * as PAGES from 'constants/pages';
import React, { useEffect, useRef, useState, useLayoutEffect } from 'react'; import React, { useEffect, useRef, useState, useLayoutEffect } from 'react';
import { lazyImport } from 'util/lazyImport'; import { lazyImport } from 'util/lazyImport';
import { tusUnlockAndNotify, tusHandleTabUpdates } from 'util/tus';
import classnames from 'classnames'; import classnames from 'classnames';
import analytics from 'analytics'; import analytics from 'analytics';
import { setSearchUserId } from 'redux/actions/search'; import { setSearchUserId } from 'redux/actions/search';
@ -232,29 +231,12 @@ function App(props: Props) {
useEffect(() => { useEffect(() => {
if (!uploadCount) return; if (!uploadCount) return;
const handleUnload = (event) => tusUnlockAndNotify();
const handleBeforeUnload = (event) => { const handleBeforeUnload = (event) => {
event.preventDefault(); event.preventDefault();
event.returnValue = __('There are pending uploads.'); // without setting this to something it doesn't work event.returnValue = 'magic'; // without setting this to something it doesn't work
}; };
window.addEventListener('unload', handleUnload);
window.addEventListener('beforeunload', handleBeforeUnload); window.addEventListener('beforeunload', handleBeforeUnload);
return () => window.removeEventListener('beforeunload', handleBeforeUnload);
return () => {
window.removeEventListener('unload', handleUnload);
window.removeEventListener('beforeunload', handleBeforeUnload);
};
}, [uploadCount]);
useEffect(() => {
if (!uploadCount) return;
const onStorageUpdate = (e) => tusHandleTabUpdates(e.key);
window.addEventListener('storage', onStorageUpdate);
return () => window.removeEventListener('storage', onStorageUpdate);
}, [uploadCount]); }, [uploadCount]);
// allows user to pause miniplayer using the spacebar without the page scrolling down // allows user to pause miniplayer using the spacebar without the page scrolling down

View file

@ -5,12 +5,11 @@ import Button from 'component/button';
import FileThumbnail from 'component/fileThumbnail'; import FileThumbnail from 'component/fileThumbnail';
import * as MODALS from 'constants/modal_types'; import * as MODALS from 'constants/modal_types';
import { serializeFileObj } from 'util/file'; import { serializeFileObj } from 'util/file';
import { tusIsSessionLocked } from 'util/tus';
type Props = { type Props = {
uploadItem: FileUploadItem, uploadItem: FileUploadItem,
doPublishResume: (any) => void, doPublishResume: (any) => void,
doUpdateUploadRemove: (string, any) => void, doUpdateUploadRemove: (any) => void,
doOpenModal: (string, {}) => void, doOpenModal: (string, {}) => void,
}; };
@ -19,16 +18,11 @@ export default function WebUploadItem(props: Props) {
const { params, file, fileFingerprint, progress, status, resumable, uploader } = uploadItem; const { params, file, fileFingerprint, progress, status, resumable, uploader } = uploadItem;
const [showFileSelector, setShowFileSelector] = useState(false); const [showFileSelector, setShowFileSelector] = useState(false);
const locked = tusIsSessionLocked(params.guid);
function handleFileChange(newFile: WebFile, clearName = true) { function handleFileChange(newFile: WebFile, clearName = true) {
if (serializeFileObj(newFile) === fileFingerprint) { if (serializeFileObj(newFile) === fileFingerprint) {
setShowFileSelector(false); setShowFileSelector(false);
doPublishResume({ ...params, file_path: newFile }); doPublishResume({ ...params, file_path: newFile });
if (!params.guid) {
// Can remove this if-block after January 2022.
doUpdateUploadRemove('', params);
}
} else { } else {
doOpenModal(MODALS.CONFIRM, { doOpenModal(MODALS.CONFIRM, {
title: __('Invalid file'), title: __('Invalid file'),
@ -46,12 +40,6 @@ export default function WebUploadItem(props: Props) {
subtitle: __('Cancel and remove the selected upload?'), subtitle: __('Cancel and remove the selected upload?'),
body: params.name ? <p className="empty">{`lbry://${params.name}`}</p> : undefined, body: params.name ? <p className="empty">{`lbry://${params.name}`}</p> : undefined,
onConfirm: (closeModal) => { onConfirm: (closeModal) => {
if (tusIsSessionLocked(params.guid)) {
// Corner-case: it's possible for the upload to resume in another tab
// after the modal has appeared. Make a final lock-check here.
// We can invoke a toast here, but just do nothing for now.
// The upload status should make things obvious.
} else {
if (uploader) { if (uploader) {
if (resumable) { if (resumable) {
// $FlowFixMe - couldn't resolve to TusUploader manually. // $FlowFixMe - couldn't resolve to TusUploader manually.
@ -60,20 +48,13 @@ export default function WebUploadItem(props: Props) {
uploader.abort(); // XHR uploader.abort(); // XHR
} }
} }
doUpdateUploadRemove(params);
// The second parameter (params) can be removed after January 2022.
doUpdateUploadRemove(params.guid, params);
}
closeModal(); closeModal();
}, },
}); });
} }
function resolveProgressStr() { function resolveProgressStr() {
if (locked) {
return __('File being uploaded in another tab or window.');
}
if (!uploader) { if (!uploader) {
return __('Stopped.'); return __('Stopped.');
} }
@ -100,7 +81,7 @@ export default function WebUploadItem(props: Props) {
} }
function getRetryButton() { function getRetryButton() {
if (!resumable || locked) { if (!resumable) {
return null; return null;
} }
@ -128,10 +109,8 @@ export default function WebUploadItem(props: Props) {
} }
function getCancelButton() { function getCancelButton() {
if (!locked) {
return <Button label={__('Cancel')} button="link" onClick={handleCancel} />; return <Button label={__('Cancel')} button="link" onClick={handleCancel} />;
} }
}
function getFileSelector() { function getFileSelector() {
return ( return (

View file

@ -7,7 +7,7 @@ type Props = {
currentUploads: { [key: string]: FileUploadItem }, currentUploads: { [key: string]: FileUploadItem },
uploadCount: number, uploadCount: number,
doPublishResume: (any) => void, doPublishResume: (any) => void,
doUpdateUploadRemove: (string, any) => void, doUpdateUploadRemove: (any) => void,
doOpenModal: (string, {}) => void, doOpenModal: (string, {}) => void,
}; };

View file

@ -1,3 +0,0 @@
// Local Storage keys
export const TUS_LOCKED_UPLOADS = 'tusLockedUploads';
export const TUS_REMOVED_UPLOADS = 'tusRemovedUploads';

View file

@ -702,28 +702,21 @@ export function doUpdateUploadAdd(
}; };
} }
export const doUpdateUploadProgress = (props: { guid: string, progress?: string, status?: string }) => ( export const doUpdateUploadProgress = (props: {
dispatch: Dispatch params: { [key: string]: any },
) => progress?: string,
status?: string,
}) => (dispatch: Dispatch) =>
dispatch({ dispatch({
type: ACTIONS.UPDATE_UPLOAD_PROGRESS, type: ACTIONS.UPDATE_UPLOAD_PROGRESS,
data: props, data: props,
}); });
/** export function doUpdateUploadRemove(params: { [key: string]: any }) {
* doUpdateUploadRemove
*
* @param guid
* @param params Optional. Retain to allow removal of old keys, which are
* derived from `name#channel` instead of using a guid.
* Can be removed after January 2022.
* @returns {(function(Dispatch, GetState): void)|*}
*/
export function doUpdateUploadRemove(guid: string, params?: { [key: string]: any }) {
return (dispatch: Dispatch, getState: GetState) => { return (dispatch: Dispatch, getState: GetState) => {
dispatch({ dispatch({
type: ACTIONS.UPDATE_UPLOAD_REMOVE, type: ACTIONS.UPDATE_UPLOAD_REMOVE,
data: { guid, params }, data: { params },
}); });
}; };
} }

View file

@ -2,14 +2,11 @@
import { handleActions } from 'util/redux-utils'; import { handleActions } from 'util/redux-utils';
import { buildURI } from 'util/lbryURI'; import { buildURI } from 'util/lbryURI';
import { serializeFileObj } from 'util/file'; import { serializeFileObj } from 'util/file';
import { tusLockAndNotify, tusUnlockAndNotify, tusRemoveAndNotify, tusClearRemovedUploads } from 'util/tus';
import * as ACTIONS from 'constants/action_types'; import * as ACTIONS from 'constants/action_types';
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses'; import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
import { CHANNEL_ANONYMOUS } from 'constants/claim'; import { CHANNEL_ANONYMOUS } from 'constants/claim';
// This is the old key formula. Retain it for now to allow users to delete const getKeyFromParam = (params) => `${params.name}#${params.channel || 'anonymous'}`;
// any pending uploads. Can be removed from January 2022 onwards.
const getOldKeyFromParam = (params) => `${params.name}#${params.channel || 'anonymous'}`;
type PublishState = { type PublishState = {
editingURI: ?string, editingURI: ?string,
@ -141,9 +138,10 @@ export const publishReducer = handleActions(
}, },
[ACTIONS.UPDATE_UPLOAD_ADD]: (state: PublishState, action) => { [ACTIONS.UPDATE_UPLOAD_ADD]: (state: PublishState, action) => {
const { file, params, uploader } = action.data; const { file, params, uploader } = action.data;
const key = getKeyFromParam(params);
const currentUploads = Object.assign({}, state.currentUploads); const currentUploads = Object.assign({}, state.currentUploads);
currentUploads[params.guid] = { currentUploads[key] = {
file, file,
fileFingerprint: file ? serializeFileObj(file) : undefined, // TODO: get hash instead? fileFingerprint: file ? serializeFileObj(file) : undefined, // TODO: get hash instead?
progress: '0', progress: '0',
@ -155,14 +153,10 @@ export const publishReducer = handleActions(
return { ...state, currentUploads }; return { ...state, currentUploads };
}, },
[ACTIONS.UPDATE_UPLOAD_PROGRESS]: (state: PublishState, action) => { [ACTIONS.UPDATE_UPLOAD_PROGRESS]: (state: PublishState, action) => {
const { guid, progress, status } = action.data; const { params, progress, status } = action.data;
const key = guid; const key = getKeyFromParam(params);
const currentUploads = Object.assign({}, state.currentUploads); const currentUploads = Object.assign({}, state.currentUploads);
if (guid === 'force--update') {
return { ...state, currentUploads };
}
if (!currentUploads[key]) { if (!currentUploads[key]) {
return state; return state;
} }
@ -171,17 +165,11 @@ export const publishReducer = handleActions(
currentUploads[key].progress = progress; currentUploads[key].progress = progress;
delete currentUploads[key].status; delete currentUploads[key].status;
if (currentUploads[key].uploader.url) { if (currentUploads[key].uploader.url && !currentUploads[key].params.uploadUrl) {
// TUS has finally obtained an upload url from the server... // TUS has finally obtained an upload url from the server. Stash that to check later when resuming.
if (!currentUploads[key].params.uploadUrl) {
// ... Stash that to check later when resuming.
// Ignoring immutable-update requirement (probably doesn't matter to the GUI). // Ignoring immutable-update requirement (probably doesn't matter to the GUI).
currentUploads[key].params.uploadUrl = currentUploads[key].uploader.url; currentUploads[key].params.uploadUrl = currentUploads[key].uploader.url;
} }
// ... lock this tab as the active uploader.
tusLockAndNotify(key);
}
} else if (status) { } else if (status) {
currentUploads[key].status = status; currentUploads[key].status = status;
if (status === 'error') { if (status === 'error') {
@ -192,19 +180,13 @@ export const publishReducer = handleActions(
return { ...state, currentUploads }; return { ...state, currentUploads };
}, },
[ACTIONS.UPDATE_UPLOAD_REMOVE]: (state: PublishState, action) => { [ACTIONS.UPDATE_UPLOAD_REMOVE]: (state: PublishState, action) => {
const { guid, params } = action.data; const { params } = action.data;
const key = guid || getOldKeyFromParam(params); const key = getKeyFromParam(params);
if (state.currentUploads[key]) {
const currentUploads = Object.assign({}, state.currentUploads); const currentUploads = Object.assign({}, state.currentUploads);
delete currentUploads[key]; delete currentUploads[key];
tusUnlockAndNotify(key);
tusRemoveAndNotify(key);
return { ...state, currentUploads }; return { ...state, currentUploads };
}
return state;
}, },
[ACTIONS.REHYDRATE]: (state: PublishState, action) => { [ACTIONS.REHYDRATE]: (state: PublishState, action) => {
if (action && action.payload && action.payload.publish) { if (action && action.payload && action.payload.publish) {
@ -212,10 +194,7 @@ export const publishReducer = handleActions(
// Cleanup for 'publish::currentUploads' // Cleanup for 'publish::currentUploads'
if (newPublish.currentUploads) { if (newPublish.currentUploads) {
const uploadKeys = Object.keys(newPublish.currentUploads); Object.keys(newPublish.currentUploads).forEach((key) => {
if (uploadKeys.length > 0) {
// Clear uploader and corrupted params
uploadKeys.forEach((key) => {
const params = newPublish.currentUploads[key].params; const params = newPublish.currentUploads[key].params;
if (!params || Object.keys(params).length === 0) { if (!params || Object.keys(params).length === 0) {
delete newPublish.currentUploads[key]; delete newPublish.currentUploads[key];
@ -223,9 +202,6 @@ export const publishReducer = handleActions(
delete newPublish.currentUploads[key].uploader; delete newPublish.currentUploads[key].uploader;
} }
}); });
} else {
tusClearRemovedUploads();
}
} }
return newPublish; return newPublish;

View file

@ -1,15 +0,0 @@
export function isLocalStorageAvailable() {
try {
return Boolean(window.localStorage);
} catch (e) {
return false;
}
}
export function isSessionStorageAvailable() {
try {
return Boolean(window.sessionStorage);
} catch (e) {
return false;
}
}

View file

@ -1,129 +0,0 @@
// @flow
/**
* This serves a bridge between tabs using localStorage to indicate whether an
* upload is currently in progress (locked) or removed.
*
* An alternative is to sync the redux's 'publish::currentUploads' through the
* wallet's sync process, but let's not pollute the wallet for now.
*/
import { v4 as uuid } from 'uuid';
import { TUS_LOCKED_UPLOADS, TUS_REMOVED_UPLOADS } from 'constants/storage';
import { isLocalStorageAvailable } from 'util/storage';
import { doUpdateUploadRemove, doUpdateUploadProgress } from 'redux/actions/publish';
const localStorageAvailable = isLocalStorageAvailable();
let gTabId: string = '';
function getTabId() {
if (!gTabId) {
// We want to maximize bootup speed, so only initialize
// the tab ID on first use instead when declared.
gTabId = uuid();
}
return gTabId;
}
// ****************************************************************************
// Locked
// ****************************************************************************
function getLockedUploads() {
if (localStorageAvailable) {
const storedValue = window.localStorage.getItem(TUS_LOCKED_UPLOADS);
return storedValue ? JSON.parse(storedValue) : {};
}
return {};
}
export function tusIsSessionLocked(guid: string) {
const lockedUploads = getLockedUploads();
return lockedUploads[guid] && lockedUploads[guid] !== getTabId();
}
export function tusLockAndNotify(guid: string) {
const lockedUploads = getLockedUploads();
if (!lockedUploads[guid] && localStorageAvailable) {
lockedUploads[guid] = getTabId();
window.localStorage.setItem(TUS_LOCKED_UPLOADS, JSON.stringify(lockedUploads));
}
}
/**
* tusUnlockAndNotify
*
* @param guid The upload session to unlock and notify other tabs of.
* Passing 'undefined' will clear all sessions locked by this tab.
*/
export function tusUnlockAndNotify(guid?: string) {
if (!localStorageAvailable) return;
const lockedUploads = getLockedUploads();
if (guid) {
delete lockedUploads[guid];
} else {
const ourTabId = getTabId();
const lockedUploadsEntries = Object.entries(lockedUploads);
lockedUploadsEntries.forEach(([lockedGuid, tabId]) => {
if (tabId === ourTabId) {
delete lockedUploads[lockedGuid];
}
});
}
if (Object.keys(lockedUploads).length > 0) {
window.localStorage.setItem(TUS_LOCKED_UPLOADS, JSON.stringify(lockedUploads));
} else {
window.localStorage.removeItem(TUS_LOCKED_UPLOADS);
}
}
// ****************************************************************************
// Removed
// ****************************************************************************
function getRemovedUploads() {
if (localStorageAvailable) {
const storedValue = window.localStorage.getItem(TUS_REMOVED_UPLOADS);
return storedValue ? storedValue.split(',') : [];
}
return [];
}
export function tusRemoveAndNotify(guid: string) {
if (!localStorageAvailable) return;
const removedUploads = getRemovedUploads();
removedUploads.push(guid);
window.localStorage.setItem(TUS_REMOVED_UPLOADS, removedUploads.join(','));
}
export function tusClearRemovedUploads() {
if (!localStorageAvailable) return;
window.localStorage.removeItem(TUS_REMOVED_UPLOADS);
}
// ****************************************************************************
// Respond to changes from other tabs.
// ****************************************************************************
export function tusHandleTabUpdates(storageKey: string) {
switch (storageKey) {
case TUS_LOCKED_UPLOADS:
// The locked IDs are in localStorage, but related GUI is unaware.
// Send a redux update to force an update.
window.store.dispatch(doUpdateUploadProgress({ guid: 'force--update' }));
break;
case TUS_REMOVED_UPLOADS:
// The other tab's store has removed this upload, so it's safe to do the
// same without affecting rehydration.
if (localStorageAvailable) {
const removedUploads = getRemovedUploads();
removedUploads.forEach((guid) => window.store.dispatch(doUpdateUploadRemove(guid)));
}
break;
}
}

View file

@ -30,12 +30,10 @@ export function makeUploadRequest(
delete params['remote_url']; delete params['remote_url'];
} }
const { uploadUrl, guid, ...sdkParams } = params;
const jsonPayload = JSON.stringify({ const jsonPayload = JSON.stringify({
jsonrpc: '2.0', jsonrpc: '2.0',
method: ENDPOINT_METHOD, method: ENDPOINT_METHOD,
params: sdkParams, params,
id: new Date().getTime(), id: new Date().getTime(),
}); });
@ -49,18 +47,18 @@ export function makeUploadRequest(
xhr.responseType = 'json'; xhr.responseType = 'json';
xhr.upload.onprogress = (e) => { xhr.upload.onprogress = (e) => {
const percentage = ((e.loaded / e.total) * 100).toFixed(2); const percentage = ((e.loaded / e.total) * 100).toFixed(2);
window.store.dispatch(doUpdateUploadProgress({ guid, progress: percentage })); window.store.dispatch(doUpdateUploadProgress({ params, progress: percentage }));
}; };
xhr.onload = () => { xhr.onload = () => {
window.store.dispatch(doUpdateUploadRemove(guid)); window.store.dispatch(doUpdateUploadRemove(params));
resolve(xhr); resolve(xhr);
}; };
xhr.onerror = () => { xhr.onerror = () => {
window.store.dispatch(doUpdateUploadProgress({ guid, status: 'error' })); window.store.dispatch(doUpdateUploadProgress({ params, status: 'error' }));
reject(new Error(__('There was a problem with your upload. Please try again.'))); reject(new Error(__('There was a problem with your upload. Please try again.')));
}; };
xhr.onabort = () => { xhr.onabort = () => {
window.store.dispatch(doUpdateUploadRemove(guid)); window.store.dispatch(doUpdateUploadRemove(params));
}; };
if (!isPreview) { if (!isPreview) {

View file

@ -38,12 +38,13 @@ export function makeResumableUploadRequest(
reject(new Error('Publish: v2 does not support remote_url')); reject(new Error('Publish: v2 does not support remote_url'));
} }
const { uploadUrl, guid, ...sdkParams } = params; const payloadParams = Object.assign({}, params);
delete payloadParams.uploadUrl; // cleanup
const jsonPayload = JSON.stringify({ const jsonPayload = JSON.stringify({
jsonrpc: '2.0', jsonrpc: '2.0',
method: RESUMABLE_ENDPOINT_METHOD, method: RESUMABLE_ENDPOINT_METHOD,
params: sdkParams, params: payloadParams,
id: new Date().getTime(), id: new Date().getTime(),
}); });
@ -69,7 +70,7 @@ export function makeResumableUploadRequest(
filetype: file instanceof File ? file.type : undefined, filetype: file instanceof File ? file.type : undefined,
}, },
onShouldRetry: (err, retryAttempt, options) => { onShouldRetry: (err, retryAttempt, options) => {
window.store.dispatch(doUpdateUploadProgress({ guid, status: 'retry' })); window.store.dispatch(doUpdateUploadProgress({ params, status: 'retry' }));
const status = err.originalResponse ? err.originalResponse.getStatus() : 0; const status = err.originalResponse ? err.originalResponse.getStatus() : 0;
return !inStatusCategory(status, 400); return !inStatusCategory(status, 400);
}, },
@ -78,17 +79,17 @@ export function makeResumableUploadRequest(
const errMsg = typeof err === 'string' ? err : err.message; const errMsg = typeof err === 'string' ? err : err.message;
if (status === STATUS_CONFLICT || status === STATUS_LOCKED || errMsg === 'file currently locked') { if (status === STATUS_CONFLICT || status === STATUS_LOCKED || errMsg === 'file currently locked') {
window.store.dispatch(doUpdateUploadProgress({ guid, status: 'conflict' })); window.store.dispatch(doUpdateUploadProgress({ params, status: 'conflict' }));
// prettier-ignore // prettier-ignore
reject(new Error(`${status}: concurrent upload detected. Uploading the same file from multiple tabs or windows is not allowed.`)); reject(new Error(`${status}: concurrent upload detected. Uploading the same file from multiple tabs or windows is not allowed.`));
} else { } else {
window.store.dispatch(doUpdateUploadProgress({ guid, status: 'error' })); window.store.dispatch(doUpdateUploadProgress({ params, status: 'error' }));
reject(new Error(err)); reject(new Error(err));
} }
}, },
onProgress: (bytesUploaded, bytesTotal) => { onProgress: (bytesUploaded, bytesTotal) => {
const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2); const percentage = ((bytesUploaded / bytesTotal) * 100).toFixed(2);
window.store.dispatch(doUpdateUploadProgress({ guid, progress: percentage })); window.store.dispatch(doUpdateUploadProgress({ params, progress: percentage }));
}, },
onSuccess: () => { onSuccess: () => {
let retries = 1; let retries = 1;
@ -101,7 +102,7 @@ export function makeResumableUploadRequest(
xhr.setRequestHeader(X_LBRY_AUTH_TOKEN, token); xhr.setRequestHeader(X_LBRY_AUTH_TOKEN, token);
xhr.responseType = 'json'; xhr.responseType = 'json';
xhr.onload = () => { xhr.onload = () => {
window.store.dispatch(doUpdateUploadRemove(guid)); window.store.dispatch(doUpdateUploadRemove(params));
resolve(xhr); resolve(xhr);
}; };
xhr.onerror = () => { xhr.onerror = () => {
@ -110,12 +111,12 @@ export function makeResumableUploadRequest(
analytics.error('notify: first attempt failed (status=0). Retrying after 10s...'); analytics.error('notify: first attempt failed (status=0). Retrying after 10s...');
setTimeout(() => makeNotifyRequest(), 10000); // Auto-retry after 10s delay. setTimeout(() => makeNotifyRequest(), 10000); // Auto-retry after 10s delay.
} else { } else {
window.store.dispatch(doUpdateUploadProgress({ guid, status: 'error' })); window.store.dispatch(doUpdateUploadProgress({ params, status: 'error' }));
reject(new Error(`There was a problem in the processing. Please retry. (${xhr.status})`)); reject(new Error(`There was a problem in the processing. Please retry. (${xhr.status})`));
} }
}; };
xhr.onabort = () => { xhr.onabort = () => {
window.store.dispatch(doUpdateUploadRemove(guid)); window.store.dispatch(doUpdateUploadRemove(params));
}; };
xhr.send(jsonPayload); xhr.send(jsonPayload);

View file

@ -1,6 +1,5 @@
// @flow // @flow
import * as tus from 'tus-js-client'; import * as tus from 'tus-js-client';
import { v4 as uuid } from 'uuid';
import { makeUploadRequest } from './publish-v1'; import { makeUploadRequest } from './publish-v1';
import { makeResumableUploadRequest } from './publish-v2'; import { makeResumableUploadRequest } from './publish-v2';
@ -35,12 +34,6 @@ export default function apiPublishCallViaWeb(
params.file_path = '__POST_FILE__'; params.file_path = '__POST_FILE__';
} }
// Add a random ID to serve as the redux key.
// If it already exists, then it is a resumed session.
if (!params.guid) {
params.guid = uuid();
}
const useV1 = remoteUrl || preview || !tus.isSupported; const useV1 = remoteUrl || preview || !tus.isSupported;
// Note: both function signature (params) should match. // Note: both function signature (params) should match.