diff --git a/.jshintrc b/.jshintrc index daeaf45072..9240a3ae9f 100644 --- a/.jshintrc +++ b/.jshintrc @@ -27,5 +27,5 @@ "jest": true, "pit": true }, - "predef": [ "Promise" ] + "predef": [ "-Promise" ] } diff --git a/src/ContainerList.react.js b/src/ContainerList.react.js index 1d6d25a034..dd2ae9b139 100644 --- a/src/ContainerList.react.js +++ b/src/ContainerList.react.js @@ -13,15 +13,9 @@ var ContainerList = React.createClass({ ); }); - var newItem; - if (!this.props.downloading) { - newItem = ; - } else { - newItem = ''; - } return ( ); diff --git a/src/ContainerStore.js b/src/ContainerStore.js index d4a7615f31..70de5b65a5 100644 --- a/src/ContainerStore.js +++ b/src/ContainerStore.js @@ -297,10 +297,6 @@ var ContainerStore = assign(Object.create(EventEmitter.prototype), { var imageName = repository + ':' + tag; var containerName = this._generateName(repository); - if (_pending && _pending.repository === repository && _pending.tag === tag) { - _pending = null; - } - _placeholders[containerName] = { Name: containerName, Image: imageName, diff --git a/src/Containers.react.js b/src/Containers.react.js index 62f316c1b2..ab613bb61a 100644 --- a/src/Containers.react.js +++ b/src/Containers.react.js @@ -10,8 +10,6 @@ var metrics = require('./Metrics'); var autoUpdater = remote.require('auto-updater'); var RetinaImage = require('react-retina-image'); var machine = require('./DockerMachine'); -var OverlayTrigger = require('react-bootstrap').OverlayTrigger; -var Tooltip = require('react-bootstrap').Tooltip; var util = require('./Util'); var Containers = React.createClass({ @@ -33,14 +31,6 @@ var Containers = React.createClass({ ContainerStore.on(ContainerStore.SERVER_CONTAINER_EVENT, this.update); ContainerStore.on(ContainerStore.CLIENT_CONTAINER_EVENT, this.updateFromClient); - console.log(this.state); - if (this.state.pending) { - console.log('pending'); - this.transitionTo('pull'); - } else if (this.state.sorted.length) { - this.transitionTo('containerHome', {name: this.state.sorted[0].Name}); - } - ipc.on('application:update-available', () => { this.setState({ updateAvailable: true @@ -52,44 +42,33 @@ var Containers = React.createClass({ ContainerStore.removeListener(ContainerStore.SERVER_CONTAINER_EVENT, this.update); ContainerStore.removeListener(ContainerStore.CLIENT_CONTAINER_EVENT, this.updateFromClient); }, - onDestroy: function () { - if (this.state.sorted.length) { - this.transitionTo('containerHome', {name: this.state.sorted[0].Name}); - } else { - this.transitionTo('containers'); - } - }, updateError: function (err) { this.setState({ error: err }); }, update: function (name, status) { + var sorted = ContainerStore.sorted(); this.setState({ containers: ContainerStore.containers(), - sorted: ContainerStore.sorted(), - downloading: ContainerStore.downloading(), - pending: ContainerStore.pending() + sorted: sorted, + pending: ContainerStore.pending(), + downloading: ContainerStore.downloading() }); if (status === 'destroy') { - this.onDestroy(); + if (sorted.length) { + this.transitionTo('containerHome', {name: sorted[0].Name}); + } else { + this.transitionTo('containers'); + } } }, updateFromClient: function (name, status) { - this.setState({ - containers: ContainerStore.containers(), - sorted: ContainerStore.sorted(), - downloading: ContainerStore.downloading(), - pending: ContainerStore.pending() - }); - console.log('update from client'); - - if (this.state.pending) { - this.transitionTo('pull'); - } else if (status === 'create') { + this.update(name, status); + if (status === 'create') { this.transitionTo('containerHome', {name: name}); - } else if (status === 'destroy') { - this.onDestroy(); + } else if (status === 'pending' && ContainerStore.pending()) { + this.transitionTo('pull'); } }, handleScroll: function (e) { @@ -172,17 +151,6 @@ var Containers = React.createClass({ ); } - var button; - if (this.state.downloading) { - button = ( - Only one Docker image can be downloaded at a time.}> - - - ); - } else { - button = ; - } - var container = this.getParams().name ? this.state.containers[this.getParams().name] : {}; return (
@@ -192,7 +160,7 @@ var Containers = React.createClass({

Containers

- {button} +
diff --git a/src/Main.js b/src/Main.js index 72588cbac0..729025ce88 100644 --- a/src/Main.js +++ b/src/Main.js @@ -51,16 +51,18 @@ ipc.on('application:open-url', opts => { ContainerStore.setPending(repo, 'latest'); } }); -ContainerStore.setPending('kitematic/ghost', 'latest'); SetupStore.setup().then(() => { + if (ContainerStore.pending()) { + router.transitionTo('pull'); + } else { + router.transitionTo('new'); + } Menu.setApplicationMenu(Menu.buildFromTemplate(template())); ContainerStore.on(ContainerStore.SERVER_ERROR_EVENT, (err) => { bugsnag.notify(err); }); - ContainerStore.init(function () { - router.transitionTo('containers'); - }); + ContainerStore.init(function () {}); }).catch(err => { metrics.track('Setup Failed', { step: 'catch', diff --git a/src/NewContainerPull.react.js b/src/NewContainerPull.react.js new file mode 100644 index 0000000000..3efd71aab5 --- /dev/null +++ b/src/NewContainerPull.react.js @@ -0,0 +1,42 @@ +var React = require('react/addons'); +var Router = require('react-router'); +var shell = require('shell'); +var ContainerStore = require('./ContainerStore'); + +module.exports = React.createClass({ + mixins: [Router.Navigation], + handleOpenClick: function () { + var repo = this.props.pending.repository; + if (repo.indexOf('/') === -1) { + shell.openExternal(`https://registry.hub.docker.com/_/${this.props.pending.repository}`); + } else { + shell.openExternal(`https://registry.hub.docker.com/u/${this.props.pending.repository}`); + } + }, + handleCancelClick: function () { + ContainerStore.clearPending(); + this.transitionTo('new'); + }, + handleConfirmClick: function () { + ContainerStore.clearPending(); + ContainerStore.create(this.props.pending.repository, this.props.pending.tag, function () {}); + }, + render: function () { + if (!this.props.pending) { + return false; + } + return ( +
+
+
+

You're about to download {this.props.pending.repository}.

+

Please confirm to create the container.

+ +
+
+
+ ); + } +}); diff --git a/src/NewContainer.react.js b/src/NewContainerSearch.react.js similarity index 95% rename from src/NewContainer.react.js rename to src/NewContainerSearch.react.js index eb8059a31a..3ac67f2882 100644 --- a/src/NewContainer.react.js +++ b/src/NewContainerSearch.react.js @@ -4,13 +4,13 @@ var React = require('react/addons'); var RetinaImage = require('react-retina-image'); var Radial = require('./Radial.react'); var ImageCard = require('./ImageCard.react'); -var metrics = require('./Metrics'); var Promise = require('bluebird'); +var metrics = require('./Metrics'); var _recommended = []; var _searchPromise = null; -var NewContainer = React.createClass({ +module.exports = React.createClass({ getInitialState: function () { return { query: '', @@ -47,7 +47,7 @@ var NewContainer = React.createClass({ loading: true }); - _searchPromise = Promise.delay(200).then(() => Promise.resolve($.get('https://registry.hub.docker.com/v1/search?q=' + query))).cancellable().then(data => { + _searchPromise = Promise.delay(200).cancellable().then(() => Promise.resolve($.get('https://registry.hub.docker.com/v1/search?q=' + query))).then(data => { metrics.track('Searched for Images'); this.setState({ results: data.results, @@ -142,7 +142,6 @@ var NewContainer = React.createClass({ 'icon-magnifier': true, 'search-icon': true }); - return (
@@ -167,5 +166,3 @@ var NewContainer = React.createClass({ ); } }); - -module.exports = NewContainer; diff --git a/src/Routes.js b/src/Routes.js index 05dd638a0e..cfdade8b51 100644 --- a/src/Routes.js +++ b/src/Routes.js @@ -9,13 +9,14 @@ var ContainerSettingsGeneral = require('./ContainerSettingsGeneral.react'); var ContainerSettingsPorts = require('./ContainerSettingsPorts.react'); var ContainerSettingsVolumes = require('./ContainerSettingsVolumes.react'); var Preferences = require('./Preferences.react'); -var NewContainer = require('./NewContainer.react'); -var PullContainer = require('./PullContainer.react'); +var NewContainerSearch = require('./NewContainerSearch.react'); +var NewContainerPull = require('./NewContainerPull.react'); var Router = require('react-router'); var Route = Router.Route; var DefaultRoute = Router.DefaultRoute; var RouteHandler = Router.RouteHandler; +var Redirect = Router.Redirect; var App = React.createClass({ render: function () { @@ -28,18 +29,21 @@ var App = React.createClass({ var routes = ( - - - - - - - + + + + + + + + + + + - - + diff --git a/styles/new-container.less b/styles/new-container.less index a00f9c3eb3..86b60d8903 100644 --- a/styles/new-container.less +++ b/styles/new-container.less @@ -1,3 +1,32 @@ +.new-container-pull { + display: flex; + flex: 1 auto; + align-items: center; + justify-content: center; + .content { + text-align: center; + + .buttons { + margin-top: 30px; + .btn { + margin-left: 10px; + margin-right: 10px; + padding: 8px 18px; + font-size: 14px; + background: white; + font-weight: 300; + } + } + } + h1 { + font-size: 20px; + color: @gray-normal; + font-weight: 400; + text-align: center; + margin-top: 10px; + } +} + .new-container { display: flex; flex: 1 auto; diff --git a/styles/theme.less b/styles/theme.less index 07e8cedd22..d20daccc76 100644 --- a/styles/theme.less +++ b/styles/theme.less @@ -134,7 +134,6 @@ input[type="text"] { font-weight: 400; text-shadow: none; padding: 5px 14px 5px 14px; - height: 30px; cursor: default; &.small {