diff --git a/lib/gui/app/components/file-selector/controllers/file-selector.js b/lib/gui/app/components/file-selector/controllers/file-selector.js
index 342448d8..ca703296 100644
--- a/lib/gui/app/components/file-selector/controllers/file-selector.js
+++ b/lib/gui/app/components/file-selector/controllers/file-selector.js
@@ -48,11 +48,10 @@ module.exports = function (
* @example
* FileSelectorController.getFolderConstraint()
*/
- this.getFolderConstraints = utils.memoize(() => {
- // TODO(Shou): get this dynamically from the mountpoint of a specific port in Etcher Pro
+ this.getFolderConstraint = utils.memoize(() => {
return settings.has('fileBrowserConstraintPath')
- ? settings.get('fileBrowserConstraintPath').split(',')
- : []
+ ? settings.get('fileBrowserConstraintPath')
+ : ''
}, angular.equals)
/**
@@ -66,7 +65,6 @@ module.exports = function (
*
*/
this.getPath = () => {
- const [ constraint ] = this.getFolderConstraints()
- return constraint || os.homedir()
+ return this.getFolderConstraint() ? '/' : os.homedir()
}
}
diff --git a/lib/gui/app/components/file-selector/file-selector/file-list.jsx b/lib/gui/app/components/file-selector/file-selector/file-list.jsx
index 58433c43..fca8d7f0 100644
--- a/lib/gui/app/components/file-selector/file-selector/file-list.jsx
+++ b/lib/gui/app/components/file-selector/file-selector/file-list.jsx
@@ -228,15 +228,38 @@ const File = styled(UnstyledFile)`
class FileList extends React.Component {
constructor (props) {
super(props)
+
this.state = {
path: props.path,
highlighted: null,
files: [],
}
+
+ debug('FileList', props)
}
readdir (dirname) {
debug('FileList:readdir', dirname)
+
+ if (this.props.constraintPath && dirname === '/') {
+ if (this.props.constraint) {
+ const mountpoints = this.props.constraint.mountpoints.map(( mount ) => {
+ const entry = new files.FileEntry(mount.path, {
+ size: 0,
+ isFile: () => false,
+ isDirectory: () => true
+ })
+ entry.name = mount.label
+ return entry
+ })
+ debug('FileList:readdir', mountpoints)
+ window.requestAnimationFrame(() => {
+ this.setState({ files: mountpoints })
+ })
+ }
+ return
+ }
+
files.readdirAsync(dirname).then((files) => {
window.requestAnimationFrame(() => {
this.setState({ files: files })
@@ -263,8 +286,10 @@ class FileList extends React.Component {
shouldComponentUpdate (nextProps, nextState) {
const shouldUpdate = (this.state.files !== nextState.files)
debug('FileList:shouldComponentUpdate', shouldUpdate)
- if (this.props.path !== nextProps.path) {
- this.readdir(nextProps.path)
+ if (this.props.path !== nextProps.path || this.props.constraint !== nextProps.constraint) {
+ process.nextTick(() => {
+ this.readdir(nextProps.path)
+ })
}
return shouldUpdate
}
@@ -293,11 +318,4 @@ class FileList extends React.Component {
}
}
-FileList.propTypes = {
- path: propTypes.string,
- onNavigate: propTypes.func,
- onSelect: propTypes.func,
- constraints: propTypes.arrayOf(propTypes.string)
-}
-
module.exports = FileList
diff --git a/lib/gui/app/components/file-selector/file-selector/file-selector.jsx b/lib/gui/app/components/file-selector/file-selector/file-selector.jsx
index f52a672e..59fd3386 100644
--- a/lib/gui/app/components/file-selector/file-selector/file-selector.jsx
+++ b/lib/gui/app/components/file-selector/file-selector/file-selector.jsx
@@ -28,6 +28,7 @@ const colors = require('./colors')
const Breadcrumbs = require('./path-breadcrumbs')
const FileList = require('./file-list')
const RecentFiles = require('./recent-files')
+const files = require('../../../models/files')
const selectionState = require('../../../models/selection-state')
const osDialog = require('../../../os/dialog')
@@ -113,11 +114,20 @@ const FilePath = styled(UnstyledFilePath)`
class FileSelector extends React.PureComponent {
constructor (props) {
super(props)
+
this.state = {
path: props.path,
highlighted: null,
+ constraint: null,
files: [],
}
+
+ if (props.constraintpath) {
+ files.getConstraintDevice(props.constraintpath, (error, device) => {
+ debug('FileSelector:getConstraintDevice', error || device)
+ this.setState({ constraint: device })
+ })
+ }
}
confirmSelection () {
@@ -134,13 +144,25 @@ class FileSelector extends React.PureComponent {
debug('FileSelector:componentDidUpdate')
}
+ containPath (newPath) {
+ if (this.state.constraint) {
+ const isContained = this.state.constraint.mountpoints.some((mount) => {
+ return !path.relative(mount.path, newPath).startsWith('..')
+ })
+ if (!isContained) {
+ return '/'
+ }
+ }
+ return newPath
+ }
+
navigate (newPath) {
debug('FileSelector:navigate', newPath)
- this.setState({ path: newPath })
+ this.setState({ path: this.containPath(newPath) })
}
navigateUp () {
- const newPath = path.join( this.state.path, '..' )
+ let newPath = this.containPath(path.join(this.state.path, '..'))
debug('FileSelector:navigateUp', this.state.path, '->', newPath)
this.setState({ path: newPath })
}
@@ -254,12 +276,15 @@ class FileSelector extends React.PureComponent {
@@ -282,7 +307,7 @@ class FileSelector extends React.PureComponent {
FileSelector.propTypes = {
path: propTypes.string,
close: propTypes.func,
- constraints: propTypes.arrayOf(propTypes.string)
+ constraintpath: propTypes.string,
}
module.exports = FileSelector
diff --git a/lib/gui/app/components/file-selector/templates/file-selector-modal.tpl.html b/lib/gui/app/components/file-selector/templates/file-selector-modal.tpl.html
index 2fc18654..89eb1771 100644
--- a/lib/gui/app/components/file-selector/templates/file-selector-modal.tpl.html
+++ b/lib/gui/app/components/file-selector/templates/file-selector-modal.tpl.html
@@ -1,4 +1,4 @@
diff --git a/lib/gui/app/models/files.js b/lib/gui/app/models/files.js
index 53a8d44d..e7d01d32 100644
--- a/lib/gui/app/models/files.js
+++ b/lib/gui/app/models/files.js
@@ -18,6 +18,7 @@
const fs = require('fs')
const path = require('path')
+const drivelist = require('drivelist')
/* eslint-disable lodash/prefer-lodash-method */
/* eslint-disable no-undefined */
@@ -70,7 +71,6 @@ class FileEntry {
this.isFile = stats.isFile()
this.isDirectory = stats.isDirectory()
this.size = stats.size
- this.stats = stats
}
}
@@ -138,3 +138,30 @@ exports.splitPath = (fullpath, subpaths = []) => {
return exports.splitPath(dir, [ base ].concat(subpaths))
}
+
+/**
+ * @summary Get constraint path device
+ * @param {String} pathname - device path
+ * @param {Function} callback - callback(error, constraintDevice)
+ * @example
+ * files.getConstraintDevice('/dev/disk2', (error, device) => {
+ * // ...
+ * })
+ */
+exports.getConstraintDevice = (pathname, callback) => {
+ drivelist.list((error, devices) => {
+ if (error) {
+ callback()
+ return
+ }
+
+ const constraintDevice = devices.find((device) => {
+ return device.device === pathname ||
+ device.devicePath === pathname
+ })
+
+ callback(null, constraintDevice)
+ })
+}
+
+exports.FileEntry = FileEntry