Skip to content

Commit 90272b5

Browse files
committed
Merge branch 'feature/mobile-login' of https://github.com/ghalestrilo/p5.js-web-editor into feature/switch-mobile-desktop
2 parents 551a6bc + 2169a6e commit 90272b5

File tree

9 files changed

+221
-82
lines changed

9 files changed

+221
-82
lines changed

client/modules/IDE/components/ErrorModal.jsx

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,33 @@
11
import PropTypes from 'prop-types';
22
import React from 'react';
33
import { Link } from 'react-router';
4+
import { withTranslation } from 'react-i18next';
45

56
class ErrorModal extends React.Component {
67
forceAuthentication() {
78
return (
89
<p>
9-
In order to save sketches, you must be logged in. Please&nbsp;
10-
<Link to="/login" onClick={this.props.closeModal}>Login</Link>
11-
&nbsp;or&nbsp;
12-
<Link to="/signup" onClick={this.props.closeModal}>Sign Up</Link>.
10+
{this.props.t('ErrorModal.MessageLogin')}
11+
<Link to="/login" onClick={this.props.closeModal}> {this.props.t('ErrorModal.Login')}</Link>
12+
{this.props.t('ErrorModal.LoginOr')}
13+
<Link to="/signup" onClick={this.props.closeModal}>{this.props.t('ErrorModal.SignUp')}</Link>.
1314
</p>
1415
);
1516
}
1617

1718
staleSession() {
1819
return (
1920
<p>
20-
It looks like you&apos;ve been logged out. Please&nbsp;
21-
<Link to="/login" onClick={this.props.closeModal}>log in</Link>.
21+
{this.props.t('ErrorModal.MessageLoggedOut')}
22+
<Link to="/login" onClick={this.props.closeModal}>{this.props.t('ErrorModal.LogIn')}</Link>.
2223
</p>
2324
);
2425
}
2526

2627
staleProject() {
2728
return (
2829
<p>
29-
The project you have attempted to save has been saved from another window.
30-
Please refresh the page to see the latest version.
30+
{this.props.t('ErrorModal.SavedDifferentWindow')}
3131
</p>
3232
);
3333
}
@@ -51,7 +51,8 @@ class ErrorModal extends React.Component {
5151

5252
ErrorModal.propTypes = {
5353
type: PropTypes.string.isRequired,
54-
closeModal: PropTypes.func.isRequired
54+
closeModal: PropTypes.func.isRequired,
55+
t: PropTypes.func.isRequired
5556
};
5657

57-
export default ErrorModal;
58+
export default withTranslation()(ErrorModal);

client/modules/IDE/components/FileUploader.jsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import React from 'react';
33
import Dropzone from 'dropzone';
44
import { bindActionCreators } from 'redux';
55
import { connect } from 'react-redux';
6+
import { withTranslation } from 'react-i18next';
67
import * as UploaderActions from '../actions/uploader';
78
import getConfig from '../../../utils/getConfig';
89
import { fileExtensionsAndMimeTypes } from '../../../../server/utils/fileUtils';
@@ -30,7 +31,7 @@ class FileUploader extends React.Component {
3031
thumbnailWidth: 200,
3132
thumbnailHeight: 200,
3233
acceptedFiles: fileExtensionsAndMimeTypes,
33-
dictDefaultMessage: 'Drop files here or click to use the file browser',
34+
dictDefaultMessage: this.props.t('FileUploader.DictDefaultMessage'),
3435
accept: this.props.dropzoneAcceptCallback.bind(this, userId),
3536
sending: this.props.dropzoneSendingCallback,
3637
complete: this.props.dropzoneCompleteCallback
@@ -59,7 +60,8 @@ FileUploader.propTypes = {
5960
}),
6061
user: PropTypes.shape({
6162
id: PropTypes.string
62-
})
63+
}),
64+
t: PropTypes.func.isRequired
6365
};
6466

