From 92dfdc6edd6f214aa50500d56f0ef6ecc062de44 Mon Sep 17 00:00:00 2001 From: Alexis Svinartchouk Date: Tue, 25 Aug 2020 11:51:28 +0200 Subject: [PATCH] URL selector cancel button cancels ongoing url selection Changelog-entry: URL selector cancel button cancels ongoing url selection Change-type: patch --- .../source-selector/source-selector.tsx | 188 ++++++++++-------- 1 file changed, 108 insertions(+), 80 deletions(-) diff --git a/lib/gui/app/components/source-selector/source-selector.tsx b/lib/gui/app/components/source-selector/source-selector.tsx index 92ac1c3f..7d8fa78f 100644 --- a/lib/gui/app/components/source-selector/source-selector.tsx +++ b/lib/gui/app/components/source-selector/source-selector.tsx @@ -290,7 +290,7 @@ export class SourceSelector extends React.Component< await this.selectImageByPath({ imagePath, SourceType: isURL ? sourceDestination.Http : sourceDestination.File, - }); + }).promise; } private reselectImage() { @@ -346,74 +346,97 @@ export class SourceSelector extends React.Component< } } - private async selectImageByPath({ imagePath, SourceType }: SourceOptions) { - try { - imagePath = await replaceWindowsNetworkDriveLetter(imagePath); - } catch (error) { - analytics.logException(error); - } + private selectImageByPath({ + imagePath, + SourceType, + }: SourceOptions): { promise: Promise; cancel: () => void } { + let cancelled = false; + return { + cancel: () => { + cancelled = true; + }, + promise: (async () => { + try { + imagePath = await replaceWindowsNetworkDriveLetter(imagePath); + } catch (error) { + analytics.logException(error); + } + if (cancelled) { + return; + } - let source; - if (SourceType === sourceDestination.File) { - source = new sourceDestination.File({ - path: imagePath, - }); - } else { - if ( - !imagePath.startsWith('https://') && - !imagePath.startsWith('http://') - ) { - const invalidImageError = errors.createUserError({ - title: 'Unsupported protocol', - description: messages.error.unsupportedProtocol(), - }); + let source; + if (SourceType === sourceDestination.File) { + source = new sourceDestination.File({ + path: imagePath, + }); + } else { + if ( + !imagePath.startsWith('https://') && + !imagePath.startsWith('http://') + ) { + const invalidImageError = errors.createUserError({ + title: 'Unsupported protocol', + description: messages.error.unsupportedProtocol(), + }); - osDialog.showError(invalidImageError); - analytics.logEvent('Unsupported protocol', { path: imagePath }); - return; - } - source = new sourceDestination.Http({ url: imagePath }); - } + osDialog.showError(invalidImageError); + analytics.logEvent('Unsupported protocol', { path: imagePath }); + return; + } + source = new sourceDestination.Http({ url: imagePath }); + } - try { - const innerSource = await source.getInnerSource(); - const metadata = (await innerSource.getMetadata()) as sourceDestination.Metadata & { - hasMBR: boolean; - partitions: MBRPartition[] | GPTPartition[]; - path: string; - extension: string; - }; - const partitionTable = await innerSource.getPartitionTable(); - if (partitionTable) { - metadata.hasMBR = true; - metadata.partitions = partitionTable.partitions; - } else { - metadata.hasMBR = false; - } - metadata.path = imagePath; - metadata.extension = path.extname(imagePath).slice(1); - this.selectImage(metadata); - this.afterSelected({ - imagePath, - SourceType, - }); - } catch (error) { - const imageError = errors.createUserError({ - title: 'Error opening image', - description: messages.error.openImage( - path.basename(imagePath), - error.message, - ), - }); - osDialog.showError(imageError); - analytics.logException(error); - } finally { - try { - await source.close(); - } catch (error) { - // Noop - } - } + try { + const innerSource = await source.getInnerSource(); + if (cancelled) { + return; + } + const metadata = (await innerSource.getMetadata()) as sourceDestination.Metadata & { + hasMBR: boolean; + partitions: MBRPartition[] | GPTPartition[]; + path: string; + extension: string; + }; + if (cancelled) { + return; + } + const partitionTable = await innerSource.getPartitionTable(); + if (cancelled) { + return; + } + if (partitionTable) { + metadata.hasMBR = true; + metadata.partitions = partitionTable.partitions; + } else { + metadata.hasMBR = false; + } + metadata.path = imagePath; + metadata.extension = path.extname(imagePath).slice(1); + this.selectImage(metadata); + this.afterSelected({ + imagePath, + SourceType, + }); + } catch (error) { + const imageError = errors.createUserError({ + title: 'Error opening image', + description: messages.error.openImage( + path.basename(imagePath), + error.message, + ), + }); + osDialog.showError(imageError); + analytics.logException(error); + } finally { + try { + await source.close(); + } catch (error) { + // Noop + } + } + })(), + }; } private async openImageSelector() { @@ -427,22 +450,22 @@ export class SourceSelector extends React.Component< analytics.logEvent('Image selector closed'); return; } - this.selectImageByPath({ + await this.selectImageByPath({ imagePath, SourceType: sourceDestination.File, - }); + }).promise; } catch (error) { exceptionReporter.report(error); } } - private onDrop(event: React.DragEvent) { + private async onDrop(event: React.DragEvent) { const [file] = event.dataTransfer.files; if (file) { - this.selectImageByPath({ + await this.selectImageByPath({ imagePath: file.path, SourceType: sourceDestination.File, - }); + }).promise; } } @@ -486,6 +509,9 @@ export class SourceSelector extends React.Component< const imageName = selectionState.getImageName(); const imageSize = selectionState.getImageSize(); const imageLogo = selectionState.getImageLogo(); + let cancelURLSelection = () => { + // noop + }; return ( <> @@ -587,6 +613,7 @@ export class SourceSelector extends React.Component< {showURLSelector && ( { + cancelURLSelection(); this.setState({ showURLSelector: false, }); @@ -596,16 +623,17 @@ export class SourceSelector extends React.Component< // if no file was resolved from the dialog. if (!imageURL) { analytics.logEvent('URL selector closed'); - this.setState({ - showURLSelector: false, - }); - return; + } else { + let promise; + ({ + promise, + cancel: cancelURLSelection, + } = this.selectImageByPath({ + imagePath: imageURL, + SourceType: sourceDestination.Http, + })); + await promise; } - - await this.selectImageByPath({ - imagePath: imageURL, - SourceType: sourceDestination.Http, - }); this.setState({ showURLSelector: false, });