Fix emitter leaks, style, tree swaps

This commit is contained in:
Thomas Nordquist
2019-01-22 12:17:59 +01:00
parent 221abd8c48
commit d4ce58a8ec
22 changed files with 411 additions and 164 deletions

View File

@@ -1,8 +1,6 @@
import * as React from 'react'
import * as q from '../../../../backend/src/Model'
import { makeConnectionMessageEvent, rendererEvents, MqttMessage } from '../../../../events'
import { AppState } from '../../reducers'
import TreeNode from './TreeNode'
import { connect } from 'react-redux'
@@ -84,11 +82,11 @@ class Tree extends React.Component<Props, {}> {
lineHeight: '1.1',
cursor: 'default',
}
const key = `rootNode-${filter}`
return (
<div style={style}>
<TreeNode
key={key}
key={tree.hash()}
animateChages={true}
isRoot={true}
treeNode={tree}

View File

@@ -67,8 +67,8 @@ class TreeNode extends React.Component<Props, State> {
private cssAnimationWasSetAt?: number
private willUpdateTime: number = performance.now()
private titleRef = React.createRef<HTMLDivElement>()
private topicSelectRef = React.createRef<HTMLDivElement>()
private titleRef?: React.RefObject<HTMLDivElement> = React.createRef<HTMLDivElement>()
private topicSelectRef?: React.RefObject<HTMLDivElement> = React.createRef<HTMLDivElement>()
private subnodesDidchange = () => {
this.dirtySubnodes = true
@@ -90,18 +90,52 @@ class TreeNode extends React.Component<Props, State> {
}
}
private writeStats(what: string) {
const w: any = window
if (!w.stats) {
w.stats = {}
}
if (!w.stats[what]) {
w.stats[what] = 0
}
w.stats[what] += 1
}
public componentDidMount() {
const { treeNode } = this.props
this.addSubscriber(treeNode)
}
private addSubscriber(treeNode: q.TreeNode) {
this.writeStats('subscribe')
treeNode.onMerge.subscribe(this.subnodesDidchange)
treeNode.onEdgesChange.subscribe(this.edgesDidChange)
treeNode.onMessage.subscribe(this.messageDidChange)
}
private removeSubscriber(treeNode: q.TreeNode) {
this.writeStats('unsubscribe')
treeNode.onMerge.unsubscribe(this.subnodesDidchange)
treeNode.onEdgesChange.unsubscribe(this.edgesDidChange)
treeNode.onMessage.unsubscribe(this.messageDidChange)
}
public componentWillReceiveProps(nextProps: Props) {
if (nextProps.treeNode !== this.props.treeNode) {
this.removeSubscriber(this.props.treeNode)
this.addSubscriber(nextProps.treeNode)
}
}
public componentWillUnmount() {
this.writeStats('unsubscribe')
const { treeNode } = this.props
treeNode.onMerge.unsubscribe(this.subnodesDidchange)
treeNode.onEdgesChange.unsubscribe(this.edgesDidChange)
treeNode.onMessage.unsubscribe(this.messageDidChange)
this.topicSelectRef = undefined
this.titleRef = undefined
}
private stateHasChanged(newState: State) {
@@ -189,20 +223,20 @@ class TreeNode extends React.Component<Props, State> {
private mouseOver = (event: React.MouseEvent) => {
event.stopPropagation()
if (this.topicSelectRef.current) {
if (this.topicSelectRef && this.topicSelectRef.current) {
this.topicSelectRef.current.style.opacity = '1'
}
}
private mouseOut = (event: React.MouseEvent) => {
event.stopPropagation()
if (this.topicSelectRef.current) {
if (this.topicSelectRef && this.topicSelectRef.current) {
this.topicSelectRef.current.style.opacity = '0'
}
}
private didSelectNode = (event: React.MouseEvent) => {
event.stopPropagation()
if (this.topicSelectRef.current) {
if (this.topicSelectRef && this.topicSelectRef.current) {
this.topicSelectRef.current.style.opacity = '1'
}
this.props.actions.selectTopic(this.props.treeNode)

View File

@@ -2,7 +2,6 @@ import * as React from 'react'
import * as q from '../../../../backend/src/Model'
import { AppState } from '../../reducers'
import { Theme, withTheme } from '@material-ui/core/styles'
import TreeNode from './TreeNode'
import { connect } from 'react-redux'
@@ -14,9 +13,9 @@ export interface Props {
animateChanges: boolean
treeNode: q.TreeNode
autoExpandLimit: number
filter?: string
collapsed?: boolean | undefined
didSelectNode?: (node: q.TreeNode) => void
theme: Theme
}
interface State {
@@ -76,15 +75,15 @@ class TreeNodeSubnodes extends React.Component<Props, State> {
const nodes = this.sortedNodes().slice(0, this.state.alreadyAdded)
const listItems = nodes.map(node => (
<div key={node.hash()}>
<TreeNode
animateChages={this.props.animateChanges}
treeNode={node}
lastUpdate={node.lastUpdate}
style={listItemStyle}
/>
</div>
))
<div key={`${node.hash()}-${this.props.filter}`}>
<TreeNode
animateChages={this.props.animateChanges}
treeNode={node}
lastUpdate={node.lastUpdate}
style={listItemStyle}
/>
</div>
))
return (
<span style={{ display: 'block', clear: 'both' }} >
@@ -97,7 +96,8 @@ class TreeNodeSubnodes extends React.Component<Props, State> {
const mapStateToProps = (state: AppState) => {
return {
topicOrder: state.settings.topicOrder,
filter: state.tree.filter,
}
}
export default withTheme()(connect(mapStateToProps)(TreeNodeSubnodes))
export default connect(mapStateToProps)(TreeNodeSubnodes)

View File

@@ -3,23 +3,20 @@ import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { treeActions } from '../../actions'
import * as q from '../../../../backend/src/Model'
import { withTheme, Theme } from '@material-ui/core/styles'
export interface TreeNodeProps extends React.HTMLAttributes<HTMLElement> {
treeNode: q.TreeNode
actions: any
name?: string | undefined
collapsed?: boolean | undefined
theme: Theme
lastUpdate: number
}
class TreeNodeTitle extends React.Component<TreeNodeProps, {}> {
private getStyles() {
const { theme } = this.props
return {
collapsedSubnodes: {
color: theme.palette.text.secondary,
color: 'white', // theme.palette.text.secondary,
},
container: {
display: 'block',
@@ -97,4 +94,4 @@ const mapDispatchToProps = (dispatch: any) => {
}
}
export default withTheme()(connect(null, mapDispatchToProps)(TreeNodeTitle))
export default connect(null, mapDispatchToProps)(TreeNodeTitle)