Work in progress
This commit is contained in:
@@ -118,9 +118,7 @@ class Settings extends React.Component<Props, {}> {
|
|||||||
<Select
|
<Select
|
||||||
value={nodeOrder}
|
value={nodeOrder}
|
||||||
onChange={ (e: React.ChangeEvent<HTMLSelectElement>) => {
|
onChange={ (e: React.ChangeEvent<HTMLSelectElement>) => {
|
||||||
window.requestAnimationFrame(() => {
|
|
||||||
actions.setNodeOrder(e.target.value)
|
actions.setNodeOrder(e.target.value)
|
||||||
})
|
|
||||||
}}
|
}}
|
||||||
input={<Input name="node-order" id="node-order-label-placeholder" />}
|
input={<Input name="node-order" id="node-order-label-placeholder" />}
|
||||||
displayEmpty={true}
|
displayEmpty={true}
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ class Tree extends React.Component<Props, TreeState> {
|
|||||||
|
|
||||||
this.updateTimer = setTimeout(() => {
|
this.updateTimer = setTimeout(() => {
|
||||||
window.requestAnimationFrame(() => {
|
window.requestAnimationFrame(() => {
|
||||||
console.log('doRender')
|
|
||||||
this.lastUpdate = performance.now()
|
this.lastUpdate = performance.now()
|
||||||
this.updateTimer && clearTimeout(this.updateTimer)
|
this.updateTimer && clearTimeout(this.updateTimer)
|
||||||
this.updateTimer = undefined
|
this.updateTimer = undefined
|
||||||
@@ -97,12 +96,19 @@ class Tree extends React.Component<Props, TreeState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
|
console.log('render called')
|
||||||
|
|
||||||
const style: React.CSSProperties = {
|
const style: React.CSSProperties = {
|
||||||
lineHeight: '1.1',
|
lineHeight: '1.1',
|
||||||
cursor: 'default',
|
cursor: 'default',
|
||||||
}
|
}
|
||||||
|
|
||||||
return <Typography style={style}>
|
const performanceCallback = (ms: number) => {
|
||||||
|
average.push(Date.now(), ms)
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Typography style={style}>
|
||||||
<TreeNode
|
<TreeNode
|
||||||
animateChages={true}
|
animateChages={true}
|
||||||
autoExpandLimit={this.props.autoExpandLimit}
|
autoExpandLimit={this.props.autoExpandLimit}
|
||||||
@@ -112,11 +118,11 @@ class Tree extends React.Component<Props, TreeState> {
|
|||||||
name="/"
|
name="/"
|
||||||
collapsed={false}
|
collapsed={false}
|
||||||
key="rootNode"
|
key="rootNode"
|
||||||
performanceCallback={(ms: number) => {
|
lastUpdate={0}
|
||||||
average.push(Date.now(), ms)
|
performanceCallback={this.performanceCallback}
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
</Typography>
|
</Typography>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ const styles = (theme: Theme) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
lastUpdate: number
|
||||||
animateChages: boolean
|
animateChages: boolean
|
||||||
isRoot?: boolean
|
isRoot?: boolean
|
||||||
treeNode: q.TreeNode
|
treeNode: q.TreeNode
|
||||||
@@ -48,6 +49,7 @@ class TreeNode extends React.Component<Props, State> {
|
|||||||
private dirtySubnodes: boolean = true
|
private dirtySubnodes: boolean = true
|
||||||
private dirtyEdges: boolean = true
|
private dirtyEdges: boolean = true
|
||||||
private dirtyMessage: boolean = true
|
private dirtyMessage: boolean = true
|
||||||
|
private animationDirty: boolean = false
|
||||||
|
|
||||||
private cssAnimationWasSetAt?: number
|
private cssAnimationWasSetAt?: number
|
||||||
|
|
||||||
@@ -103,6 +105,7 @@ class TreeNode extends React.Component<Props, State> {
|
|||||||
|| this.dirtyEdges
|
|| this.dirtyEdges
|
||||||
|| this.dirtyMessage
|
|| this.dirtyMessage
|
||||||
|| this.dirtySubnodes
|
|| this.dirtySubnodes
|
||||||
|
|| this.animationDirty
|
||||||
|| shouldRenderToRemoveCssAnimation
|
|| shouldRenderToRemoveCssAnimation
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +114,12 @@ class TreeNode extends React.Component<Props, State> {
|
|||||||
const renderTime = performance.now() - this.willUpdateTime
|
const renderTime = performance.now() - this.willUpdateTime
|
||||||
this.props.performanceCallback(renderTime)
|
this.props.performanceCallback(renderTime)
|
||||||
}
|
}
|
||||||
|
// setTimeout(() => {
|
||||||
|
// this.setState(this.state)
|
||||||
|
// }, 500)
|
||||||
|
// this.addCssAnimation()
|
||||||
|
// setTimeout(this.removeCssAnimation, 500)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUpdate() {
|
public componentWillUpdate() {
|
||||||
@@ -131,18 +140,36 @@ class TreeNode extends React.Component<Props, State> {
|
|||||||
return this.props.treeNode.edgeCount() > this.props.autoExpandLimit
|
return this.props.treeNode.edgeCount() > this.props.autoExpandLimit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// private addCssAnimation = () => {
|
||||||
|
// const element = this.titleRef.current
|
||||||
|
// if ((this.dirtyEdges || this.dirtyMessage || this.dirtySubnodes) && element && isElementInViewport(element)) {
|
||||||
|
// element.style.animation = 'example 0.5s'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// private removeCssAnimation = () => {
|
||||||
|
// const element = this.titleRef.current
|
||||||
|
// if (element && element.style.animation) {
|
||||||
|
// element.style.animation = ''
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const animationStyle = this.indicatingChangeAnimationStyle()
|
|
||||||
const { classes } = this.props
|
const { classes } = this.props
|
||||||
|
const isDirty = this.dirtyEdges || this.dirtyMessage || this.dirtySubnodes
|
||||||
this.dirtyEdges = this.dirtyMessage = this.dirtySubnodes = false
|
this.dirtyEdges = this.dirtyMessage = this.dirtySubnodes = false
|
||||||
|
|
||||||
|
const shouldStartAnimation = (isDirty && !this.animationDirty) && !this.props.isRoot
|
||||||
|
const animation = shouldStartAnimation ? { animation: 'example 0.5s' } : {}
|
||||||
|
this.animationDirty = shouldStartAnimation
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={this.props.treeNode.hash()}
|
key={this.props.treeNode.hash()}
|
||||||
className={`${classes.node} ${!this.props.isRoot ? classes.hover : ''}`}
|
className={`${classes.node} ${!this.props.isRoot ? classes.hover : ''}`}
|
||||||
onClick={this.didClickNode}
|
onClick={this.didClickNode}
|
||||||
>
|
>
|
||||||
<span ref={this.titleRef} style={animationStyle}>
|
<span ref={this.titleRef} style={animation}>
|
||||||
<TreeNodeTitle
|
<TreeNodeTitle
|
||||||
collapsed={this.collapsed()}
|
collapsed={this.collapsed()}
|
||||||
treeNode={this.props.treeNode}
|
treeNode={this.props.treeNode}
|
||||||
@@ -169,29 +196,10 @@ class TreeNode extends React.Component<Props, State> {
|
|||||||
autoExpandLimit={this.props.autoExpandLimit}
|
autoExpandLimit={this.props.autoExpandLimit}
|
||||||
didSelectNode={this.props.didSelectNode}
|
didSelectNode={this.props.didSelectNode}
|
||||||
treeNode={this.props.treeNode}
|
treeNode={this.props.treeNode}
|
||||||
|
lastUpdate={this.props.treeNode.lastUpdate}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private indicatingChangeAnimationStyle(): React.CSSProperties {
|
|
||||||
if (this.props.isRoot) {
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
if (this.cssAnimationWasSetAt && (performance.now() - this.cssAnimationWasSetAt) > 500) {
|
|
||||||
this.cssAnimationWasSetAt = undefined
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
const isInViewPort = this.titleRef.current && isElementInViewport(this.titleRef.current)
|
|
||||||
const isDirty = this.dirtyMessage || this.dirtyEdges
|
|
||||||
if (this.props.animateChages && isDirty && isInViewPort) {
|
|
||||||
if (!this.cssAnimationWasSetAt) {
|
|
||||||
this.cssAnimationWasSetAt = performance.now()
|
|
||||||
}
|
|
||||||
return { animation: 'example 0.5s' }
|
|
||||||
}
|
|
||||||
|
|
||||||
return {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default withStyles(styles)(TreeNode)
|
export default withStyles(styles)(TreeNode)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { AppState, NodeOrder } from '../../reducers'
|
|||||||
import TreeNode from './TreeNode'
|
import TreeNode from './TreeNode'
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
|
lastUpdate: number
|
||||||
nodeOrder?: NodeOrder
|
nodeOrder?: NodeOrder
|
||||||
animateChanges: boolean
|
animateChanges: boolean
|
||||||
treeNode: q.TreeNode
|
treeNode: q.TreeNode
|
||||||
@@ -54,6 +55,7 @@ class TreeNodeSubnodes extends React.Component<Props, {}> {
|
|||||||
treeNode={node}
|
treeNode={node}
|
||||||
didSelectNode={this.props.didSelectNode}
|
didSelectNode={this.props.didSelectNode}
|
||||||
autoExpandLimit={this.props.autoExpandLimit}
|
autoExpandLimit={this.props.autoExpandLimit}
|
||||||
|
lastUpdate={node.lastUpdate}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ export class TreeNode {
|
|||||||
public edges: {[s: string]: Edge} = {}
|
public edges: {[s: string]: Edge} = {}
|
||||||
public collapsed = false
|
public collapsed = false
|
||||||
public messages: number = 0
|
public messages: number = 0
|
||||||
|
public lastUpdate: number = Date.now()
|
||||||
|
|
||||||
public onMerge = new EventDispatcher<void, TreeNode>(this)
|
public onMerge = new EventDispatcher<void, TreeNode>(this)
|
||||||
public onEdgesChange = new EventDispatcher<void, TreeNode>(this)
|
public onEdgesChange = new EventDispatcher<void, TreeNode>(this)
|
||||||
@@ -24,6 +25,13 @@ export class TreeNode {
|
|||||||
this.onMerge.subscribe(() => {
|
this.onMerge.subscribe(() => {
|
||||||
this.cachedLeafes = undefined
|
this.cachedLeafes = undefined
|
||||||
this.cachedLeafMessageCount = undefined
|
this.cachedLeafMessageCount = undefined
|
||||||
|
this.lastUpdate = Date.now()
|
||||||
|
})
|
||||||
|
this.onEdgesChange.subscribe(() => {
|
||||||
|
this.lastUpdate = Date.now()
|
||||||
|
})
|
||||||
|
this.onMessage.subscribe(() => {
|
||||||
|
this.lastUpdate = Date.now()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user