-
Notifications
You must be signed in to change notification settings - Fork 344
feat(content-uploader): allow host app to reset upload items state #4617
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -110,6 +110,7 @@ export interface ContentUploaderProps { | |
| uploadHost: string; | ||
| useUploadsManager?: boolean; | ||
| enableModernizedUploads?: boolean; | ||
| setClearItemsCallback?: (callback: () => void) => void; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nvm I see what's happening here. why do you need to call the reset callback outside of ContentUploader? Ideally, all the functionality should live within the UI Element (ContentUploader) and not within the host applications. The UI Elements (like ContentUploader, ContentSidebar, etc) are supposed to be self-contained, essentially "uncontrolled" components. We publish these elements for external customers to use in their own applications. |
||
| } | ||
|
|
||
| type State = { | ||
|
|
@@ -213,13 +214,15 @@ class ContentUploader extends Component<ContentUploaderProps, State> { | |
| * @return {void} | ||
| */ | ||
| componentDidMount() { | ||
| const { setClearItemsCallback } = this.props; | ||
| this.rootElement = document.getElementById(this.id); | ||
| this.appElement = this.rootElement; | ||
| const { files, isPrepopulateFilesEnabled } = this.props; | ||
| // isPrepopulateFilesEnabled is a prop used to pre-populate files without clicking upload button. | ||
| if (isPrepopulateFilesEnabled && files && files.length > 0) { | ||
| this.addFilesToUploadQueue(files, this.upload); | ||
| } | ||
| setClearItemsCallback?.(this.resetUploadsManagerItemsWhenUploadsComplete); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -230,6 +233,8 @@ class ContentUploader extends Component<ContentUploaderProps, State> { | |
| * @return {void} | ||
| */ | ||
| componentWillUnmount() { | ||
| const { setClearItemsCallback } = this.props; | ||
| setClearItemsCallback?.(noop); | ||
| this.cancel(); | ||
| } | ||
|
|
||
|
|
@@ -1323,6 +1328,11 @@ class ContentUploader extends Component<ContentUploaderProps, State> { | |
| * @return {void} | ||
| */ | ||
| checkClearUploadItems = () => { | ||
| const { enableModernizedUploads } = this.props; | ||
| if (enableModernizedUploads) { | ||
| return; | ||
| } | ||
|
|
||
| this.resetItemsTimeout = setTimeout( | ||
| this.resetUploadsManagerItemsWhenUploadsComplete, | ||
| HIDE_UPLOAD_MANAGER_DELAY_MS_DEFAULT, | ||
|
|
@@ -1394,12 +1404,15 @@ class ContentUploader extends Component<ContentUploaderProps, State> { | |
| * @return {void} | ||
| */ | ||
| resetUploadsManagerItemsWhenUploadsComplete = (): void => { | ||
| const { onCancel, useUploadsManager } = this.props; | ||
| const { onCancel, useUploadsManager, enableModernizedUploads } = this.props; | ||
| const { isUploadsManagerExpanded, view } = this.state; | ||
|
|
||
| // Do not reset items when upload manger is expanded or there're uploads in progress | ||
| // Do not reset items when upload manger is expanded (for non-modernized uploader) or there're uploads in progress | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typo? manager instead of manger |
||
| if ( | ||
| (isUploadsManagerExpanded && useUploadsManager && !!this.itemsRef.current.length) || | ||
| (isUploadsManagerExpanded && | ||
| useUploadsManager && | ||
| !!this.itemsRef.current.length && | ||
| !enableModernizedUploads) || | ||
| view === VIEW_UPLOAD_IN_PROGRESS | ||
| ) { | ||
| return; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Question] Does the host only calls this while the uploader is visibly mounted? If not perhaps it's safer to add this as a no-op into componentWillUnmount()?
Please correct me if I'm wrong but here's the concern:
The callback registered via setClearItemsCallback gives the host app a direct reference to
this.resetUploadsManagerItemsWhenUploadsComplete. If ContentUploader unmounts while the host still holds that reference:this.setState(...)fires on an unmounted component (React will silently swallow it, but onCancel still fires against stale itemsRef data)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, makes sense, added setting of the clear callback to noop on unmount