From 224f10663dc836e30af59835091a678f6c9593c2 Mon Sep 17 00:00:00 2001 From: infinite-persistence Date: Fri, 10 Dec 2021 20:27:04 +0800 Subject: [PATCH] Prevent concurrent uploads with same lbry name ## Ticket 426 ## Issue Currently, we check if we have any existing claims with the same name when uploading, i.e. "lbry://". It does not include claims that you are still uploading, so you might end up with duplicate claims. In the ticket, there is also the issue of 2 uploads sharing the same slot, causing the progress indicator to jumpy between the uploads. That has been fixed by using a guid instead of using `name`. ## Aside I think there is another request to allow the same name but on different channel ... next time, next time .... --- static/app-strings.json | 1 + ui/component/publishName/index.js | 2 ++ ui/component/publishName/name-help-text.jsx | 24 ++++++++++++++++++++- ui/component/publishName/view.jsx | 3 +++ 4 files changed, 29 insertions(+), 1 deletion(-) diff --git a/static/app-strings.json b/static/app-strings.json index e79a29143..0acacacfc 100644 --- a/static/app-strings.json +++ b/static/app-strings.json @@ -1206,6 +1206,7 @@ "YB": "YB", "Edit existing claim instead": "Edit existing claim instead", "You already have a claim at %existing_uri%. Publishing will update (overwrite) your existing claim.": "You already have a claim at %existing_uri%. Publishing will update (overwrite) your existing claim.", + "You already have a pending upload at %existing_uri%.": "You already have a pending upload at %existing_uri%.", "Save": "Save", "Saved": "Saved", "Saving...": "Saving...", diff --git a/ui/component/publishName/index.js b/ui/component/publishName/index.js index 974309f36..9112121d6 100644 --- a/ui/component/publishName/index.js +++ b/ui/component/publishName/index.js @@ -5,6 +5,7 @@ import { selectIsStillEditing, selectMyClaimForUri, selectTakeOverAmount, + selectCurrentUploads, } from 'redux/selectors/publish'; import { selectActiveChannelClaim, selectIncognito } from 'redux/selectors/app'; import { doSetActiveChannel } from 'redux/actions/app'; @@ -15,6 +16,7 @@ const select = (state) => ({ uri: makeSelectPublishFormValue('uri')(state), isStillEditing: selectIsStillEditing(state), myClaimForUri: selectMyClaimForUri(state), + currentUploads: selectCurrentUploads(state), activeChannelClaim: selectActiveChannelClaim(state), incognito: selectIncognito(state), amountNeededForTakeover: selectTakeOverAmount(state), diff --git a/ui/component/publishName/name-help-text.jsx b/ui/component/publishName/name-help-text.jsx index c567e734a..f86c4a4a0 100644 --- a/ui/component/publishName/name-help-text.jsx +++ b/ui/component/publishName/name-help-text.jsx @@ -4,19 +4,41 @@ import Button from 'component/button'; import { buildURI } from 'util/lbryURI'; import I18nMessage from 'component/i18nMessage'; +function isUriPendingUpload(uri: ?string, currentUploadNames: Array) { + const protocol = 'lbry://'; + const uriName = uri && uri.startsWith(protocol) ? uri.substring(protocol.length) : uri; + return currentUploadNames.includes(uriName); +} + type Props = { uri: ?string, myClaimForUri: ?StreamClaim, + currentUploads: { [key: string]: FileUploadItem }, isStillEditing: boolean, onEditMyClaim: (any, string) => void, }; function NameHelpText(props: Props) { - const { uri, myClaimForUri, onEditMyClaim, isStillEditing } = props; + const { uri, myClaimForUri, currentUploads, onEditMyClaim, isStillEditing } = props; + + const currentUploadNames: Array = React.useMemo(() => { + // $FlowFixMe - unable to resolve mixed + return Object.values(currentUploads).map((x) => (x.params ? x.params.name : '')); + }, [currentUploads]); + let nameHelpText; if (isStillEditing) { nameHelpText = __('You are currently editing this claim.'); + } else if (isUriPendingUpload(uri, currentUploadNames)) { + nameHelpText = ( +
+ {/* prettier-ignore */} + {uri}) }}> + You already have a pending upload at %existing_uri%. + +
+ ); } else if (uri && myClaimForUri) { const editUri = buildURI({ streamName: myClaimForUri.name, diff --git a/ui/component/publishName/view.jsx b/ui/component/publishName/view.jsx index 3c5ff7f85..e2ec774b2 100644 --- a/ui/component/publishName/view.jsx +++ b/ui/component/publishName/view.jsx @@ -16,6 +16,7 @@ type Props = { updatePublishForm: ({}) => void, activeChannelClaim: ?ChannelClaim, incognito: boolean, + currentUploads: { [key: string]: FileUploadItem }, }; function PublishName(props: Props) { @@ -28,6 +29,7 @@ function PublishName(props: Props) { updatePublishForm, activeChannelClaim, incognito, + currentUploads, } = props; const [nameError, setNameError] = useState(undefined); const [blurred, setBlurred] = React.useState(false); @@ -84,6 +86,7 @@ function PublishName(props: Props) { uri={uri} isStillEditing={isStillEditing} myClaimForUri={myClaimForUri} + currentUploads={currentUploads} onEditMyClaim={editExistingClaim} />