🚧 mound the <PreviewFrame /> properly on Mobile Preview screen

This commit is contained in:
ghalestrilo 2020-06-18 22:52:25 -03:00
parent 123c2b0006
commit d00506a70e
5 changed files with 110 additions and 115 deletions

View file

@ -1,58 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import SortArrowUp from '../images/sort-arrow-up.svg';
import SortArrowDown from '../images/sort-arrow-down.svg';
import Github from '../images/github.svg';
import Google from '../images/google.svg';
import Plus from '../images/plus-icon.svg';
import Close from '../images/close.svg';
import DropdownArrow from '../images/down-filled-triangle.svg';
import Play from '../images/triangle-arrow-right.svg';
import Preferences from '../images/preferences.svg';
import Exit from '../images/exit.svg';
// HOC that adds the right web accessibility props
// https://www.scottohara.me/blog/2019/05/22/contextual-images-svgs-and-a11y.html
// could also give these a default size, color, etc. based on the theme
// Need to add size to these - like small icon, medium icon, large icon. etc.
function withLabel(SvgComponent) {
const Icon = (props) => {
const { 'aria-label': ariaLabel } = props;
if (ariaLabel) {
return (<SvgComponent
{...props}
aria-label={ariaLabel}
role="img"
focusable="false"
/>);
}
return (<SvgComponent
{...props}
aria-hidden
focusable="false"
/>);
};
Icon.propTypes = {
'aria-label': PropTypes.string
};
Icon.defaultProps = {
'aria-label': null
};
return Icon;
}
export const SortArrowUpIcon = withLabel(SortArrowUp);
export const SortArrowDownIcon = withLabel(SortArrowDown);
export const GithubIcon = withLabel(Github);
export const GoogleIcon = withLabel(Google);
export const PlusIcon = withLabel(Plus);
export const CloseIcon = withLabel(Close);
export const DropdownArrowIcon = withLabel(DropdownArrow);
export const PlayIcon = withLabel(Play);
export const PreferencesIcon = withLabel(Preferences);
export const ExitIcon = withLabel(Exit);

View file

@ -1,7 +1,7 @@
import React from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import styled from 'styled-components'; import styled from 'styled-components';
import { remSize, prop } from '../theme'; import { prop } from '../theme';
import SortArrowUp from '../images/sort-arrow-up.svg'; import SortArrowUp from '../images/sort-arrow-up.svg';
import SortArrowDown from '../images/sort-arrow-down.svg'; import SortArrowDown from '../images/sort-arrow-down.svg';
import Github from '../images/github.svg'; import Github from '../images/github.svg';

View file

@ -20,7 +20,6 @@ import { getHTMLFile } from '../reducers/files';
// Local Imports // Local Imports
import Editor from '../components/Editor'; import Editor from '../components/Editor';
import { prop, remSize } from '../../../theme';
import { ExitIcon } from '../../../common/icons'; import { ExitIcon } from '../../../common/icons';
import PreferencesIcon from '../../../images/preferences.svg'; import PreferencesIcon from '../../../images/preferences.svg';
@ -32,16 +31,6 @@ import Screen from '../../../components/mobile/MobileScreen';
import Footer from '../../../components/mobile/Footer'; import Footer from '../../../components/mobile/Footer';
import IDEWrapper from '../../../components/mobile/IDEWrapper'; import IDEWrapper from '../../../components/mobile/IDEWrapper';
const textColor = prop('primaryTextColor');
const Icon = styled.a`
> svg {
fill: ${textColor};
color: ${textColor};
margin-left: ${remSize(16)};
}
`;
const IconLinkWrapper = styled(Link)` const IconLinkWrapper = styled(Link)`
width: 3rem; width: 3rem;
margin-right: 1.25rem; margin-right: 1.25rem;

View file

