Skip to content

Commit d912502

Browse files
committed
Fix full view by waiting until frame registers
1 parent 2e9878a commit d912502

File tree

4 files changed

+99
-53
lines changed

4 files changed

+99
-53
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// https://overreacted.io/making-setinterval-declarative-with-react-hooks/
2+
import { useState, useEffect, useRef } from 'react';
3+
4+
export default function useInterval(callback, delay) {
5+
const savedCallback = useRef();
6+
const [intervalId, setIntervalId] = useState();
7+
8+
// Remember the latest callback.
9+
useEffect(() => {
10+
savedCallback.current = callback;
11+
}, [callback]);
12+
13+
// Set up the interval.
14+
useEffect(() => {
15+
function tick() {
16+
savedCallback.current();
17+
}
18+
if (delay !== null) {
19+
const id = setInterval(tick, delay);
20+
setIntervalId(id);
21+
return () => clearInterval(id);
22+
}
23+
return null;
24+
}, [delay]);
25+
return () => clearInterval(intervalId);
26+
}

client/modules/IDE/pages/FullView.jsx

Lines changed: 57 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,75 @@
11
import PropTypes from 'prop-types';
2-
import React from 'react';
2+
import React, { useEffect, useState } from 'react';
33
import Helmet from 'react-helmet';
4-
import { bindActionCreators } from 'redux';
5-
import { connect } from 'react-redux';
4+
import { useDispatch, useSelector } from 'react-redux';
65
import PreviewFrame from '../components/PreviewFrame';
76
import PreviewNav from '../../../components/PreviewNav';
87
import { getProject } from '../actions/project';
98
import { startSketch } from '../actions/ide';
9+
import {
10+
listen,
11+
dispatchMessage,
12+
MessageTypes
13+
} from '../../../utils/dispatcher';
14+
import useInterval from '../hooks/useInterval';
1015

11-
class FullView extends React.Component {
12-
componentDidMount() {
13-
this.props
14-
.getProject(this.props.params.project_id, this.props.params.username)
15-
.then(this.props.startSketch);
16+
function FullView(props) {
17+
const dispatch = useDispatch();
18+
const project = useSelector((state) => state.project);
19+
20+
useEffect(() => {
21+
dispatch(getProject(props.params.project_id, props.params.username));
22+
}, []);
23+
24+
// send register event until iframe is loaded and sends a message back.
25+
const [isRendered, setIsRendered] = useState(false);
26+
const clearInterval = useInterval(() => {
27+
dispatchMessage({ type: MessageTypes.REGISTER });
28+
}, 100);
29+
if (isRendered) {
30+
clearInterval();
1631
}
1732

18-
render() {
19-
return (
20-
<div className="fullscreen-preview">
21-
<Helmet>
22-
<title>{this.props.project.name}</title>
23-
</Helmet>
24-
<PreviewNav
25-
owner={{
26-
username: this.props.project.owner
27-
? `${this.props.project.owner.username}`
28-
: ''
29-
}}
30-
project={{
31-
name: this.props.project.name,
32-
id: this.props.params.project_id
33-
}}
34-
/>
35-
<main className="preview-frame-holder">
36-
<PreviewFrame fullView />
37-
</main>
38-
</div>
39-
);
33+
function handleMessageEvent(message) {
34+
if (message.type === MessageTypes.REGISTER) {
35+
if (!isRendered) {
36+
setIsRendered(true);
37+
dispatch(startSketch());
38+
}
39+
}
4040
}
41+
useEffect(() => {
42+
const unsubscribe = listen(handleMessageEvent);
43+
return function cleanup() {
44+
unsubscribe();
45+
};
46+
}, []);
47+
return (
48+
<div className="fullscreen-preview">
49+
<Helmet>
50+
<title>{project.name}</title>
51+
</Helmet>
52+
<PreviewNav
53+
owner={{
54+
username: project.owner ? `${project.owner.username}` : ''
55+
}}
56+
project={{
57+
name: project.name,
58+
id: props.params.project_id
59+
}}
60+
/>
61+
<main className="preview-frame-holder">
62+
<PreviewFrame fullView />
63+
</main>
64+
</div>
65+
);
4166
}
4267

4368
FullView.propTypes = {
4469
params: PropTypes.shape({
4570
project_id: PropTypes.string,
4671
username: PropTypes.string
47-
}).isRequired,
48-
project: PropTypes.shape({
49-
name: PropTypes.string,
50-
owner: PropTypes.shape({
51-
username: PropTypes.string
52-
})
53-
}).isRequired,
54-
getProject: PropTypes.func.isRequired,
55-
startSketch: PropTypes.func.isRequired
72+
}).isRequired
5673
};
5774

58-
function mapStateToProps(state) {
59-
return {
60-
project: state.project
61-
};
62-
}
63-
64-
function mapDispatchToProps(dispatch) {
65-
return bindActionCreators({ getProject, startSketch }, dispatch);
66-
}
67-
68-
export default connect(mapStateToProps, mapDispatchToProps)(FullView);
75+
export default FullView;

client/modules/Preview/previewIndex.jsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,15 @@ import React, { useReducer, useState, useEffect } from 'react';
22
import { render } from 'react-dom';
33
import { hot } from 'react-hot-loader/root';
44
import { createGlobalStyle } from 'styled-components';
5-
import { listen, MessageTypes } from '../../utils/dispatcher';
5+
import {
6+
registerFrame,
7+
listen,
8+
MessageTypes,
9+
dispatchMessage
10+
} from '../../utils/dispatcher';
611
import { filesReducer, initialState, setFiles } from './filesReducer';
712
import EmbedFrame from './EmbedFrame';
13+
import getConfig from '../../utils/getConfig';
814

915
const GlobalStyle = createGlobalStyle`
1016
body {
@@ -15,6 +21,8 @@ const GlobalStyle = createGlobalStyle`
1521
const App = () => {
1622
const [state, dispatch] = useReducer(filesReducer, [], initialState);
1723
const [isPlaying, setIsPlaying] = useState(false);
24+
registerFrame(window.parent, getConfig('EDITOR_URL'));
25+
1826
function handleMessageEvent(message) {
1927
const { type, payload } = message;
2028
switch (type) {
@@ -27,10 +35,14 @@ const App = () => {
2735
case MessageTypes.STOP:
2836
setIsPlaying(false);
2937
break;
38+
case MessageTypes.REGISTER:
39+
dispatchMessage({ type: MessageTypes.REGISTER });
40+
break;
3041
default:
3142
break;
3243
}
3344
}
45+
3446
useEffect(() => {
3547
const unsubscribe = listen(handleMessageEvent);
3648
return function cleanup() {

client/utils/dispatcher.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ let origin = null;
99
export const MessageTypes = {
1010
START: 'START',
1111
STOP: 'STOP',
12-
FILES: 'FILES'
12+
FILES: 'FILES',
13+
REGISTER: 'REGISTER'
1314
};
1415

1516
// could instead register multiple frames here
@@ -36,7 +37,7 @@ function notifyFrame(message) {
3637
export function dispatchMessage(message) {
3738
if (!message) return;
3839

39-
notifyListener(message);
40+
// notifyListener(message);
4041
notifyFrame(message);
4142
}
4243

0 commit comments

Comments
 (0)