* fix(gui): Re-enable application menu
This re-enables the application menu to allow for OS native shortcuts
to work again (i.e. hide/minimize window), which also allows us to
get rid of the global-shortcuts hack to prevent window reloads.
Change-Type: patch
Changelog-Entry: Fix disabled native OS window shortcuts
* refactor(gui): Update kbd shortcut comment to be less specific
We load localStorage settings into the Redux store in an asynchronous
way. This means that user settings might not be loaded by the time the
application starts, resulting in Mixpanel sending a few tracking events
before Etcher realises that the user opted out from anonoymous analytics
and error reporting.
In order to fix that, we remove `ng-app` and we manually bootstrap the
Angular.js application *after* the local settings are loaded.
Change-Type: patch
Changelog-Entry: Don't send initial Mixpanel events before "Anonymous Tracking" settings are loaded.
Fixes: https://github.com/resin-io/etcher/issues/1772
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
This implements an SDK.Scanner which handles any given
adapters and manages the scans. This change enables continuous
scanning without the need to `.scan()` scheduling in other places.
Change-Type: minor
We fix the DEBUG environment variable by setting it on the `electron.remote`
instead, and we also move the code to `lib/gui/app.js` and away from
`lib/gui/index.html`.
Changelog-Entry: Set the DEBUG environment variable on the remote
electron process.
Change-Type: patch
* use debug.enabled, fix drivelist env setting
* fix: set debug env variable on remote electron process
As another step towards moving to GitHub Releases, this commit makes the
application care much less about the actual release type of the current
version, instead checking if the application is stable or not, which is
more aligned to what GitHub provides us.
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
We send an HTTP request to S3 to determine the latest available version.
There are various error that can happen that we don't have control over
(like `ETIMEDOUT`).
The current approach is to whitelist certain errors and pretend there is
no update available, however this commit improves that whole situation.
Instead of swallowing these errors, we throw a user error from the
function that determines the latest available version. From the
application code, we check if that function throws a user error, and if
so, instead of showing it to the user, we log a mixpanel event and carry
on.
This change is motivated by the latest reporter error we can't do
anything about: `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`.
Fixes: https://github.com/resin-io/etcher/issues/1525
Change-Type: patch
Changelog-Entry: Fix `UNABLE_TO_GET_ISSUER_CERT_LOCALLY` error at startup when behind certain proxies.
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
- Extend the `standard` ESLint configuration
- Remove ESLint rules that are defined in the `standard` configuration
- Get rid of semi-colons
See: https://github.com/resin-io/etcher/pull/1657
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
This commit changes the whole codebase to adhere to all StandardJS
guidelines rules except semicolons, since the removal of semicolons
affect pretty much all lines, and the final diff is very hard to follow
(and to assess other more involved changes).
In a nutshell:
- When using `function`, we now require a space before the opening
parenthesis
- If a line with operators is broken into multiple lines, the operator
should now go after the line break
- Unnecessary padding lines are now forbidden
There were also some minor things that the `standard` CLI caught that I
updated here.
See: https://standardjs.com
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
This is part of the process of implementing support for a configuration
file. We previously decoupled the Redux store from localStorage by
moving the logic that actually persists the data to localStorage to a
local-settings.js file, however the localStorage API is synchronous, so
it follows that at the moment, all functions that interact with are also
synchronous.
Moving to storing the settings to a file means turning all these
functions to promises, which we do in this commit, in order to not mix
the addition of the configuration file feature with the huge amount of
refactoring it requires.
See: https://github.com/resin-io/etcher/issues/1356
Change-Type: patch
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
Now that the Redux store is no longer front-end dependent, we can move
most of the models to lib/shared. Currently, lib/shared is a mess, and
contains all sorts of functionality, however moving things out of the
GUI is the first step. Once we have everything decoupled, we can
organise all the code we have there.
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
This commit adds a `packageType` property to package.json, which is set
according to the package type of the Etcher target (e.g: dmg, nsis, deb,
etc).
This information is then sent to Mixpanel as the `packageType` property
of the "Application start" event.
Change-Type: patch
Changelog-Entry: Send anonymous analytics about package types.
Fixes: https://github.com/resin-io/etcher/issues/1328
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
We remove the Angular dependency from `lib/gui/os/dialog` and
`lib/gui/modules/error` which is also now renamed to
`lib/gui/modules/exception`.
Changelog-Entry: Deangular the os-dialog and error modules
After https://github.com/resin-io/etcher/pull/1569, the redux store can
run outside of a browser context. This commit moves it to `lib/shared`,
where we will likely move all the other models as well. As an extra, I
renamed `Store` to `store`, since there was no reason for that variable
to be capitalized.
Change-Type: patch
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
We're currently persisting the user settings in localSettings by using a
redux plugin called redux-localstorage. As a way to decouple the redux
store from a technology that is browser specific, this commit makes the
following changes:
- Create local-settings.js, which is concerned with managing settings in
a persisting location
- Decouple the redux store from the persisting storage method
- Extend the settings model to persist settings, cache reads, etc
Change-Type: patch
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
Etcher supports disabling the update notification dialog by setting the
`ETCHER_DISABLE_UPDATES` environment variable.
In order to simplify disabling updates for when these are managed by a
package manager (e.g. in a debian package), this removes support for the
`ETCHER_DISABLE_UPDATES` environment variable, and instead requires
packagers to tweak the `updates.enabled` property of the package.json
file, which is set to `true` by default.
We don't want to encourage end users to disable the update mechanism, so
the documention was removed from `USER-DOCUMENTATION.md`. This option
will remain as something only packagers should tweak.
Change-Type: minor
Changelog-Entry: Remove support for the `ETCHER_DISABLE_UPDATES` environment variable.
Signed-off-by: Juan Cruz Viotti <jv@jviotti.com>
We reload and reset the webview to its original URL when the user
navigates away from the success screen.
Changelog-Entry: Reset webview after navigating away from the success screen.
Electron v1.6.1 introduced checkbox support to the native message
dialog, giving us everything that was needed to implement the update
notifier modal using a native dialog.
This change allows us to get rid of a lot code.
See: https://github.com/electron/electron/pull/8590
Change-Type: patch
Changelog-Entry: Turn the update notifier modal into a native dialog.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
* feat(GUI): dynamic finish page
We implement an externally loaded dynamic finish page in React with
`react2angular`. If the Internet connection is unreliable or unavailable, or a
non-200 HTTP response is returned we display a fallback default finish banner.
Change-Type: minor
Changelog-Entry: Implement a dynamic finish page.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
`etcher-latest-version` was kept in a separate repository in order to
re-use it with the Etcher website, however the Etcher website is not
using it at all, and we're moving towards having the website in the main
repository.
Therefore, this commit brings back the logic from
`etcher-latest-version`, but introduces it as
`lib/shared/s3-packages.js`, in order to not tie ourselves to the
AngularJS framework, and as a step towards the Etcher SDK.
As a nice little bonus, this commit adds support for an
`ETCHER_FAKE_S3_LATEST_VERSION` environment variable that can be used to
trick Etcher that there is an available update, and therefore show the
update notifier modal.
Also, this commit adds support for snapshot builds update-checks, by
checking the `resin-nightly-downloads` S3 bucket if the current version
contains a git commit hash build number.
If the version is not a production release, then the update notifier
modal doesn't present the checkbox to disable update notifications for X
days.
We also add a property called `updates.semverRange` to `package.json`,
which can be used to fine control which versions are considered as
candidates for an update notification.
This commit adds a setting called `includeUnstableChannel`, which can be
used to tweak whether unstable (beta) releases are considered or not
when checking for the latest available version.
See: https://github.com/resin-io-modules/etcher-latest-version
Fixes: https://github.com/resin-io/etcher/issues/953
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
We remove the usage of Angular from 'FlashStateModel' and its usage
throughout the project comes under the new 'flashState' moniker.
Depends: https://github.com/resin-io/etcher/pull/1261
* feat(GUI): improve analytics events
This commit adds more events to our current analytics.
Will further improve in a future commit.
Change-Type: patch
See: https://github.com/resin-io/etcher/issues/1100
* refactor(gui): use single function to set normal and dangerous settings
Change-Type: patch
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
If the drive scanning scripts cause an error, the error will be
presented to the user over and over again. Not only this is terrible UX,
which even makes hard to close the application since dialogs keep coming
in, but it also spams TrackJS, our error reporting service, and makes it
seem that errors happened dozens of times, and thus obscuring real
trending errors.
Change-Type: patch
Changelog-Entry: Stop drive scanning loop if an error occurs.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
There are a lot of new rules since the last time I revised the ESLint
rules documentation.
I've updated the main `.eslintrc.yml` to include some newer additions,
plus I added another ESLint configuration file inside `tests`, so we can
add some stricted rules to the production code while relaxing them for
the test suite (due to the fact that Mocha is not very ES6 friendly and
Angular tests require a bit of dark magic to setup).
This is a summary of the most important changes:
- Disallow "magic numbers"
These should now be extracted to constants, which forces us to think of
a good name for them, and thus make the code more self-documenting (I
had to Google up the meaning of some existing magic numbers, so I guess
this will be great for readability purposes).
- Require consistent `return` statements
Some functions relied on JavaScript relaxed casting mechanism to work,
which now have explicit return values. This flag also helped me detect
some promises that were not being returned, and therefore risked not
being caught by the exception handlers in case of errors.
- Disallow redefining function arguments
Immutability makes functions easier to reason about.
- Enforce JavaScript string templates instead of string concatenation
We were heavily mixing boths across the codebase.
There are some extra rules that I tweaked, however most of codebase
changes in this commit are related to the rules mentioned above.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
We change the drive selector button text to be a static 'select drive'
and allow the user to open the dialog even if there are no drives,
displaying the 'no drives' warning inside the modal.
Closes: https://github.com/resin-io/etcher/issues/884
Changelog-Entry: Allow opening the drive selector modal when there are no
drives.
For better OS integration purposes.
This commit also fixes a bug where the dialog would be shown for some
milliseconds even if the application is not flashing.
Change-Type: minor
Changelog-Entry: Use a OS dialog to show the "exit while flashing" warning.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
We currently attempt to read extra metadata from ZIP files, such as a
logo, image name, image url, etc. In order to simplify the metadata
story, we decided that this metadata will not live on the image itself,
but rather on a centralised repo, which greatly simplified our custom
archive extraction logic and allows us to make use of these nice
features even when streaming the image directly from the internet.
We'll be working on bringing back this functionality from a centralised
repo in subsequent commits.
Change-Type: major
Changelog-Entry: Remove extended archives metadata extraction logic.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
There are certain application messages that should be re-used between
the CLI and the GUI. In order to allow such re-usability, we extract out
the application messages used in JavaScript into
`lib/shared/messages.js` as a collection of Lodash `_.template`
templates.
Notice this file doesn't include application messages included in
Angular templates directly since it'd be hard to refactor all of them.
We plan to move to React soon, which will allow moving the remaining
messages very easily.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
`SelectionStateModel`'s methods `isSystemDrive` and `isDriveLocked`
don't depend on application state. They have been extracted in a different
AngularJS service: `DriveConstraintsModel`. The new service's actual
implementation is in `lib/src`, in order to be reused by the CLI.
Miscellaneous changes:
- Rename `lib/src` to `lib/shared`
- Refactor `drive-constraints` to throw when image is undefined
The default behaviour was to pretend that we're all good if the if
the image is not specified. We're not using this "feature", and
it can be dangerous if we forget to pass in the image.
- Make `isSystemDrive` return `false` if `system` property is undefined
- Use `drive-constraints` in `store.js`
Change-Type: patch
We show the Etcher version string in the update notifier modal, by giving
the version string to the template through options similar to the warning
modal.
- We memoize the version Promise and assume the update version won't change
during runtime.
Changelog-Entry: Show available Etcher version in the update notifier.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
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 PR makes use of `node-ipc` to emit progress information from the
child CLI to the GUI process rather than the tailing approach we've
been doing until now.
This change was motivated by the following Electron fix which landed in
v1.4.4: https://github.com/electron/electron/pull/7578. Before such fix,
Electron would not output anything to stdout/stderr if the Electron
process was running with `ELECTRON_RUN_AS_NODE` under Windows, which
forced us to implement `--log` option in the Etcher CLI to output state
information to a file.
Since this issue is fixed, we can consume the Etcher CLI output from
within `child_process.spawn`, which opens more interesting possibilities
for sharing information between both processes.
This coindentally fixes a Windows issue where the tailing module would
receive malformed JSON, causing Etcher to crash at `JSON.parse`. The
reason of this problem was a bug in the tailing module we were using.
Fixes: https://github.com/resin-io/etcher/issues/642
Change-Type: patch
Changelog-Entry: Fix "Unexpected end of JSON" error in Windows.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
The "dropzone" directive, which we use to implement drag and drop
support, was not being loaded in the application at all for some reason.
It was probably accidentally deleted during major refactorings.
Change-Type: patch
Changelog-Entry: Fix drag and drop not working anymore.
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
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>
We've recently added support for a `supportUrl` property in an archive
image `_info/manifest.json`, which the publisher can use to define the
URL where it would like to redirect users facing problems.
This PR makes the "Need help?" link at the top right corner open the
configured `supportUrl` url, and fallback to the original Etcher's help
page if no `supportUrl` is found.
In order to accomplish this, we made the following changes:
- Implement `SelectionStateModel.getImageSupportUrl()`
- Implement `HeaderController` controller
Change-Type: minor
Changelog-Entry: Make the "Need help?" link dynamically open the image support url.
Fixes: https://github.com/resin-io/etcher/issues/662
Signed-off-by: Juan Cruz Viotti <jviotti@openmailbox.org>
Currently, the logic the controls the drive scanner and populates the
drive model lives in the main application controller.
This is not optimal because:
- The drive scanner stops populating the drives model when the
application is not on the main screen.
- An event handler subscribes to the drive scanner every time the user
navigates back to the main screen.
This PR moves the drive scanner logic to a run block in the entry point
of the application.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>