@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react'; import React from 'react';
import PropTypes from 'prop-types'; import PropTypes from 'prop-types';
import { Link } from 'react-router'; import { Link } from 'react-router';
import { bindActionCreators } from 'redux'; import { bindActionCreators } from 'redux';
@ -9,11 +9,14 @@ import PreviewFrame from '../IDE/components/PreviewFrame';
import Screen from '../../components/mobile/MobileScreen'; import Screen from '../../components/mobile/MobileScreen';
import * as ProjectActions from '../IDE/actions/project'; import * as ProjectActions from '../IDE/actions/project';
import * as IDEActions from '../IDE/actions/ide'; import * as IDEActions from '../IDE/actions/ide';
import * as PreferencesActions from '../IDE/actions/preferences';
import * as ConsoleActions from '../IDE/actions/console';
import * as FilesActions from '../IDE/actions/files';
import { getHTMLFile, getJSFiles, getCSSFiles } from '../IDE/reducers/files'; import { getHTMLFile } from '../IDE/reducers/files';
import { ExitIcon } from '../../common/Icons'; import { ExitIcon } from '../../common/icons';
import { remSize } from '../../theme'; import { remSize } from '../../theme';
@ -28,12 +31,7 @@ const IconLinkWrapper = styled(Link)`
margin-left: none; margin-left: none;
`; `;
const noop = () => {};
const MobileSketchView = (props) => { const MobileSketchView = (props) => {
const [overlay, setOverlay] = useState(null);
// TODO: useSelector requires react-redux ^7.1.0 // TODO: useSelector requires react-redux ^7.1.0
// const htmlFile = useSelector(state => getHTMLFile(state.files)); // const htmlFile = useSelector(state => getHTMLFile(state.files));
// const jsFiles = useSelector(state => getJSFiles(state.files)); // const jsFiles = useSelector(state => getJSFiles(state.files));
@ -41,11 +39,18 @@ const MobileSketchView = (props) => {
// const files = useSelector(state => state.files); // const files = useSelector(state => state.files);
const { const {
htmlFile, jsFiles, cssFiles, files, params htmlFile, files, selectedFile
} = props; } = props;
// Actions // Actions
const { getProject, startSketch } = props; const {
setTextOutput, setGridOutput, setSoundOutput,
endSketchRefresh, stopSketch,
dispatchConsoleEvent, expandConsole, clearConsole,
setBlobUrl,
} = props;
const { preferences, ide } = props;
// useEffect(() => { // useEffect(() => {
// console.log(params); // console.log(params);
@ -65,30 +70,35 @@ const MobileSketchView = (props) => {
</Header> </Header>
<Content> <Content>
<h1>Hello</h1> <h1>Hello</h1>
<main className="preview-frame-holder"> <section className="preview-frame-holder">
<PreviewFrame <PreviewFrame
fullView
isPlaying
htmlFile={htmlFile} htmlFile={htmlFile}
jsFiles={jsFiles}
cssFiles={cssFiles}
files={files} files={files}
head={<link type="text/css" rel="stylesheet" href="/preview-styles.css" />} fullView
isAccessibleOutputPlaying={false}
textOutput={false}
gridOutput={false}
soundOutput={false}
previewIsRefreshing={false}
dispatchConsoleEvent={noop} content={selectedFile.content}
endSketchRefresh={noop}
setBlobUrl={noop} isPlaying={ide.isPlaying}
stopSketch={noop} isAccessibleOutputPlaying={ide.isAccessibleOutputPlaying}
expandConsole={noop} previewIsRefreshing={ide.previewIsRefreshing}
clearConsole={noop}
textOutput={preferences.textOutput}
gridOutput={preferences.gridOutput}
soundOutput={preferences.soundOutput}
autorefresh={preferences.autorefresh}
setTextOutput={setTextOutput}
setGridOutput={setGridOutput}
setSoundOutput={setSoundOutput}
dispatchConsoleEvent={dispatchConsoleEvent}
endSketchRefresh={endSketchRefresh}
stopSketch={stopSketch}
setBlobUrl={setBlobUrl}
expandConsole={expandConsole}
clearConsole={clearConsole}
/> />
</main> </section>
</Content> </Content>
</Screen>); </Screen>);
}; };
@ -98,42 +108,93 @@ MobileSketchView.propTypes = {
project_id: PropTypes.string, project_id: PropTypes.string,
username: PropTypes.string username: PropTypes.string
}).isRequired, }).isRequired,
htmlFile: PropTypes.shape({ htmlFile: PropTypes.shape({
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
content: PropTypes.string.isRequired, content: PropTypes.string.isRequired,
name: PropTypes.string.isRequired name: PropTypes.string.isRequired
}).isRequired, }).isRequired,
jsFiles: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
})).isRequired,
cssFiles: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
})).isRequired,
files: PropTypes.arrayOf(PropTypes.shape({ files: PropTypes.arrayOf(PropTypes.shape({
id: PropTypes.string.isRequired, id: PropTypes.string.isRequired,
content: PropTypes.string.isRequired, content: PropTypes.string.isRequired,
name: PropTypes.string.isRequired name: PropTypes.string.isRequired
})).isRequired, })).isRequired,
getProject: PropTypes.func.isRequired,
startSketch: PropTypes.func.isRequired, selectedFile: PropTypes.shape({
id: PropTypes.string.isRequired,
content: PropTypes.string.isRequired,
name: PropTypes.string.isRequired
}).isRequired,
preferences: PropTypes.shape({
fontSize: PropTypes.number.isRequired,
autosave: PropTypes.bool.isRequired,
linewrap: PropTypes.bool.isRequired,
lineNumbers: PropTypes.bool.isRequired,
lintWarning: PropTypes.bool.isRequired,
textOutput: PropTypes.bool.isRequired,
gridOutput: PropTypes.bool.isRequired,
soundOutput: PropTypes.bool.isRequired,
theme: PropTypes.string.isRequired,
autorefresh: PropTypes.bool.isRequired
}).isRequired,
ide: PropTypes.shape({
isPlaying: PropTypes.bool.isRequired,
isAccessibleOutputPlaying: PropTypes.bool.isRequired,
consoleEvent: PropTypes.array,
modalIsVisible: PropTypes.bool.isRequired,
sidebarIsExpanded: PropTypes.bool.isRequired,
consoleIsExpanded: PropTypes.bool.isRequired,
preferencesIsVisible: PropTypes.bool.isRequired,
projectOptionsVisible: PropTypes.bool.isRequired,
newFolderModalVisible: PropTypes.bool.isRequired,
shareModalVisible: PropTypes.bool.isRequired,
shareModalProjectId: PropTypes.string.isRequired,
shareModalProjectName: PropTypes.string.isRequired,
shareModalProjectUsername: PropTypes.string.isRequired,
editorOptionsVisible: PropTypes.bool.isRequired,
keyboardShortcutVisible: PropTypes.bool.isRequired,
unsavedChanges: PropTypes.bool.isRequired,
infiniteLoop: PropTypes.bool.isRequired,
previewIsRefreshing: PropTypes.bool.isRequired,
infiniteLoopMessage: PropTypes.string.isRequired,
projectSavedTime: PropTypes.string,
previousPath: PropTypes.string.isRequired,
justOpenedProject: PropTypes.bool.isRequired,
errorType: PropTypes.string,
runtimeErrorWarningVisible: PropTypes.bool.isRequired,
uploadFileModalVisible: PropTypes.bool.isRequired
}).isRequired,
setTextOutput: PropTypes.func.isRequired,
setGridOutput: PropTypes.func.isRequired,
setSoundOutput: PropTypes.func.isRequired,
dispatchConsoleEvent: PropTypes.func.isRequired,
endSketchRefresh: PropTypes.func.isRequired,
stopSketch: PropTypes.func.isRequired,
setBlobUrl: PropTypes.func.isRequired,
expandConsole: PropTypes.func.isRequired,
clearConsole: PropTypes.func.isRequired,
}; };
function mapStateToProps(state) { function mapStateToProps(state) {
return { return {
htmlFile: getHTMLFile(state.files), htmlFile: getHTMLFile(state.files),
jsFiles: getJSFiles(state.files),
cssFiles: getCSSFiles(state.files),
project: state.project, project: state.project,
files: state.files files: state.files,
ide: state.ide,
preferences: state.preferences,
selectedFile: state.files.find(file => file.isSelectedFile) ||
state.files.find(file => file.name === 'sketch.js') ||
state.files.find(file => file.name !== 'root'),
}; };
} }
function mapDispatchToProps(dispatch) { function mapDispatchToProps(dispatch) {
return bindActionCreators({ ...ProjectActions, ...IDEActions }, dispatch); return bindActionCreators({
...ProjectActions, ...IDEActions, ...PreferencesActions, ...ConsoleActions, ...FilesActions
}, dispatch);
} }
export default connect(mapStateToProps, mapDispatchToProps)(MobileSketchView); export default connect(mapStateToProps, mapDispatchToProps)(MobileSketchView);

View file

@ -1,4 +1,4 @@
import { Route, IndexRoute, Router, Switch, useRouteMatch } from 'react-router'; import { Route, IndexRoute } from 'react-router';
import React from 'react'; import React from 'react';
import App from './modules/App/App'; import App from './modules/App/App';
import IDEView from './modules/IDE/pages/IDEView'; import IDEView from './modules/IDE/pages/IDEView';
@ -23,6 +23,9 @@ const checkAuth = (store) => {
}; };
const onRouteChange = (store) => { const onRouteChange = (store) => {
// FIXME: This seems unnecessary - using the mobile <Switch /> navigator should prevent this from being called
const path = window.location.pathname;
if (path.includes('/mobile')) return;
store.dispatch(stopSketch()); store.dispatch(stopSketch());
}; };