From 38f511c2fb0d98a18542eb3968b4859a692c0cc9 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Fri, 5 Nov 2021 08:38:51 +0800 Subject: [PATCH] Move 'currentUploads' to 'publish' reducer `publish` is currently rehydrated, so we can ride on that and don't need to store the `currentUploads` in `localStorage` for persistence. This would allow us to store Markdown Post data too, as `localStorage` has a 5MB limit per app. We could have also made `webReducer` rehydrate, but in this repo, there is no need to split it to another reducer. It also makes more sense to be part of publish anyway (at least to me). This change is mostly moving items between files, with the exception of 1. An additional REHYDRATE in the publish reducer to clean up the tusUploader. 2. Not clearing `currentUploads` in CLEAR_PUBLISH. --- extras/lbryinc/constants/action_types.js | 3 - extras/lbryinc/index.js | 3 - extras/lbryinc/redux/actions/web.js | 30 --------- extras/lbryinc/redux/reducers/web.js | 81 ------------------------ extras/lbryinc/redux/selectors/web.js | 10 --- flow-typed/File.js | 9 --- flow-typed/publish.js | 9 +++ ui/component/app/index.js | 2 +- ui/component/webUploadList/index.js | 4 +- ui/constants/action_types.js | 8 +-- ui/page/fileListPublished/index.js | 2 +- ui/reducers.js | 3 +- ui/redux/actions/publish.js | 28 ++++++++ ui/redux/reducers/publish.js | 64 +++++++++++++++++++ ui/redux/selectors/publish.js | 7 ++ web/setup/publish.js | 2 +- 16 files changed, 117 insertions(+), 148 deletions(-) delete mode 100644 extras/lbryinc/redux/actions/web.js delete mode 100644 extras/lbryinc/redux/reducers/web.js delete mode 100644 extras/lbryinc/redux/selectors/web.js diff --git a/extras/lbryinc/constants/action_types.js b/extras/lbryinc/constants/action_types.js index 82c3a819d..b978223c7 100644 --- a/extras/lbryinc/constants/action_types.js +++ b/extras/lbryinc/constants/action_types.js @@ -83,9 +83,6 @@ export const SYNC_APPLY_FAILED = 'SYNC_APPLY_FAILED'; export const SYNC_APPLY_BAD_PASSWORD = 'SYNC_APPLY_BAD_PASSWORD'; export const SYNC_RESET = 'SYNC_RESET'; -// Lbry.tv -export const UPDATE_UPLOAD_PROGRESS = 'UPDATE_UPLOAD_PROGRESS'; - // User export const GENERATE_AUTH_TOKEN_FAILURE = 'GENERATE_AUTH_TOKEN_FAILURE'; export const GENERATE_AUTH_TOKEN_STARTED = 'GENERATE_AUTH_TOKEN_STARTED'; diff --git a/extras/lbryinc/index.js b/extras/lbryinc/index.js index b62b3a998..cd87cad0c 100644 --- a/extras/lbryinc/index.js +++ b/extras/lbryinc/index.js @@ -27,7 +27,6 @@ export { doResetSync, doSyncEncryptAndDecrypt, } from 'redux/actions/sync'; -export { doUpdateUploadAdd, doUpdateUploadProgress, doUpdateUploadRemove } from './redux/actions/web'; // reducers export { authReducer } from './redux/reducers/auth'; @@ -37,7 +36,6 @@ export { filteredReducer } from './redux/reducers/filtered'; // export { homepageReducer } from './redux/reducers/homepage'; export { statsReducer } from './redux/reducers/stats'; export { syncReducer } from './redux/reducers/sync'; -export { webReducer } from './redux/reducers/web'; // selectors export { selectAuthToken, selectIsAuthenticating } from './redux/selectors/auth'; @@ -70,4 +68,3 @@ export { selectSyncApplyErrorMessage, selectSyncApplyPasswordError, } from './redux/selectors/sync'; -export { selectCurrentUploads, selectUploadCount } from './redux/selectors/web'; diff --git a/extras/lbryinc/redux/actions/web.js b/extras/lbryinc/redux/actions/web.js deleted file mode 100644 index 562d6e1a0..000000000 --- a/extras/lbryinc/redux/actions/web.js +++ /dev/null @@ -1,30 +0,0 @@ -// @flow -import * as ACTIONS from 'constants/action_types'; - -export function doUpdateUploadAdd(file: File, params: { [key: string]: any }, tusUploader: any) { - return (dispatch: Dispatch, getState: GetState) => { - dispatch({ - type: ACTIONS.UPDATE_UPLOAD_ADD, - data: { file, params, tusUploader }, - }); - }; -} - -export const doUpdateUploadProgress = (props: { - params: { [key: string]: any }, - progress?: string, - status?: string, -}) => (dispatch: Dispatch) => - dispatch({ - type: ACTIONS.UPDATE_UPLOAD_PROGRESS, - data: props, - }); - -export function doUpdateUploadRemove(params: { [key: string]: any }) { - return (dispatch: Dispatch, getState: GetState) => { - dispatch({ - type: ACTIONS.UPDATE_UPLOAD_REMOVE, - data: { params }, - }); - }; -} diff --git a/extras/lbryinc/redux/reducers/web.js b/extras/lbryinc/redux/reducers/web.js deleted file mode 100644 index 60ed9ccc5..000000000 --- a/extras/lbryinc/redux/reducers/web.js +++ /dev/null @@ -1,81 +0,0 @@ -// @flow -import * as ACTIONS from 'constants/action_types'; -import { serializeFileObj } from 'util/file'; - -const CURRENT_UPLOADS = 'current_uploads'; -const getKeyFromParam = (params) => `${params.name}#${params.channel || 'anonymous'}`; - -export type TvState = { - currentUploads: { [key: string]: FileUploadItem }, -}; - -const reducers = {}; - -const defaultState: TvState = { - currentUploads: {}, -}; - -try { - const uploads = JSON.parse(window.localStorage.getItem(CURRENT_UPLOADS)); - if (uploads) { - defaultState.currentUploads = uploads; - Object.keys(defaultState.currentUploads).forEach((key) => { - delete defaultState.currentUploads[key].tusUploader; - }); - } -} catch (e) { - console.log(e); -} - -reducers[ACTIONS.UPDATE_UPLOAD_ADD] = (state: TvState, action) => { - const { file, params, tusUploader } = action.data; - const key = getKeyFromParam(params); - const currentUploads = Object.assign({}, state.currentUploads); - - currentUploads[key] = { - file, - fileFingerprint: serializeFileObj(file), // TODO: get hash instead? - progress: '0', - params, - tusUploader, - }; - - window.localStorage.setItem(CURRENT_UPLOADS, JSON.stringify(currentUploads)); - return { ...state, currentUploads }; -}; - -reducers[ACTIONS.UPDATE_UPLOAD_PROGRESS] = (state: TvState, action) => { - const { params, progress, status } = action.data; - const key = getKeyFromParam(params); - const currentUploads = Object.assign({}, state.currentUploads); - - if (progress) { - currentUploads[key].progress = progress; - delete currentUploads[key].status; - } else if (status) { - currentUploads[key].status = status; - if (status === 'error') { - delete currentUploads[key].tusUploader; - } - } - - window.localStorage.setItem(CURRENT_UPLOADS, JSON.stringify(currentUploads)); - return { ...state, currentUploads }; -}; - -reducers[ACTIONS.UPDATE_UPLOAD_REMOVE] = (state: TvState, action) => { - const { params } = action.data; - const key = getKeyFromParam(params); - const currentUploads = Object.assign({}, state.currentUploads); - - delete currentUploads[key]; - - window.localStorage.setItem(CURRENT_UPLOADS, JSON.stringify(currentUploads)); - return { ...state, currentUploads }; -}; - -export function webReducer(state: TvState = defaultState, action: any) { - const handler = reducers[action.type]; - if (handler) return handler(state, action); - return state; -} diff --git a/extras/lbryinc/redux/selectors/web.js b/extras/lbryinc/redux/selectors/web.js deleted file mode 100644 index de676f837..000000000 --- a/extras/lbryinc/redux/selectors/web.js +++ /dev/null @@ -1,10 +0,0 @@ -import { createSelector } from 'reselect'; - -const selectState = (state) => state.web || {}; - -export const selectCurrentUploads = (state) => selectState(state).currentUploads; - -export const selectUploadCount = createSelector( - selectCurrentUploads, - (currentUploads) => currentUploads && Object.keys(currentUploads).length -); diff --git a/flow-typed/File.js b/flow-typed/File.js index 581319441..44dc4f398 100644 --- a/flow-typed/File.js +++ b/flow-typed/File.js @@ -76,12 +76,3 @@ declare type DeletePurchasedUri = { uri: string, }, }; - -declare type FileUploadItem = { - params: UpdatePublishFormData, - file: File, - fileFingerprint: string, - progress: string, - status?: string, - tusUploader?: any, -}; diff --git a/flow-typed/publish.js b/flow-typed/publish.js index f237b12c9..2ab052846 100644 --- a/flow-typed/publish.js +++ b/flow-typed/publish.js @@ -52,3 +52,12 @@ declare type PublishParams = { nsfw: boolean, tags: Array, }; + +declare type FileUploadItem = { + params: UpdatePublishFormData, + file: File, + fileFingerprint: string, + progress: string, + status?: string, + tusUploader?: any, +}; diff --git a/ui/component/app/index.js b/ui/component/app/index.js index 3c3563506..9103a2e0b 100644 --- a/ui/component/app/index.js +++ b/ui/component/app/index.js @@ -1,6 +1,5 @@ import { hot } from 'react-hot-loader/root'; import { connect } from 'react-redux'; -import { selectUploadCount } from 'lbryinc'; import { selectGetSyncErrorMessage, selectSyncFatalError } from 'redux/selectors/sync'; import { doFetchAccessToken, doUserSetReferrer } from 'redux/actions/user'; import { selectUser, selectAccessToken, selectUserVerifiedEmail } from 'redux/selectors/user'; @@ -22,6 +21,7 @@ import { selectActiveChannelClaim, selectIsReloadRequired, } from 'redux/selectors/app'; +import { selectUploadCount } from 'redux/selectors/publish'; import { doGetWalletSyncPreference, doSetLanguage } from 'redux/actions/settings'; import { doSyncLoop } from 'redux/actions/sync'; import { diff --git a/ui/component/webUploadList/index.js b/ui/component/webUploadList/index.js index 35a754c09..2c546f202 100644 --- a/ui/component/webUploadList/index.js +++ b/ui/component/webUploadList/index.js @@ -1,7 +1,7 @@ import { connect } from 'react-redux'; -import { selectCurrentUploads, selectUploadCount, doUpdateUploadRemove } from 'lbryinc'; import { doOpenModal } from 'redux/actions/app'; -import { doPublishResume } from 'redux/actions/publish'; +import { doPublishResume, doUpdateUploadRemove } from 'redux/actions/publish'; +import { selectCurrentUploads, selectUploadCount } from 'redux/selectors/publish'; import WebUploadList from './view'; const select = (state) => ({ diff --git a/ui/constants/action_types.js b/ui/constants/action_types.js index d5ca9bb96..3dbefc1e1 100644 --- a/ui/constants/action_types.js +++ b/ui/constants/action_types.js @@ -331,6 +331,9 @@ export const PUBLISH_FAIL = 'PUBLISH_FAIL'; export const CLEAR_PUBLISH_ERROR = 'CLEAR_PUBLISH_ERROR'; export const REMOVE_PENDING_PUBLISH = 'REMOVE_PENDING_PUBLISH'; export const DO_PREPARE_EDIT = 'DO_PREPARE_EDIT'; +export const UPDATE_UPLOAD_ADD = 'UPDATE_UPLOAD_ADD'; +export const UPDATE_UPLOAD_PROGRESS = 'UPDATE_UPLOAD_PROGRESS'; +export const UPDATE_UPLOAD_REMOVE = 'UPDATE_UPLOAD_REMOVE'; // Media export const MEDIA_PLAY = 'MEDIA_PLAY'; @@ -491,11 +494,6 @@ export const FETCH_SUB_COUNT_STARTED = 'FETCH_SUB_COUNT_STARTED'; export const FETCH_SUB_COUNT_FAILED = 'FETCH_SUB_COUNT_FAILED'; export const FETCH_SUB_COUNT_COMPLETED = 'FETCH_SUB_COUNT_COMPLETED'; -// Lbry.tv -export const UPDATE_UPLOAD_ADD = 'UPDATE_UPLOAD_ADD'; -export const UPDATE_UPLOAD_PROGRESS = 'UPDATE_UPLOAD_PROGRESS'; -export const UPDATE_UPLOAD_REMOVE = 'UPDATE_UPLOAD_REMOVE'; - // User export const GENERATE_AUTH_TOKEN_FAILURE = 'GENERATE_AUTH_TOKEN_FAILURE'; export const GENERATE_AUTH_TOKEN_STARTED = 'GENERATE_AUTH_TOKEN_STARTED'; diff --git a/ui/page/fileListPublished/index.js b/ui/page/fileListPublished/index.js index fe0188c00..a7a929049 100644 --- a/ui/page/fileListPublished/index.js +++ b/ui/page/fileListPublished/index.js @@ -5,9 +5,9 @@ import { selectMyClaimsPageItemCount, selectFetchingMyClaimsPageError, } from 'redux/selectors/claims'; +import { selectUploadCount } from 'redux/selectors/publish'; import { doFetchClaimListMine, doCheckPendingClaims } from 'redux/actions/claims'; import { doClearPublish } from 'redux/actions/publish'; -import { selectUploadCount } from 'lbryinc'; import FileListPublished from './view'; import { withRouter } from 'react-router'; import { MY_CLAIMS_PAGE_SIZE, PAGE_PARAM, PAGE_SIZE_PARAM } from 'constants/claim'; diff --git a/ui/reducers.js b/ui/reducers.js index 2728436b5..12457bdde 100644 --- a/ui/reducers.js +++ b/ui/reducers.js @@ -1,6 +1,6 @@ import { combineReducers } from 'redux'; import { connectRouter } from 'connected-react-router'; -import { costInfoReducer, blacklistReducer, filteredReducer, statsReducer, webReducer } from 'lbryinc'; +import { costInfoReducer, blacklistReducer, filteredReducer, statsReducer } from 'lbryinc'; import { claimsReducer } from 'redux/reducers/claims'; import { fileInfoReducer } from 'redux/reducers/file_info'; import { walletReducer } from 'redux/reducers/wallet'; @@ -50,6 +50,5 @@ export default (history) => user: userReducer, wallet: walletReducer, sync: syncReducer, - web: webReducer, collections: collectionsReducer, }); diff --git a/ui/redux/actions/publish.js b/ui/redux/actions/publish.js index 0a58d6d7e..b145b35eb 100644 --- a/ui/redux/actions/publish.js +++ b/ui/redux/actions/publish.js @@ -688,3 +688,31 @@ export const doCheckReflectingFiles = () => (dispatch: Dispatch, getState: GetSt }, 5000); } }; + +export function doUpdateUploadAdd(file: File | string, params: { [key: string]: any }, tusUploader: any) { + return (dispatch: Dispatch, getState: GetState) => { + dispatch({ + type: ACTIONS.UPDATE_UPLOAD_ADD, + data: { file, params, tusUploader }, + }); + }; +} + +export const doUpdateUploadProgress = (props: { + params: { [key: string]: any }, + progress?: string, + status?: string, +}) => (dispatch: Dispatch) => + dispatch({ + type: ACTIONS.UPDATE_UPLOAD_PROGRESS, + data: props, + }); + +export function doUpdateUploadRemove(params: { [key: string]: any }) { + return (dispatch: Dispatch, getState: GetState) => { + dispatch({ + type: ACTIONS.UPDATE_UPLOAD_REMOVE, + data: { params }, + }); + }; +} diff --git a/ui/redux/reducers/publish.js b/ui/redux/reducers/publish.js index 4b0b27149..d39d2d6d2 100644 --- a/ui/redux/reducers/publish.js +++ b/ui/redux/reducers/publish.js @@ -1,10 +1,13 @@ // @flow import { handleActions } from 'util/redux-utils'; import { buildURI } from 'util/lbryURI'; +import { serializeFileObj } from 'util/file'; 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'}`; + type PublishState = { editingURI: ?string, fileText: ?string, @@ -38,6 +41,7 @@ type PublishState = { tags: Array, optimize: boolean, useLBRYUploader: boolean, + currentUploads: { [key: string]: FileUploadItem }, }; const defaultState: PublishState = { @@ -78,6 +82,7 @@ const defaultState: PublishState = { publishError: undefined, optimize: false, useLBRYUploader: false, + currentUploads: {}, }; export const publishReducer = handleActions( @@ -96,6 +101,7 @@ export const publishReducer = handleActions( bid: state.bid, optimize: state.optimize, language: state.language, + currentUploads: state.currentUploads, }), [ACTIONS.PUBLISH_START]: (state: PublishState): PublishState => ({ ...state, @@ -127,8 +133,66 @@ export const publishReducer = handleActions( ...publishData, editingURI: uri, uri: shortUri, + currentUploads: state.currentUploads, }; }, + [ACTIONS.UPDATE_UPLOAD_ADD]: (state: PublishState, action) => { + const { file, params, tusUploader } = action.data; + const key = getKeyFromParam(params); + const currentUploads = Object.assign({}, state.currentUploads); + + currentUploads[key] = { + file, + fileFingerprint: serializeFileObj(file), // TODO: get hash instead? + progress: '0', + params, + tusUploader, + }; + + return { ...state, currentUploads }; + }, + [ACTIONS.UPDATE_UPLOAD_PROGRESS]: (state: PublishState, action) => { + const { params, progress, status } = action.data; + const key = getKeyFromParam(params); + const currentUploads = Object.assign({}, state.currentUploads); + + if (progress) { + currentUploads[key].progress = progress; + delete currentUploads[key].status; + } else if (status) { + currentUploads[key].status = status; + if (status === 'error') { + delete currentUploads[key].tusUploader; + } + } + + return { ...state, currentUploads }; + }, + [ACTIONS.UPDATE_UPLOAD_REMOVE]: (state: PublishState, action) => { + const { params } = action.data; + const key = getKeyFromParam(params); + const currentUploads = Object.assign({}, state.currentUploads); + + delete currentUploads[key]; + + return { ...state, currentUploads }; + }, + [ACTIONS.REHYDRATE]: (state: PublishState, action) => { + if (action && action.payload && action.payload.publish) { + const newPublish = { ...action.payload.publish }; + + // Cleanup for 'publish::currentUploads' + if (newPublish.currentUploads) { + Object.keys(newPublish.currentUploads).forEach((key) => { + delete newPublish.currentUploads[key].tusUploader; + }); + } + + return newPublish; + } + + return state; + }, }, defaultState ); diff --git a/ui/redux/selectors/publish.js b/ui/redux/selectors/publish.js index d75a45cae..b62103ba2 100644 --- a/ui/redux/selectors/publish.js +++ b/ui/redux/selectors/publish.js @@ -119,3 +119,10 @@ export const selectTakeOverAmount = createSelector( return null; } ); + +export const selectCurrentUploads = (state) => selectState(state).currentUploads; + +export const selectUploadCount = createSelector( + selectCurrentUploads, + (currentUploads) => currentUploads && Object.keys(currentUploads).length +); diff --git a/web/setup/publish.js b/web/setup/publish.js index 05bd42f29..f30908115 100644 --- a/web/setup/publish.js +++ b/web/setup/publish.js @@ -9,7 +9,7 @@ */ import * as tus from 'tus-js-client'; import { X_LBRY_AUTH_TOKEN } from '../../ui/constants/token'; -import { doUpdateUploadAdd, doUpdateUploadProgress, doUpdateUploadRemove } from 'lbryinc'; +import { doUpdateUploadAdd, doUpdateUploadProgress, doUpdateUploadRemove } from '../../ui/redux/actions/publish'; const UPLOAD_CHUNK_SIZE_BYTE = 100000000;