* Got the basis covered, now I need to style all this * Corrected and upgraded Share window * Changed the routes again, and set correct design * Made some of the requested changes * Removed PreviewFrame errors * Redesigned Preview Header * Corrected style of the FullView * Corrected most of the css mistakes * Corrected logo size
This commit is contained in:
parent
f4ff0b1c34
commit
996a1b988a
16 changed files with 137 additions and 31 deletions
37
client/components/PreviewNav.jsx
Normal file
37
client/components/PreviewNav.jsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import { Link } from 'react-router';
|
||||
import InlineSVG from 'react-inlinesvg';
|
||||
|
||||
const logoUrl = require('../images/p5js-logo-small.svg');
|
||||
const editorUrl = require('../images/code.svg');
|
||||
|
||||
const PreviewNav = ({ owner, project }) => (
|
||||
<nav className="nav">
|
||||
<div className="nav__items-left">
|
||||
<div className="nav__item-logo">
|
||||
<InlineSVG src={logoUrl} alt="p5.js logo" />
|
||||
</div>
|
||||
<Link className="nav__item" to={`/${owner.username}/sketches/${project.id}`}>{project.name}</Link>
|
||||
<p className="toolbar__project-owner">by</p>
|
||||
<Link className="nav__item" to={`/${owner.username}/sketches/`}>{owner.username}</Link>
|
||||
</div>
|
||||
<div className="nav__items-right">
|
||||
<Link to={`/${owner.username}/sketches/${project.id}`}>
|
||||
<InlineSVG className="preview-nav__editor-svg" src={editorUrl} />
|
||||
</Link>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
|
||||
PreviewNav.propTypes = {
|
||||
owner: PropTypes.shape({
|
||||
username: PropTypes.string.isRequired
|
||||
}).isRequired,
|
||||
project: PropTypes.shape({
|
||||
name: PropTypes.string.isRequired,
|
||||
id: PropTypes.string.isRequired,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default PreviewNav;
|
8
client/images/code.svg
Normal file
8
client/images/code.svg
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generated by IcoMoon.io -->
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="20" height="16" viewBox="0 0 20 16">
|
||||
<path d="M13 11.5l1.5 1.5 5-5-5-5-1.5 1.5 3.5 3.5z"></path>
|
||||
<path d="M7 4.5l-1.5-1.5-5 5 5 5 1.5-1.5-3.5-3.5z"></path>
|
||||
<path d="M10.958 2.352l1.085 0.296-3 11-1.085-0.296 3-11z"></path>
|
||||
</svg>
|
After Width: | Height: | Size: 513 B |
|
@ -31,7 +31,8 @@ class CopyableInput extends React.Component {
|
|||
render() {
|
||||
const {
|
||||
label,
|
||||
value
|
||||
value,
|
||||
hasPreviewLink
|
||||
} = this.props;
|
||||
return (
|
||||
<div className="copyable-input">
|
||||
|
@ -42,7 +43,12 @@ class CopyableInput extends React.Component {
|
|||
onMouseLeave={this.onMouseLeaveHandler}
|
||||
>
|
||||
<label className="copyable-input__label" htmlFor={`copyable-input__value-${label}`}>
|
||||
{label}
|
||||
<div className="copyable-input__label-container">
|
||||
{label} {hasPreviewLink &&
|
||||
<a target="_blank" href={value}>
|
||||
Open
|
||||
</a>}
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
className="copyable-input__value"
|
||||
|
@ -60,7 +66,12 @@ class CopyableInput extends React.Component {
|
|||
|
||||
CopyableInput.propTypes = {
|
||||
label: PropTypes.string.isRequired,
|
||||
value: PropTypes.string.isRequired
|
||||
value: PropTypes.string.isRequired,
|
||||
hasPreviewLink: PropTypes.bool
|
||||
};
|
||||
|
||||
CopyableInput.defaultProps = {
|
||||
hasPreviewLink: false
|
||||
};
|
||||
|
||||
export default CopyableInput;
|
||||
|
|
|
@ -317,8 +317,9 @@ class PreviewFrame extends React.Component {
|
|||
|
||||
renderSketch() {
|
||||
const doc = this.iframeElement;
|
||||
const localFiles = this.injectLocalFiles();
|
||||
if (this.props.isPlaying) {
|
||||
srcDoc.set(doc, this.injectLocalFiles());
|
||||
srcDoc.set(doc, localFiles);
|
||||
if (this.props.endSketchRefresh) {
|
||||
this.props.endSketchRefresh();
|
||||
}
|
||||
|
@ -331,6 +332,7 @@ class PreviewFrame extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<iframe
|
||||
id="canvas_frame"
|
||||
className="preview-frame"
|
||||
aria-label="sketch output"
|
||||
role="main"
|
||||
|
|
|
@ -17,11 +17,12 @@ class ShareModal extends React.PureComponent {
|
|||
</h3>
|
||||
<CopyableInput
|
||||
label="Embed"
|
||||
value={`<iframe src="${hostname}/embed/${projectId}"></iframe>`}
|
||||
value={`<iframe src="${hostname}/${ownerUsername}/embed/${projectId}"></iframe>`}
|
||||
/>
|
||||
<CopyableInput
|
||||
label="Fullscreen"
|
||||
value={`${hostname}/full/${projectId}`}
|
||||
hasPreviewLink
|
||||
value={`${hostname}/${ownerUsername}/full/${projectId}`}
|
||||
/>
|
||||
<CopyableInput
|
||||
label="Edit"
|
||||
|
|
|
@ -1,24 +1,38 @@
|
|||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import Helmet from 'react-helmet';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import PreviewFrame from '../components/PreviewFrame';
|
||||
import PreviewNav from '../../../components/PreviewNav';
|
||||
import { getHTMLFile, getJSFiles, getCSSFiles } from '../reducers/files';
|
||||
import * as ProjectActions from '../actions/project';
|
||||
|
||||
|
||||
class FullView extends React.Component {
|
||||
componentDidMount() {
|
||||
this.props.getProject(this.props.params.project_id);
|
||||
document.body.className = this.props.theme;
|
||||
}
|
||||
|
||||
componentWillUpdate(nextProps) {
|
||||
if (nextProps.theme !== this.props.theme) {
|
||||
document.body.className = nextProps.theme;
|
||||
}
|
||||
}
|
||||
|
||||
ident = () => {}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className="fullscreen-preview">
|
||||
<h1 className="fullscreen-preview__title">
|
||||
{this.props.project.name} {this.props.project.owner ? `by ${this.props.project.owner.username}` : ''}
|
||||
</h1>
|
||||
<div className="fullscreen-preview__frame-wrapper">
|
||||
<Helmet>
|
||||
<title>{this.props.project.name}</title>
|
||||
</Helmet>
|
||||
<PreviewNav
|
||||
owner={{ username: this.props.project.owner ? `${this.props.project.owner.username}` : '' }}
|
||||
project={{ name: this.props.project.name, id: this.props.params.project_id }}
|
||||
/>
|
||||
<div className="preview-frame-holder">
|
||||
<PreviewFrame
|
||||
htmlFile={this.props.htmlFile}
|
||||
jsFiles={this.props.jsFiles}
|
||||
|
@ -29,6 +43,16 @@ class FullView extends React.Component {
|
|||
}
|
||||
fullView
|
||||
isPlaying
|
||||
isAccessibleOutputPlaying={false}
|
||||
textOutput={false}
|
||||
gridOutput={false}
|
||||
soundOutput={false}
|
||||
dispatchConsoleEvent={this.ident}
|
||||
endSketchRefresh={this.ident}
|
||||
previewIsRefreshing={false}
|
||||
setBlobUrl={this.ident}
|
||||
stopSketch={this.ident}
|
||||
expandConsole={this.ident}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -37,6 +61,7 @@ class FullView extends React.Component {
|
|||
}
|
||||
|
||||
FullView.propTypes = {
|
||||
theme: PropTypes.string.isRequired,
|
||||
params: PropTypes.shape({
|
||||
project_id: PropTypes.string
|
||||
}).isRequired,
|
||||
|
@ -72,6 +97,7 @@ FullView.propTypes = {
|
|||
function mapStateToProps(state) {
|
||||
return {
|
||||
user: state.user,
|
||||
theme: state.preferences.theme,
|
||||
htmlFile: getHTMLFile(state.files),
|
||||
jsFiles: getJSFiles(state.files),
|
||||
cssFiles: getCSSFiles(state.files),
|
||||
|
|
|
@ -33,6 +33,7 @@ const routes = store => (
|
|||
component={NewPasswordView}
|
||||
/>
|
||||
<Route path="/projects/:project_id" component={IDEView} />
|
||||
<Route path="/:username/full/:project_id" component={FullView} />
|
||||
<Route path="/full/:project_id" component={FullView} />
|
||||
<Route path="/sketches" component={IDEView} />
|
||||
<Route path="/assets" component={IDEView} />
|
||||
|
|
|
@ -30,6 +30,7 @@ $themes: (
|
|||
toolbar-button-background-color: #f4f4f4,
|
||||
button-background-hover-color: $p5js-pink,
|
||||
button-background-active-color: #f10046,
|
||||
button-nav-inactive-color: #a0a0a0,
|
||||
button-hover-color: $white,
|
||||
button-active-color: $white,
|
||||
modal-background-color: #f4f4f4,
|
||||
|
@ -77,6 +78,7 @@ $themes: (
|
|||
toolbar-button-background-color: #424242,
|
||||
button-background-hover-color: $p5js-pink,
|
||||
button-background-active-color: #f10046,
|
||||
button-nav-inactive-color: #a0a0a0,
|
||||
button-hover-color: $white,
|
||||
button-active-color: $white,
|
||||
modal-background-color: #444,
|
||||
|
@ -122,6 +124,7 @@ $themes: (
|
|||
toolbar-button-background-color: #C1C1C1,
|
||||
button-background-hover-color: $yellow,
|
||||
button-background-active-color: #f10046,
|
||||
button-nav-inactive-color: #a0a0a0,
|
||||
button-hover-color: #333333,
|
||||
button-active-color: #333333,
|
||||
modal-background-color: #444,
|
||||
|
@ -171,4 +174,4 @@ $form-button-active-color: $white;
|
|||
$form-navigation-options-color: #999999;
|
||||
|
||||
$about-play-background-color: rgba(255, 255, 255, 0.7);
|
||||
$about-button-border-color: rgba(151, 151, 151, 0.7);
|
||||
$about-button-border-color: rgba(151, 151, 151, 0.7);
|
||||
|
|
|
@ -24,6 +24,11 @@
|
|||
}
|
||||
}
|
||||
|
||||
.copyable-input__label-container {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.copyable-input {
|
||||
padding-bottom: #{30 / $base-font-size}rem;
|
||||
display: flex;
|
||||
|
@ -50,4 +55,4 @@
|
|||
color: getThemifyVariable('button-background-hover-color');
|
||||
border-top-color: getThemifyVariable('button-background-hover-color');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
.nav {
|
||||
width: calc(100% - #{10 / $base-font-size}rem);
|
||||
height: #{42 / $base-font-size}rem;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
|
@ -225,4 +224,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,4 +46,4 @@
|
|||
.preview-frame__content {
|
||||
position: relative;
|
||||
flex: 1 1 0;
|
||||
}
|
||||
}
|
||||
|
|
14
client/styles/components/_preview-nav.scss
Normal file
14
client/styles/components/_preview-nav.scss
Normal file
|
@ -0,0 +1,14 @@
|
|||
.preview-nav__editor-svg {
|
||||
& svg {
|
||||
width: #{22 / $base-font-size}rem;
|
||||
height: #{22 / $base-font-size}rem;
|
||||
@include themify() {
|
||||
fill: getThemifyVariable('button-nav-inactive-color');
|
||||
}
|
||||
&:hover {
|
||||
@include themify() {
|
||||
fill: getThemifyVariable('button-background-hover-color');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -3,15 +3,7 @@
|
|||
width: 100%;
|
||||
height: 100%;
|
||||
flex-flow: column;
|
||||
@include themify() {
|
||||
background-color: getThemifyVariable('background-color');
|
||||
}
|
||||
}
|
||||
|
||||
.fullscreen-preview__title {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.fullscreen-preview__frame-wrapper {
|
||||
width: 100%;
|
||||
flex: 1 0 0%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
@import 'components/p5-contrast-codemirror-theme';
|
||||
@import 'components/editor';
|
||||
@import 'components/nav';
|
||||
@import 'components/preview-nav';
|
||||
@import 'components/toolbar';
|
||||
@import 'components/preferences';
|
||||
@import 'components/reset-password';
|
||||
|
|
|
@ -3,7 +3,7 @@ import * as EmbedController from '../controllers/embed.controller';
|
|||
|
||||
const router = new Router();
|
||||
|
||||
router.get('/:username/embed/:project_id', EmbedController.serveProject);
|
||||
router.get('/embed/:project_id', EmbedController.serveProject);
|
||||
router.get('/full/:project_id', EmbedController.serveProject);
|
||||
|
||||
export default router;
|
||||
|
|
|
@ -32,10 +32,17 @@ router.get('/:username/sketches/:project_id', (req, res) => {
|
|||
));
|
||||
});
|
||||
|
||||
router.get('/:username/full/:project_id', (req, res) => {
|
||||
projectForUserExists(req.params.username, req.params.project_id, exists => (
|
||||
exists ? res.send(renderIndex()) : get404Sketch(html => res.send(html))
|
||||
));
|
||||
});
|
||||
|
||||
// router.get('/full/:project_id', (req, res) => {
|
||||
// res.send(renderIndex());
|
||||
// });
|
||||
router.get('/full/:project_id', (req, res) => {
|
||||
projectExists(req.params.project_id, exists => (
|
||||
exists ? res.send(renderIndex()) : get404Sketch(html => res.send(html))
|
||||
));
|
||||
});
|
||||
|
||||
router.get('/login', (req, res) => {
|
||||
if (req.user) {
|
||||
|
|
Loading…
Reference in a new issue