Skip to content

Commit 4fcf288

Browse files
authored
Merge branch 'develop' into feature/Internationalize-mobile-text
2 parents e2afc15 + a6cc2b3 commit 4fcf288

File tree

11 files changed

+328
-286
lines changed

11 files changed

+328
-286
lines changed

client/common/icons.jsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import Preferences from '../images/preferences.svg';
1414
import Play from '../images/triangle-arrow-right.svg';
1515
import More from '../images/more.svg';
1616
import Code from '../images/code.svg';
17+
import Save from '../images/save.svg';
1718
import Terminal from '../images/terminal.svg';
1819

1920
import Folder from '../images/folder-padded.svg';
@@ -87,6 +88,7 @@ export const PlayIcon = withLabel(Play);
8788
export const MoreIcon = withLabel(More);
8889
export const TerminalIcon = withLabel(Terminal);
8990
export const CodeIcon = withLabel(Code);
91+
export const SaveIcon = withLabel(Save);
9092

9193
export const FolderIcon = withLabel(Folder);
9294

Lines changed: 23 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,16 @@
11
import React from 'react';
2-
import styled from 'styled-components';
32
import PropTypes from 'prop-types';
4-
import { bindActionCreators } from 'redux';
5-
import { useDispatch, useSelector } from 'react-redux';
3+
import styled from 'styled-components';
64
import { remSize, prop } from '../../theme';
75
import IconButton from './IconButton';
8-
import { TerminalIcon, FolderIcon } from '../../common/icons';
9-
import * as IDEActions from '../../modules/IDE/actions/ide';
106

