Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ const config = {

target: 'web',

mainFields: ['browser', 'module', 'jsnext:main', 'main'],

output: getOutput(),

Expand Down Expand Up @@ -138,11 +137,16 @@ const config = {
],
},
resolve: {
mainFields: ['browser', 'module', 'jsnext:main', 'main'],
modules: [
'node_modules',
],

extensions: ['.js', '.json'],

alias: {
moment: 'moment/moment.js',
},
},

plugins: [
Expand Down
1 change: 1 addition & 0 deletions src/app/components/buttons/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ const styles = props => `
transition: 0.3s ease all;
text-transform: uppercase;
text-decoration: none;
line-height: 1;
background-color: ${props.disabled ? props.theme.background2.darken(0.1)() : props.theme.secondary()};
color: ${props.disabled ? props.theme.background2.lighten(1.5)() : 'white'};
${(() => {
Expand Down
21 changes: 17 additions & 4 deletions src/app/pages/SandboxView/Editor/Content/View/EditorPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import type { ModuleTab } from '../../../../../store/reducers/views/sandbox';
import CodeEditor from './subviews/CodeEditor';
import Preview from './subviews/Preview';
import { directoriesBySandboxSelector } from '../../../../../store/entities/directories/selector';
import { modulesBySandboxSelector, singleModuleSelector } from '../../../../../store/entities/modules/selector';
import { modulesBySandboxSelector, singleModuleSelector, modulePathSelector } from '../../../../../store/entities/modules/selector';
import { singleSourceSelector } from '../../../../../store/entities/sources/selector';

import type { Sandbox } from '../../../../../store/entities/sandboxes/index';
Expand All @@ -33,6 +33,7 @@ type Props = {
sandbox: ?Sandbox;
moduleActions: moduleEntity.actions;
sourceActions: sourceEntity.actions;
modulePath: ?string;
};

type State = {
Expand All @@ -51,6 +52,7 @@ const mapStateToProps = (state, props) => ({
boilerplates: boilerplatesBySandboxSelector(state, { id: props.sandbox.id }),
module: singleModuleSelector(state, { id: props.tab ? props.tab.moduleId : null }),
source: singleSourceSelector(state, { id: props.sandbox.source }),
modulePath: modulePathSelector(state, { id: props.tab ? props.tab.moduleId : null }),
});
const mapDispatchToProps = dispatch => ({
moduleActions: bindActionCreators(moduleEntity.actions, dispatch),
Expand All @@ -67,9 +69,17 @@ class EditorPreview extends React.PureComponent {
startResizing = () => this.setState({ resizing: true });
stopResizing = () => this.setState({ resizing: false });

saveCode = () => {
const { module, moduleActions } = this.props;

if (module == null) return;

moduleActions.saveCode(module.id);
};

render() {
const { source, modules, directories, boilerplates,
moduleActions, module, sourceActions } = this.props;
moduleActions, module, sourceActions, modulePath } = this.props;

if (module == null || source == null) return null;
return (
Expand All @@ -81,15 +91,18 @@ class EditorPreview extends React.PureComponent {
defaultSize="50%"
minSize={360}
primary="second"
paneStyle={{ height: 'calc(100% - 35px)' }}
paneStyle={{ height: '100%' }}
>
<FullSize>
<CodeEditor
changeCode={moduleActions.changeCode}
id={module.id}
error={module.error}
code={module.code}
saveCode={moduleActions.saveCode}
saveCode={this.saveCode}
title={module.title}
modulePath={modulePath}
canSave={module.isNotSynced}
/>
</FullSize>
<FullSize inactive={this.state.resizing}>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import React from 'react';
import styled from 'styled-components';

import SaveIcon from 'react-icons/lib/md/save';
import Button from '../../../../../../../components/buttons/Button';

const Container = styled.div`
display: flex;
background-color: ${props => props.theme.background};
box-shadow: 0 3px 3px ${props => props.theme.background2};
color: ${props => props.theme.white};
padding: 0.5rem 1rem;
height: 3rem;
box-sizing: border-box;
justify-content: space-between;
vertical-align: middle;
align-items: center;
`;

const Path = styled.span`
color: ${props => props.theme.background.lighten(1.25)};
padding-right: 0.1rem;
`;


type Props = {
title: string;
path: string;
saveComponent?: () => void;
};

export default ({ path, title, saveComponent }: Props) => (
<Container>

<div>
<Path>{path}</Path>
{title}
</div>

<Button disabled={!saveComponent} onClick={saveComponent} small>
<SaveIcon />
&nbsp;Save
</Button>
</Container>
);
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@ import 'codemirror/addon/fold/foldcode';
import 'codemirror/addon/fold/foldgutter';
import 'codemirror/addon/fold/brace-fold';

import theme from '../../../../../../../common/theme';
import theme from '../../../../../../../../common/theme';
import Header from './Header';

const documentCache = {};

type Props = {
code: ?string;
error: ?Object;
id: string;
title: string;
modulePath: string;
changeCode: (id: string, code: string) => void;
saveCode: (id: string) => void;
saveCode: () => void;
canSave: boolean;
};

const Container = styled.div`
Expand Down Expand Up @@ -54,14 +58,6 @@ const ErrorMessage = styled.div`
color: ${props => props.theme.red};
`;

const TopMessage = styled.div`
flex: 0 0 auto;
padding: 0.5rem 1rem;
font-size: 14px;
color: ${props => props.theme.background.lighten(1.5)};
vertical-align: middle;
`;

const handleError = (cm, currentError, nextError, nextCode, nextId) => {
if (currentError || nextError) {
if (currentError && nextError &&
Expand Down Expand Up @@ -97,8 +93,7 @@ export default class CodeEditor extends React.PureComponent {
window.addEventListener('keydown', (event: KeyboardEvent) => {
if (event.ctrlKey || event.metaKey) {
if (event.key === 's' || event.keyCode === 83) {
const { id } = this.props;
this.props.saveCode(id);
this.props.saveCode();
event.preventDefault();
return false;
}
Expand All @@ -108,7 +103,9 @@ export default class CodeEditor extends React.PureComponent {
}

shouldComponentUpdate(nextProps: Props) {
return nextProps.id !== this.props.id || nextProps.error !== this.props.error;
return nextProps.id !== this.props.id ||
nextProps.error !== this.props.error ||
this.props.canSave !== nextProps.canSave;
}

componentWillReceiveProps(nextProps: Props) {
Expand Down Expand Up @@ -170,15 +167,10 @@ export default class CodeEditor extends React.PureComponent {
codemirror: typeof CodeMirror;

render() {
const { error } = this.props;
const { error, title, saveCode, canSave, modulePath } = this.props;
return (
<Container>
<TopMessage>
<SaveIcon />
<span style={{ verticalAlign: 'middle', marginLeft: '0.5rem' }}>
Last update: 5 seconds ago
</span>
</TopMessage>
<Header saveComponent={canSave && saveCode} title={title} path={modulePath} />
<CodeContainer>
<div style={{ height: '100%' }} ref={this.getCodeMirror} />
</CodeContainer>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import styled from 'styled-components';
import theme from '../../../../../../../../common/theme';

const TEXT_COLOR = theme.gray.darken(0.2)();

const Container = styled.div`
position: relative;
color: ${TEXT_COLOR};
vertical-align: middle;
`;

const Input = styled.input`
padding: 0.2rem 1rem;
color: ${TEXT_COLOR};
width: 100%;
box-sizing: border-box;
`;

const Slash = styled.span`
position: absolute;
padding: 0.3rem 0.75rem;
top: 0;
bottom: 0;
left: 0;
vertical-align: middle;
line-height: 1.15;
`;

type Props = {
url: string;
onChange: (url: string) => void;
onConfirm: () => void;
};

export default class extends React.PureComponent {
props: Props;

onChange = (evt) => {
const { onChange } = this.props;

onChange(evt.target.value);
};

handleKeyDown = (e) => {
const { onConfirm } = this.props;

if (e.keyCode === 13) {
// Enter
onConfirm();
}
}

render() {
const { url = '' } = this.props;
return (
<Container>
<Slash>/</Slash>
<Input onChange={this.onChange} onKeyDown={this.handleKeyDown} value={url} />
</Container>
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from 'react';
import styled from 'styled-components';

import LeftIcon from 'react-icons/lib/fa/angle-left';
import RightIcon from 'react-icons/lib/fa/angle-right';
import RefreshIcon from 'react-icons/lib/md/refresh';

import AddressBar from './AddressBar';
import Switch from './Switch';

const Container = styled.div`
display: flex;
background-color: #f2f2f2;
padding: 0.5rem;
align-items: center;
line-height: 1;
box-shadow: 0 1px 3px #ddd;
`;

const Icons = styled.div`
display: flex;
`;

const Icon = styled.div`
display: inline-block;
color: ${props => (props.disabled ? props.theme.gray : props.theme.gray.darken(0.3))};
font-size: 1.5rem;
line-height: 0.5;
margin: 0 0.1rem;
vertical-align: middle;
text-align: center;

${props => !props.disabled && `
&:hover {
background-color: #e2e2e2;
cursor: pointer;
}`}
`;

const AddressBarContainer = styled.div`
width: 100%;
box-sizing: border-box;
margin: 0 0.5rem;
`;

type Props = {
url: string,
onChange: (text: string) => void;
onConfirm: () => void;
onBack?: () => void;
onForward?: () => void;
onRefresh?: () => void;
isProjectView: boolean;
toggleProjectView: () => void;
};

export default ({
url,
onChange,
onConfirm,
onBack,
onForward,
onRefresh,
isProjectView,
toggleProjectView,
}: Props) => (
<Container>
<Icons>
<Icon disabled={!onBack} onClick={onBack}><LeftIcon /></Icon>
<Icon disabled={!onForward} onClick={onForward}><RightIcon /></Icon>
<Icon onClick={onRefresh}><RefreshIcon /></Icon>
</Icons>
<AddressBarContainer>
<AddressBar url={url} onChange={onChange} onConfirm={onConfirm} />
</AddressBarContainer>
<Switch right={isProjectView} onClick={toggleProjectView} />
</Container>
);
Loading