@@ -21,8 +21,7 @@ import {
2121 getAbortFunction ,
2222 getCheckedSharingOptions ,
2323 getFilenameString ,
24- getDownloadSize ,
25- getCompressedProfileBlob ,
24+ getSanitizedProfileData ,
2625 getUploadPhase ,
2726 getUploadProgress ,
2827 getUploadProgressString ,
@@ -32,6 +31,7 @@ import {
3231import { getTimelineTrackOrganization } from 'firefox-profiler/selectors/url-state' ;
3332import { BlobUrlLink } from 'firefox-profiler/components/shared/BlobUrlLink' ;
3433import { assertExhaustiveCheck } from 'firefox-profiler/utils/flow' ;
34+ import prettyBytes from 'firefox-profiler/utils/pretty-bytes' ;
3535
3636import explicitConnect , {
3737 type ConnectedProps ,
@@ -59,14 +59,13 @@ type StateProps = {|
5959 + shouldShowPreferenceOption : boolean ,
6060 + profileContainsPrivateBrowsingInformation : boolean ,
6161 + checkedSharingOptions : CheckedSharingOptions ,
62- + downloadSizePromise : Promise < string > ,
63- + compressedProfileBlobPromise : Promise < Blob > ,
62+ + sanitizedProfileDataPromise : Promise < Uint8Array > ,
6463 + downloadFileName : string ,
6564 + uploadPhase : UploadPhase ,
6665 + uploadProgress : number ,
6766 + uploadProgressString : string ,
6867 + shouldSanitizeByDefault : boolean ,
69- + error : mixed ,
68+ + uploadError : mixed ,
7069 + abortFunction : ( ) = > mixed ,
7170 + timelineTrackOrganizationType : 'full' | 'active-tab' | 'origins' ,
7271| } ;
@@ -78,8 +77,16 @@ type DispatchProps = {|
7877| } ;
7978
8079type PublishProps = ConnectedProps < OwnProps , StateProps , DispatchProps > ;
80+ type PublishState = { |
81+ compressError : Error | string | null ,
82+ prevCompressedPromise : Promise < Uint8Array > | null ,
83+ | } ;
8184
82- class MenuButtonsPublishImpl extends React . PureComponent < PublishProps > {
85+ class MenuButtonsPublishImpl extends React . PureComponent <
86+ PublishProps ,
87+ PublishState
88+ > {
89+ state = { compressError : null , prevCompressedPromise : null } ;
8390 _toggles : { [ $Keys < CheckedSharingOptions > ] : ( ) => mixed } = {
8491 includeHiddenThreads : ( ) =>
8592 this . props . toggleCheckedSharingOptions ( 'includeHiddenThreads' ) ,
@@ -120,14 +127,31 @@ class MenuButtonsPublishImpl extends React.PureComponent<PublishProps> {
120127 ) ;
121128 }
122129
130+ static getDerivedStateFromProps (
131+ props : PublishProps ,
132+ state : PublishState
133+ ) : $Shape < PublishState > | null {
134+ if ( state . prevCompressedPromise !== props . sanitizedProfileDataPromise ) {
135+ return {
136+ // Invalidate the old error info
137+ prevCompressedPromise : props . sanitizedProfileDataPromise ,
138+ compressError : null ,
139+ } ;
140+ }
141+ return null ;
142+ }
143+
144+ _onCompressError = ( error ) => {
145+ this . setState ( { compressError : error } ) ;
146+ } ;
147+
123148 _renderPublishPanel ( ) {
124149 const {
125150 shouldShowPreferenceOption,
126151 profileContainsPrivateBrowsingInformation,
127- downloadSizePromise ,
152+ sanitizedProfileDataPromise ,
128153 attemptToPublish,
129154 downloadFileName,
130- compressedProfileBlobPromise,
131155 shouldSanitizeByDefault,
132156 isRepublish,
133157 timelineTrackOrganizationType,
@@ -222,15 +246,26 @@ class MenuButtonsPublishImpl extends React.PureComponent<PublishProps> {
222246 )
223247 : null }
224248 </ div >
249+ { this . state . compressError ? (
250+ < div className = "photon-message-bar photon-message-bar-error photon-message-bar-inner-content" >
251+ < div className = "photon-message-bar-inner-text" >
252+ < Localized id = "MenuButtons--publish--error-while-compressing" >
253+ Error while compressing, try unchecking some checkboxes to
254+ reduce the profile size.
255+ </ Localized >
256+ </ div >
257+ </ div >
258+ ) : null }
225259 < div className = "menuButtonsPublishButtons" >
226260 < DownloadButton
227261 downloadFileName = { downloadFileName }
228- compressedProfileBlobPromise = { compressedProfileBlobPromise }
229- downloadSizePromise = { downloadSizePromise }
262+ sanitizedProfileDataPromise = { sanitizedProfileDataPromise }
263+ onCompressError = { this . _onCompressError }
230264 />
231265 < button
232266 type = "submit"
233267 className = "photon-button photon-button-primary menuButtonsPublishButton menuButtonsPublishButtonsUpload"
268+ disabled = { this . state . compressError }
234269 >
235270 < span className = "menuButtonsPublishButtonsSvg menuButtonsPublishButtonsSvgUpload" />
236271 < Localized id = "MenuButtons--publish--button-upload" >
@@ -249,8 +284,7 @@ class MenuButtonsPublishImpl extends React.PureComponent<PublishProps> {
249284 uploadProgressString,
250285 abortFunction,
251286 downloadFileName,
252- compressedProfileBlobPromise,
253- downloadSizePromise,
287+ sanitizedProfileDataPromise,
254288 } = this . props ;
255289
256290 return (
@@ -277,8 +311,8 @@ class MenuButtonsPublishImpl extends React.PureComponent<PublishProps> {
277311 < div className = "menuButtonsPublishButtons" >
278312 < DownloadButton
279313 downloadFileName = { downloadFileName }
280- compressedProfileBlobPromise = { compressedProfileBlobPromise }
281- downloadSizePromise = { downloadSizePromise }
314+ sanitizedProfileDataPromise = { sanitizedProfileDataPromise }
315+ onCompressError = { this . _onCompressError }
282316 />
283317 < button
284318 type = "button"
@@ -295,7 +329,7 @@ class MenuButtonsPublishImpl extends React.PureComponent<PublishProps> {
295329 }
296330
297331 _renderErrorPanel ( ) {
298- const { error, resetUploadState } = this . props ;
332+ const { uploadError : error , resetUploadState } = this . props ;
299333 let message : string =
300334 'There was an unknown error when trying to upload the profile.' ;
301335 if (
@@ -365,13 +399,12 @@ export const MenuButtonsPublish = explicitConnect<
365399 profileContainsPrivateBrowsingInformation :
366400 getContainsPrivateBrowsingInformation ( state ) ,
367401 checkedSharingOptions : getCheckedSharingOptions ( state ) ,
368- downloadSizePromise : getDownloadSize ( state ) ,
369402 downloadFileName : getFilenameString ( state ) ,
370- compressedProfileBlobPromise : getCompressedProfileBlob ( state ) ,
403+ sanitizedProfileDataPromise : getSanitizedProfileData ( state ) ,
371404 uploadPhase : getUploadPhase ( state ) ,
372405 uploadProgress : getUploadProgress ( state ) ,
373406 uploadProgressString : getUploadProgressString ( state ) ,
374- error : getUploadError ( state ) ,
407+ uploadError : getUploadError ( state ) ,
375408 shouldSanitizeByDefault : getShouldSanitizeByDefault ( state ) ,
376409 abortFunction : getAbortFunction ( state ) ,
377410 timelineTrackOrganizationType : getTimelineTrackOrganization ( state ) . type ,
@@ -384,69 +417,16 @@ export const MenuButtonsPublish = explicitConnect<
384417 component : MenuButtonsPublishImpl ,
385418} ) ;
386419
387- type DownloadSizeProps = { |
388- + downloadSizePromise : Promise < string > ,
389- | } ;
390-
391- type DownloadSizeState = { |
392- downloadSize : string | null ,
393- | } ;
394-
395- /**
396- * The DownloadSize handles unpacking the downloadSizePromise.
397- */
398- class DownloadSize extends React . PureComponent <
399- DownloadSizeProps ,
400- DownloadSizeState
401- > {
402- _isMounted : boolean = true ;
403-
404- state = {
405- downloadSize : null ,
406- } ;
407-
408- _unwrapPromise ( ) {
409- const { downloadSizePromise } = this . props ;
410- downloadSizePromise . then ( ( downloadSize ) => {
411- if ( this . _isMounted ) {
412- this . setState ( { downloadSize } ) ;
413- }
414- } ) ;
415- }
416-
417- componentDidUpdate ( prevProps : DownloadSizeProps ) {
418- if ( prevProps . downloadSizePromise !== this . props . downloadSizePromise ) {
419- this . _unwrapPromise ( ) ;
420- }
421- }
422-
423- componentDidMount ( ) {
424- this . _isMounted = true ;
425- this . _unwrapPromise ( ) ;
426- }
427-
428- componentWillUnmount ( ) {
429- this . _isMounted = false ;
430- }
431-
432- render ( ) {
433- const { downloadSize } = this . state ;
434- if ( downloadSize === null ) {
435- return null ;
436- }
437- return < span className = "menuButtonsDownloadSize" > ({ downloadSize } )</ span > ;
438- }
439- }
440-
441420type DownloadButtonProps = { |
442- + compressedProfileBlobPromise : Promise < Blob > ,
443- + downloadSizePromise : Promise < string > ,
421+ + sanitizedProfileDataPromise : Promise < Uint8Array > ,
444422 + downloadFileName : string ,
423+ + onCompressError : ( Error | string ) = > mixed ,
445424| } ;
446425
447426type DownloadButtonState = { |
448- compressedProfileBlob : Blob | null ,
449- prevPromise : Promise < Blob > | null ,
427+ sanitizedProfileData : Uint8Array | null ,
428+ prevPromise : Promise < Uint8Array > | null ,
429+ error : Error | string | null ,
450430| } ;
451431
452432/**
@@ -458,31 +438,42 @@ class DownloadButton extends React.PureComponent<
458438> {
459439 _isMounted : boolean = false ;
460440 state = {
461- compressedProfileBlob : null ,
441+ sanitizedProfileData : null ,
462442 prevPromise : null ,
443+ error : null ,
463444 } ;
464445
465446 static getDerivedStateFromProps (
466447 props : DownloadButtonProps ,
467448 state : DownloadButtonState
468449 ) : $Shape < DownloadButtonState > | null {
469- if ( state . prevPromise !== props . compressedProfileBlobPromise ) {
450+ if ( state . prevPromise !== props . sanitizedProfileDataPromise ) {
470451 return {
471452 // Invalidate the old download size.
472- compressedProfileBlob : null ,
473- prevPromise : props . compressedProfileBlobPromise ,
453+ sanitizedProfileData : null ,
454+ prevPromise : props . sanitizedProfileDataPromise ,
455+ error : null ,
474456 } ;
475457 }
476458 return null ;
477459 }
478460
479461 _unwrapPromise ( ) {
480- const { compressedProfileBlobPromise } = this . props ;
481- compressedProfileBlobPromise . then ( ( compressedProfileBlob ) => {
482- if ( this . _isMounted ) {
483- this . setState ( { compressedProfileBlob } ) ;
462+ const { sanitizedProfileDataPromise } = this . props ;
463+ sanitizedProfileDataPromise . then (
464+ ( sanitizedProfileData ) => {
465+ if ( this . _isMounted ) {
466+ this . setState ( { sanitizedProfileData, error : null } ) ;
467+ }
468+ } ,
469+ ( error ) => {
470+ if ( this . _isMounted ) {
471+ this . props . onCompressError ( error ) ;
472+ console . error ( 'Error while compressing the profile data' , error ) ;
473+ this . setState ( { sanitizedProfileData : null , error } ) ;
474+ }
484475 }
485- } ) ;
476+ ) ;
486477 }
487478
488479 componentDidMount ( ) {
@@ -492,8 +483,8 @@ class DownloadButton extends React.PureComponent<
492483
493484 componentDidUpdate ( prevProps : DownloadButtonProps ) {
494485 if (
495- prevProps . compressedProfileBlobPromise !==
496- this . props . compressedProfileBlobPromise
486+ prevProps . sanitizedProfileDataPromise !==
487+ this . props . sanitizedProfileDataPromise
497488 ) {
498489 this . _unwrapPromise ( ) ;
499490 }
@@ -504,25 +495,38 @@ class DownloadButton extends React.PureComponent<
504495 }
505496
506497 render ( ) {
507- const { downloadFileName, downloadSizePromise } = this . props ;
508- const { compressedProfileBlob } = this . state ;
498+ const { downloadFileName } = this . props ;
499+ const { sanitizedProfileData , error } = this . state ;
509500 const className =
510501 'photon-button menuButtonsPublishButton menuButtonsPublishButtonsDownload' ;
511502
512- if ( compressedProfileBlob ) {
503+ if ( sanitizedProfileData ) {
504+ const blob = new Blob ( [ sanitizedProfileData ] , {
505+ type : 'application/octet-binary' ,
506+ } ) ;
513507 return (
514508 < BlobUrlLink
515- blob = { compressedProfileBlob }
509+ blob = { blob }
516510 download = { `${ downloadFileName } .gz` }
517511 className = { className }
518512 >
519513 < span className = "menuButtonsPublishButtonsSvg menuButtonsPublishButtonsSvgDownload" />
520514 < Localized id = "MenuButtons--publish--download" > Download</ Localized > { ' ' }
521- < DownloadSize downloadSizePromise = { downloadSizePromise } />
515+ < span className = "menuButtonsDownloadSize" >
516+ ({ prettyBytes ( blob . size ) } )
517+ </ span >
522518 </ BlobUrlLink >
523519 ) ;
524520 }
525521
522+ if ( error ) {
523+ return (
524+ < button type = "button" className = { className } disabled >
525+ < Localized id = "MenuButtons--publish--download" > Download</ Localized >
526+ </ button >
527+ ) ;
528+ }
529+
526530 return (
527531 < button
528532 type = "button"
0 commit comments