🚧 mound the <PreviewFrame /> properly on Mobile Preview screen
This commit is contained in:
parent
123c2b0006
commit
d00506a70e
5 changed files with 110 additions and 115 deletions
|
@ -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);
|
|
|
@ -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';
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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());
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue