Currently, we take the image extension casing into account when
determining if the extension is a recognised one (e.g: `img`, `iso`,
etc). This causes an "Invalid image" error to be thrown when selecting
an image with an uppercase extension, like `UBUNTU.ISO`.
Change-Type: patch
Changelog-Entry: Don't throw an "Invalid image" error if the extension is not in lowercase.
Fixes: https://github.com/resin-io/etcher/issues/567
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* upgrade: etcher-image-stream to v2.3.0
This version contains support for `hddimg` files.
Changelog-Entry: Add support for `hddimg` images.
Change-Type: minor
Fixes: https://github.com/resin-io/etcher/issues/549
Link: https://github.com/resin-io-modules/etcher-image-stream/blob/master/CHANGELOG.md#v230---2016-07-01
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* minifix(GUI): add a "many more" tooltip in the first step
The amount of image types we support is growing exponentially. Adding
the uncompressed extensions and the compressed ones in a tooltip gave us
room the breathe in the past, but its not enough anymore.
The current approach allows us to scale forever: we list the first three
extensions, and add a "many more" tooltip that shows all the rest.
Change-Type: patch
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* refactor: getter/setter interface for SettingsModel
This PR introduces a getter/setter interface for `SettingsModel`, which
replaces the old way of managing setting values by simply assigning
properties to an object.
This is the first step towards moving the settings functionality to the
Redux store.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* refactor: store settings in redux store
The state data structure now contains a property called `settings`,
which is a map containing all setting values.
The list of supported settings can be calculated by retrieving the keys
from the `settings` object, which means that if we support a setting, we
must include a default.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* feat: store settings in localStorage
This functionality was deleted by acb0de2 when moving the settings
object to the redux store, promising that the feature will be added back
in a future commit.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Now that we have a central source of truth for state mutations, the
auto-select feature fits really well in the redux store, particularly
inside the `SET_AVAILABLE_DRIVES` action.
This also has the great benefit that we can unit test the auto-selection
logic, which was not particularly trivial before, when such code lived
in the controller instead.
The only downside of this approach is that we lose the nice "Auto-select
drive" analytics event, which will be re-added very soon in a future PR.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
If the user has a selected drive, but a new scan shows that such drive
is no longer available, then the selected drive should be de-selected.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
We shouldn't allow a write-protected drive from being selected, since
users will get confusing `EPERM` errors later on.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, Etcher's application state is stored among various models,
making it a bit hard to mentually visualise the application state at a
certain point of execution. This also means that some quirky bugs
appear, and we have to take non-elegant measures to mitigate them, for
example:
- The current drive selection might be invalid if the current available
drive list doesn't contain it anymore.
- The progress state might be modified while there is no flashing in
process.
- We have to rely on event emission to propagate the current state to
the application progress bar.
- The validity of a selected drive might depend on the currently
selected image.
While all these issues can be addressed with common programming
techniques, Redux introduces a new way of thinking about the application
state that make the above problems non-existent, or trivial to fix.
This PR creates a Redux store containing the logic used to mutate state
from:
- `SelectionStateModel`.
- `DrivesMode`.
- `ImageWriterService`.
We are also making extra effort to preserve the public APIs from the
models, which we will be simplifying in later commits.
There is still much to be done, but we're happy to be taking the first
steo towards a much cleaner architecture.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, we extract all the extensions from an image path and report
back that the image is invalid if *any* of the extensions is not a
valida extension, however this can cause trouble with images including
information between dots that are not strictly extensions.
For example:
```
elementaryos-0.3.2-stable-i386.20151209.iso
```
Etcher will consider `20151209` to be an invalid extension and therefore
will prevent such image from being selected.
As a way to allow these corner cases but will make use of our enforced
check controls, the validation routine will only consider extensions
starting from the first non compressed extension.
This PR also includes logic to show a nice GUI dialog saying that the
image is invalid in order to provide a much better experience than just
silently failing.
Fixes: https://github.com/resin-io/etcher/issues/492
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Implement SelectionStateModel.isDriveLocked()
Notice we also increase the maximum number of lines JSCS check, since
the `SelectionStateModel` test suite already met that limit.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Show a "Locked" label if the drive is write-protected
Fixes: https://github.com/resin-io/etcher/issues/458
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, we detect the extensions of an image path by finding the
first dot, and splitting everything afterwards, however this will fail
with image paths containing dots, like `foo.1.2.3-bar.iso.gz`.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
Currently, `DriveScannerService` is in charge of both scanning the
available drives and maintaining the state of the currently detected
drives.
To honour the single responsibility principle, we split this service
into a `DrivesModel`, which is incharge of maintaining the state without
caring how they are detected, and `DriveScannerService`, which only
scans the available drives and modified `DrivesModel` accordingly.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Make .selectImage() dialog return an object with a `path` property
This allows to return more than one value for the selected image,
like image size and other metadata for example.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Return image size from .selectImage() dialog
This property will be useful to perform some sanity checks, like
ensuring the selected drive is large enough to contain the image.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Store both the image path and the image size in the selection model
In order to simplify accessing such properties in an encapsulated
manner, `SelectionStateModel.getImage()` was replaced with the following
functions:
- `SelectionStateModel.getImagePath()`.
- `SelectionStateModel.getImageSize()`.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Increase SelectionStateModel setter validation
The model not providing any kind of validation was the source of some
bugs I encountered while implementing the previous commits that would
not have happened otherwise.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Prevent selection of drives that are not large enough
- The drive selector modal was modified such that drives that are not
large enough are crossed out, and the user is not able to click them.
- In the case of drive auto-selection, not large enough drives won't
attempt to get autoselected.
This commit introduces:
- The `SelectionStateModel.isDriveLargeEnough()` function.
Fixes: https://github.com/resin-io/etcher/issues/344
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Refactor SelectionStateModel.isCurrentDrive() to only check `.device`
This set of changes modify `SelectionStateModel.isCurrentDrive()` to
only return true if the `.device` property is equal, and ignore the
rest, since there can be tons of false positives if the drive doesn't
exactly matches otherwise.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Implement SelectionStateModel.toggleSetDrive()
This function is useful to toggle the current drive selected based on a
drive object.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
* Make use of SelectionStateModel directly in DriveSelectorModal
Currently, we were basically proxying (with some additions)
`SelectionStateModel` through a service called
`DriveSelectorStateService`, which was completely unnecessary.
Now, we make use of `SelectionStateModel`, after moving any custom logic
from `DriveSelectorStateService` to `SelectionStateModel`.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>
This refactoring will be useful on future changes, where there will be
a single application entry point that will execute the CLI or the GUI
version depending on the environment.
Signed-off-by: Juan Cruz Viotti <jviottidc@gmail.com>