Skip to content

Commit 1410dfa

Browse files
Merge branch 'master' into change-message
2 parents 3ad8d1b + d79f112 commit 1410dfa

File tree

97 files changed

+5904
-2448
lines changed

Some content is hidden

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

97 files changed

+5904
-2448
lines changed

.circleci/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ workflows:
389389
- typecheck
390390
- test-integrations
391391
- test-jest
392+
- test-visual-regressions
392393
filters:
393394
branches:
394395
only:

packages/app/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@
222222
"subworkers": "^1.0.1",
223223
"svg-react-loader": "^0.4.4",
224224
"tern": "^0.21.0",
225+
"textextensions": "^3.3.0",
225226
"use-interval": "^1.2.1",
226227
"util": "0.11.1",
227228
"vue": "^2.5.2",

packages/app/src/app/components/CreateNewSandbox/CreateSandbox/Create/PersonalTemplates/FilteredTemplates.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ export const FilteredTemplates = ({
2525
threshold: 0.3,
2626
distance: 10,
2727
keys: [
28-
{ name: 'sandbox.title', weight: 0.5 },
29-
{ name: 'sandbox.description', weight: 0.5 },
28+
{ name: 'sandbox.title', weight: 0.3 },
29+
{ name: 'sandbox.description', weight: 0.25 },
3030
{ name: 'sandbox.alias', weight: 0.2 },
3131
{ name: 'sandbox.source.template', weight: 0.2 },
3232
{ name: 'sandbox.id', weight: 0.05 },

packages/app/src/app/components/Integration/DetailInfo/DetailInfo.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import React from 'react';
22
import CrossIcon from 'react-icons/lib/md/clear';
33
import Margin from '@codesandbox/common/lib/components/spacing/Margin';
44
import Tooltip from '@codesandbox/common/lib/components/Tooltip';
5-
import { Button } from '@codesandbox/common/lib/components/Button';
5+
import { Button } from '@codesandbox/components';
66
import { Details, Heading, Info, Action } from './elements';
77

88
interface IDetailInfoProps {
@@ -31,7 +31,7 @@ export const DetailInfo: React.FC<IDetailInfoProps> = ({
3131
</Action>
3232
</Tooltip>
3333
) : (
34-
<Button small onClick={onSignIn}>
34+
<Button style={{ width: 'auto' }} onClick={onSignIn}>
3535
Sign in
3636
</Button>
3737
)}

packages/app/src/app/components/Integration/elements.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export const Container = styled.div<{
88
display: inline-flex;
99
width: 100%;
1010
border-radius: 4px;
11+
border: 1px solid ${theme.colors.avatar.border};
1112
color: ${theme.light ? css`#636363` : css`rgba(255, 255, 255, 0.8)`};
1213
overflow: hidden;
1314

packages/app/src/app/components/Modal/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ class ModalComponent extends React.Component {
7474
left: 0,
7575
right: 0,
7676
margin: `0 auto ${top}vh`,
77+
fontFamily: "'Inter', sans-serif",
7778
outline: 'none',
7879
},
7980
});
Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,8 @@
11
import styled from 'styled-components';
2-
import Input from '@codesandbox/common/lib/components/Input';
2+
import { Input } from '@codesandbox/components';
33

44
export const CardContainer = styled.div`
5-
padding: 0.5rem;
65
margin-top: 0.25rem;
7-
margin-bottom: 0.5rem;
8-
border-radius: 4px;
9-
background-color: rgba(0, 0, 0, 0.3);
106
`;
117

128
export const StripeInput = styled(Input)`
@@ -23,8 +19,3 @@ export const ErrorText = styled.div`
2319
color: ${props => props.theme.red};
2420
font-size: 0.875rem;
2521
`;
26-
27-
export const Label = styled.label`
28-
font-size: 0.875rem;
29-
color: rgba(255, 255, 255, 0.5);
30-
`;

packages/app/src/app/components/SubscribeForm/CheckoutForm/index.tsx

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import {
44
CardElement,
55
ReactStripeElements,
66
} from 'react-stripe-elements';
7-
import { Button } from '@codesandbox/common/lib/components/Button';
7+
import { withTheme } from 'styled-components';
8+
import css from '@styled-system/css';
89
import { logError } from '@codesandbox/common/lib/utils/analytics';
10+
import { Button, Label, Element } from '@codesandbox/components';
911

10-
import { CardContainer, StripeInput, ErrorText, Label } from './elements';
12+
import { CardContainer, StripeInput, ErrorText } from './elements';
1113

1214
interface Props {
1315
name: string;
@@ -18,6 +20,7 @@ interface Props {
1820
stripe?: ReactStripeElements.StripeProps;
1921
error?: Error | string;
2022
hasCoupon?: boolean;
23+
theme?: any;
2124
}
2225

2326
interface State {
@@ -106,6 +109,7 @@ class CheckoutFormComponent extends React.PureComponent<Props, State> {
106109
isLoading,
107110
error,
108111
hasCoupon = false,
112+
theme,
109113
} = this.props;
110114
const { errors, loading: stateLoading } = this.state;
111115

@@ -115,34 +119,61 @@ class CheckoutFormComponent extends React.PureComponent<Props, State> {
115119

116120
return (
117121
<form onSubmit={this.handleSubmit}>
118-
<Label>Cardholder Name</Label>
122+
<Label variant="muted" size={3} paddingBottom={1}>
123+
Cardholder Name
124+
</Label>
119125
{errors.name != null && <ErrorText>{errors.name}</ErrorText>}
120-
<div>
126+
<Element>
121127
<StripeInput
122128
value={this.state.name}
123129
onChange={this.setName}
124130
placeholder="Please enter your name"
125131
/>
126-
</div>
132+
</Element>
127133

128-
<Label>Card</Label>
134+
<Label variant="muted" size={3} paddingBottom={1}>
135+
Card
136+
</Label>
129137
{stripeError != null && <ErrorText>{stripeError}</ErrorText>}
130138
<CardContainer>
131-
<CardElement
132-
style={{ base: { color: 'white', fontWeight: '500' } }}
133-
/>
139+
<Element
140+
css={css({
141+
height: '32px',
142+
paddingTop: '6px',
143+
width: '100%',
144+
paddingX: 2,
145+
fontSize: 3,
146+
lineHeight: 1, // trust the height
147+
fontFamily: 'Inter, sans-serif',
148+
borderRadius: 'small',
149+
backgroundColor: 'input.background',
150+
border: '1px solid',
151+
borderColor: 'input.border',
152+
color: 'input.foreground',
153+
})}
154+
>
155+
<CardElement
156+
style={{
157+
base: {
158+
color: theme.colors.input.foreground,
159+
},
160+
}}
161+
/>
162+
</Element>
134163
</CardContainer>
135164

136165
{hasCoupon && (
137166
<>
138-
<Label>Coupon</Label>
139-
<div>
167+
<Label variant="muted" size={3} paddingBottom={1}>
168+
Coupon
169+
</Label>
170+
<Element>
140171
<StripeInput
141172
value={this.state.coupon}
142173
onChange={this.setCoupon}
143174
placeholder="Coupon or Discount Code"
144175
/>
145-
</div>
176+
</Element>
146177
</>
147178
)}
148179

@@ -157,5 +188,5 @@ class CheckoutFormComponent extends React.PureComponent<Props, State> {
157188
);
158189
}
159190
}
160-
161-
export const CheckoutForm = injectStripe(CheckoutFormComponent);
191+
// @ts-ignore
192+
export const CheckoutForm = injectStripe(withTheme(CheckoutFormComponent));

packages/app/src/app/components/SubscribeForm/elements.ts

Lines changed: 0 additions & 8 deletions
This file was deleted.

packages/app/src/app/components/SubscribeForm/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

packages/app/src/app/components/SubscribeForm/SubscribeForm.tsx renamed to packages/app/src/app/components/SubscribeForm/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@ import React from 'react';
22
import { StripeProvider, Elements } from 'react-stripe-elements';
33
import { STRIPE_API_KEY } from '@codesandbox/common/lib/utils/config';
44
import { useScript } from 'app/hooks';
5+
import { Element } from '@codesandbox/components';
6+
import css from '@styled-system/css';
57
import { CheckoutForm } from './CheckoutForm';
6-
import { Container } from './elements';
78

89
interface ISubscribeFormProps {
910
name: string;
@@ -37,7 +38,12 @@ export const SubscribeForm: React.FC<ISubscribeFormProps> = ({
3738

3839
return (
3940
<>
40-
<Container>
41+
<Element
42+
css={css({
43+
width: 300,
44+
borderRadius: 3,
45+
})}
46+
>
4147
<StripeProvider stripe={stripe}>
4248
<Elements>
4349
<CheckoutForm
@@ -51,7 +57,7 @@ export const SubscribeForm: React.FC<ISubscribeFormProps> = ({
5157
/>
5258
</Elements>
5359
</StripeProvider>
54-
</Container>
60+
</Element>
5561
</>
5662
);
5763
};

packages/app/src/app/index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@ window.getSignal = path =>
139139
overmind.initialized.then(() => {
140140
requirePolyfills().then(() => {
141141
if (isSafari) {
142+
// eslint-disable-next-line
142143
import('subworkers');
143144
}
144145

packages/app/src/app/overmind/effects/vscode/SandboxFsSync/index.ts

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
SandboxFs,
1313
} from '@codesandbox/common/lib/types';
1414
import { getGlobal } from '@codesandbox/common/lib/utils/global';
15+
import delay from '@codesandbox/common/lib/utils/delay';
1516
import { protocolAndHost } from '@codesandbox/common/lib/utils/url-generator';
1617
import { getSavedCode } from 'app/overmind/utils/sandbox';
1718
import { json } from 'overmind';
@@ -22,6 +23,49 @@ import { appendFile, mkdir, rename, rmdir, unlink, writeFile } from './utils';
2223
const global = getGlobal() as Window & { BrowserFS: any };
2324

2425
const SERVICE_URL = 'https://ata.codesandbox.io/api/v8';
26+
const BUCKET_URL = 'https://prod-packager-packages.codesandbox.io/v1/typings';
27+
28+
async function callApi(url: string, method = 'GET') {
29+
const response = await fetch(url, {
30+
method,
31+
});
32+
33+
if (!response.ok) {
34+
const error = new Error(response.statusText || '' + response.status);
35+
const message = await response.json();
36+
// @ts-ignore
37+
error.response = message;
38+
// @ts-ignore
39+
error.statusCode = response.status;
40+
throw error;
41+
}
42+
43+
return response.json();
44+
}
45+
46+
async function requestPackager(url: string, retryCount = 0, method = 'GET') {
47+
let retries = 0;
48+
49+
// eslint-disable-next-line no-constant-condition
50+
while (true) {
51+
try {
52+
const manifest = await callApi(url, method); // eslint-disable-line no-await-in-loop
53+
54+
return manifest;
55+
} catch (e) {
56+
if (e.response && e.statusCode !== 504) {
57+
throw new Error(e.response.error);
58+
}
59+
// 403 status code means the bundler is still bundling
60+
if (retries < retryCount) {
61+
retries += 1;
62+
await delay(1000 * 2); // eslint-disable-line no-await-in-loop
63+
} else {
64+
throw e;
65+
}
66+
}
67+
}
68+
}
2569

2670
declare global {
2771
interface Window {
@@ -396,13 +440,18 @@ class SandboxFsSync {
396440

397441
private async fetchDependencyTypingFiles(name: string, version: string) {
398442
const dependencyQuery = encodeURIComponent(`${name}@${version}`);
399-
const fetchRequest = await fetch(`${SERVICE_URL}/${dependencyQuery}.json`);
400443

401-
if (!fetchRequest.ok) {
402-
throw new Error('Fetch error');
444+
try {
445+
const url = `${BUCKET_URL}/${name}/${version}.json`;
446+
return await requestPackager(url, 0).then(x => x.files);
447+
} catch (e) {
448+
// Hasn't been generated
403449
}
404450

405-
const { files } = await fetchRequest.json();
451+
const { files } = await requestPackager(
452+
`${SERVICE_URL}/${dependencyQuery}.json`,
453+
3
454+
);
406455

407456
return files;
408457
}

packages/app/src/app/overmind/factories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export const withLoadApp = <T>(
3434
actions.internal.setPatronPrice();
3535
actions.internal.setSignedInCookie();
3636
effects.analytics.identify('signed_in', true);
37-
effects.analytics.setUserId(state.user.id);
37+
effects.analytics.setUserId(state.user.id, state.user.email);
3838
try {
3939
actions.internal.trackCurrentTeams();
4040
} catch (e) {

packages/app/src/app/overmind/internalActions.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export const signIn: AsyncAction<{ useExtraScopes?: boolean }> = async (
3131
actions.internal.setPatronPrice();
3232
actions.internal.setSignedInCookie();
3333
effects.analytics.identify('signed_in', true);
34-
effects.analytics.setUserId(state.user.id);
34+
effects.analytics.setUserId(state.user.id, state.user.email);
3535
actions.internal.setStoredSettings();
3636
effects.live.connect();
3737
actions.userNotifications.internal.initialize(); // Seemed a bit different originally?

packages/app/src/app/overmind/namespaces/files/internalActions.ts

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ export const uploadFiles: AsyncAction<
7878
const filePaths = Object.keys(files);
7979
const chunkedFilePaths = chunk(filePaths, 5);
8080

81+
const textExtensions = (await import('textextensions/source/index.json'))
82+
.default;
83+
8184
// We traverse all files and upload them when necessary, then add them to the
8285
// parsedFiles object
8386
/* eslint-disable no-restricted-syntax, no-await-in-loop */
@@ -87,20 +90,10 @@ export const uploadFiles: AsyncAction<
8790
const file = files[filePath];
8891
const { dataURI } = file;
8992

93+
const extension = filePath.split('.').pop();
94+
9095
if (
91-
(/\.(j|t)sx?$/.test(filePath) ||
92-
/\.coffee$/.test(filePath) ||
93-
/\.json$/.test(filePath) ||
94-
/\.html$/.test(filePath) ||
95-
/\.vue$/.test(filePath) ||
96-
/\.styl$/.test(filePath) ||
97-
/\.(le|sc|sa)ss$/.test(filePath) ||
98-
/\.haml$/.test(filePath) ||
99-
/\.pug$/.test(filePath) ||
100-
/\.svg$/.test(filePath) ||
101-
/\.md$/.test(filePath) ||
102-
/\.svelte$/.test(filePath) ||
103-
/\.hbs$/.test(filePath) ||
96+
((extension && textExtensions.includes(extension)) ||
10497
file.type.startsWith('text/') ||
10598
file.type === 'application/json') &&
10699
dataURI.length < MAX_FILE_SIZE

0 commit comments

Comments
 (0)