Skip to content

Commit b8ce727

Browse files
author
Ives van Hoorne
committed
We're doing it live!
1 parent 6ef1f2f commit b8ce727

File tree

25 files changed

+718
-89
lines changed

25 files changed

+718
-89
lines changed

packages/app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,7 @@
151151
"monaco-vue": "^0.2.1",
152152
"normalize.css": "^5.0.0",
153153
"normalizr": "^3.2.3",
154+
"phoenix": "^1.3.0",
154155
"postcss": "^6.0.9",
155156
"postcss-selector-parser": "^2.2.3",
156157
"posthtml": "^0.11.3",

packages/app/src/app/components/CodeEditor/Monaco/index.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,10 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
8888
) {
8989
this.resizeEditor();
9090
}
91+
92+
if (this.props.readOnly !== nextProps.readOnly && this.editor) {
93+
this.editor.updateOptions({ readOnly: !!nextProps.readOnly });
94+
}
9195
return false;
9296
}
9397

@@ -1040,6 +1044,8 @@ class MonacoEditor extends React.Component<Props, State> implements Editor {
10401044
folding: true,
10411045
glyphMargin: false,
10421046
fixedOverflowWidgets: true,
1047+
1048+
readOnly: !!this.props.readOnly,
10431049
};
10441050
};
10451051

packages/app/src/app/components/CodeEditor/types.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ export interface Editor {
3636
corrections?: Array<ModuleCorrection>
3737
) => any;
3838
changeCode?: (code: string) => any;
39-
4039
currentModule?: Module;
4140
setTSConfig?: (tsConfig: Object) => void;
4241
}
@@ -56,4 +55,5 @@ export type Props = {
5655
dependencies?: ?{ [name: string]: string },
5756
highlightedLines?: Array<number>,
5857
tsconfig?: Object,
58+
readOnly?: boolean,
5959
};
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import * as React from 'react';
2+
import { inject, observer } from 'mobx-react';
3+
import { Link } from 'react-router-dom';
4+
import { DragDropContext } from 'react-dnd';
5+
import HTML5Backend from 'react-dnd-html5-backend';
6+
import QuickActions from 'app/pages/Sandbox/QuickActions';
7+
8+
import Title from 'app/components/Title';
9+
import SubTitle from 'app/components/SubTitle';
10+
import Centered from 'common/components/flex/Centered';
11+
import Skeleton from 'app/components/Skeleton';
12+
13+
import Editor from '../Sandbox/Editor';
14+
15+
class LivePage extends React.Component {
16+
componentWillMount() {
17+
this.initializeLive();
18+
}
19+
20+
initializeLive = () => {
21+
this.props.signals.live.roomJoined({
22+
roomId: this.props.match.params.id,
23+
});
24+
};
25+
26+
componentDidUpdate(prevProps) {
27+
if (prevProps.match.params.id !== this.props.match.params.id) {
28+
this.initializeLive();
29+
}
30+
}
31+
32+
render() {
33+
const { match, store } = this.props;
34+
35+
if (store.live.isLoading) {
36+
return (
37+
<Centered horizontal vertical>
38+
<Skeleton
39+
titles={[
40+
{
41+
content: 'Loading sandbox...',
42+
delay: 0,
43+
},
44+
{
45+
content: 'Fetching git repository...',
46+
delay: 2,
47+
},
48+
]}
49+
/>
50+
</Centered>
51+
);
52+
}
53+
54+
if (store.live.error) {
55+
return (
56+
<Centered style={{ height: '100vh' }} horizontal vertical>
57+
<Title>An error occured when connecting to the live session:</Title>
58+
<SubTitle>{store.editor.error}</SubTitle>
59+
<br />
60+
<br />
61+
<Link to="/s">Create Sandbox</Link>
62+
</Centered>
63+
);
64+
}
65+
66+
const sandbox = store.editor.currentSandbox;
67+
68+
if (sandbox) {
69+
document.title = `${sandbox.title || sandbox.id} - CodeSandbox`;
70+
}
71+
72+
return (
73+
<React.Fragment>
74+
<Editor match={match} />
75+
<QuickActions />
76+
</React.Fragment>
77+
);
78+
}
79+
}
80+
81+
export default inject('signals', 'store')(
82+
DragDropContext(HTML5Backend)(observer(LivePage))
83+
);

