Skip to content

Commit 5e78936

Browse files
authored
Git support (codesandbox#26)
* Add fetching from github * Update components to fetch git repo * Apply linting rules * Remove redundant message check * Remove console statements * Remove duplicate import * Adjust url generation to use git * DRY up the statistics * Change url-generator to encode git paths * Prevent githubUrl from creating an empty text node * Remove unnecessary eslint-disable-lines * Use helper function to encodeUriComponent
1 parent 2d282f2 commit 5e78936

File tree

28 files changed

+403
-128
lines changed

28 files changed

+403
-128
lines changed

src/app/components/Loading.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,9 @@ const LogoContainer = styled.div`
1313
animation-duration: 800ms;
1414
`;
1515

16-
export default () => (
16+
export default () =>
1717
<Centered vertical horizontal>
1818
<LogoContainer>
1919
<Logo width={490} height={490} />
2020
</LogoContainer>
21-
</Centered>
22-
);
21+
</Centered>;

src/app/components/sandbox/Preview/index.js

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ import type { Preferences } from 'app/store/preferences/reducer';
88
import type { Module, Sandbox, Directory, ModuleError } from 'common/types';
99

1010
import { frameUrl } from 'app/utils/url-generator';
11-
import { isMainModule } from 'app/store/entities/sandboxes/modules/selectors';
12-
import defaultBoilerplates
13-
from 'app/store/entities/sandboxes/boilerplates/default-boilerplates';
11+
import { findMainModule } from 'app/store/entities/sandboxes/modules/selectors';
12+
import defaultBoilerplates from 'app/store/entities/sandboxes/boilerplates/default-boilerplates';
1413
import sandboxActionCreators from 'app/store/entities/sandboxes/actions';
1514

1615
import Navigator from './Navigator';
@@ -193,7 +192,7 @@ export default class Preview extends React.PureComponent {
193192

194193
getRenderedModule = () => {
195194
const { modules, module, isInProjectView } = this.props;
196-
return isInProjectView ? modules.find(isMainModule) : module;
195+
return isInProjectView ? findMainModule(modules) : module;
197196
};
198197

199198
executeCodeImmediately = () => {

src/app/components/text/SubTitle.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,6 @@ export default styled.h2`
88
font-size: 1.75rem;
99
color: ${props => props.theme.background2.lighten(2)};
1010
font-weight: 300;
11+
margin-top: 0;
1112
margin-bottom: 1.5rem;
1213
`;
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`hoc show-alternative-component only renders app if all prop exists and is falsy 1`] = `
4+
<div>
5+
Loading
6+
</div>
7+
`;
8+
9+
exports[`hoc show-alternative-component only renders app if all prop exists and is falsy 2`] = `
10+
<div>
11+
App
12+
</div>
13+
`;
14+
15+
exports[`hoc show-alternative-component renders app if prop exists 1`] = `
16+
<div>
17+
App
18+
</div>
19+
`;
20+
21+
exports[`hoc show-alternative-component renders app if prop exists and is falsy 1`] = `
22+
<div>
23+
App
24+
</div>
25+
`;
26+
27+
exports[`hoc show-alternative-component renders loading component if prop doesn't exist 1`] = `
28+
<div>
29+
Loading
30+
</div>
31+
`;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import { createElement } from 'react';
2+
3+
/**
4+
* Shows a loading component if any of the props provided by `fields` does
5+
* not exist
6+
*/
7+
export default (LoadingComponent, fields = []) => Component => props => {
8+
const componentLoaded = fields.every(
9+
field => typeof props[field] !== 'undefined' && props[field] !== null,
10+
);
11+
12+
if (componentLoaded) {
13+
return createElement(Component, props);
14+
}
15+
16+
return createElement(LoadingComponent, props);
17+
};
18+
19+
// AlternativeComponent(LoadingComponent, ['field'])(Component)
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react';
2+
import testRemder from 'app/utils/test/render';
3+
4+
import showAlternativeComponent from './show-alternative-component';
5+
6+
describe('hoc', () => {
7+
describe('show-alternative-component', () => {
8+
const LoadingComponent = () => <div>Loading</div>;
9+
const AppComponent = () => <div>App</div>;
10+
it("renders loading component if prop doesn't exist", () => {
11+
const ComposedComponent = showAlternativeComponent(LoadingComponent, [
12+
'field',
13+
])(AppComponent);
14+
15+
testRemder(<ComposedComponent />);
16+
});
17+
18+
it('renders app if prop exists', () => {
19+
const ComposedComponent = showAlternativeComponent(LoadingComponent, [
20+
'field',
21+
])(AppComponent);
22+
23+
testRemder(<ComposedComponent field="test" />);
24+
});
25+
26+
it('renders app if prop exists and is falsy', () => {
27+
const ComposedComponent = showAlternativeComponent(LoadingComponent, [
28+
'field',
29+
])(AppComponent);
30+
31+
testRemder(<ComposedComponent field={false} />);
32+
});
33+
34+
it('only renders app if all prop exists and is falsy', () => {
35+
const ComposedComponent = showAlternativeComponent(LoadingComponent, [
36+
'field',
37+
'field2',
38+
])(AppComponent);
39+
40+
testRemder(<ComposedComponent field={false} />);
41+
testRemder(<ComposedComponent field={false} field2={false} />);
42+
});
43+
});
44+
});

src/app/pages/Profile/Showcase/ShowcasePreview.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,16 @@ import Preview from 'app/components/sandbox/Preview';
99
import delayEffect from 'app/utils/animation/delay-effect';
1010
import {
1111
modulesFromSandboxSelector,
12-
isMainModule,
12+
findMainModule,
1313
} from 'app/store/entities/sandboxes/modules/selectors';
1414
import sandboxActionCreators from 'app/store/entities/sandboxes/actions';
1515

16-
import {
17-
directoriesFromSandboxSelector,
18-
} from 'app/store/entities/sandboxes/directories/selectors';
16+
import { directoriesFromSandboxSelector } from 'app/store/entities/sandboxes/directories/selectors';
1917
import { preferencesSelector } from '../../../store/preferences/selectors';
2018

2119
const Container = styled.div`
2220
position: relative;
23-
${delayEffect(0.40)}
21+
${delayEffect(0.4)}
2422
height: 500px;
2523
box-shadow: 0 3px 3px rgba(0, 0, 0, 0.5);
2624
@@ -62,7 +60,7 @@ class ShowcasePreview extends React.PureComponent {
6260
directories,
6361
} = this.props;
6462

65-
const mainModule = modules.find(isMainModule);
63+
const mainModule = findMainModule(modules);
6664

6765
return (
6866
<Container>

src/app/pages/Sandbox/Editor/Content/Header/ShareView.js

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,10 @@ import ShareIcon from 'react-icons/lib/md/share';
66
import Files from 'embed/components/Files';
77
import ModeIcons from 'app/components/sandbox/ModeIcons';
88
import {
9-
isMainModule,
9+
findMainModule,
1010
modulesFromSandboxSelector,
1111
} from 'app/store/entities/sandboxes/modules/selectors';
12-
import {
13-
directoriesFromSandboxSelector,
14-
} from 'app/store/entities/sandboxes/directories/selectors';
12+
import { directoriesFromSandboxSelector } from 'app/store/entities/sandboxes/directories/selectors';
1513
import {
1614
optionsToParameterizedUrl,
1715
protocolAndHost,
@@ -31,6 +29,11 @@ const Container = styled.div`
3129
height: 100%;
3230
`;
3331

32+
const FilesContainer = styled.div`
33+
max-height: 300px;
34+
overflow: auto;
35+
`;
36+
3437
const PaddedPreference = styled(Preference)`
3538
color: rgba(255, 255, 255, 0.6);
3639
padding-bottom: 1rem;
@@ -223,7 +226,8 @@ class ShareView extends React.PureComponent {
223226
// eslint-disable-next-line
224227
getButtonMarkdown = () => {
225228
const { sandbox } = this.props;
226-
return `[![Edit ${sandbox.title || sandbox.id}](${BUTTON_URL})](${this.getEditorUrl()})`;
229+
return `[![Edit ${sandbox.title ||
230+
sandbox.id}](${BUTTON_URL})](${this.getEditorUrl()})`;
227231
};
228232

229233
// eslint-disable-next-line
@@ -248,7 +252,7 @@ class ShareView extends React.PureComponent {
248252
const { showEditor, showPreview, autoResize, hideNavigation } = this.state;
249253

250254
const defaultModule =
251-
this.state.defaultModule || modules.find(isMainModule).id;
255+
this.state.defaultModule || findMainModule(modules).id;
252256

253257
return (
254258
<Container>
@@ -260,7 +264,7 @@ class ShareView extends React.PureComponent {
260264
moreInfo: true,
261265
}}
262266
>
263-
{() => (
267+
{() =>
264268
<ShareOptions>
265269
<h3>Share options</h3>
266270
<Divider>
@@ -302,13 +306,15 @@ class ShareView extends React.PureComponent {
302306
<div>
303307
<h4>Default module to show and preview</h4>
304308

305-
<Files
306-
modules={modules}
307-
directories={directories}
308-
directoryId={null}
309-
currentModule={defaultModule}
310-
setCurrentModule={this.setDefaultModule}
311-
/>
309+
<FilesContainer>
310+
<Files
311+
modules={modules}
312+
directories={directories}
313+
directoryId={null}
314+
currentModule={defaultModule}
315+
setCurrentModule={this.setDefaultModule}
316+
/>
317+
</FilesContainer>
312318
</div>
313319
</Column>
314320
<Column>
@@ -352,8 +358,7 @@ class ShareView extends React.PureComponent {
352358
</Inputs>
353359
</Column>
354360
</Divider>
355-
</ShareOptions>
356-
)}
361+
</ShareOptions>}
357362
</HoverMenu>
358363
</Container>
359364
);

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ const Chevron = styled.div`
6565
6666
cursor: pointer;
6767
&:hover {
68-
transform: rotateZ(${props => (props.workspaceHidden ? '135deg' : '45deg')});
68+
transform: rotateZ(${props =>
69+
props.workspaceHidden ? '135deg' : '45deg'});
6970
color: white;
7071
}
7172
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
4+
import Fullscreen from 'app/components/flex/Fullscreen';
5+
import Title from 'app/components/text/Title';
6+
import SubTitle from 'app/components/text/SubTitle';
7+
import Centered from 'app/components/flex/Centered';
8+
9+
const Header = styled.div`
10+
position: absolute;
11+
top: 0;
12+
height: 3rem;
13+
left: 0;
14+
right: 0;
15+
background-color: ${props => props.theme.background2};
16+
z-index: 40;
17+
border-bottom: 1px solid ${props => props.theme.background2.darken(0.3)};
18+
`;
19+
20+
export default () =>
21+
<Fullscreen>
22+
<Header />
23+
<Centered horizontal vertical>
24+
<Title delay={0.6}>Loading Sandbox...</Title>
25+
<SubTitle delay={1}>Fetching git repository...</SubTitle>
26+
</Centered>
27+
</Fullscreen>;

0 commit comments

Comments
 (0)