6567
FileUploader.defaultProps = {
@@ -84,4 +86,4 @@ function mapDispatchToProps(dispatch) {
8486
return bindActionCreators(UploaderActions, dispatch);
8587
}
8688

87-
export default connect(mapStateToProps, mapDispatchToProps)(FileUploader);
89+
export default withTranslation()(connect(mapStateToProps, mapDispatchToProps)(FileUploader));

client/modules/IDE/components/ShareModal.jsx

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import PropTypes from 'prop-types';
22
import React from 'react';
3+
import { withTranslation } from 'react-i18next';
34
import CopyableInput from './CopyableInput';
45

56
class ShareModal extends React.PureComponent {
@@ -16,21 +17,21 @@ class ShareModal extends React.PureComponent {
1617
{projectName}
1718
</h3>
1819
<CopyableInput
19-
label="Embed"
20+
label={this.props.t('ShareModal.Embed')}
2021
value={`<iframe src="${hostname}/${ownerUsername}/embed/${projectId}"></iframe>`}
2122
/>
2223
<CopyableInput
23-
label="Present"
24+
label={this.props.t('ShareModal.Present')}
2425
hasPreviewLink
2526
value={`${hostname}/${ownerUsername}/present/${projectId}`}
2627
/>
2728
<CopyableInput
28-
label="Fullscreen"
29+
label={this.props.t('ShareModal.Fullscreen')}
2930
hasPreviewLink
3031
value={`${hostname}/${ownerUsername}/full/${projectId}`}
3132
/>
3233
<CopyableInput
33-
label="Edit"
34+
label={this.props.t('ShareModal.Edit')}
3435
hasPreviewLink
3536
value={`${hostname}/${ownerUsername}/sketches/${projectId}`}
3637
/>
@@ -42,7 +43,8 @@ class ShareModal extends React.PureComponent {
4243
ShareModal.propTypes = {
4344
projectId: PropTypes.string.isRequired,
4445
ownerUsername: PropTypes.string.isRequired,
45-
projectName: PropTypes.string.isRequired
46+
projectName: PropTypes.string.isRequired,
47+
t: PropTypes.func.isRequired
4648
};
4749

48-
export default ShareModal;
50+
export default withTranslation()(ShareModal);

client/modules/IDE/components/UploadFileModal.jsx

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import React from 'react';
22
import PropTypes from 'prop-types';
33
import { connect } from 'react-redux';
44
import { Link } from 'react-router';
5+
import { withTranslation } from 'react-i18next';
56
import prettyBytes from 'pretty-bytes';
67
import getConfig from '../../../utils/getConfig';
78
import FileUploader from './FileUploader';
@@ -14,7 +15,8 @@ const limitText = prettyBytes(limit);
1415
class UploadFileModal extends React.Component {
1516
propTypes = {
1617
reachedTotalSizeLimit: PropTypes.bool.isRequired,
17-
closeModal: PropTypes.func.isRequired
18+
closeModal: PropTypes.func.isRequired,
19+
t: PropTypes.func.isRequired
1820
}
1921

2022
componentDidMount() {
@@ -31,22 +33,18 @@ class UploadFileModal extends React.Component {
3133
<section className="modal" ref={(element) => { this.modal = element; }}>
3234
<div className="modal-content">
3335
<div className="modal__header">
34-
<h2 className="modal__title">Upload File</h2>
36+
<h2 className="modal__title">{this.props.t('UploadFileModal.Title')}</h2>
3537
<button
3638
className="modal__exit-button"
3739
onClick={this.props.closeModal}
38-
aria-label="Close upload file modal"
40+
aria-label={this.props.t('UploadFileModal.CloseButtonARIA')}
3941
>
4042
<ExitIcon focusable="false" aria-hidden="true" />
4143
</button>
4244
</div>
4345
{ this.props.reachedTotalSizeLimit &&
4446
<p>
45-
{
46-
`Error: You cannot upload any more files. You have reached the total size limit of ${limitText}.
47-
If you would like to upload more, please remove the ones you aren't using anymore by
48-
in your `
49-
}
47+
{this.props.t('UploadFileModal.SizeLimitError', { sizeLimit: limitText })}
5048
<Link to="/assets" onClick={this.props.closeModal}>assets</Link>
5149
.
5250
</p>
@@ -68,4 +66,4 @@ function mapStateToProps(state) {
6866
};
6967
}
7068

71-
export default connect(mapStateToProps)(UploadFileModal);
69+
export default withTranslation()(connect(mapStateToProps)(UploadFileModal));
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import PropTypes from 'prop-types';
4+
import { remSize } from '../../../theme';
5+
6+
7+
const ResponsiveFormWrapper = styled.div`
8+
.form-container__content {
9+
width: unset !important;
10+
padding-top: ${remSize(16)};
11+
padding-bottom: ${remSize(64)};
12+
}
13+
14+
.form__input {
15+
min-width: unset;
16+
padding: 0px ${remSize(12)};
17+
height: ${remSize(28)};
18+
}
19+
.form-container__title { margin-bottom: ${remSize(14)}}
20+
p.form__field { margin-top: 0px !important; }
21+
label.form__label { margin-top: ${remSize(8)} !important; }
22+
23+
.form-error { width: 100% }
24+
25+
.nav__items-right:last-child { display: none }
26+
27+
.form-container {
28+
height: 100%
29+
}
30+
31+
.form-container__stack {
32+
svg {
33+
width: ${remSize(12)};
34+
height: ${remSize(12)}
35+
}
36+
a { padding: 0px }
37+
}
38+
`;
39+
40+
const ResponsiveForm = props =>
41+
(props.mobile === true
42+
? (
43+
<ResponsiveFormWrapper>
44+
{props.children}
45+
</ResponsiveFormWrapper>
46+
47+
)
48+
: props.children);
49+
50+
ResponsiveForm.propTypes = {
51+
mobile: PropTypes.bool,
52+
children: PropTypes.oneOfType([PropTypes.node, PropTypes.array]),
53+
};
54+
ResponsiveForm.defaultProps = {
55+
mobile: false,
56+
children: []
57+
};
58+
59+
export default ResponsiveForm;

client/modules/User/pages/LoginView.jsx

Lines changed: 33 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import LoginForm from '../components/LoginForm';
1010
import { validateLogin } from '../../../utils/reduxFormUtils';
1111
import SocialAuthButton from '../components/SocialAuthButton';
1212
import Nav from '../../../components/Nav';
13+
import ResponsiveForm from '../components/ResponsiveForm';
1314

1415
class LoginView extends React.Component {
1516
constructor(props) {
@@ -27,36 +28,40 @@ class LoginView extends React.Component {
2728
}
2829

2930
render() {
31+
const isMobile = () => (window.innerWidth < 770);
3032
if (this.props.user.authenticated) {
3133
this.gotoHomePage();
3234
return null;
3335
}
36+
// TODO: mobile currently forced to true
3437
return (
35-
<div className="login">
36-
<Nav layout="dashboard" />
37-
<main className="form-container">
38-
<Helmet>
39-
<title>{this.props.t('LoginView.Title')}</title>
40-
</Helmet>
41-
<div className="form-container__content">
42-
<h2 className="form-container__title">{this.props.t('LoginView.Login')}</h2>
43-
<LoginForm {...this.props} />
44-
<h2 className="form-container__divider">{this.props.t('LoginView.LoginOr')}</h2>
45-
<div className="form-container__stack">
46-
<SocialAuthButton service={SocialAuthButton.services.github} />
47-
<SocialAuthButton service={SocialAuthButton.services.google} />
38+
<ResponsiveForm mobile={isMobile() || this.props.mobile}>
39+
<div className="login">
40+
<Nav layout="dashboard" />
41+
<main className="form-container">
42+
<Helmet>
43+
<title>{this.props.t('LoginView.Title')}</title>
44+
</Helmet>
45+
<div className="form-container__content">
46+
<h2 className="form-container__title">{this.props.t('LoginView.Login')}</h2>
47+
<LoginForm {...this.props} />
48+
<h2 className="form-container__divider">{this.props.t('LoginView.LoginOr')}</h2>
49+
<div className="form-container__stack">
50+
<SocialAuthButton service={SocialAuthButton.services.github} />
51+
<SocialAuthButton service={SocialAuthButton.services.google} />
52+
</div>
53+
<p className="form__navigation-options">
54+
{this.props.t('LoginView.DontHaveAccount')}
55+
<Link className="form__signup-button" to="/signup">{this.props.t('LoginView.SignUp')}</Link>
56+
</p>
57+
<p className="form__navigation-options">
58+
{this.props.t('LoginView.ForgotPassword')}
59+
<Link className="form__reset-password-button" to="/reset-password"> {this.props.t('LoginView.ResetPassword')}</Link>
60+
</p>
4861
</div>
49-
<p className="form__navigation-options">
50-
{this.props.t('LoginView.DontHaveAccount')}
51-
<Link className="form__signup-button" to="/signup">{this.props.t('LoginView.SignUp')}</Link>
52-
</p>
53-
<p className="form__navigation-options">
54-
{this.props.t('LoginView.ForgotPassword')}
55-
<Link className="form__reset-password-button" to="/reset-password"> {this.props.t('LoginView.ResetPassword')}</Link>
56-
</p>
57-
</div>
58-
</main>
59-
</div>
62+
</main>
63+
</div>
64+
</ResponsiveForm>
6065
);
6166
}
6267
}
@@ -79,13 +84,15 @@ LoginView.propTypes = {
7984
user: PropTypes.shape({
8085
authenticated: PropTypes.bool
8186
}),
82-
t: PropTypes.func.isRequired
87+
t: PropTypes.func.isRequired,
88+
mobile: PropTypes.bool
8389
};
8490

8591
LoginView.defaultProps = {
8692
user: {
8793
authenticated: false
88-
}
94+
},
95+
mobile: false
8996
};
9097

9198
export default withTranslation()(reduxForm({

0 commit comments

Comments
 (0)