-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
118 lines (101 loc) · 2.65 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
import { _set } from './import.js'
import createHistory from './history.js'
import getDimensions from './get-dimensions.js'
import getViews from './get-views.js'
import normaliseUri from './normalise-uri/index.js'
import onDimensionsChange from './on-dimensions-change.js'
import parseMountedApps from './parse-mounted-apps.js'
import React, { Component, PropTypes } from 'react'
import RuntimeReplace from './runtime-replace.js'
const SCHEMA = /^(.+?:\/\/).+/i
export default class Teleports extends Component {
constructor(props) {
super(props)
const { height, width } = getDimensions()
onDimensionsChange(this.onDimensionsChange)
_set(props.apps)
this.history = createHistory(props.uri)
this.history.onChange(this.onUriChange)
this.state = {
height,
Runtime: RuntimeReplace,
uri: '',
views: [],
width
}
this.navigate(props.uri, true)
}
componentDidUpdate(prevProps, prevState) {
const { state } = this
if (state.uri !== prevState.uri) {
if (this.uriChangedOutside) {
this.uriChangedOutside = false
} else {
this.history.push(state.uri)
}
}
}
getChildContext = () => ({
navigate: this.navigate
})
navigate = (to, raw = false) => {
const { state } = this
// TODO normalise uri
// https://github.com/UXtemple/panels/blob/master/utils/normalise-uri/index.js
const uri = normaliseUri(raw ? to : `${state.uri}${to}`)
// find out which apps are mounted now
const mounted = this.mounted = parseMountedApps(uri)
const schema = uri.match(SCHEMA)[1]
// gather their views
getViews({ mounted, schema, uri }).then(({ Runtime, views }) => {
this.setState({
uri,
Runtime,
views
})
})
}
onDimensionsChange = ({ height, width }) => {
this.setState({
height,
width
})
}
onUriChange = uri => {
this.uriChangedOutside = true
this.navigate(this.history.getUri(), true)
}
render() {
const { height, Runtime, views, width } = this.state
return (
<Runtime
height={height}
views={views}
width={width}
/>
)
}
}
Teleports.childContextTypes = {
navigate: PropTypes.func.isRequired
}
Teleports.defaultProps = {
apps: {},
Runtime: RuntimeReplace,
uri: '',
views: []
}
Teleports.propTypes = {
// TODO app shape
apps: PropTypes.shape({
}).isRequired,
Runtime: PropTypes.func.isRequired,
uri: PropTypes.string.isRequired,
views: PropTypes.arrayOf(
PropTypes.shape({
component: PropTypes.func.isRequired,
path: PropTypes.string.isRequired,
props: PropTypes.object
})
).isRequired
}