109 lines
3.0 KiB
TypeScript
109 lines
3.0 KiB
TypeScript
import * as q from '../../../../../backend/src/Model'
|
||
import * as React from 'react'
|
||
import CodeDiff from '../../CodeDiff'
|
||
import { AppState } from '../../../reducers'
|
||
import { connect } from 'react-redux'
|
||
import { default as ReactResizeDetector } from 'react-resize-detector'
|
||
import { ValueRendererDisplayMode } from '../../../reducers/Settings'
|
||
|
||
interface Props {
|
||
message: q.Message
|
||
messageHistory: q.RingBuffer<q.Message>
|
||
compareWith?: q.Message
|
||
renderMode: ValueRendererDisplayMode
|
||
}
|
||
|
||
interface State {
|
||
width: number
|
||
}
|
||
|
||
class ValueRenderer extends React.Component<Props, State> {
|
||
constructor(props: Props) {
|
||
super(props)
|
||
this.state = { width: 0 }
|
||
}
|
||
|
||
public render() {
|
||
return (
|
||
<div style={{ padding: '8px 0px 8px 8px' }}>
|
||
<ReactResizeDetector handleWidth={true} onResize={this.updateWidth} />
|
||
{this.renderValue()}
|
||
</div>
|
||
)
|
||
}
|
||
|
||
public renderValue() {
|
||
const { message, messageHistory, compareWith, renderMode } = this.props
|
||
|
||
const previousMessages = messageHistory.toArray()
|
||
const previousMessage = previousMessages[previousMessages.length - 2]
|
||
let compareMessage = compareWith || previousMessage || message
|
||
if (renderMode === 'raw') {
|
||
compareMessage = message
|
||
}
|
||
|
||
let json
|
||
try {
|
||
json = JSON.parse(message.value)
|
||
} catch (error) {
|
||
return this.renderRawValue(message.value, compareMessage.value)
|
||
}
|
||
|
||
if (typeof json === 'string') {
|
||
return this.renderRawValue(message.value, compareMessage.value)
|
||
} else if (typeof json === 'number') {
|
||
return this.renderRawValue(message.value, compareMessage.value)
|
||
} else if (typeof json === 'boolean') {
|
||
return this.renderRawValue(message.value, compareMessage.value)
|
||
} else {
|
||
const current = this.messageToPrettyJson(message) || message.value
|
||
const compare = this.messageToPrettyJson(compareMessage) || compareMessage.value
|
||
const language = current && compare ? 'json' : undefined
|
||
|
||
return this.renderDiff(current, compare, language)
|
||
}
|
||
}
|
||
|
||
private renderDiff(current: string = '', previous: string = '', language?: 'json') {
|
||
return (
|
||
<CodeDiff
|
||
previous={previous}
|
||
current={current}
|
||
language={language}
|
||
nameOfCompareMessage={this.props.compareWith ? 'selected' : 'previous'}
|
||
/>
|
||
)
|
||
}
|
||
|
||
private messageToPrettyJson(message?: q.Message): string | undefined {
|
||
if (!message || !message.value) {
|
||
return undefined
|
||
}
|
||
|
||
try {
|
||
const json = JSON.parse(message.value)
|
||
return JSON.stringify(json, undefined, ' ')
|
||
} catch {
|
||
return undefined
|
||
}
|
||
}
|
||
|
||
private updateWidth = (width: number) => {
|
||
if (width !== this.state.width) {
|
||
this.setState({ width })
|
||
}
|
||
}
|
||
|
||
private renderRawValue(value: string, compare: string) {
|
||
return this.renderDiff(value, compare)
|
||
}
|
||
}
|
||
|
||
const mapStateToProps = (state: AppState) => {
|
||
return {
|
||
renderMode: state.settings.valueRendererDisplayMode,
|
||
}
|
||
}
|
||
|
||
export default connect(mapStateToProps)(ValueRenderer)
|