Upload: fix redux key clash

## Issue
`params` is the "final" value that will be passed to the SDK and  `channel` is not a valid argument (it should be `channel_name`). Also, it seems like we only pass the channel ID now and skip the channel name entirely.

For the anonymous case, a clash will still happen when since the channel part is hardcoded to `anonymous`.

## Approach
Generate a guid in `params` and use that as the key to handle all the cases above. We couldn't use the `uploadUrl` because v1 doesn't have it.

The old formula is retained to allow users to retry or cancel their existing uploads one last time (otherwise it will persist forever). The next upload will be using the new key.
This commit is contained in:
infinite-persistence 2021-12-06 11:25:03 +08:00
parent 994d9c6027
commit ded021cc76
No known key found for this signature in database
GPG key ID: B9C3252EDC3D0AA0
6 changed files with 24 additions and 12 deletions

View file

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

View file

@ -23,6 +23,10 @@ export default function WebUploadItem(props: Props) {
if (serializeFileObj(newFile) === fileFingerprint) {
setShowFileSelector(false);
doPublishResume({ ...params, file_path: newFile });
if (!params.guid) {
// Can remove this if-block after January 2022.
doUpdateUploadRemove(params);
}
} else {
doOpenModal(MODALS.CONFIRM, {
title: __('Invalid file'),

View file

@ -6,7 +6,9 @@ import * as ACTIONS from 'constants/action_types';
import * as THUMBNAIL_STATUSES from 'constants/thumbnail_upload_statuses';
import { CHANNEL_ANONYMOUS } from 'constants/claim';
const getKeyFromParam = (params) => `${params.name}#${params.channel || 'anonymous'}`;
// This is the old key formula. Retain it for now to allow users to delete
// any pending uploads. Can be removed from January 2022 onwards.
const getOldKeyFromParam = (params) => `${params.name}#${params.channel || 'anonymous'}`;
type PublishState = {
editingURI: ?string,
@ -138,10 +140,9 @@ export const publishReducer = handleActions(
},
[ACTIONS.UPDATE_UPLOAD_ADD]: (state: PublishState, action) => {
const { file, params, uploader } = action.data;
const key = getKeyFromParam(params);
const currentUploads = Object.assign({}, state.currentUploads);
currentUploads[key] = {
currentUploads[params.guid] = {
file,
fileFingerprint: file ? serializeFileObj(file) : undefined, // TODO: get hash instead?
progress: '0',
@ -154,7 +155,7 @@ export const publishReducer = handleActions(
},
[ACTIONS.UPDATE_UPLOAD_PROGRESS]: (state: PublishState, action) => {
const { params, progress, status } = action.data;
const key = getKeyFromParam(params);
const key = params.guid || getOldKeyFromParam(params);
const currentUploads = Object.assign({}, state.currentUploads);
if (!currentUploads[key]) {
@ -181,11 +182,9 @@ export const publishReducer = handleActions(
},
[ACTIONS.UPDATE_UPLOAD_REMOVE]: (state: PublishState, action) => {
const { params } = action.data;
const key = getKeyFromParam(params);
const key = params.guid || getOldKeyFromParam(params);
const currentUploads = Object.assign({}, state.currentUploads);
delete currentUploads[key];
return { ...state, currentUploads };
},
[ACTIONS.REHYDRATE]: (state: PublishState, action) => {

View file

@ -30,10 +30,12 @@ export function makeUploadRequest(
delete params['remote_url'];
}
const { uploadUrl, guid, ...sdkParams } = params;
const jsonPayload = JSON.stringify({
jsonrpc: '2.0',
method: ENDPOINT_METHOD,
params,
params: sdkParams,
id: new Date().getTime(),
});

View file

@ -38,13 +38,12 @@ export function makeResumableUploadRequest(
reject(new Error('Publish: v2 does not support remote_url'));
}
const payloadParams = Object.assign({}, params);
delete payloadParams.uploadUrl; // cleanup
const { uploadUrl, guid, ...sdkParams } = params;
const jsonPayload = JSON.stringify({
jsonrpc: '2.0',
method: RESUMABLE_ENDPOINT_METHOD,
params: payloadParams,
params: sdkParams,
id: new Date().getTime(),
});

View file

@ -1,5 +1,6 @@
// @flow
import * as tus from 'tus-js-client';
import { v4 as uuid } from 'uuid';
import { makeUploadRequest } from './publish-v1';
import { makeResumableUploadRequest } from './publish-v2';
@ -34,6 +35,12 @@ export default function apiPublishCallViaWeb(
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;
// Note: both function signature (params) should match.