Skip to content

Commit 89c806a

Browse files
authored
Profile view support (codesandbox#12)
* React loadable * Work * Intermediate * Yarn updates * Profile page progress * Redesign button * Profile page tweaks * Profile page redesign * Get path for user * Intermediate * Update deps * Redesign work * Adjusting places * Intermediate * Showcase view * Change to sandbox shortid * Change chevron * Use new tooltip system * Modals * Select sandbox * Progress * Likes * Unique module ids (codesandbox#14) * Default to project view in embed if module is undefined * Better tab indenting * Add two examples * Warmup cache for new packager (codesandbox#13) * Warmup cache for new packager * Throw initial error * Put new packager full on * Unique modules * Prevent confirm modal when forking * Tweaks * Finishing touches * Update logo * Update snapshots
1 parent a754448 commit 89c806a

File tree

96 files changed

+2913
-981
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+2913
-981
lines changed

.babelrc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
"babel-plugin-transform-object-rest-spread",
1111
"babel-plugin-transform-class-properties",
1212
"babel-plugin-transform-runtime",
13+
"babel-plugin-syntax-dynamic-import",
14+
"babel-plugin-lodash",
15+
[
16+
"react-loadable/babel",
17+
{
18+
"server": true,
19+
"webpack": true
20+
}
21+
],
1322
"babel-plugin-lodash",
1423
"babel-plugin-system-import-transformer"
1524
]

config/babel.dev.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,14 @@ module.exports = {
1616
require.resolve('babel-plugin-transform-class-properties'),
1717
require.resolve('babel-plugin-transform-runtime'),
1818
require.resolve('babel-plugin-lodash'),
19+
require.resolve('babel-plugin-syntax-dynamic-import'),
20+
[
21+
require.resolve('react-loadable/babel'),
22+
{
23+
server: true,
24+
webpack: true,
25+
},
26+
],
1927
require.resolve('react-hot-loader/babel'),
2028
],
2129
};

