feat(GUI): confirm before quitting etcher while writing (#868)

When Etcher is writing to a drive and the user closes the window,
currently there is no confirmation. This commit changes that and
the user has to confirm the exit.

Other changes include the warning modal taking a `rejectionLabel` option
that shows a reject button when provided.

Closes: https://github.com/resin-io/etcher/issues/744
Change-Type: minor
Changelog-Entry: Confirm before user quits while writing.
This commit is contained in:
Benedict Aas 2016-12-05 14:56:38 +00:00 committed by Juan Cruz Viotti
parent ae6b707bb4
commit e24c2b6466
5 changed files with 56 additions and 3 deletions

View File

@ -6269,6 +6269,8 @@ body {
.modal-text {
padding: 20px; }
.modal-text > p {
white-space: pre-line; }
.modal-text > p:last-child {
margin-bottom: 0; }

View File

@ -23,6 +23,8 @@
/* eslint-disable no-var */
var angular = require('angular');
const electron = require('electron');
const EXIT_CODES = require('../src/exit-codes');
/* eslint-enable no-var */
@ -48,6 +50,7 @@ const app = angular.module('Etcher', [
require('./components/svg-icon/svg-icon'),
require('./components/update-notifier/update-notifier'),
require('./components/drive-selector/drive-selector'),
require('./components/warning-modal/warning-modal'),
// Pages
require('./pages/main/main'),
@ -145,6 +148,45 @@ app.run(($timeout, DriveScannerService, DrivesModel, ErrorService, DriveSelector
DriveScannerService.start();
});
app.run(($window, WarningModalService, ErrorService, FlashStateModel) => {
let popupExists = false;
$window.addEventListener('beforeunload', (event) => {
// Don't close window while flashing
if (FlashStateModel.isFlashing()) {
event.returnValue = false;
}
if (popupExists) {
return;
}
// Don't open any more popups
popupExists = true;
WarningModalService.display({
confirmationLabel: 'Yes, quit',
rejectionLabel: 'Cancel',
description: [
'You are currently flashing a drive. Closing Etcher may leave',
'your drive in an unusable state.\n\nAre you sure you want to',
'close Etcher?'
].join(' ')
}).then((confirmed) => {
if (confirmed) {
// This circumvents the 'beforeunload' event unlike
// electron.remote.app.quit() which does not.
electron.remote.process.exit(EXIT_CODES.SUCCESS);
}
popupExists = false;
}).catch(ErrorService.reportException);
});
});
app.config(($urlRouterProvider) => {
$urlRouterProvider.otherwise('/main');
});

View File

@ -92,6 +92,10 @@
.modal-text {
padding: 20px;
> p {
white-space: pre-line;
}
> p:last-child {
margin-bottom: 0;
}

View File

@ -27,7 +27,8 @@ module.exports = function(ModalService) {
*
* @param {Object} options - options
* @param {String} options.description - danger message
* @param {String} options.confirmationLabel - danger message
* @param {String} options.confirmationLabel - confirmation button text
* @param {String} options.rejectionLabel - rejection button text
* @fulfil {Boolean} - whether the user accepted or rejected the warning
* @returns {Promise}
*

View File

@ -13,7 +13,11 @@
</div>
<div class="modal-footer">
<button class="button button-danger button-block"
ng-click="modal.accept()">{{ ::modal.options.confirmationLabel }}</button>
<div class="modal-menu">
<button class="button button-danger button-block"
ng-click="modal.accept()">{{ ::modal.options.confirmationLabel }}</button>
<button ng-if="modal.options.rejectionLabel" class="button button-block"
ng-click="modal.reject()">{{ ::modal.options.rejectionLabel }}</button>
</div>
</div>