117
const BottomBarContent = styled.div`
128
padding: ${remSize(8)};
13-
display: flex;
9+
display: grid;
10+
grid-template-columns: repeat(8,1fr);
1411
1512
svg {
1613
max-height: ${remSize(32)};
17-
1814
}
1915
2016
path { fill: ${prop('primaryTextColor')} !important }
@@ -25,42 +21,28 @@ const BottomBarContent = styled.div`
2521
}
2622
`;
2723

28-
// Maybe this component shouldn't be connected, and instead just receive the `actions` prop
29-
const ActionStrip = ({ toggleExplorer }) => {
30-
const { expandConsole, collapseConsole } = bindActionCreators(IDEActions, useDispatch());
31-
const { consoleIsExpanded } = useSelector(state => state.ide);
32-
33-
const actions = [
34-
{
35-
icon: TerminalIcon, inverted: true, aria: 'Open terminal console', action: consoleIsExpanded ? collapseConsole : expandConsole
36-
},
37-
{ icon: FolderIcon, aria: 'Open files explorer', action: toggleExplorer }
38-
];
39-
40-
return (
41-
<BottomBarContent>
42-
{actions.map(({
43-
icon, aria, action, inverted
44-
}) =>
45-
(
46-
<IconButton
47-
inverted={inverted}
48-
className={inverted && 'inverted'}
49-
icon={icon}
50-
aria-label={aria}
51-
key={`bottom-bar-${aria}`}
52-
onClick={() => action()}
53-
/>))}
54-
</BottomBarContent>
55-
);
56-
};
24+
const ActionStrip = ({ actions }) => (
25+
<BottomBarContent>
26+
{actions.map(({
27+
icon, aria, action, inverted
28+
}) =>
29+
(<IconButton
30+
inverted={inverted}
31+
className={inverted && 'inverted'}
32+
icon={icon}
33+
aria-label={aria}
34+
key={`bottom-bar-${aria}`}
35+
onClick={action}
36+
/>))}
37+
</BottomBarContent>);
5738

5839
ActionStrip.propTypes = {
59-
toggleExplorer: PropTypes.func
60-
};
61-
62-
ActionStrip.defaultProps = {
63-
toggleExplorer: () => {}
40+
actions: PropTypes.arrayOf(PropTypes.shape({
41+
icon: PropTypes.any,
42+
aria: PropTypes.string.isRequired,
43+
action: PropTypes.func.isRequired,
44+
inverted: PropTypes.bool
45+
})).isRequired
6446
};
6547

6648
export default ActionStrip;

client/components/mobile/Header.jsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ const HeaderDiv = styled.div`
3535
}
3636
3737
& svg path { fill: ${textColor} !important; }
38+
39+
.editor__unsaved-changes svg {
40+
width: ${remSize(16)};
41+
padding: 0;
42+
vertical-align: top
43+
}
3844
`;
3945

4046
const IconContainer = styled.div`
@@ -71,8 +77,9 @@ const Header = ({
7177
</HeaderDiv>
7278
);
7379

80+
7481
Header.propTypes = {
75-
title: PropTypes.string,
82+
title: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
7683
subtitle: PropTypes.string,
7784
leftButton: PropTypes.element,
7885
children: PropTypes.oneOfType([PropTypes.element, PropTypes.arrayOf(PropTypes.element)]),

client/components/mobile/Sidebar.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const SidebarWrapper = styled.div`
1616
z-index: 2;
1717
left: 0;
1818
19-
background: white;
19+
background: ${prop('backgroundColor')};
2020
box-shadow: 0 6px 6px 0 rgba(0,0,0,0.10);
2121
`;
2222

client/images/save.svg

Lines changed: 3 additions & 0 deletions
Loading

client/modules/IDE/actions/project.js

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ function getSynchedProject(currentState, responseProject) {
126126
};
127127
}
128128

129-
export function saveProject(selectedFile = null, autosave = false) {
129+
export function saveProject(selectedFile = null, autosave = false, mobile = false) {
130130
return (dispatch, getState) => {
131131
const state = getState();
132132
if (state.project.isSaving) {
@@ -185,16 +185,15 @@ export function saveProject(selectedFile = null, autosave = false) {
185185
.then((response) => {
186186
dispatch(endSavingProject());
187187
const { hasChanges, synchedProject } = getSynchedProject(getState(), response.data);
188+
189+
dispatch(setNewProject(synchedProject));
190+
dispatch(setUnsavedChanges(false));
191+
browserHistory.push(`/${response.data.user.username}/sketches/${response.data.id}`);
192+
188193
if (hasChanges) {
189-
dispatch(setNewProject(synchedProject));
190-
dispatch(setUnsavedChanges(false));
191-
browserHistory.push(`/${response.data.user.username}/sketches/${response.data.id}`);
192194
dispatch(setUnsavedChanges(true));
193-
} else {
194-
dispatch(setNewProject(synchedProject));
195-
dispatch(setUnsavedChanges(false));
196-
browserHistory.push(`/${response.data.user.username}/sketches/${response.data.id}`);
197195
}
196+
198197
dispatch(projectSaveSuccess());
199198
if (!autosave) {
200199
if (state.preferences.autosave) {
@@ -222,9 +221,9 @@ export function saveProject(selectedFile = null, autosave = false) {
222221
};
223222
}
224223

225-
export function autosaveProject() {
224+
export function autosaveProject(mobile = false) {
226225
return (dispatch, getState) => {
227-
saveProject(null, true)(dispatch, getState);
226+
saveProject(null, true, mobile)(dispatch, getState);
228227
};
229228
}
230229

client/modules/IDE/components/Editor.jsx

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import { CSSLint } from 'csslint';
2727
import { HTMLHint } from 'htmlhint';
2828
import classNames from 'classnames';
2929
import { debounce } from 'lodash';
30+
import { connect } from 'react-redux';
31+
import { bindActionCreators } from 'redux';
3032
import '../../../utils/htmlmixed';
3133
import '../../../utils/p5-javascript';
3234
import '../../../utils/webGL-clike';
@@ -40,6 +42,16 @@ import beepUrl from '../../../sounds/audioAlert.mp3';
4042
import UnsavedChangesDotIcon from '../../../images/unsaved-changes-dot.svg';
4143
import RightArrowIcon from '../../../images/right-arrow.svg';
4244
import LeftArrowIcon from '../../../images/left-arrow.svg';
45+
import { getHTMLFile } from '../reducers/files';
46+
47+
import * as FileActions from '../actions/files';
48+
import * as IDEActions from '../actions/ide';
49+
import * as ProjectActions from '../actions/project';
50+
import * as EditorAccessibilityActions from '../actions/editorAccessibility';
51+
import * as PreferencesActions from '../actions/preferences';
52+
import * as UserActions from '../../User/actions';
53+
import * as ToastActions from '../actions/toast';
54+
import * as ConsoleActions from '../actions/console';
4355

4456
search(CodeMirror);
4557

@@ -413,4 +425,47 @@ Editor.defaultProps = {
413425
consoleEvents: [],
414426
};
415427

416-
export default withTranslation()(Editor);
428+
429+
function mapStateToProps(state) {
430+
return {
431+
files: state.files,
432+
file:
433+
state.files.find(file => file.isSelectedFile) ||
434+
state.files.find(file => file.name === 'sketch.js') ||
435+
state.files.find(file => file.name !== 'root'),
436+
htmlFile: getHTMLFile(state.files),
437+
ide: state.ide,
438+
preferences: state.preferences,
439+
editorAccessibility: state.editorAccessibility,
440+
user: state.user,
441+
project: state.project,
442+
toast: state.toast,
443+
console: state.console,
444+
445+
...state.preferences,
446+
...state.ide,
447+
...state.project,
448+
...state.editorAccessibility,
449+
isExpanded: state.ide.consoleIsExpanded,
450+
projectSavedTime: state.project.updatedAt
451+
};
452+
}
453+
454+
function mapDispatchToProps(dispatch) {
455+
return bindActionCreators(
456+
Object.assign(
457+
{},
458+
EditorAccessibilityActions,
459+
FileActions,
460+
ProjectActions,
461+
IDEActions,
462+
PreferencesActions,
463+
UserActions,
464+
ToastActions,
465+
ConsoleActions
466+
),
467+
dispatch
468+
);
469+
}
470+
471+
export default withTranslation()(connect(mapStateToProps, mapDispatchToProps)(Editor));

0 commit comments

Comments
 (0)