packages/app/src/app/pages/Sandbox/Editor/Content/Preview/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class Preview extends React.Component<Props, State> {
4141
this.handleModuleSyncedChange.bind(this, preview)
4242
);
4343
const disposeHandleCodeChange = reaction(
44-
() => this.props.store.editor.currentModule.code,
44+
() => this.props.store.editor.currentSandbox.modules.map(m => m.code),
4545
() => {
4646
if (preventCodeExecution) {
4747
preventCodeExecution = false;

packages/app/src/app/pages/Sandbox/Editor/Content/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,6 +326,7 @@ class EditorPreview extends React.Component<Props, State> {
326326
width={editorWidth}
327327
height={editorHeight}
328328
settings={settings(store)}
329+
readOnly={store.live.isLive && !store.live.isCurrentEditor}
329330
onNpmDependencyAdded={name => {
330331
if (sandbox.owned) {
331332
signals.editor.addNpmDependency({ name, isDev: true });

packages/app/src/app/pages/Sandbox/Editor/Navigation/index.js

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import React from 'react';
22
import { inject, observer } from 'mobx-react';
33

44
import GitHubIcon from 'react-icons/lib/go/mark-github';
5+
import LiveIcon from 'react-icons/lib/md/cast-connected';
56

6-
import workspaceItems from 'app/store/modules/workspace/items';
7+
import getWorkspaceItems from 'app/store/modules/workspace/items';
78
import Tooltip from 'common/components/Tooltip';
89

910
import InfoIcon from './InfoIcon';
@@ -19,31 +20,34 @@ const IDS_TO_ICONS = {
1920
github: GitHubIcon,
2021
deploy: RocketIcon,
2122
config: ConfigurationIcon,
23+
live: LiveIcon,
2224
};
2325

2426
const Navigation = ({ store, signals }) => (
2527
<Container>
26-
{workspaceItems.filter(w => !w.show || w.show(store)).map(item => {
27-
const { id, name } = item;
28-
const Icon = IDS_TO_ICONS[id];
29-
const selected = id === store.workspace.openedWorkspaceItem;
30-
return (
31-
<Tooltip key={id} position="right" title={name}>
32-
<IconContainer
33-
selected={selected}
34-
onClick={() => {
35-
if (selected) {
36-
signals.workspace.setWorkspaceItem({ item: null });
37-
} else {
38-
signals.workspace.setWorkspaceItem({ item: id });
39-
}
40-
}}
41-
>
42-
<Icon />
43-
</IconContainer>
44-
</Tooltip>
45-
);
46-
})}
28+
{getWorkspaceItems(store)
29+
.filter(w => !w.show || w.show(store))
30+
.map(item => {
31+
const { id, name } = item;
32+
const Icon = IDS_TO_ICONS[id];
33+
const selected = id === store.workspace.openedWorkspaceItem;
34+
return (
35+
<Tooltip key={id} position="right" title={name}>
36+
<IconContainer
37+
selected={selected}
38+
onClick={() => {
39+
if (selected) {
40+
signals.workspace.setWorkspaceItem({ item: null });
41+
} else {
42+
signals.workspace.setWorkspaceItem({ item: id });
43+
}
44+
}}
45+
>
46+
<Icon />
47+
</IconContainer>
48+
</Tooltip>
49+
);
50+
})}
4751
</Container>
4852
);
4953

packages/app/src/app/pages/Sandbox/Editor/Workspace/Files/DirectoryEntry/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ class DirectoryEntry extends React.Component {
222222
showDeleteDirectoryModal: false,
223223
});
224224
this.props.signals.files.directoryDeleted({
225-
moduleShortid: shortid,
225+
directoryShortid: shortid,
226226
});
227227
}}
228228
/>

packages/app/src/app/pages/Sandbox/Editor/Workspace/index.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ import { inject, observer } from 'mobx-react';
33

44
import VERSION from 'common/version';
55

6-
import workspaceItems from 'app/store/modules/workspace/items';
6+
import getWorkspaceItems from 'app/store/modules/workspace/items';
77
import SocialInfo from 'app/components/SocialInfo';
88

99
import Files from './items/Files';
1010
import ProjectInfo from './items/ProjectInfo';
1111
import GitHub from './items/GitHub';
12+
import Live from './items/Live';
1213
import Deployment from './items/Deployment';
1314
import ConfigurationFiles from './items/ConfigurationFiles';
1415
import NotOwnedSandboxInfo from './items/NotOwnedSandboxInfo';
@@ -24,6 +25,7 @@ const idToItem = {
2425
github: GitHub,
2526
deploy: Deployment,
2627
config: ConfigurationFiles,
28+
live: Live,
2729
};
2830

2931
function Workspace({ store }) {
@@ -38,7 +40,7 @@ function Workspace({ store }) {
3840

3941
const Component = sandbox.owned ? idToItem[currentItem] : NotOwnedSandboxInfo;
4042

41-
const item = workspaceItems.find(i => i.id === currentItem);
43+
const item = getWorkspaceItems(store).find(i => i.id === currentItem);
4244
return (
4345
<Container>
4446
{sandbox.owned && <ItemTitle>{item.name}</ItemTitle>}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import React from 'react';
2+
import { inject, observer } from 'mobx-react';
3+
4+
import Button from 'app/components/Button';
5+
6+
import {
7+
Description,
8+
WorkspaceInputContainer,
9+
WorkspaceSubtitle,
10+
} from '../../elements';
11+
12+
const Live = ({ signals, store }) => (
13+
<div>
14+
<Description>
15+
Invite others to live edit this sandbox with you. We{"'"}re doing it live!
16+
</Description>
17+
18+
<WorkspaceSubtitle>Create live room</WorkspaceSubtitle>
19+
<Description>
20+
To invite others you need to generate a URL that others can join.
21+
</Description>
22+
<WorkspaceInputContainer>
23+
<Button
24+
onClick={() => {
25+
signals.live.createLiveClicked({ sandboxId: store.editor.currentId });
26+
}}
27+
block
28+
>
29+
Go Live
30+
</Button>
31+
</WorkspaceInputContainer>
32+
</div>
33+
);
34+
35+
export default inject('signals', 'store')(observer(Live));

0 commit comments

Comments
 (0)