mirror of
https://github.com/balena-io/etcher.git
synced 2025-04-24 15:27:17 +00:00
feat(GUI): add button to cancel flash process (#2301)
We add a cancel button next to the flash progress bar that gracefully aborts the flash process. Closes: https://github.com/resin-io/etcher/issues/1791 Closes: https://github.com/resin-io/etcher/issues/2234 Closes: https://github.com/resin-io/etcher/issues/2245 Change-Type: patch Changelog-Entry: Add a button to cancel the flash process.
This commit is contained in:
parent
71064cc760
commit
674019ea75
@ -30,6 +30,7 @@ const permissions = require('../../../shared/permissions')
|
||||
const windowProgress = require('../os/window-progress')
|
||||
const analytics = require('../modules/analytics')
|
||||
const packageJSON = require('../../../../package.json')
|
||||
const selectionState = require('../../../shared/models/selection-state')
|
||||
|
||||
/**
|
||||
* @summary Number of threads per CPU to allocate to the UV_THREADPOOL
|
||||
@ -175,6 +176,13 @@ exports.performWrite = (image, drives, onProgress) => {
|
||||
_.merge(flashResults, event)
|
||||
})
|
||||
|
||||
ipc.server.on('abort', () => {
|
||||
terminateServer()
|
||||
resolve({
|
||||
cancelled: true
|
||||
})
|
||||
})
|
||||
|
||||
ipc.server.on('state', onProgress)
|
||||
|
||||
ipc.server.on('ready', (data, socket) => {
|
||||
@ -321,3 +329,28 @@ exports.flash = (image, drives) => {
|
||||
windowProgress.clear()
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Cancel write operation
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @example
|
||||
* imageWriter.cancel()
|
||||
*/
|
||||
exports.cancel = () => {
|
||||
analytics.logEvent('Cancel', {
|
||||
image: selectionState.getImagePath(),
|
||||
drives: selectionState.getSelectedDevices(),
|
||||
uuid: flashState.getFlashUuid(),
|
||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess')
|
||||
})
|
||||
|
||||
try {
|
||||
const [ socket ] = ipc.server.sockets
|
||||
ipc.server.emit(socket, 'cancel')
|
||||
} catch (error) {
|
||||
analytics.logException(error)
|
||||
}
|
||||
}
|
||||
|
@ -209,4 +209,14 @@ module.exports = function (
|
||||
|
||||
return progressStatus.fromFlashState(flashState.getFlashState())
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Abort write process
|
||||
* @function
|
||||
* @public
|
||||
*
|
||||
* @example
|
||||
* FlashController.cancelFlash()
|
||||
*/
|
||||
this.cancelFlash = imageWriter.cancel
|
||||
}
|
||||
|
@ -41,6 +41,10 @@ svg-icon > img[disabled] {
|
||||
min-width: $btn-min-width;
|
||||
}
|
||||
|
||||
.page-main .button-abort-write {
|
||||
margin-right: -35px;
|
||||
}
|
||||
|
||||
%step-border {
|
||||
height: 2px;
|
||||
background-color: $palette-theme-dark-foreground;
|
||||
|
@ -106,6 +106,12 @@
|
||||
<span ng-bind="flash.getProgressButtonLabel()"></span>
|
||||
</progress-button>
|
||||
|
||||
<button class="button button-link button-abort-write"
|
||||
ng-if="main.state.isFlashing()"
|
||||
ng-click="flash.cancelFlash()">
|
||||
<span class="glyphicon glyphicon-remove-sign"></span>
|
||||
</button>
|
||||
|
||||
<p class="step-footer step-footer-split" ng-if="main.state.getFlashState().speed && main.state.getFlashState().percentage != 100">
|
||||
<span ng-bind="main.state.getFlashState().speed.toFixed(2) + ' MB/s'"></span>
|
||||
<span>ETA: {{ main.state.getFlashState().eta | secondsToDate | amDateFormat:'m[m]ss[s]' }}</span>
|
||||
|
@ -6523,6 +6523,9 @@ svg-icon > img[disabled] {
|
||||
.page-main .button-brick {
|
||||
min-width: 170px; }
|
||||
|
||||
.page-main .button-abort-write {
|
||||
margin-right: -35px; }
|
||||
|
||||
.page-main .step-border-left, .page-main .step-border-right {
|
||||
height: 2px;
|
||||
background-color: #fff;
|
||||
|
@ -111,6 +111,8 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
||||
terminate(EXIT_CODES.SUCCESS)
|
||||
})
|
||||
|
||||
let writer = null
|
||||
|
||||
ipc.of[IPC_SERVER_ID].on('write', (options) => {
|
||||
const destinations = [].concat(options.destinations)
|
||||
|
||||
@ -146,6 +148,17 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
||||
terminate(exitCode)
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Abort handler
|
||||
* @example
|
||||
* writer.on('abort', onAbort)
|
||||
*/
|
||||
const onAbort = () => {
|
||||
log('Abort')
|
||||
ipc.of[IPC_SERVER_ID].emit('abort')
|
||||
terminate(exitCode)
|
||||
}
|
||||
|
||||
/**
|
||||
* @summary Error handler
|
||||
* @param {Error} error - error
|
||||
@ -171,7 +184,7 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
||||
})
|
||||
}
|
||||
|
||||
const writer = new ImageWriter({
|
||||
writer = new ImageWriter({
|
||||
verify: options.validateWriteOnSuccess,
|
||||
unmountOnSuccess: options.unmountOnSuccess,
|
||||
checksumAlgorithms: options.checksumAlgorithms || []
|
||||
@ -181,10 +194,17 @@ ipc.connectTo(IPC_SERVER_ID, () => {
|
||||
writer.on('fail', onFail)
|
||||
writer.on('progress', onProgress)
|
||||
writer.on('finish', onFinish)
|
||||
writer.on('abort', onAbort)
|
||||
|
||||
writer.write(options.imagePath, destinations)
|
||||
})
|
||||
|
||||
ipc.of[IPC_SERVER_ID].on('cancel', () => {
|
||||
if (writer) {
|
||||
writer.abort()
|
||||
}
|
||||
})
|
||||
|
||||
ipc.of[IPC_SERVER_ID].on('connect', () => {
|
||||
log(`Successfully connected to IPC server: ${IPC_SERVER_ID}, socket root ${ipc.config.socketRoot}`)
|
||||
ipc.of[IPC_SERVER_ID].emit('ready', {})
|
||||
|
@ -4,3 +4,4 @@ rules:
|
||||
no-param-reassign: off
|
||||
no-underscore-dangle: off
|
||||
lodash/prefer-lodash-method: off
|
||||
lodash/prefer-get: off
|
||||
|
@ -568,8 +568,8 @@ class ImageWriter extends EventEmitter {
|
||||
* imageWriter.abort()
|
||||
*/
|
||||
abort () {
|
||||
if (this.source) {
|
||||
this.source.destroy()
|
||||
if (this.source && this.source.stream) {
|
||||
this.source.stream.destroy()
|
||||
}
|
||||
this.emit('abort')
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user