etcher/lib/gui/app.js
Juan Cruz Viotti 5d54e2b7e3 feat(GUI): allow disabling auto-update notifications (#704)
This feature is very appealing when running Etcher ouside a common
desktop environment, for example, as a Resin.io application. In such a
platform, an update notifier that points the user to the website makes
no sense, since the platform itself is responsible for the update.

For such cases, we added support for an environment variable called
`ETCHER_DISABLE_UPDATES`, that when set, will prevent the update check
altogether.

Change-Type: minor
Changelog-Entry: Allow the user to disable auto-update notifications with an environment variable.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
2016-09-14 18:19:10 -07:00

168 lines
4.8 KiB
JavaScript

/*
* Copyright 2016 Resin.io
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @module Etcher
*/
'use strict';
/* eslint-disable no-var */
var angular = require('angular');
/* eslint-enable no-var */
const _ = require('lodash');
const Store = require('./models/store');
const app = angular.module('Etcher', [
require('angular-ui-router'),
require('angular-ui-bootstrap'),
require('angular-if-state'),
// Etcher modules
require('./modules/analytics'),
require('./modules/error'),
require('./modules/drive-scanner'),
// Models
require('./models/selection-state'),
require('./models/flash-state'),
require('./models/drives'),
// Components
require('./components/svg-icon/svg-icon'),
require('./components/update-notifier/update-notifier'),
require('./components/drive-selector/drive-selector'),
// Pages
require('./pages/main/main'),
require('./pages/finish/finish'),
require('./pages/settings/settings'),
// OS
require('./os/window-progress/window-progress'),
require('./os/open-external/open-external'),
// Utils
require('./utils/manifest-bind/manifest-bind')
]);
app.run((AnalyticsService, UpdateNotifierService, SelectionStateModel) => {
AnalyticsService.logEvent('Application start');
if (UpdateNotifierService.shouldCheckForUpdates() && !process.env.ETCHER_DISABLE_UPDATES) {
AnalyticsService.logEvent('Checking for updates');
UpdateNotifierService.isLatestVersion().then((isLatestVersion) => {
// In case the internet connection is not good and checking the
// latest published version takes too long, only show notify
// the user about the new version if he didn't start the flash
// process (e.g: selected an image), otherwise such interruption
// might be annoying.
if (!isLatestVersion && !SelectionStateModel.hasImage()) {
AnalyticsService.logEvent('Notifying update');
UpdateNotifierService.notify();
}
});
}
});
app.run((AnalyticsService, OSWindowProgressService, FlashStateModel) => {
Store.subscribe(() => {
const flashState = FlashStateModel.getFlashState();
// There is usually a short time period between the `isFlashing()`
// property being set, and the flashing actually starting, which
// might cause some non-sense flashing state logs including
// `undefined` values.
//
// We use the presence of `.eta` to determine that the actual
// writing started.
if (!FlashStateModel.isFlashing() || !flashState.eta) {
return;
}
AnalyticsService.logDebug([
`Progress (${flashState.type}):`,
`${flashState.percentage}% at ${flashState.speed} MB/s`,
`(eta ${flashState.eta}s)`
].join(' '));
OSWindowProgressService.set(flashState.percentage);
});
});
app.run(($timeout, DriveScannerService, DrivesModel, ErrorService, DriveSelectorService) => {
DriveScannerService.on('drives', (drives) => {
// Safely trigger a digest cycle.
// In some cases, AngularJS doesn't aknowledge that the
// available drives list has changed, and incorrectly
// keeps asking the user to "Connect a drive".
$timeout(() => {
DrivesModel.setDrives(drives);
});
if (_.isEmpty(drives)) {
DriveSelectorService.close();
}
});
DriveScannerService.on('error', ErrorService.reportException);
DriveScannerService.start();
});
app.config(($urlRouterProvider) => {
$urlRouterProvider.otherwise('/main');
});
app.config(($provide) => {
$provide.decorator('$exceptionHandler', ($delegate, $injector) => {
return (exception, cause) => {
const ErrorService = $injector.get('ErrorService');
ErrorService.reportException(exception);
$delegate(exception, cause);
};
});
});
app.controller('HeaderController', function(SelectionStateModel, OSOpenExternalService) {
/**
* @summary Open help page
* @function
* @public
*
* @description
* This application will open either the image's support url, declared
* in the archive `manifest.json`, or the default Etcher help page.
*
* @example
* HeaderController.openHelpPage();
*/
this.openHelpPage = () => {
const DEFAULT_SUPPORT_URL = 'https://github.com/resin-io/etcher/blob/master/SUPPORT.md';
const supportUrl = SelectionStateModel.getImageSupportUrl() || DEFAULT_SUPPORT_URL;
OSOpenExternalService.open(supportUrl);
};
});