config/babel.prod.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ module.exports = {
1515
require.resolve('babel-plugin-transform-class-properties'),
1616
require.resolve('babel-plugin-transform-runtime'),
1717
require.resolve('babel-plugin-lodash'),
18+
require.resolve('babel-plugin-syntax-dynamic-import'),
19+
[
20+
require.resolve('react-loadable/babel'),
21+
{
22+
server: true,
23+
webpack: true,
24+
},
25+
],
1826
// Optimization: hoist JSX that never changes out of render()
1927
// Disabled because of issues:
2028
// * https://github.com/facebookincubator/create-react-app/issues/525

package.json

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
"babel-jest": "^19.0.0",
1010
"babel-loader": "^7.0.0",
1111
"babel-plugin-lodash": "^3.2.11",
12+
"babel-plugin-syntax-dynamic-import": "^6.18.0",
1213
"babel-plugin-transform-class-properties": "^6.24.1",
1314
"babel-plugin-transform-object-rest-spread": "^6.23.0",
1415
"babel-plugin-transform-react-constant-elements": "^6.23.0",
@@ -22,7 +23,7 @@
2223
"chalk": "1.1.3",
2324
"connect-history-api-fallback": "1.3.0",
2425
"cross-spawn": "^5.0.1",
25-
"css-loader": "^0.28.0",
26+
"css-loader": "^0.28.1",
2627
"detect-port": "^1.1.1",
2728
"eslint": "^3.19.0",
2829
"eslint-config-airbnb": "^14.1.0",
@@ -36,7 +37,7 @@
3637
"extract-text-webpack-plugin": "^2.1.0",
3738
"file-loader": "^0.11.1",
3839
"filesize": "^3.5.6",
39-
"flow-bin": "^0.44.2",
40+
"flow-bin": "^0.45.0",
4041
"fs-extra": "^2.1.2",
4142
"gulp-replace": "^0.5.4",
4243
"gzip-size": "3.0.0",
@@ -49,7 +50,7 @@
4950
"opn": "4.0.2",
5051
"path-exists": "3.0.0",
5152
"postcss-loader": "^1.2.1",
52-
"prettier": "^1.2.2",
53+
"prettier": "^1.3.1",
5354
"promise": "7.1.1",
5455
"raw-loader": "^0.5.1",
5556
"react-hot-loader": "^3.0.0-beta.6",
@@ -58,11 +59,11 @@
5859
"rimraf": "^2.6.1",
5960
"run-sequence": "^1.2.2",
6061
"strip-ansi": "3.0.1",
61-
"style-loader": "^0.16.1",
62+
"style-loader": "^0.17.0",
6263
"url-loader": "^0.5.8",
63-
"webpack": "^2.4.1",
64+
"webpack": "^2.5.0",
6465
"webpack-dev-middleware": "^1.10.2",
65-
"webpack-dev-server": "^2.4.4",
66+
"webpack-dev-server": "^2.4.5",
6667
"whatwg-fetch": "^2.0.3"
6768
},
6869
"dependencies": {
@@ -79,9 +80,9 @@
7980
"codemirror": "^5.25.2",
8081
"color": "^0.11.4",
8182
"cssnano": "^3.10.0",
82-
"debug": "^2.6.4",
83+
"debug": "^2.6.6",
8384
"file-saver": "^1.3.3",
84-
"glamor": "^2.20.12",
85+
"glamor": "^2.20.25",
8586
"gulp": "^3.9.1",
8687
"gulp-filter": "^5.0.0",
8788
"gulp-postcss": "^6.4.0",
@@ -97,21 +98,24 @@
9798
"react-deep-force-update": "^2.0.1",
9899
"react-dnd": "^2.3.0",
99100
"react-dnd-html5-backend": "^2.3.0",
100-
"react-docgen": "^2.14.1",
101+
"react-docgen": "^2.15.0",
101102
"react-dom": "^15.5.4",
102103
"react-frame-component": "^1.0.3",
103104
"react-icons": "^2.2.2",
104-
"react-motion": "^0.4.8",
105+
"react-loadable": "^3.3.1",
106+
"react-modal": "^1.7.7",
107+
"react-motion": "^0.5.0",
105108
"react-proxy": "2",
106109
"react-redux": "^5.0.4",
107110
"react-router-dom": "^4.1.1",
108111
"react-router-redux": "next",
109112
"react-split-pane": "^0.1.63",
113+
"react-tippy": "^0.11.1",
110114
"redbox-react": "^1.3.6",
111115
"redux": "^3.6.0",
112116
"reselect": "^3.0.0",
113117
"store": "^2.0.4",
114-
"styled-components": "^1.4.5",
118+
"styled-components": "^1.4.6",
115119
"tern": "^0.21.0"
116120
},
117121
"scripts": {

src/app/components/HoverMenu.js

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import React from 'react';
2+
3+
type Props = {
4+
children: Function,
5+
onClose: Function,
6+
};
7+
8+
type State = {
9+
clicked: boolean,
10+
};
11+
12+
export default class HoverMenu extends React.PureComponent {
13+
props: Props;
14+
15+
state: State = {
16+
clicked: false,
17+
};
18+
19+
handleDocumentClick = () => {
20+
if (!this.state.clicked) {
21+
this.props.onClose();
22+
}
23+
};
24+
25+
componentDidMount() {
26+
document.addEventListener('click', this.handleDocumentClick);
27+
}
28+
29+
handleViewClick = () => {
30+
// Prevent element from closing itself when you click on it
31+
this.setState({ clicked: true });
32+
33+
setTimeout(() => {
34+
this.setState({ clicked: false });
35+
});
36+
};
37+
38+
setOnclickListener = el => {
39+
this.element = el;
40+
if (el) {
41+
el.addEventListener('click', this.handleViewClick);
42+
}
43+
};
44+
45+
componentWillUnmount() {
46+
document.removeEventListener('click', this.handleDocumentClick);
47+
48+
if (this.element) {
49+
this.element.removeEventListener('click', this.handleViewClick);
50+
}
51+
}
52+
53+
render() {
54+
const { children } = this.props;
55+
return (
56+
<div ref={this.setOnclickListener}>
57+
{children}
58+
</div>
59+
);
60+
}
61+
}

src/app/components/Loading.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import React from 'react';
2+
import styled, { keyframes } from 'styled-components';
3+
import Logo from './Logo';
4+
import Centered from './flex/Centered';
5+
6+
const animation = keyframes`
7+
0%, 10% { transform: rotateZ(0deg); }
8+
90%, 100% { transform: rotateZ(360deg); }
9+
`;
10+
11+
const LogoContainer = styled.div`
12+
animation-name: ${animation};
13+
animation-duration: 800ms;
14+
`;
15+
16+
export default () => (
17+
<Centered vertical horizontal>
18+
<LogoContainer>
19+
<Logo width={490} height={490} />
20+
</LogoContainer>
21+
</Centered>
22+
);

src/app/components/Logo.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,24 @@ export default ({
3131
<polyline
3232
fill="none"
3333
stroke="#FFFFFF"
34-
strokeWidth="50"
34+
strokeWidth="80"
3535
strokeMiterlimit="10"
3636
points="899,287.833 509,513 509,963"
3737
/>
3838
<line
3939
fill="none"
4040
stroke="#FFFFFF"
41-
strokeWidth="50"
41+
strokeWidth="80"
4242
strokeMiterlimit="10"
4343
x1="122.167"
4444
y1="289"
4545
x2="511.5"
4646
y2="513"
4747
/>
48-
<path
49-
fill="none"
50-
stroke="#000000"
51-
strokeWidth="4"
52-
strokeMiterlimit="10"
53-
d="M122.167,739"
54-
/>
5548
<polygon
5649
fill="none"
5750
stroke="#FFFFFF"
58-
strokeWidth="50"
51+
strokeWidth="80"
5952
strokeMiterlimit="10"
6053
points="121,739.083 510.917,963.042 901,738.333 901,288 511,62 121,289"
6154
/>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`formatNumber handles all numbers over 1000 1`] = `"1.0k"`;
4+
5+
exports[`formatNumber handles all numbers over 1000 2`] = `"1.1k"`;
6+
7+
exports[`formatNumber handles all numbers over 1000 3`] = `"1.0k"`;
8+
9+
exports[`formatNumber handles all numbers over 1000 4`] = `"2.1k"`;
10+
11+
exports[`formatNumber handles all numbers over 1000 5`] = `"20.3k"`;
12+
13+
exports[`formatNumber handles all numbers under 1000 1`] = `"42"`;
14+
15+
exports[`formatNumber handles all numbers under 1000 2`] = `"142"`;
16+
17+
exports[`formatNumber handles all numbers under 1000 3`] = `"999"`;
18+
19+
exports[`formatNumber handles all numbers under 1000 4`] = `"1"`;
20+
21+
exports[`formatNumber handles all numbers under 1000 5`] = `"0"`;
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
export default function(count: number): string {
2+
if (count >= 1000) {
3+
return `${(count / 1000).toFixed(1)}k`;
4+
}
5+
6+
return `${count}`;
7+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import formatNumber from './format-number';
2+
3+
describe('formatNumber', () => {
4+
it('handles all numbers under 1000', () => {
5+
expect(formatNumber(42)).toMatchSnapshot();
6+
expect(formatNumber(142)).toMatchSnapshot();
7+
expect(formatNumber(999)).toMatchSnapshot();
8+
expect(formatNumber(1)).toMatchSnapshot();
9+
expect(formatNumber(0)).toMatchSnapshot();
10+
});
11+
12+
it('handles all numbers over 1000', () => {
13+
expect(formatNumber(1042)).toMatchSnapshot();
14+
expect(formatNumber(1142)).toMatchSnapshot();
15+
expect(formatNumber(1000)).toMatchSnapshot();
16+
expect(formatNumber(2099)).toMatchSnapshot();
17+
expect(formatNumber(20299)).toMatchSnapshot();
18+
});
19+
});

0 commit comments

Comments
 (0)