Skip to content

Commit 95a096d

Browse files
committed
Merge develop
2 parents 48833c9 + 835ec3c commit 95a096d

Some content is hidden

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

50 files changed

+885
-321
lines changed

client/components/Nav.jsx

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { logoutUser } from '../modules/User/actions';
1414

1515
import getConfig from '../utils/getConfig';
1616
import { metaKeyName, } from '../utils/metaKey';
17+
import { getIsUserOwner } from '../modules/IDE/selectors/users';
1718

1819
import CaretLeftIcon from '../images/left-arrow.svg';
1920
import TriangleIcon from '../images/down-filled-triangle.svg';
@@ -215,10 +216,6 @@ class Nav extends React.PureComponent {
215216
}
216217
}
217218

218-
isUserOwner() {
219-
return this.props.project.owner && this.props.project.owner.id === this.props.user.id;
220-
}
221-
222219
handleFocus(dropdown) {
223220
this.clearHideTimeout();
224221
this.setDropdown(dropdown);
@@ -283,7 +280,7 @@ class Nav extends React.PureComponent {
283280
{this.props.t('Nav.File.New')}
284281
</button>
285282
</li>
286-
{ getConfig('LOGIN_ENABLED') && (!this.props.project.owner || this.isUserOwner()) &&
283+
{ getConfig('LOGIN_ENABLED') && (!this.props.project.owner || this.props.isUserOwner) &&
287284
<li className="nav__dropdown-item">
288285
<button
289286
onClick={this.handleSave}
@@ -797,6 +794,7 @@ Nav.propTypes = {
797794
t: PropTypes.func.isRequired,
798795
setLanguage: PropTypes.func.isRequired,
799796
language: PropTypes.string.isRequired,
797+
isUserOwner: PropTypes.bool.isRequired
800798
};
801799

802800
Nav.defaultProps = {
@@ -818,7 +816,8 @@ function mapStateToProps(state) {
818816
user: state.user,
819817
unsavedChanges: state.ide.unsavedChanges,
820818
rootFile: state.files.filter(file => file.name === 'root')[0],
821-
language: state.preferences.language
819+
language: state.preferences.language,
820+
isUserOwner: getIsUserOwner(state)
822821
};
823822
}
824823

client/components/mobile/Explorer.jsx

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
import React from 'react';
2+
import { useTranslation } from 'react-i18next';
23
import styled from 'styled-components';
34
import PropTypes from 'prop-types';
45
import Sidebar from './Sidebar';
56
import ConnectedFileNode from '../../modules/IDE/components/FileNode';
67

78

8-
const Explorer = ({ id, canEdit, onPressClose }) => (
9-
<Sidebar title="Files" onPressClose={onPressClose}>
10-
<ConnectedFileNode id={id} canEdit={canEdit} onClickFile={() => onPressClose()} />
11-
</Sidebar>
12-
);
9+
const Explorer = ({ id, canEdit, onPressClose }) => {
10+
const { t } = useTranslation();
11+
return (
12+
<Sidebar title={t('Explorer.Files')} onPressClose={onPressClose}>
13+
<ConnectedFileNode id={id} canEdit={canEdit} onClickFile={() => onPressClose()} />
14+
</Sidebar>
15+
);
16+
};
1317

1418
Explorer.propTypes = {
1519
id: PropTypes.number.isRequired,
Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,36 @@
11
import React from 'react';
22
import PropTypes from 'prop-types';
3+
import styled from 'styled-components';
4+
import { remSize } from '../../theme';
35

4-
const Screen = ({ children, fullscreen }) => (
5-
<div className={fullscreen && 'fullscreen-preview'}>
6+
const ScreenWrapper = styled.div`
7+
.toast {
8+
font-size: ${remSize(12)};
9+
padding: ${remSize(8)};
10+
11+
border-radius: ${remSize(4)};
12+
width: 92%;
13+
top: unset;
14+
min-width: unset;
15+
bottom: ${remSize(64)}
16+
}
17+
`;
18+
19+
const Screen = ({ children, fullscreen, slimheader }) => (
20+
<ScreenWrapper className={fullscreen && 'fullscreen-preview'} slimheader={slimheader}>
621
{children}
7-
</div>
22+
</ScreenWrapper>
823
);
924

1025
Screen.defaultProps = {
11-
fullscreen: false
26+
fullscreen: false,
27+
slimheader: false,
1228
};
1329

1430
Screen.propTypes = {
1531
children: PropTypes.node.isRequired,
16-
fullscreen: PropTypes.bool
32+
fullscreen: PropTypes.bool,
33+
slimheader: PropTypes.bool
1734
};
1835

1936
export default Screen;

client/i18n.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import i18n from 'i18next';
22
import { initReactI18next } from 'react-i18next';
33
import LanguageDetector from 'i18next-browser-languagedetector';
44
import Backend from 'i18next-http-backend';
5+
import { enUS, es } from 'date-fns/locale';
56

67
const fallbackLng = ['en-US'];
78
const availableLanguages = ['en-US', 'es-419'];
@@ -14,6 +15,18 @@ export function languageKeyToLabel(lang) {
1415
return languageMap[lang];
1516
}
1617

18+
export function languageKeyToDateLocale(lang) {
19+
const languageMap = {
20+
'en-US': enUS,
21+
'es-419': es
22+
};
23+
return languageMap[lang];
24+
}
25+
26+
export function currentDateLocale() {
27+
return languageKeyToDateLocale(i18n.language);
28+
}
29+
1730
const options = {
1831
loadPath: '/locales/{{lng}}/translations.json',
1932
requestOptions: { // used for fetch, can also be a function (payload) => ({ method: 'GET' })

client/modules/App/App.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class App extends React.Component {
4141
render() {
4242
return (
4343
<div className="app">
44-
{this.state.isMounted && !window.devToolsExtension && getConfig('NODE_ENV') === 'development' && <DevTools />}
44+
{false && this.state.isMounted && !window.devToolsExtension && getConfig('NODE_ENV') === 'development' && <DevTools />}
4545
{this.props.children}
4646
</div>
4747
);

client/modules/IDE/actions/uploader.js

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,6 @@ export function dropzoneSendingCallback(file, xhr, formData) {
7777
Object.keys(file.postData).forEach((key) => {
7878
formData.append(key, file.postData[key]);
7979
});
80-
formData.append('Content-type', file.type);
81-
formData.append('Content-length', '');
82-
formData.append('acl', 'public-read');
8380
}
8481
};
8582
}

client/modules/IDE/components/CollectionList/CollectionList.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ class CollectionList extends React.Component {
140140
{this._renderLoader()}
141141
{this._renderEmptyTable()}
142142
{this.hasCollections() &&
143-
<table className="sketches-table" summary="table containing all collections">
143+
<table className="sketches-table" summary={this.props.t('CollectionList.TableSummary')}>
144144
<thead>
145145
<tr>
146146
{this._renderFieldHeader('name', this.props.t('CollectionList.HeaderName'))}

client/modules/IDE/components/CollectionList/CollectionListRow.jsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import format from 'date-fns/format';
21
import PropTypes from 'prop-types';
32
import React from 'react';
43
import { connect } from 'react-redux';
@@ -9,11 +8,10 @@ import * as ProjectActions from '../../actions/project';
98
import * as CollectionsActions from '../../actions/collections';
109
import * as IdeActions from '../../actions/ide';
1110
import * as ToastActions from '../../actions/toast';
11+
import dates from '../../../../utils/formatDate';
1212

1313
import DownFilledTriangleIcon from '../../../../images/down-filled-triangle.svg';
1414

15-
const formatDateCell = (date, mobile = false) => format(new Date(date), 'MMM D, YYYY');
16-
1715
class CollectionListRowBase extends React.Component {
1816
static projectInCollection(project, collection) {
1917
return collection.items.find(item => item.project.id === project.id) != null;
@@ -214,8 +212,8 @@ class CollectionListRowBase extends React.Component {
214212
{this.renderCollectionName()}
215213
</span>
216214
</th>
217-
<td>{mobile && 'Created: '}{format(new Date(collection.createdAt), 'MMM D, YYYY')}</td>
218-
<td>{mobile && 'Updated: '}{formatDateCell(collection.updatedAt)}</td>
215+
<td>{mobile && 'Created: '}{dates.format(collection.createdAt)}</td>
216+
<td>{mobile && 'Updated: '}{dates.format(collection.updatedAt)}</td>
219217
<td>{mobile && '# sketches: '}{(collection.items || []).length}</td>
220218
<td className="sketch-list__dropdown-column">
221219
{this.renderActions()}

client/modules/IDE/components/Editor.jsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ import UnsavedChangesDotIcon from '../../../images/unsaved-changes-dot.svg';
4343
import RightArrowIcon from '../../../images/right-arrow.svg';
4444
import LeftArrowIcon from '../../../images/left-arrow.svg';
4545
import { getHTMLFile } from '../reducers/files';
46+
import { getIsUserOwner } from '../selectors/users';
4647

4748
import * as FileActions from '../actions/files';
4849
import * as IDEActions from '../actions/ide';
@@ -412,7 +413,7 @@ Editor.propTypes = {
412413
isExpanded: PropTypes.bool.isRequired,
413414
collapseSidebar: PropTypes.func.isRequired,
414415
expandSidebar: PropTypes.func.isRequired,
415-
isUserOwner: PropTypes.bool,
416+
isUserOwner: PropTypes.bool.isRequired,
416417
clearConsole: PropTypes.func.isRequired,
417418
showRuntimeErrorWarning: PropTypes.func.isRequired,
418419
hideRuntimeErrorWarning: PropTypes.func.isRequired,
@@ -422,7 +423,6 @@ Editor.propTypes = {
422423
};
423424

424425
Editor.defaultProps = {
425-
isUserOwner: false,
426426
consoleEvents: [],
427427
};
428428

@@ -448,7 +448,8 @@ function mapStateToProps(state) {
448448
...state.project,
449449
...state.editorAccessibility,
450450
isExpanded: state.ide.sidebarIsExpanded,
451-
projectSavedTime: state.project.updatedAt
451+
projectSavedTime: state.project.updatedAt,
452+
isUserOwner: getIsUserOwner(state)
452453
};
453454
}
454455

client/modules/IDE/components/ErrorModal.jsx

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,19 @@ class ErrorModal extends React.Component {
1515
);
1616
}
1717

18+
oauthError() {
19+
const { t, service } = this.props;
20+
const serviceLabels = {
21+
github: 'GitHub',
22+
google: 'Google'
23+
};
24+
return (
25+
<p>
26+
{t('ErrorModal.LinkMessage', { serviceauth: serviceLabels[service] })}
27+
</p>
28+
);
29+
}
30+
1831
staleSession() {
1932
return (
2033
<p>
@@ -42,6 +55,8 @@ class ErrorModal extends React.Component {
4255
return this.staleSession();
4356
} else if (this.props.type === 'staleProject') {
4457
return this.staleProject();
58+
} else if (this.props.type === 'oauthError') {
59+
return this.oauthError();
4560
}
4661
})()}
4762
</div>
@@ -52,7 +67,12 @@ class ErrorModal extends React.Component {
5267
ErrorModal.propTypes = {
5368
type: PropTypes.string.isRequired,
5469
closeModal: PropTypes.func.isRequired,
55-
t: PropTypes.func.isRequired
70+
t: PropTypes.func.isRequired,
71+
service: PropTypes.string
72+
};
73+
74+
ErrorModal.defaultProps = {
75+
service: ''
5676
};
5777

5878
export default withTranslation()(ErrorModal);

0 commit comments

Comments
 (0)