feeles-ide
Version:
The hackable and serializable IDE to make learning material
590 lines (517 loc) • 18.7 kB
JavaScript
import _regeneratorRuntime from 'babel-runtime/regenerator';
import _asyncToGenerator from 'babel-runtime/helpers/asyncToGenerator';
import _Object$getPrototypeOf from 'babel-runtime/core-js/object/get-prototype-of';
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _createClass from 'babel-runtime/helpers/createClass';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
import moment from 'moment';
import Dialog from 'material-ui/Dialog';
import { Tabs, Tab } from 'material-ui/Tabs';
import RaisedButton from 'material-ui/RaisedButton';
import FlatButton from 'material-ui/FlatButton';
import CircularProgress from 'material-ui/CircularProgress';
import { Card, CardHeader, CardActions, CardText } from 'material-ui/Card';
import ContentAddCircle from 'material-ui/svg-icons/content/add-circle';
import ActionOpenInBrowser from 'material-ui/svg-icons/action/open-in-browser';
import ActionDelete from 'material-ui/svg-icons/action/delete';
import { brown50, red400 } from 'material-ui/styles/colors';
import { personalDB, createProject, updateProject, deleteProject } from '../database/';
import EditableLabel from '../jsx/EditableLabel';
var CloneDialog = function (_PureComponent) {
_inherits(CloneDialog, _PureComponent);
function CloneDialog() {
var _ref,
_this2 = this;
var _temp, _this, _ret;
_classCallCheck(this, CloneDialog);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = CloneDialog.__proto__ || _Object$getPrototypeOf(CloneDialog)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
error: null,
projects: null,
processing: false,
currentProject: _this.props.project,
// Default show projects same url (origin + pathname)
showAllUrls: false
}, _this.handleCreate = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
var project, deployURL;
return _regeneratorRuntime.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
if (!_this.hasSaved) {
_context.next = 2;
break;
}
return _context.abrupt('return');
case 2:
_this.setState({ processing: true });
_context.prev = 3;
_context.next = 6;
return createProject(_this.props.files.map(function (item) {
return item.serialize();
}));
case 6:
project = _context.sent;
_context.next = 9;
return _this.props.setProject(project);
case 9:
_context.next = 11;
return _this.refreshState(project);
case 11:
deployURL = _this.props.deployURL;
if (!deployURL) {
_context.next = 15;
break;
}
_context.next = 15;
return updateProject(project.id, { deployURL: deployURL });
case 15:
_context.next = 21;
break;
case 17:
_context.prev = 17;
_context.t0 = _context['catch'](3);
console.log(_context.t0);
if (typeof _context.t0 === 'string' && _context.t0 in _this.props.localization.cloneDialog) {
alert(_this.props.localization.cloneDialog[_context.t0]);
}
case 21:
_this.setState({ processing: false });
case 22:
case 'end':
return _context.stop();
}
}
}, _callee, _this2, [[3, 17]]);
})), _this.handleTitleChange = function () {
var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(project, title) {
var localization, nextProject;
return _regeneratorRuntime.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
localization = _this.props.localization;
_this.setState({ processing: true });
_context2.prev = 2;
_context2.next = 5;
return updateProject(project.id, { title: title });
case 5:
nextProject = _context2.sent;
if (!(_this.hasSaved && _this.state.currentProject.id === project.id)) {
_context2.next = 13;
break;
}
_context2.next = 9;
return _this.props.setProject(nextProject);
case 9:
_context2.next = 11;
return _this.refreshState(nextProject);
case 11:
_context2.next = 15;
break;
case 13:
_context2.next = 15;
return _this.refreshState();
case 15:
_context2.next = 20;
break;
case 17:
_context2.prev = 17;
_context2.t0 = _context2['catch'](2);
if (typeof _context2.t0 === 'string') {
alert(localization.cloneDialog[_context2.t0]);
}
case 20:
_this.setState({ processing: false });
case 21:
case 'end':
return _context2.stop();
}
}
}, _callee2, _this2, [[2, 17]]);
}));
return function (_x, _x2) {
return _ref3.apply(this, arguments);
};
}(), _this.handleProcessStart = function () {
_this.setState({ processing: true });
}, _this.handleProcessEnd = function () {
_this.setState({ processing: false });
_this.refreshState();
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(CloneDialog, [{
key: 'componentWillMount',
value: function componentWillMount() {
this.refreshState();
}
}, {
key: 'refreshState',
value: function () {
var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3(nextProject) {
var _this3 = this;
var projects;
return _regeneratorRuntime.wrap(function _callee3$(_context3) {
while (1) {
switch (_context3.prev = _context3.next) {
case 0:
_context3.next = 2;
return personalDB.projects.toArray();
case 2:
projects = _context3.sent;
projects.sort(function (a, b) {
return b.updated - a.updated;
});
this.setState({
projects: projects,
currentProject: nextProject || (this.hasSaved ? projects.find(function (item) {
return item.id === _this3.state.currentProject.id;
}) : null)
});
case 5:
case 'end':
return _context3.stop();
}
}
}, _callee3, this);
}));
function refreshState(_x3) {
return _ref4.apply(this, arguments);
}
return refreshState;
}()
}, {
key: 'render',
value: function render() {
var _this4 = this;
var _props = this.props,
onRequestClose = _props.onRequestClose,
localization = _props.localization;
var currentProject = this.state.currentProject;
var styles = {
body: {
padding: 0
},
button: {
marginLeft: 16
},
header: {
marginLeft: 24
},
radio: {
marginBottom: 16
},
group: {
padding: 24
},
center: {
textAlign: 'center'
},
container: {
margin: 16,
padding: 8,
paddingBottom: 16,
height: '20rem',
overflow: 'scroll',
backgroundColor: brown50
},
card: {
marginTop: 16
},
label: {
fontWeight: 600,
marginRight: '1rem'
}
};
var actions = [React.createElement(FlatButton, {
key: 'showAll',
label: localization.menu.showAllUrls,
style: styles.button,
onClick: function onClick() {
return _this4.setState(function (prevState) {
return { showAllUrls: !prevState.showAllUrls };
});
}
}), React.createElement(FlatButton, {
key: 'cancel',
label: localization.cloneDialog.cancel,
style: styles.button,
onClick: onRequestClose
})];
var url = location.origin + location.pathname;
var projects = (this.state.projects || []).filter(function (project) {
return _this4.state.showAllUrls || project.url === url;
});
return React.createElement(
Dialog,
{
open: true,
modal: this.state.processing,
bodyStyle: styles.body,
actions: actions,
onRequestClose: onRequestClose
},
React.createElement(
Tabs,
null,
React.createElement(
Tab,
{ label: localization.cloneDialog.saveTitle },
React.createElement(
'h1',
{ style: styles.header },
localization.cloneDialog.saveHeader
),
React.createElement(
'div',
{ style: styles.container },
this.hasSaved ? [React.createElement(
'span',
{ key: '' },
localization.cloneDialog.autoSaved
), React.createElement(
Card,
{ key: 'current', style: styles.card },
React.createElement(CardHeader, {
title: React.createElement(EditableLabel, {
id: 'title',
openImmediately: !currentProject.title,
defaultValue: currentProject.title,
tapTwiceQuickly: localization.common.tapTwiceQuickly,
hintText: localization.cloneDialog.setTitle,
onEditEnd: function onEditEnd(text) {
return _this4.handleTitleChange(currentProject, text);
}
}),
subtitle: new Date(currentProject.updated).toLocaleString()
})
)] : React.createElement(RaisedButton, {
fullWidth: true,
key: 'new_project',
label: localization.cloneDialog.saveInNew,
style: styles.card,
icon: React.createElement(ContentAddCircle, null),
disabled: this.state.processing,
onClick: this.handleCreate
})
)
),
React.createElement(
Tab,
{ label: localization.cloneDialog.loadTitle },
React.createElement(
'h1',
{ style: styles.header },
localization.cloneDialog.loadHeader
),
!this.state.projects ? React.createElement(
'div',
{ style: { textAlign: 'center' } },
React.createElement(CircularProgress, { size: 120 })
) : React.createElement(
'div',
{ style: styles.container },
projects.map(function (item) {
return React.createElement(ProjectCard, {
key: item.id,
project: item,
showURL: _this4.state.showAllUrls,
launchIDE: _this4.props.launchIDE,
processing: _this4.state.processing,
onProcessStart: _this4.handleProcessStart,
onProcessEnd: _this4.handleProcessEnd,
requestTitleChange: _this4.handleTitleChange,
requestProjectSet: _this4.props.setProject,
localization: localization
});
})
)
)
)
);
}
}, {
key: 'hasSaved',
get: function get() {
return !!this.state.currentProject;
}
}]);
return CloneDialog;
}(PureComponent);
CloneDialog.propTypes = {
resolve: PropTypes.func.isRequired,
onRequestClose: PropTypes.func.isRequired,
files: PropTypes.array.isRequired,
localization: PropTypes.object.isRequired,
project: PropTypes.object,
setProject: PropTypes.func.isRequired,
launchIDE: PropTypes.func.isRequired,
deployURL: PropTypes.string
};
export default CloneDialog;
export var ProjectCard = function (_PureComponent2) {
_inherits(ProjectCard, _PureComponent2);
function ProjectCard() {
var _ref5,
_this6 = this;
var _temp2, _this5, _ret2;
_classCallCheck(this, ProjectCard);
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return _ret2 = (_temp2 = (_this5 = _possibleConstructorReturn(this, (_ref5 = ProjectCard.__proto__ || _Object$getPrototypeOf(ProjectCard)).call.apply(_ref5, [this].concat(args))), _this5), _this5.handleLoad = function () {
return _this5.props.launchIDE(_this5.props.project);
}, _this5.handleRemove = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
var _this5$props, project, localization;
return _regeneratorRuntime.wrap(function _callee4$(_context4) {
while (1) {
switch (_context4.prev = _context4.next) {
case 0:
_this5$props = _this5.props, project = _this5$props.project, localization = _this5$props.localization;
if (confirm(localization.common.cannotBeUndone)) {
_context4.next = 3;
break;
}
return _context4.abrupt('return');
case 3:
_this5.props.onProcessStart();
_context4.prev = 4;
_context4.next = 7;
return deleteProject(project.id);
case 7:
_context4.next = 9;
return _this5.props.requestProjectSet(null);
case 9:
_context4.next = 14;
break;
case 11:
_context4.prev = 11;
_context4.t0 = _context4['catch'](4);
alert(localization.cloneDialog.failedToRemove);
case 14:
_this5.props.onProcessEnd();
case 15:
case 'end':
return _context4.stop();
}
}
}, _callee4, _this6, [[4, 11]]);
})), _temp2), _possibleConstructorReturn(_this5, _ret2);
}
_createClass(ProjectCard, [{
key: 'render',
value: function render() {
var _this7 = this;
var _props2 = this.props,
localization = _props2.localization,
project = _props2.project;
var styles = {
button: {
marginLeft: 16
},
card: {
marginTop: 16
},
remove: {
color: red400
},
label: {
fontWeight: 600,
marginRight: '1rem'
}
};
return React.createElement(
Card,
{ key: project.id, style: styles.card },
React.createElement(CardHeader, {
showExpandableButton: true,
title: React.createElement(EditableLabel, {
id: 'title',
defaultValue: project.title,
tapTwiceQuickly: localization.common.tapTwiceQuickly,
onEditEnd: function onEditEnd(text) {
return _this7.props.requestTitleChange(project, text);
}
}),
subtitle: [moment(project.updated).fromNow(), this.props.showURL ? project.url : ''].join(' ')
}),
React.createElement(
CardText,
{ expandable: true },
React.createElement(
'div',
null,
React.createElement(
'span',
{ style: styles.label },
localization.cloneDialog.created
),
new Date(project.created).toLocaleString()
),
React.createElement(
'div',
null,
React.createElement(
'span',
{ style: styles.label },
localization.cloneDialog.updated
),
new Date(project.updated).toLocaleString()
),
React.createElement(
'div',
null,
React.createElement(
'span',
{ style: styles.label },
localization.cloneDialog.size
),
(project.size / 1024 / 1024).toFixed(2) + 'MB'
)
),
React.createElement(
CardActions,
null,
React.createElement(FlatButton, {
label: localization.cloneDialog.openOnThisTab,
icon: React.createElement(ActionOpenInBrowser, null),
disabled: this.props.processing,
onClick: this.handleLoad
}),
React.createElement(FlatButton, {
label: localization.cloneDialog.remove,
icon: React.createElement(ActionDelete, { color: red400 }),
labelStyle: styles.remove,
disabled: this.props.processing,
onClick: this.handleRemove
})
)
);
}
}]);
return ProjectCard;
}(PureComponent);
ProjectCard.propTypes = {
project: PropTypes.object.isRequired,
showURL: PropTypes.bool.isRequired,
launchIDE: PropTypes.func.isRequired,
processing: PropTypes.bool.isRequired,
onProcessStart: PropTypes.func.isRequired,
onProcessEnd: PropTypes.func.isRequired,
requestProjectSet: PropTypes.func.isRequired,
requestTitleChange: PropTypes.func.isRequired,
localization: PropTypes.object.isRequired
};
ProjectCard.defaultProps = {
showURL: false,
processing: false,
onProcessStart: function onProcessStart() {},
onProcessEnd: function onProcessEnd() {},
requestProjectSet: function requestProjectSet() {},
requestTitleChange: function requestTitleChange() {}
};