mirror of
https://github.com/balena-io/etcher.git
synced 2025-07-23 11:16:39 +00:00
Merge pull request #2420 from resin-io/better-analytics
fix(GUI): Additional data on events
This commit is contained in:
commit
ea834f6778
@ -29,6 +29,7 @@ var angular = require('angular')
|
|||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const Bluebird = require('bluebird')
|
const Bluebird = require('bluebird')
|
||||||
const semver = require('semver')
|
const semver = require('semver')
|
||||||
|
const uuidV4 = require('uuid/v4')
|
||||||
const EXIT_CODES = require('../../shared/exit-codes')
|
const EXIT_CODES = require('../../shared/exit-codes')
|
||||||
const messages = require('../../shared/messages')
|
const messages = require('../../shared/messages')
|
||||||
const s3Packages = require('../../shared/s3-packages')
|
const s3Packages = require('../../shared/s3-packages')
|
||||||
@ -58,6 +59,21 @@ const updateLock = require('./modules/update-lock')
|
|||||||
process.env.DRIVELIST_DEBUG = /drivelist|^\*$/i.test(process.env.DEBUG) ? '1' : ''
|
process.env.DRIVELIST_DEBUG = /drivelist|^\*$/i.test(process.env.DEBUG) ? '1' : ''
|
||||||
window.localStorage.debug = process.env.DEBUG
|
window.localStorage.debug = process.env.DEBUG
|
||||||
|
|
||||||
|
// Set application session UUID
|
||||||
|
store.dispatch({
|
||||||
|
type: store.Actions.SET_APPLICATION_SESSION_UUID,
|
||||||
|
data: uuidV4()
|
||||||
|
})
|
||||||
|
|
||||||
|
// Set first flashing workflow UUID
|
||||||
|
store.dispatch({
|
||||||
|
type: store.Actions.SET_FLASHING_WORKFLOW_UUID,
|
||||||
|
data: uuidV4()
|
||||||
|
})
|
||||||
|
|
||||||
|
const applicationSessionUuid = store.getState().toJS().applicationSessionUuid
|
||||||
|
const flashingWorkflowUuid = store.getState().toJS().flashingWorkflowUuid
|
||||||
|
|
||||||
const app = angular.module('Etcher', [
|
const app = angular.module('Etcher', [
|
||||||
require('angular-ui-router'),
|
require('angular-ui-router'),
|
||||||
require('angular-ui-bootstrap'),
|
require('angular-ui-bootstrap'),
|
||||||
@ -103,7 +119,8 @@ app.run(() => {
|
|||||||
|
|
||||||
analytics.logEvent('Application start', {
|
analytics.logEvent('Application start', {
|
||||||
packageType: packageJSON.packageType,
|
packageType: packageJSON.packageType,
|
||||||
version: currentVersion
|
version: currentVersion,
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
const shouldCheckForUpdates = updateNotifier.shouldCheckForUpdates({
|
const shouldCheckForUpdates = updateNotifier.shouldCheckForUpdates({
|
||||||
@ -119,7 +136,8 @@ app.run(() => {
|
|||||||
analytics.logEvent('Not checking for updates', {
|
analytics.logEvent('Not checking for updates', {
|
||||||
shouldCheckForUpdates,
|
shouldCheckForUpdates,
|
||||||
updatesEnabled,
|
updatesEnabled,
|
||||||
stable: isStableRelease
|
stable: isStableRelease,
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
return Bluebird.resolve()
|
return Bluebird.resolve()
|
||||||
@ -132,7 +150,8 @@ app.run(() => {
|
|||||||
currentVersion,
|
currentVersion,
|
||||||
stable: isStableRelease,
|
stable: isStableRelease,
|
||||||
updateSemverRange,
|
updateSemverRange,
|
||||||
includeUnstableChannel
|
includeUnstableChannel,
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
return s3Packages.getLatestVersion(release.getReleaseType(currentVersion), {
|
return s3Packages.getLatestVersion(release.getReleaseType(currentVersion), {
|
||||||
@ -141,7 +160,8 @@ app.run(() => {
|
|||||||
}).then((latestVersion) => {
|
}).then((latestVersion) => {
|
||||||
if (semver.gte(currentVersion, latestVersion || '0.0.0')) {
|
if (semver.gte(currentVersion, latestVersion || '0.0.0')) {
|
||||||
analytics.logEvent('Update notification skipped', {
|
analytics.logEvent('Update notification skipped', {
|
||||||
reason: 'Latest version'
|
reason: 'Latest version',
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
return Bluebird.resolve()
|
return Bluebird.resolve()
|
||||||
}
|
}
|
||||||
@ -153,13 +173,15 @@ app.run(() => {
|
|||||||
// might be annoying.
|
// might be annoying.
|
||||||
if (selectionState.hasImage()) {
|
if (selectionState.hasImage()) {
|
||||||
analytics.logEvent('Update notification skipped', {
|
analytics.logEvent('Update notification skipped', {
|
||||||
reason: 'Image selected'
|
reason: 'Image selected',
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
return Bluebird.resolve()
|
return Bluebird.resolve()
|
||||||
}
|
}
|
||||||
|
|
||||||
analytics.logEvent('Notifying update', {
|
analytics.logEvent('Notifying update', {
|
||||||
latestVersion
|
latestVersion,
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
return updateNotifier.notify(latestVersion, {
|
return updateNotifier.notify(latestVersion, {
|
||||||
@ -174,7 +196,8 @@ app.run(() => {
|
|||||||
}, (error) => {
|
}, (error) => {
|
||||||
analytics.logEvent('Update check user error', {
|
analytics.logEvent('Update check user error', {
|
||||||
title: errors.getTitle(error),
|
title: errors.getTitle(error),
|
||||||
description: errors.getDescription(error)
|
description: errors.getDescription(error),
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
}).catch(exceptionReporter.report)
|
}).catch(exceptionReporter.report)
|
||||||
})
|
})
|
||||||
@ -247,7 +270,8 @@ app.run(($window) => {
|
|||||||
$window.addEventListener('beforeunload', (event) => {
|
$window.addEventListener('beforeunload', (event) => {
|
||||||
if (!flashState.isFlashing() || popupExists) {
|
if (!flashState.isFlashing() || popupExists) {
|
||||||
analytics.logEvent('Close application', {
|
analytics.logEvent('Close application', {
|
||||||
isFlashing: flashState.isFlashing()
|
isFlashing: flashState.isFlashing(),
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -258,7 +282,7 @@ app.run(($window) => {
|
|||||||
// Don't open any more popups
|
// Don't open any more popups
|
||||||
popupExists = true
|
popupExists = true
|
||||||
|
|
||||||
analytics.logEvent('Close attempt while flashing')
|
analytics.logEvent('Close attempt while flashing', { applicationSessionUuid, flashingWorkflowUuid })
|
||||||
|
|
||||||
osDialog.showWarning({
|
osDialog.showWarning({
|
||||||
confirmationLabel: 'Yes, quit',
|
confirmationLabel: 'Yes, quit',
|
||||||
@ -268,7 +292,9 @@ app.run(($window) => {
|
|||||||
}).then((confirmed) => {
|
}).then((confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
analytics.logEvent('Close confirmed while flashing', {
|
analytics.logEvent('Close confirmed while flashing', {
|
||||||
uuid: flashState.getFlashUuid()
|
flashInstanceUuid: flashState.getFlashUuid(),
|
||||||
|
applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
// This circumvents the 'beforeunload' event unlike
|
// This circumvents the 'beforeunload' event unlike
|
||||||
@ -276,7 +302,7 @@ app.run(($window) => {
|
|||||||
electron.remote.process.exit(EXIT_CODES.SUCCESS)
|
electron.remote.process.exit(EXIT_CODES.SUCCESS)
|
||||||
}
|
}
|
||||||
|
|
||||||
analytics.logEvent('Close rejected while flashing')
|
analytics.logEvent('Close rejected while flashing', { applicationSessionUuid, flashingWorkflowUuid })
|
||||||
popupExists = false
|
popupExists = false
|
||||||
}).catch(exceptionReporter.report)
|
}).catch(exceptionReporter.report)
|
||||||
})
|
})
|
||||||
@ -308,7 +334,8 @@ app.run(($rootScope) => {
|
|||||||
|
|
||||||
analytics.logEvent('Navigate', {
|
analytics.logEvent('Navigate', {
|
||||||
to: toState.name,
|
to: toState.name,
|
||||||
from: fromState.name
|
from: fromState.name,
|
||||||
|
applicationSessionUuid
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -20,6 +20,7 @@ const angular = require('angular')
|
|||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const Bluebird = require('bluebird')
|
const Bluebird = require('bluebird')
|
||||||
const constraints = require('../../../../../shared/drive-constraints')
|
const constraints = require('../../../../../shared/drive-constraints')
|
||||||
|
const store = require('../../../models/store')
|
||||||
const analytics = require('../../../modules/analytics')
|
const analytics = require('../../../modules/analytics')
|
||||||
const availableDrives = require('../../../models/available-drives')
|
const availableDrives = require('../../../models/available-drives')
|
||||||
const selectionState = require('../../../models/selection-state')
|
const selectionState = require('../../../models/selection-state')
|
||||||
@ -96,7 +97,9 @@ module.exports = function (
|
|||||||
if (canChangeDriveSelectionState) {
|
if (canChangeDriveSelectionState) {
|
||||||
analytics.logEvent('Toggle drive', {
|
analytics.logEvent('Toggle drive', {
|
||||||
drive,
|
drive,
|
||||||
previouslySelected: selectionState.isCurrentDrive(drive.device)
|
previouslySelected: selectionState.isCurrentDrive(drive.device),
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
selectionState.toggleDrive(drive.device)
|
selectionState.toggleDrive(drive.device)
|
||||||
@ -125,7 +128,9 @@ module.exports = function (
|
|||||||
this.installMissingDrivers = (drive) => {
|
this.installMissingDrivers = (drive) => {
|
||||||
if (drive.link) {
|
if (drive.link) {
|
||||||
analytics.logEvent('Open driver link modal', {
|
analytics.logEvent('Open driver link modal', {
|
||||||
url: drive.link
|
url: drive.link,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
return ConfirmModalService.show({
|
return ConfirmModalService.show({
|
||||||
@ -187,7 +192,10 @@ module.exports = function (
|
|||||||
if (canChangeDriveSelectionState) {
|
if (canChangeDriveSelectionState) {
|
||||||
selectionState.selectDrive(drive.device)
|
selectionState.selectDrive(drive.device)
|
||||||
|
|
||||||
analytics.logEvent('Drive selected (double click)')
|
analytics.logEvent('Drive selected (double click)', {
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
|
|
||||||
this.closeModal()
|
this.closeModal()
|
||||||
}
|
}
|
||||||
|
@ -177,7 +177,11 @@ class FileSelector extends React.PureComponent {
|
|||||||
})
|
})
|
||||||
|
|
||||||
osDialog.showError(invalidImageError)
|
osDialog.showError(invalidImageError)
|
||||||
analytics.logEvent('Invalid image', image)
|
analytics.logEvent('Invalid image', {
|
||||||
|
image,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -185,10 +189,18 @@ class FileSelector extends React.PureComponent {
|
|||||||
let message = null
|
let message = null
|
||||||
|
|
||||||
if (supportedFormats.looksLikeWindowsImage(image.path)) {
|
if (supportedFormats.looksLikeWindowsImage(image.path)) {
|
||||||
analytics.logEvent('Possibly Windows image', image)
|
analytics.logEvent('Possibly Windows image', {
|
||||||
|
image,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
message = messages.warning.looksLikeWindowsImage()
|
message = messages.warning.looksLikeWindowsImage()
|
||||||
} else if (!image.hasMBR) {
|
} else if (!image.hasMBR) {
|
||||||
analytics.logEvent('Missing partition table', image)
|
analytics.logEvent('Missing partition table', {
|
||||||
|
image,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
message = messages.warning.missingPartitionTable()
|
message = messages.warning.missingPartitionTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +230,11 @@ class FileSelector extends React.PureComponent {
|
|||||||
image.logo = Boolean(image.logo)
|
image.logo = Boolean(image.logo)
|
||||||
image.bmap = Boolean(image.bmap)
|
image.bmap = Boolean(image.bmap)
|
||||||
|
|
||||||
analytics.logEvent('Select image', image)
|
analytics.logEvent('Select image', {
|
||||||
|
image,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
}).catch(exceptionReporter.report)
|
}).catch(exceptionReporter.report)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
const flashState = require('../../../models/flash-state')
|
const flashState = require('../../../models/flash-state')
|
||||||
const selectionState = require('../../../models/selection-state')
|
const selectionState = require('../../../models/selection-state')
|
||||||
|
const store = require('../../../models/store')
|
||||||
const analytics = require('../../../modules/analytics')
|
const analytics = require('../../../modules/analytics')
|
||||||
|
|
||||||
module.exports = function (WarningModalService) {
|
module.exports = function (WarningModalService) {
|
||||||
@ -40,7 +41,10 @@ module.exports = function (WarningModalService) {
|
|||||||
flashState.resetState()
|
flashState.resetState()
|
||||||
|
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
analytics.logEvent('Restart after failure')
|
analytics.logEvent('Restart after failure', {
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
} else {
|
} else {
|
||||||
selectionState.clear()
|
selectionState.clear()
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
const store = require('../../../models/store')
|
||||||
const analytics = require('../../../modules/analytics')
|
const analytics = require('../../../modules/analytics')
|
||||||
|
|
||||||
module.exports = function ($uibModal, $q) {
|
module.exports = function ($uibModal, $q) {
|
||||||
@ -45,7 +46,9 @@ module.exports = function ($uibModal, $q) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
analytics.logEvent('Open modal', {
|
analytics.logEvent('Open modal', {
|
||||||
name: options.name
|
name: options.name,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
const modal = $uibModal.open({
|
const modal = $uibModal.open({
|
||||||
@ -62,7 +65,9 @@ module.exports = function ($uibModal, $q) {
|
|||||||
modal.result.then((value) => {
|
modal.result.then((value) => {
|
||||||
analytics.logEvent('Modal accepted', {
|
analytics.logEvent('Modal accepted', {
|
||||||
name: options.name,
|
name: options.name,
|
||||||
value
|
value,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
resolve(value)
|
resolve(value)
|
||||||
@ -71,7 +76,9 @@ module.exports = function ($uibModal, $q) {
|
|||||||
if (error === 'escape key press' || error === 'backdrop click') {
|
if (error === 'escape key press' || error === 'backdrop click') {
|
||||||
analytics.logEvent('Modal rejected', {
|
analytics.logEvent('Modal rejected', {
|
||||||
name: options.name,
|
name: options.name,
|
||||||
method: error
|
method: error,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
return resolve()
|
return resolve()
|
||||||
@ -79,7 +86,9 @@ module.exports = function ($uibModal, $q) {
|
|||||||
|
|
||||||
analytics.logEvent('Modal rejected', {
|
analytics.logEvent('Modal rejected', {
|
||||||
name: options.name,
|
name: options.name,
|
||||||
value: error
|
value: error,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
return reject(error)
|
return reject(error)
|
||||||
|
@ -25,6 +25,7 @@ const react = require('react')
|
|||||||
const propTypes = require('prop-types')
|
const propTypes = require('prop-types')
|
||||||
const { react2angular } = require('react2angular')
|
const { react2angular } = require('react2angular')
|
||||||
const analytics = require('../modules/analytics')
|
const analytics = require('../modules/analytics')
|
||||||
|
const store = require('../models/store')
|
||||||
const settings = require('../models/settings')
|
const settings = require('../models/settings')
|
||||||
const packageJSON = require('../../../../package.json')
|
const packageJSON = require('../../../../package.json')
|
||||||
|
|
||||||
@ -198,7 +199,10 @@ class SafeWebview extends react.PureComponent {
|
|||||||
if (event.resourceType === 'mainFrame') {
|
if (event.resourceType === 'mainFrame') {
|
||||||
const HTTP_OK = 200
|
const HTTP_OK = 200
|
||||||
|
|
||||||
analytics.logEvent(event)
|
analytics.logEvent(event, {
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
|
|
||||||
this.setState({
|
this.setState({
|
||||||
shouldShow: event.httpResponseCode === HTTP_OK
|
shouldShow: event.httpResponseCode === HTTP_OK
|
||||||
@ -248,7 +252,10 @@ class SafeWebview extends react.PureComponent {
|
|||||||
if (message.command === 'error') {
|
if (message.command === 'error') {
|
||||||
analytics.logException(message.data)
|
analytics.logException(message.data)
|
||||||
} else {
|
} else {
|
||||||
analytics.logEvent(message.data || message)
|
analytics.logEvent(message.data || message, {
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
const Bluebird = require('bluebird')
|
const Bluebird = require('bluebird')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
const store = require('../models/store')
|
||||||
const settings = require('../models/settings')
|
const settings = require('../models/settings')
|
||||||
const analytics = require('../modules/analytics')
|
const analytics = require('../modules/analytics')
|
||||||
const units = require('../../../shared/units')
|
const units = require('../../../shared/units')
|
||||||
@ -145,7 +146,9 @@ exports.notify = (version, options = {}) => {
|
|||||||
sleepUpdateCheck: results.sleepUpdateCheck,
|
sleepUpdateCheck: results.sleepUpdateCheck,
|
||||||
notifyVersion: version,
|
notifyVersion: version,
|
||||||
currentVersion: packageJSON.version,
|
currentVersion: packageJSON.version,
|
||||||
agreed: results.agreed
|
agreed: results.agreed,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
if (results.agreed) {
|
if (results.agreed) {
|
||||||
|
@ -80,6 +80,8 @@ const selectImageNoNilFields = [
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
const DEFAULT_STATE = Immutable.fromJS({
|
const DEFAULT_STATE = Immutable.fromJS({
|
||||||
|
applicationSessionUuid: '',
|
||||||
|
flashingWorkflowUuid: '',
|
||||||
availableDrives: [],
|
availableDrives: [],
|
||||||
selection: {
|
selection: {
|
||||||
devices: new Immutable.OrderedSet()
|
devices: new Immutable.OrderedSet()
|
||||||
@ -111,7 +113,9 @@ const ACTIONS = _.fromPairs(_.map([
|
|||||||
'SELECT_DRIVE',
|
'SELECT_DRIVE',
|
||||||
'SELECT_IMAGE',
|
'SELECT_IMAGE',
|
||||||
'DESELECT_DRIVE',
|
'DESELECT_DRIVE',
|
||||||
'DESELECT_IMAGE'
|
'DESELECT_IMAGE',
|
||||||
|
'SET_APPLICATION_SESSION_UUID',
|
||||||
|
'SET_FLASHING_WORKFLOW_UUID'
|
||||||
], (message) => {
|
], (message) => {
|
||||||
return [ message, message ]
|
return [ message, message ]
|
||||||
}))
|
}))
|
||||||
@ -499,6 +503,14 @@ const storeReducer = (state = DEFAULT_STATE, action) => {
|
|||||||
return state.deleteIn([ 'selection', 'image' ])
|
return state.deleteIn([ 'selection', 'image' ])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case ACTIONS.SET_APPLICATION_SESSION_UUID: {
|
||||||
|
return state.set('applicationSessionUuid', action.data)
|
||||||
|
}
|
||||||
|
|
||||||
|
case ACTIONS.SET_FLASHING_WORKFLOW_UUID: {
|
||||||
|
return state.set('flashingWorkflowUuid', action.data)
|
||||||
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
return state
|
return state
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,7 @@ const os = require('os')
|
|||||||
const ipc = require('node-ipc')
|
const ipc = require('node-ipc')
|
||||||
const isRunningInAsar = require('electron-is-running-in-asar')
|
const isRunningInAsar = require('electron-is-running-in-asar')
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
|
const store = require('../models/store')
|
||||||
const settings = require('../models/settings')
|
const settings = require('../models/settings')
|
||||||
const flashState = require('../models/flash-state')
|
const flashState = require('../models/flash-state')
|
||||||
const errors = require('../../../shared/errors')
|
const errors = require('../../../shared/errors')
|
||||||
@ -74,20 +75,26 @@ const getApplicationEntryPoint = () => {
|
|||||||
* handleErrorLogging({ code: 'EUNPLUGGED' }, { image: 'resin.img' })
|
* handleErrorLogging({ code: 'EUNPLUGGED' }, { image: 'resin.img' })
|
||||||
*/
|
*/
|
||||||
const handleErrorLogging = (error, analyticsData) => {
|
const handleErrorLogging = (error, analyticsData) => {
|
||||||
|
const eventData = _.assign({
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid,
|
||||||
|
flashInstanceUuid: flashState.getFlashUuid()
|
||||||
|
}, analyticsData)
|
||||||
|
|
||||||
if (error.code === 'EVALIDATION') {
|
if (error.code === 'EVALIDATION') {
|
||||||
analytics.logEvent('Validation error', analyticsData)
|
analytics.logEvent('Validation error', eventData)
|
||||||
} else if (error.code === 'EUNPLUGGED') {
|
} else if (error.code === 'EUNPLUGGED') {
|
||||||
analytics.logEvent('Drive unplugged', analyticsData)
|
analytics.logEvent('Drive unplugged', eventData)
|
||||||
} else if (error.code === 'EIO') {
|
} else if (error.code === 'EIO') {
|
||||||
analytics.logEvent('Input/output error', analyticsData)
|
analytics.logEvent('Input/output error', eventData)
|
||||||
} else if (error.code === 'ENOSPC') {
|
} else if (error.code === 'ENOSPC') {
|
||||||
analytics.logEvent('Out of space', analyticsData)
|
analytics.logEvent('Out of space', eventData)
|
||||||
} else if (error.code === 'ECHILDDIED') {
|
} else if (error.code === 'ECHILDDIED') {
|
||||||
analytics.logEvent('Child died unexpectedly', analyticsData)
|
analytics.logEvent('Child died unexpectedly', eventData)
|
||||||
} else {
|
} else {
|
||||||
analytics.logEvent('Flash error', _.merge({
|
analytics.logEvent('Flash error', _.merge({
|
||||||
error: errors.toJSON(error)
|
error: errors.toJSON(error)
|
||||||
}, analyticsData))
|
}, eventData))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -163,6 +170,7 @@ exports.performWrite = (image, drives, onProgress) => {
|
|||||||
drives,
|
drives,
|
||||||
driveCount: drives.length,
|
driveCount: drives.length,
|
||||||
uuid: flashState.getFlashUuid(),
|
uuid: flashState.getFlashUuid(),
|
||||||
|
flashInstanceUuid: flashState.getFlashUuid(),
|
||||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess')
|
validateWriteOnSuccess: settings.get('validateWriteOnSuccess')
|
||||||
}
|
}
|
||||||
@ -306,8 +314,12 @@ exports.flash = (image, drives) => {
|
|||||||
drives,
|
drives,
|
||||||
driveCount: drives.length,
|
driveCount: drives.length,
|
||||||
uuid: flashState.getFlashUuid(),
|
uuid: flashState.getFlashUuid(),
|
||||||
|
status: 'started',
|
||||||
|
flashInstanceUuid: flashState.getFlashUuid(),
|
||||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess')
|
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
}
|
}
|
||||||
|
|
||||||
analytics.logEvent('Flash', analyticsData)
|
analytics.logEvent('Flash', analyticsData)
|
||||||
@ -315,10 +327,17 @@ exports.flash = (image, drives) => {
|
|||||||
return exports.performWrite(image, drives, (state) => {
|
return exports.performWrite(image, drives, (state) => {
|
||||||
flashState.setProgressState(state)
|
flashState.setProgressState(state)
|
||||||
}).then(flashState.unsetFlashingFlag).then(() => {
|
}).then(flashState.unsetFlashingFlag).then(() => {
|
||||||
|
const { results } = flashState.getFlashResults()
|
||||||
|
const event = _.assign({
|
||||||
|
errors: results.errors,
|
||||||
|
devices: results.devices,
|
||||||
|
status: 'finished'
|
||||||
|
},
|
||||||
|
analyticsData)
|
||||||
if (flashState.wasLastFlashCancelled()) {
|
if (flashState.wasLastFlashCancelled()) {
|
||||||
analytics.logEvent('Elevation cancelled', analyticsData)
|
analytics.logEvent('Elevation cancelled', event)
|
||||||
} else {
|
} else {
|
||||||
analytics.logEvent('Done', analyticsData)
|
analytics.logEvent('Done', event)
|
||||||
}
|
}
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
flashState.unsetFlashingFlag({
|
flashState.unsetFlashingFlag({
|
||||||
@ -327,7 +346,14 @@ exports.flash = (image, drives) => {
|
|||||||
|
|
||||||
// eslint-disable-next-line no-magic-numbers
|
// eslint-disable-next-line no-magic-numbers
|
||||||
if (drives.length > 1) {
|
if (drives.length > 1) {
|
||||||
analytics.logEvent('Write failed', analyticsData)
|
const { results } = flashState.getFlashResults()
|
||||||
|
const event = _.assign({
|
||||||
|
errors: results.errors,
|
||||||
|
devices: results.devices,
|
||||||
|
status: 'failed'
|
||||||
|
},
|
||||||
|
analyticsData)
|
||||||
|
analytics.logEvent('Write failed', event)
|
||||||
}
|
}
|
||||||
|
|
||||||
return Bluebird.reject(error)
|
return Bluebird.reject(error)
|
||||||
@ -346,14 +372,25 @@ exports.flash = (image, drives) => {
|
|||||||
*/
|
*/
|
||||||
exports.cancel = () => {
|
exports.cancel = () => {
|
||||||
const drives = selectionState.getSelectedDevices()
|
const drives = selectionState.getSelectedDevices()
|
||||||
analytics.logEvent('Cancel', {
|
const { results } = flashState.getFlashResults()
|
||||||
|
const analyticsData = {
|
||||||
image: selectionState.getImagePath(),
|
image: selectionState.getImagePath(),
|
||||||
drives,
|
drives,
|
||||||
driveCount: drives.length,
|
driveCount: drives.length,
|
||||||
uuid: flashState.getFlashUuid(),
|
uuid: flashState.getFlashUuid(),
|
||||||
|
flashInstanceUuid: flashState.getFlashUuid(),
|
||||||
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
unmountOnSuccess: settings.get('unmountOnSuccess'),
|
||||||
validateWriteOnSuccess: settings.get('validateWriteOnSuccess')
|
validateWriteOnSuccess: settings.get('validateWriteOnSuccess'),
|
||||||
})
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
}
|
||||||
|
const event = _.assign({
|
||||||
|
errors: results.errors,
|
||||||
|
devices: results.devices,
|
||||||
|
status: 'finished'
|
||||||
|
},
|
||||||
|
analyticsData)
|
||||||
|
analytics.logEvent('Cancel', event)
|
||||||
|
|
||||||
// Re-enable lock release on inactivity
|
// Re-enable lock release on inactivity
|
||||||
updateLock.resume()
|
updateLock.resume()
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const electron = require('electron')
|
const electron = require('electron')
|
||||||
|
const store = require('../../../models/store')
|
||||||
const analytics = require('../../../modules/analytics')
|
const analytics = require('../../../modules/analytics')
|
||||||
const settings = require('../../../models/settings')
|
const settings = require('../../../models/settings')
|
||||||
|
|
||||||
@ -38,7 +39,8 @@ module.exports = function () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
analytics.logEvent('Open external link', {
|
analytics.logEvent('Open external link', {
|
||||||
url
|
url,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
if (url) {
|
if (url) {
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
const uuidV4 = require('uuid/v4')
|
||||||
|
const store = require('../../../models/store')
|
||||||
const settings = require('../../../models/settings')
|
const settings = require('../../../models/settings')
|
||||||
const flashState = require('../../../models/flash-state')
|
const flashState = require('../../../models/flash-state')
|
||||||
const selectionState = require('../../../models/selection-state')
|
const selectionState = require('../../../models/selection-state')
|
||||||
@ -57,10 +59,20 @@ module.exports = function ($state) {
|
|||||||
selectionState.deselectImage()
|
selectionState.deselectImage()
|
||||||
}
|
}
|
||||||
selectionState.deselectAllDrives()
|
selectionState.deselectAllDrives()
|
||||||
analytics.logEvent('Restart', options)
|
analytics.logEvent('Restart', _.assign({
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
}, options))
|
||||||
|
|
||||||
// Re-enable lock release on inactivity
|
// Re-enable lock release on inactivity
|
||||||
updateLock.resume()
|
updateLock.resume()
|
||||||
|
|
||||||
|
// Reset the flashing workflow uuid
|
||||||
|
store.dispatch({
|
||||||
|
type: 'SET_FLASHING_WORKFLOW_UUID',
|
||||||
|
data: uuidV4()
|
||||||
|
})
|
||||||
|
|
||||||
$state.go('main')
|
$state.go('main')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const angular = require('angular')
|
const angular = require('angular')
|
||||||
const prettyBytes = require('pretty-bytes')
|
const prettyBytes = require('pretty-bytes')
|
||||||
|
const store = require('../../../models/store')
|
||||||
const settings = require('../../../models/settings')
|
const settings = require('../../../models/settings')
|
||||||
const selectionState = require('../../../models/selection-state')
|
const selectionState = require('../../../models/selection-state')
|
||||||
const analytics = require('../../../modules/analytics')
|
const analytics = require('../../../modules/analytics')
|
||||||
@ -109,7 +110,9 @@ module.exports = function (DriveSelectorService) {
|
|||||||
|
|
||||||
analytics.logEvent('Select drive', {
|
analytics.logEvent('Select drive', {
|
||||||
device: drive.device,
|
device: drive.device,
|
||||||
unsafeMode: settings.get('unsafeMode') && !settings.get('disableUnsafeMode')
|
unsafeMode: settings.get('unsafeMode') && !settings.get('disableUnsafeMode'),
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
}).catch(exceptionReporter.report)
|
}).catch(exceptionReporter.report)
|
||||||
}
|
}
|
||||||
@ -124,7 +127,10 @@ module.exports = function (DriveSelectorService) {
|
|||||||
*/
|
*/
|
||||||
this.reselectDrive = () => {
|
this.reselectDrive = () => {
|
||||||
this.openDriveSelector()
|
this.openDriveSelector()
|
||||||
analytics.logEvent('Reselect drive')
|
analytics.logEvent('Reselect drive', {
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
const Bluebird = require('bluebird')
|
const Bluebird = require('bluebird')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
const store = require('../../../models/store')
|
||||||
const messages = require('../../../../../shared/messages')
|
const messages = require('../../../../../shared/messages')
|
||||||
const errors = require('../../../../../shared/errors')
|
const errors = require('../../../../../shared/errors')
|
||||||
const imageStream = require('../../../../../sdk/image-stream')
|
const imageStream = require('../../../../../sdk/image-stream')
|
||||||
@ -76,7 +77,10 @@ module.exports = function (
|
|||||||
})
|
})
|
||||||
|
|
||||||
osDialog.showError(invalidImageError)
|
osDialog.showError(invalidImageError)
|
||||||
analytics.logEvent('Invalid image', image)
|
analytics.logEvent('Invalid image', _.merge({
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
}, image))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,10 +88,18 @@ module.exports = function (
|
|||||||
let message = null
|
let message = null
|
||||||
|
|
||||||
if (supportedFormats.looksLikeWindowsImage(image.path)) {
|
if (supportedFormats.looksLikeWindowsImage(image.path)) {
|
||||||
analytics.logEvent('Possibly Windows image', image)
|
analytics.logEvent('Possibly Windows image', {
|
||||||
|
image,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
message = messages.warning.looksLikeWindowsImage()
|
message = messages.warning.looksLikeWindowsImage()
|
||||||
} else if (!image.hasMBR) {
|
} else if (!image.hasMBR) {
|
||||||
analytics.logEvent('Missing partition table', image)
|
analytics.logEvent('Missing partition table', {
|
||||||
|
image,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
message = messages.warning.missingPartitionTable()
|
message = messages.warning.missingPartitionTable()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -114,7 +126,11 @@ module.exports = function (
|
|||||||
image.logo = Boolean(image.logo)
|
image.logo = Boolean(image.logo)
|
||||||
image.bmap = Boolean(image.bmap)
|
image.bmap = Boolean(image.bmap)
|
||||||
|
|
||||||
return analytics.logEvent('Select image', image)
|
return analytics.logEvent('Select image', {
|
||||||
|
image,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
}).catch(exceptionReporter.report)
|
}).catch(exceptionReporter.report)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +171,10 @@ module.exports = function (
|
|||||||
* ImageSelectionController.openImageSelector();
|
* ImageSelectionController.openImageSelector();
|
||||||
*/
|
*/
|
||||||
this.openImageSelector = () => {
|
this.openImageSelector = () => {
|
||||||
analytics.logEvent('Open image selector')
|
analytics.logEvent('Open image selector', {
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
|
|
||||||
if (settings.get('experimentalFilePicker')) {
|
if (settings.get('experimentalFilePicker')) {
|
||||||
FileSelectorService.open()
|
FileSelectorService.open()
|
||||||
@ -164,7 +183,10 @@ module.exports = function (
|
|||||||
// Avoid analytics and selection state changes
|
// Avoid analytics and selection state changes
|
||||||
// if no file was resolved from the dialog.
|
// if no file was resolved from the dialog.
|
||||||
if (!imagePath) {
|
if (!imagePath) {
|
||||||
analytics.logEvent('Image selector closed')
|
analytics.logEvent('Image selector closed', {
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,7 +205,9 @@ module.exports = function (
|
|||||||
*/
|
*/
|
||||||
this.reselectImage = () => {
|
this.reselectImage = () => {
|
||||||
analytics.logEvent('Reselect image', {
|
analytics.logEvent('Reselect image', {
|
||||||
previousImage: selectionState.getImage()
|
previousImage: selectionState.getImage(),
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid,
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
this.openImageSelector()
|
this.openImageSelector()
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
|
const store = require('../../../models/store')
|
||||||
const settings = require('../../../models/settings')
|
const settings = require('../../../models/settings')
|
||||||
const flashState = require('../../../models/flash-state')
|
const flashState = require('../../../models/flash-state')
|
||||||
const analytics = require('../../../modules/analytics')
|
const analytics = require('../../../modules/analytics')
|
||||||
@ -82,7 +83,9 @@ module.exports = function (
|
|||||||
*/
|
*/
|
||||||
this.showSelectedImageDetails = () => {
|
this.showSelectedImageDetails = () => {
|
||||||
analytics.logEvent('Show selected image tooltip', {
|
analytics.logEvent('Show selected image tooltip', {
|
||||||
imagePath: selectionState.getImagePath()
|
imagePath: selectionState.getImagePath(),
|
||||||
|
flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
return TooltipModalService.show({
|
return TooltipModalService.show({
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
const os = require('os')
|
const os = require('os')
|
||||||
const _ = require('lodash')
|
const _ = require('lodash')
|
||||||
|
const store = require('../../../models/store')
|
||||||
const settings = require('../../../models/settings')
|
const settings = require('../../../models/settings')
|
||||||
const analytics = require('../../../modules/analytics')
|
const analytics = require('../../../modules/analytics')
|
||||||
const exceptionReporter = require('../../../modules/exception-reporter')
|
const exceptionReporter = require('../../../modules/exception-reporter')
|
||||||
@ -87,7 +88,8 @@ module.exports = function (WarningModalService) {
|
|||||||
analytics.logEvent('Toggle setting', {
|
analytics.logEvent('Toggle setting', {
|
||||||
setting,
|
setting,
|
||||||
value,
|
value,
|
||||||
dangerous
|
dangerous,
|
||||||
|
applicationSessionUuid: store.getState().toJS().applicationSessionUuid
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!value || !dangerous) {
|
if (!value || !dangerous) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user