From 07fc7af911bbc647e0aa56446989b7f51da6c337 Mon Sep 17 00:00:00 2001 From: Alexis Svinartchouk Date: Wed, 4 Dec 2019 15:36:36 +0100 Subject: [PATCH] Remove experimental file picker Change-type: patch --- lib/gui/app/app.js | 1 - .../controllers/file-selector.js | 72 ---- .../file-selector/file-selector/colors.js | 45 --- .../file-selector/file-selector/file-list.jsx | 321 ---------------- .../file-selector/file-selector.jsx | 358 ------------------ .../file-selector/path-breadcrumbs.jsx | 119 ------ .../file-selector/recent-files.jsx | 125 ------ lib/gui/app/components/file-selector/index.js | 37 -- .../file-selector/services/file-selector.js | 53 --- .../file-selector/styles/_file-selector.scss | 23 -- .../templates/file-selector-modal.tpl.html | 4 - .../image-selector/image-selector.jsx | 32 +- .../app/components/image-selector/index.js | 1 - lib/gui/app/pages/main/main.js | 1 - lib/gui/app/scss/main.scss | 1 - lib/gui/css/main.css | 20 - 16 files changed, 12 insertions(+), 1201 deletions(-) delete mode 100644 lib/gui/app/components/file-selector/controllers/file-selector.js delete mode 100644 lib/gui/app/components/file-selector/file-selector/colors.js delete mode 100644 lib/gui/app/components/file-selector/file-selector/file-list.jsx delete mode 100644 lib/gui/app/components/file-selector/file-selector/file-selector.jsx delete mode 100644 lib/gui/app/components/file-selector/file-selector/path-breadcrumbs.jsx delete mode 100644 lib/gui/app/components/file-selector/file-selector/recent-files.jsx delete mode 100644 lib/gui/app/components/file-selector/index.js delete mode 100644 lib/gui/app/components/file-selector/services/file-selector.js delete mode 100644 lib/gui/app/components/file-selector/styles/_file-selector.scss delete mode 100644 lib/gui/app/components/file-selector/templates/file-selector-modal.tpl.html diff --git a/lib/gui/app/app.js b/lib/gui/app/app.js index 6421cdc5..42c60b5e 100644 --- a/lib/gui/app/app.js +++ b/lib/gui/app/app.js @@ -88,7 +88,6 @@ const app = angular.module('Etcher', [ // Components require('./components/svg-icon'), require('./components/safe-webview'), - require('./components/file-selector'), // Pages require('./pages/main/main'), diff --git a/lib/gui/app/components/file-selector/controllers/file-selector.js b/lib/gui/app/components/file-selector/controllers/file-selector.js deleted file mode 100644 index 5463ec68..00000000 --- a/lib/gui/app/components/file-selector/controllers/file-selector.js +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018 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. - */ - -'use strict' - -const _ = require('lodash') -const os = require('os') -const settings = require('../../../models/settings') -const utils = require('../../../../../shared/utils') -const angular = require('angular') - -/* eslint-disable lodash/prefer-lodash-method */ - -module.exports = function ( - $uibModalInstance -) { - /** - * @summary Close the modal - * @function - * @public - * - * @example - * FileSelectorController.close(); - */ - this.close = () => { - $uibModalInstance.close() - } - - /** - * @summary Folder to constrain the file picker to - * @function - * @public - * - * @returns {String} - folder to constrain by - * - * @example - * FileSelectorController.getFolderConstraint() - */ - this.getFolderConstraint = utils.memoize(() => { - return settings.has('fileBrowserConstraintPath') - ? settings.get('fileBrowserConstraintPath') - : '' - }, angular.equals) - - /** - * @summary Get initial path - * @function - * @public - * - * @returns {String} - path - * - * @example - * - */ - this.getPath = () => { - const constraintFolderPath = this.getFolderConstraint() - return _.isEmpty(constraintFolderPath) ? os.homedir() : constraintFolderPath - } -} diff --git a/lib/gui/app/components/file-selector/file-selector/colors.js b/lib/gui/app/components/file-selector/file-selector/colors.js deleted file mode 100644 index fab0281e..00000000 --- a/lib/gui/app/components/file-selector/file-selector/colors.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2018 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. - */ - -'use strict' - -/** - * @summary Color scheme - * @constant - * @private - */ -const colors = { - primary: { - color: '#3a3c41', - background: '#ffffff', - subColor: '#ababab', - faded: '#c3c4c6' - }, - secondary: { - color: '#1c1d1e', - background: '#ebeff4', - title: '#b3b6b9' - }, - highlight: { - color: 'white', - background: '#2297de' - }, - soft: { - color: '#4d5056' - } -} - -module.exports = colors 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 deleted file mode 100644 index 60f0ad11..00000000 --- a/lib/gui/app/components/file-selector/file-selector/file-list.jsx +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright 2018 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. - */ - -'use strict' - -const React = require('react') -const propTypes = require('prop-types') -const styled = require('styled-components').default -const rendition = require('rendition') -const colors = require('./colors') - -const prettyBytes = require('pretty-bytes') -const files = require('../../../models/files') -const middleEllipsis = require('../../../utils/middle-ellipsis') -const supportedFormats = require('../../../../../shared/supported-formats') - -const debug = require('debug')('etcher:gui:file-selector') - -/** - * @summary Character limit of a filename before a middle-ellipsis is added - * @constant - * @private - */ -const FILENAME_CHAR_LIMIT = 20 - -/** - * @summary Pattern to match all supported formats for highlighting - * @constant - * @private - */ -const SUPPORTED_FORMATS_PATTERN = new RegExp(`^\\.(${supportedFormats.getAllExtensions().join('|')})$`, 'i') - -/** - * @summary Flex styled component - * @function - * @type {ReactElement} - */ -const Flex = styled.div` - display: flex; - flex: ${ props => props.flex }; - flex-direction: ${ props => props.direction }; - justify-content: ${ props => props.justifyContent }; - align-items: ${ props => props.alignItems }; - flex-wrap: ${ props => props.wrap }; - flex-grow: ${ props => props.grow }; -` - -/** - * @summary Anchor flex styled component - * @function - * @type {ReactElement} - */ -const ClickableFlex = styled.a` - display: flex; - flex: ${ props => props.flex }; - flex-direction: ${ props => props.direction }; - justify-content: ${ props => props.justifyContent }; - align-items: ${ props => props.alignItems }; - flex-wrap: ${ props => props.wrap }; - flex-grow: ${ props => props.grow }; -` - -/** - * @summary FileList scroll wrapper element - * @class - * @type {ReactElement} - */ -class UnstyledFileListWrap extends React.PureComponent { - constructor (props) { - super(props) - this.scrollElem = null - } - - render () { - return ( - - { this.props.children } - - ) - } - - setScrollElem (element) { - this.scrollElem = element - } - - componentDidUpdate (prevProps) { - if (this.scrollElem) { - this.scrollElem.scrollTop = 0 - } - } - -} - -/** - * @summary FileList scroll wrapper element - * @class - * @type {StyledComponent} - */ -const FileListWrap = styled(UnstyledFileListWrap)` - overflow-x: hidden; - overflow-y: auto; - padding: 0 20px; -` - -/** - * @summary File element - * @class - * @type {ReactElement} - */ -class UnstyledFile extends React.PureComponent { - - static getFileIconClass (file) { - return file.isDirectory - ? 'fas fa-folder' - : 'fas fa-file-alt' - } - - onHighlight (event) { - event.preventDefault() - this.props.onHighlight(this.props.file) - } - - onSelect (event) { - event.preventDefault() - this.props.onSelect(this.props.file) - } - - render () { - const file = this.props.file - return ( - - - { middleEllipsis(file.basename, FILENAME_CHAR_LIMIT) } -
{ file.isDirectory ? '' : prettyBytes(file.size || 0) }
-
- ) - } -} - -/** - * @summary File element - * @class - * @type {StyledComponent} - */ -const File = styled(UnstyledFile)` - width: 100px; - min-height: 100px; - max-height: 128px; - margin: 5px 10px; - padding: 5px; - background-color: none; - transition: 0.05s background-color ease-out; - color: ${ colors.primary.color }; - cursor: pointer; - border-radius: 5px; - word-break: break-word; - - > span:first-of-type { - align-self: center; - line-height: 1; - margin-bottom: 6px; - font-size: 48px; - color: ${ props => props.disabled ? colors.primary.faded : colors.soft.color }; - } - - > span:last-of-type { - display: flex; - justify-content: center; - text-align: center; - font-size: 16px; - } - - > div:last-child { - background-color: none; - color: ${ colors.primary.subColor }; - text-align: center; - font-size: 12px; - } - - :hover, :visited { - color: ${ colors.primary.color }; - } - - :focus, - :active { - color: ${ colors.highlight.color }; - background-color: ${ colors.highlight.background }; - } - - :focus > span:first-of-type, - :active > span:first-of-type { - color: ${ colors.highlight.color }; - } - - :focus > div:last-child, - :active > div:last-child { - color: ${ colors.highlight.color }; - } -` - -/** - * @summary FileList element - * @class - * @type {ReactElement} - */ -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 }) - }) - }) - } - - componentDidMount () { - process.nextTick(() => { - this.readdir(this.state.path) - }) - } - - onHighlight (file) { - debug('FileList:onHighlight', file) - this.props.onHighlight(file) - } - - onSelect (file) { - debug('FileList:onSelect', file.path, file.isDirectory) - this.props.onSelect(file) - } - - shouldComponentUpdate (nextProps, nextState) { - const shouldUpdate = (this.state.files !== nextState.files) - debug('FileList:shouldComponentUpdate', shouldUpdate) - if (this.props.path !== nextProps.path || this.props.constraint !== nextProps.constraint) { - process.nextTick(() => { - this.readdir(nextProps.path) - }) - } - return shouldUpdate - } - - static isSelectable (file) { - return file.isDirectory || !file.ext || - SUPPORTED_FORMATS_PATTERN.test(file.ext) - } - - render () { - return ( - - { - this.state.files.map((file) => { - return ( - - ) - }) - } - - ) - } -} - -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 deleted file mode 100644 index ba262d74..00000000 --- a/lib/gui/app/components/file-selector/file-selector/file-selector.jsx +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Copyright 2018 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. - */ - -'use strict' - -const path = require('path') -const sdk = require('etcher-sdk') - -const Bluebird = require('bluebird') -const React = require('react') -const propTypes = require('prop-types') -const styled = require('styled-components').default -const rendition = require('rendition') -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 store = require('../../../models/store') -const osDialog = require('../../../os/dialog') -const exceptionReporter = require('../../../modules/exception-reporter') -const messages = require('../../../../../shared/messages') -const errors = require('../../../../../shared/errors') -const supportedFormats = require('../../../../../shared/supported-formats') -const analytics = require('../../../modules/analytics') - -const debug = require('debug')('etcher:gui:file-selector') - -/** - * @summary Flex styled component - * @function - * @type {ReactElement} - */ -const Flex = styled.div` - display: flex; - flex: ${ props => props.flex }; - flex-direction: ${ props => props.direction }; - justify-content: ${ props => props.justifyContent }; - align-items: ${ props => props.alignItems }; - flex-wrap: ${ props => props.wrap }; - flex-grow: ${ props => props.grow }; - overflow: ${ props => props.overflow }; -` - -const Header = styled(Flex) ` - padding: 10px 15px 0; - border-bottom: 1px solid ${ colors.primary.faded }; - - > * { - margin: 5px; - } -` - -const Main = styled(Flex) `` - -const Footer = styled(Flex) ` - padding: 10px; - flex: 0 0 auto; - border-top: 1px solid ${ colors.primary.faded }; - - > * { - margin: 0 10px; - } - - > button { - flex-grow: 0; - flex-shrink: 0; - } -` - -class UnstyledFilePath extends React.PureComponent { - render () { - return ( -
- { - this.props.file && !this.props.file.isDirectory - ? this.props.file.basename - : '' - } -
- ) - } -} - -const FilePath = styled(UnstyledFilePath)` - display: flex; - flex-grow: 1; - align-items: center; - overflow: hidden; - - > span { - font-size: 16px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; - } -` - -class FileSelector extends React.PureComponent { - constructor (props) { - super(props) - - this.state = { - path: props.path, - highlighted: null, - constraint: null, - files: [], - } - - } - - componentDidMount() { - if (this.props.constraintpath) { - const device = files.getConstraintDevice(this.props.constraintpath) - debug('FileSelector:getConstraintDevice', device) - if (device !== undefined) { - this.setState({ constraint: device.drive }) - } - } - } - - confirmSelection () { - if (this.state.highlighted) { - this.selectFile(this.state.highlighted) - } - } - - close () { - this.props.close() - } - - componentDidUpdate () { - 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: this.containPath(newPath) }) - } - - navigateUp () { - let newPath = this.containPath(path.join(this.state.path, '..')) - debug('FileSelector:navigateUp', this.state.path, '->', newPath) - this.setState({ path: newPath }) - } - - selectImage (image) { - debug('FileSelector:selectImage', image) - - if (!supportedFormats.isSupportedImage(image.path)) { - const invalidImageError = errors.createUserError({ - title: 'Invalid image', - description: messages.error.invalidImage(image.path) - }) - - osDialog.showError(invalidImageError) - analytics.logEvent('Invalid image', { - image, - applicationSessionUuid: store.getState().toJS().applicationSessionUuid, - flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid - }) - return Bluebird.resolve() - } - - return Bluebird.try(() => { - let message = null - - if (supportedFormats.looksLikeWindowsImage(image.path)) { - analytics.logEvent('Possibly Windows image', { - image, - applicationSessionUuid: store.getState().toJS().applicationSessionUuid, - flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid - }) - message = messages.warning.looksLikeWindowsImage() - } else if (!image.hasMBR) { - analytics.logEvent('Missing partition table', { - image, - applicationSessionUuid: store.getState().toJS().applicationSessionUuid, - flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid - }) - message = messages.warning.missingPartitionTable() - } - - if (message) { - // TODO: `Continue` should be on a red background (dangerous action) instead of `Change`. - // We want `X` to act as `Continue`, that's why `Continue` is the `rejectionLabel` - return osDialog.showWarning({ - confirmationLabel: 'Change', - rejectionLabel: 'Continue', - title: 'Warning', - description: message - }) - } - - return false - }).then((shouldChange) => { - if (shouldChange) { - return - } - - selectionState.selectImage(image) - - this.close() - - // An easy way so we can quickly identify if we're making use of - // certain features without printing pages of text to DevTools. - image.logo = Boolean(image.logo) - image.blockMap = Boolean(image.blockMap) - - analytics.logEvent('Select image', { - image, - applicationSessionUuid: store.getState().toJS().applicationSessionUuid, - flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid - }) - }).catch(exceptionReporter.report) - } - - selectFile (file) { - debug('FileSelector:selectFile', file) - - if (file.isDirectory) { - this.navigate(file.path) - return - } - - if (!supportedFormats.isSupportedImage(file.path)) { - const invalidImageError = errors.createUserError({ - title: 'Invalid image', - description: messages.error.invalidImage(file.path) - }) - - osDialog.showError(invalidImageError) - analytics.logEvent('Invalid image', { path: file.path }) - return - } - - debug('FileSelector:getImageMetadata', file) - - const source = new sdk.sourceDestination.File(file.path, sdk.sourceDestination.File.OpenFlags.Read) - source.getInnerSource() - .then((innerSource) => { - return innerSource.getMetadata() - .then((imageMetadata) => { - debug('FileSelector:getImageMetadata', imageMetadata) - imageMetadata.path = file.path - imageMetadata.extension = path.extname(file.path).slice(1) - return innerSource.getPartitionTable() - .then((partitionTable) => { - if (partitionTable !== undefined) { - imageMetadata.hasMBR = true - imageMetadata.partitions = partitionTable.partitions - } - return this.selectImage(imageMetadata) - }) - }) - }) - .catch((error) => { - debug('FileSelector:getImageMetadata', error) - const imageError = errors.createUserError({ - title: 'Error opening image', - description: messages.error.openImage(path.basename(file.path), error.message) - }) - - osDialog.showError(imageError) - analytics.logException(error) - }) - } - - onHighlight (file) { - this.setState({ highlighted: file }) - } - - render () { - const styles = { - display: 'flex', - height: 'calc(100vh - 20px)', - } - return ( - - {/**/} - -
- - -  Back - - - -
-
- - - -
-
- - Cancel - - Select file - -
-
-
- ) - } -} - -FileSelector.propTypes = { - path: propTypes.string, - close: propTypes.func, - constraintpath: propTypes.string, -} - -module.exports = FileSelector diff --git a/lib/gui/app/components/file-selector/file-selector/path-breadcrumbs.jsx b/lib/gui/app/components/file-selector/file-selector/path-breadcrumbs.jsx deleted file mode 100644 index 23eaa5ee..00000000 --- a/lib/gui/app/components/file-selector/file-selector/path-breadcrumbs.jsx +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2018 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. - */ - -'use strict' - -const path = require('path') - -const React = require('react') -const propTypes = require('prop-types') -const styled = require('styled-components').default -const rendition = require('rendition') - -const middleEllipsis = require('../../../utils/middle-ellipsis') - -/** - * @summary How many directories to show with the breadcrumbs - * @type {Number} - * @constant - * @private - */ -const MAX_DIR_CRUMBS = 3 - -/** - * @summary Character limit of a filename before a middle-ellipsis is added - * @constant - * @private - */ -const FILENAME_CHAR_LIMIT_SHORT = 15 - -function splitComponents(dirname, root) { - const components = [] - let basename = null - root = root || path.parse(dirname).root - while( dirname !== root ) { - basename = path.basename(dirname) - components.unshift({ - path: dirname, - basename: basename, - name: basename - }) - dirname = path.join( dirname, '..' ) - } - if (components.length < MAX_DIR_CRUMBS) { - components.unshift({ - path: root, - basename: root, - name: 'Root' - }) - } - return components -} - -class Crumb extends React.PureComponent { - constructor (props) { - super(props) - } - - render () { - return ( - - - { middleEllipsis(this.props.dir.name, FILENAME_CHAR_LIMIT_SHORT) } - - - ) - } - - navigate () { - this.props.navigate(this.props.dir.path) - } -} - -class UnstyledBreadcrumbs extends React.PureComponent { - render () { - const components = splitComponents(this.props.path).slice(-MAX_DIR_CRUMBS) - return ( -
- { - components.map((dir, index) => { - return ( - - ) - }) - } -
- ) - } -} - -const Breadcrumbs = styled(UnstyledBreadcrumbs)` - font-size: 18px; - - & > button:not(:last-child)::after { - content: '/'; - margin: 9px; - } -` - -module.exports = Breadcrumbs diff --git a/lib/gui/app/components/file-selector/file-selector/recent-files.jsx b/lib/gui/app/components/file-selector/file-selector/recent-files.jsx deleted file mode 100644 index ea655b74..00000000 --- a/lib/gui/app/components/file-selector/file-selector/recent-files.jsx +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2018 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. - */ - -'use strict' - -const React = require('react') -const propTypes = require('prop-types') -const styled = require('styled-components').default -const rendition = require('rendition') -const colors = require('./colors') - -const middleEllipsis = require('../../../utils/middle-ellipsis') - -/** - * @summary Flex styled component - * @function - * @type {ReactElement} - */ -const Flex = styled.div` - display: flex; - flex: ${ props => props.flex }; - flex-direction: ${ props => props.direction }; - justify-content: ${ props => props.justifyContent }; - align-items: ${ props => props.alignItems }; - flex-wrap: ${ props => props.wrap }; - flex-grow: ${ props => props.grow }; -` - -class RecentFileLink extends React.PureComponent { - constructor (props) { - super(props) - } - - render () { - const file = this.props.file - return ( - - { middleEllipsis(file.name, FILENAME_CHAR_LIMIT_SHORT) } - - ) - } - - select () { - this.props.onSelect(this.props.file) - } -} - -class UnstyledRecentFiles extends React.PureComponent { - constructor(props) { - super(props) - this.state = { - recent: [], - favorites: [] - } - } - - render () { - return ( - -
Recent
- { - this.state.recent.map((file) => { - - }) - } -
Favorite
- { - this.state.favorites.map((file) => { - - }) - } -
- ) - } -} - -const RecentFiles = styled(UnstyledRecentFiles)` - display: flex; - flex: 0 0 auto; - flex-direction: column; - align-items: flex-start; - width: 130px; - background-color: ${ colors.secondary.background }; - padding: 20px; - color: ${ colors.secondary.color }; - - > h5 { - color: ${ colors.secondary.title }; - font-size: 11px; - font-weight: 500; - text-transform: uppercase; - margin-bottom: 15px; - } - - > h5:last-of-type { - margin-top: 20px; - } - - > button { - margin-bottom: 10px; - text-align: start; - font-size: 16px; - } -` - -module.exports = RecentFiles diff --git a/lib/gui/app/components/file-selector/index.js b/lib/gui/app/components/file-selector/index.js deleted file mode 100644 index 36f57f0b..00000000 --- a/lib/gui/app/components/file-selector/index.js +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2018 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. - */ - -'use strict' - -/* eslint-disable jsdoc/require-example */ - -/** - * @module Etcher.Components.SVGIcon - */ - -const angular = require('angular') -const react2angular = require('react2angular').react2angular - -const MODULE_NAME = 'Etcher.Components.FileSelector' -const angularFileSelector = angular.module(MODULE_NAME, [ - require('../modal/modal') -]) - -angularFileSelector.component('fileSelector', react2angular(require('./file-selector/file-selector.jsx'))) -angularFileSelector.controller('FileSelectorController', require('./controllers/file-selector')) -angularFileSelector.service('FileSelectorService', require('./services/file-selector')) - -module.exports = MODULE_NAME diff --git a/lib/gui/app/components/file-selector/services/file-selector.js b/lib/gui/app/components/file-selector/services/file-selector.js deleted file mode 100644 index 0f27fbe6..00000000 --- a/lib/gui/app/components/file-selector/services/file-selector.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2018 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. - */ - -'use strict' - -module.exports = function (ModalService, $q) { - let modal = null - - /** - * @summary Open the file selector widget - * @function - * @public - * - * @example - * DriveSelectorService.open() - */ - this.open = () => { - modal = ModalService.open({ - name: 'file-selector', - template: require('../templates/file-selector-modal.tpl.html'), - controller: 'FileSelectorController as selector', - size: 'file-selector-modal' - }) - } - - /** - * @summary Close the file selector widget - * @function - * @public - * - * @example - * DriveSelectorService.close() - */ - this.close = () => { - if (modal) { - modal.close() - } - modal = null - } -} diff --git a/lib/gui/app/components/file-selector/styles/_file-selector.scss b/lib/gui/app/components/file-selector/styles/_file-selector.scss deleted file mode 100644 index 189a3cc3..00000000 --- a/lib/gui/app/components/file-selector/styles/_file-selector.scss +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2018 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. - */ - -.modal-file-selector-modal { - width: calc(100vw - 10px); - - > .modal-content { - height: calc(100vh - 20px); - } -} 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 deleted file mode 100644 index 89eb1771..00000000 --- a/lib/gui/app/components/file-selector/templates/file-selector-modal.tpl.html +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/lib/gui/app/components/image-selector/image-selector.jsx b/lib/gui/app/components/image-selector/image-selector.jsx index 1d5e8c9b..023b001a 100644 --- a/lib/gui/app/components/image-selector/image-selector.jsx +++ b/lib/gui/app/components/image-selector/image-selector.jsx @@ -255,27 +255,19 @@ class ImageSelector extends React.Component { flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid }) - if (settings.get('experimentalFilePicker')) { - const { - FileSelectorService - } = this.props + osDialog.selectImage().then((imagePath) => { + // Avoid analytics and selection state changes + // if no file was resolved from the dialog. + if (!imagePath) { + analytics.logEvent('Image selector closed', { + applicationSessionUuid: store.getState().toJS().applicationSessionUuid, + flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid + }) + return + } - FileSelectorService.open() - } else { - osDialog.selectImage().then((imagePath) => { - // Avoid analytics and selection state changes - // if no file was resolved from the dialog. - if (!imagePath) { - analytics.logEvent('Image selector closed', { - applicationSessionUuid: store.getState().toJS().applicationSessionUuid, - flashingWorkflowUuid: store.getState().toJS().flashingWorkflowUuid - }) - return - } - - this.selectImageByPath(imagePath) - }).catch(exceptionReporter.report) - } + this.selectImageByPath(imagePath) + }).catch(exceptionReporter.report) } handleOnDrop (acceptedFiles) { diff --git a/lib/gui/app/components/image-selector/index.js b/lib/gui/app/components/image-selector/index.js index 699085aa..d9973467 100644 --- a/lib/gui/app/components/image-selector/index.js +++ b/lib/gui/app/components/image-selector/index.js @@ -33,7 +33,6 @@ ImageSelector.component( react2angular(require('./image-selector.jsx')), [], [ - 'FileSelectorService', 'WarningModalService' ] ) diff --git a/lib/gui/app/pages/main/main.js b/lib/gui/app/pages/main/main.js index 76ec8ee2..2607e7c9 100644 --- a/lib/gui/app/pages/main/main.js +++ b/lib/gui/app/pages/main/main.js @@ -31,7 +31,6 @@ const MainPage = angular.module(MODULE_NAME, [ require('../../components/drive-selector/drive-selector'), require('../../components/image-selector'), - require('../../components/file-selector'), require('../../components/featured-project'), require('../../components/reduced-flashing-infos'), require('../../components/flash-another'), diff --git a/lib/gui/app/scss/main.scss b/lib/gui/app/scss/main.scss index bb49b9bd..d478363f 100644 --- a/lib/gui/app/scss/main.scss +++ b/lib/gui/app/scss/main.scss @@ -34,7 +34,6 @@ $disabled-opacity: 0.2; @import "../components/modal/styles/modal"; @import "../components/drive-selector/styles/drive-selector"; @import "../components/svg-icon/styles/svg-icon"; -@import "../components/file-selector/styles/file-selector"; @import "../pages/main/styles/main"; @import "../pages/finish/styles/finish"; diff --git a/lib/gui/css/main.css b/lib/gui/css/main.css index a52f4df0..d5740a87 100644 --- a/lib/gui/css/main.css +++ b/lib/gui/css/main.css @@ -6286,26 +6286,6 @@ svg-icon { width: 100%; height: 100%; } -/* - * Copyright 2018 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. - */ -.modal-file-selector-modal { - width: calc(100vw - 10px); } - .modal-file-selector-modal > .modal-content { - height: calc(100vh - 20px); } - /* * Copyright 2016 resin.io *