Add quick preview switch
This commit is contained in:
@@ -1,6 +1,14 @@
|
|||||||
import * as React from 'react'
|
import * as React from 'react'
|
||||||
|
import BrokerStatistics from './BrokerStatistics'
|
||||||
|
import ChevronRight from '@material-ui/icons/ChevronRight'
|
||||||
import { AppState } from '../reducers'
|
import { AppState } from '../reducers'
|
||||||
|
import { bindActionCreators } from 'redux'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import { settingsActions } from '../actions'
|
||||||
|
import { shell } from 'electron'
|
||||||
|
import { StyleRulesCallback, withStyles } from '@material-ui/core/styles'
|
||||||
|
import { TopicOrder } from '../reducers/Settings'
|
||||||
|
|
||||||
import {
|
import {
|
||||||
Divider,
|
Divider,
|
||||||
Drawer,
|
Drawer,
|
||||||
@@ -13,15 +21,7 @@ import {
|
|||||||
Switch,
|
Switch,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@material-ui/core'
|
} from '@material-ui/core'
|
||||||
import { StyleRulesCallback, withStyles } from '@material-ui/core/styles'
|
const sha1 = require('sha1')
|
||||||
|
|
||||||
import ChevronRight from '@material-ui/icons/ChevronRight'
|
|
||||||
import { bindActionCreators } from 'redux'
|
|
||||||
import { connect } from 'react-redux'
|
|
||||||
import { settingsActions } from '../actions'
|
|
||||||
import { TopicOrder } from '../reducers/Settings'
|
|
||||||
import BrokerStatistics from './BrokerStatistics'
|
|
||||||
import { shell } from 'electron';
|
|
||||||
|
|
||||||
export const autoExpandLimitSet = [{
|
export const autoExpandLimitSet = [{
|
||||||
limit: 0,
|
limit: 0,
|
||||||
@@ -44,6 +44,7 @@ const styles: StyleRulesCallback = theme => ({
|
|||||||
drawer: {
|
drawer: {
|
||||||
backgroundColor: theme.palette.background.default,
|
backgroundColor: theme.palette.background.default,
|
||||||
flexShrink: 0,
|
flexShrink: 0,
|
||||||
|
userSelect: 'none' as 'none',
|
||||||
},
|
},
|
||||||
paper: {
|
paper: {
|
||||||
width: '300px',
|
width: '300px',
|
||||||
@@ -62,16 +63,20 @@ const styles: StyleRulesCallback = theme => ({
|
|||||||
color: theme.palette.text.hint,
|
color: theme.palette.text.hint,
|
||||||
cursor: 'pointer' as 'pointer',
|
cursor: 'pointer' as 'pointer',
|
||||||
},
|
},
|
||||||
|
switchBase: {
|
||||||
|
height: theme.spacing(4),
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
|
actions: typeof settingsActions
|
||||||
autoExpandLimit: number
|
autoExpandLimit: number
|
||||||
|
classes: any
|
||||||
highlightTopicUpdates: boolean
|
highlightTopicUpdates: boolean
|
||||||
visible: boolean
|
selectTopicWithMouseOver: boolean
|
||||||
store?: any
|
store?: any
|
||||||
topicOrder: TopicOrder
|
topicOrder: TopicOrder
|
||||||
classes: any
|
visible: boolean
|
||||||
actions: typeof settingsActions
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Settings extends React.Component<Props, {}> {
|
class Settings extends React.Component<Props, {}> {
|
||||||
@@ -105,7 +110,8 @@ class Settings extends React.Component<Props, {}> {
|
|||||||
|
|
||||||
{this.renderAutoExpand()}
|
{this.renderAutoExpand()}
|
||||||
{this.renderNodeOrder()}
|
{this.renderNodeOrder()}
|
||||||
{this.renderhighlightTopicUpdates()}
|
{this.renderHighlightTopicUpdates()}
|
||||||
|
{this.selectTopicsOnMouseOver()}
|
||||||
</div>
|
</div>
|
||||||
<Tooltip placement="top" title="App Author">
|
<Tooltip placement="top" title="App Author">
|
||||||
<Typography className={classes.author} onClick={this.openGithubPage}>
|
<Typography className={classes.author} onClick={this.openGithubPage}>
|
||||||
@@ -121,22 +127,52 @@ class Settings extends React.Component<Props, {}> {
|
|||||||
shell.openExternal('https://github.com/thomasnordquist')
|
shell.openExternal('https://github.com/thomasnordquist')
|
||||||
}
|
}
|
||||||
|
|
||||||
private renderhighlightTopicUpdates() {
|
private renderHighlightTopicUpdates() {
|
||||||
const { highlightTopicUpdates, actions } = this.props
|
const { highlightTopicUpdates, actions } = this.props
|
||||||
|
|
||||||
|
return this.renderSwitch('Show Activity', highlightTopicUpdates, actions.togglehighlightTopicUpdates, 'Topics blink when a new message arrives')
|
||||||
|
}
|
||||||
|
|
||||||
|
private renderSwitch(title: string, checked: boolean, action: any, tooltip: string) {
|
||||||
|
const { classes } = this.props
|
||||||
|
|
||||||
|
const clickHandler = (e: React.MouseEvent) => {
|
||||||
|
e.stopPropagation()
|
||||||
|
e.preventDefault()
|
||||||
|
action()
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ padding: '8px', display: 'flex' }}>
|
<div style={{ padding: '8px', display: 'flex' }}>
|
||||||
<InputLabel htmlFor="toggle-highlight-activity" style={{ flex: '1', marginTop: '8px' }}>Show Activity</InputLabel>
|
<Tooltip title={tooltip}>
|
||||||
<Switch
|
<InputLabel
|
||||||
name="toggle-highlight-activity"
|
htmlFor={`toggle-${sha1(title)}`}
|
||||||
checked={highlightTopicUpdates}
|
onClick={clickHandler}
|
||||||
onChange={actions.togglehighlightTopicUpdates}
|
style={{ flex: '1', paddingTop: '8px' }}
|
||||||
color="primary"
|
>
|
||||||
/>
|
{title}
|
||||||
|
</InputLabel>
|
||||||
|
</Tooltip>
|
||||||
|
<Tooltip title={tooltip}>
|
||||||
|
<Switch
|
||||||
|
name={`toggle-${sha1(title)}`}
|
||||||
|
checked={checked}
|
||||||
|
onChange={action}
|
||||||
|
color="primary"
|
||||||
|
classes={{ switchBase: classes.switchBase }}
|
||||||
|
/>
|
||||||
|
</Tooltip>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private selectTopicsOnMouseOver() {
|
||||||
|
const { actions, selectTopicWithMouseOver } = this.props
|
||||||
|
const toggle = () => actions.selectTopicWithMouseOver(!selectTopicWithMouseOver)
|
||||||
|
|
||||||
|
return this.renderSwitch('Quick Preview', selectTopicWithMouseOver, toggle, 'Select topics on mouse over')
|
||||||
|
}
|
||||||
|
|
||||||
private renderAutoExpand() {
|
private renderAutoExpand() {
|
||||||
const { classes, autoExpandLimit } = this.props
|
const { classes, autoExpandLimit } = this.props
|
||||||
|
|
||||||
@@ -196,6 +232,7 @@ const mapStateToProps = (state: AppState) => {
|
|||||||
topicOrder: state.settings.topicOrder,
|
topicOrder: state.settings.topicOrder,
|
||||||
visible: state.settings.visible,
|
visible: state.settings.visible,
|
||||||
highlightTopicUpdates: state.settings.highlightTopicUpdates,
|
highlightTopicUpdates: state.settings.highlightTopicUpdates,
|
||||||
|
selectTopicWithMouseOver: state.settings.selectTopicWithMouseOver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import Copy from '../Copy'
|
|||||||
import CustomIconButton from '../CustomIconButton'
|
import CustomIconButton from '../CustomIconButton'
|
||||||
import DateFormatter from '../helper/DateFormatter'
|
import DateFormatter from '../helper/DateFormatter'
|
||||||
import Delete from '@material-ui/icons/Delete'
|
import Delete from '@material-ui/icons/Delete'
|
||||||
import DeleteForever from '@material-ui/icons/DeleteForever'
|
|
||||||
import ExpandMore from '@material-ui/icons/ExpandMore'
|
import ExpandMore from '@material-ui/icons/ExpandMore'
|
||||||
import MessageHistory from './MessageHistory'
|
import MessageHistory from './MessageHistory'
|
||||||
import NodeStats from './NodeStats'
|
import NodeStats from './NodeStats'
|
||||||
@@ -99,7 +98,7 @@ class Sidebar extends React.Component<Props, State> {
|
|||||||
private detailsStyle = { padding: '0px 16px 8px 8px', display: 'block' }
|
private detailsStyle = { padding: '0px 16px 8px 8px', display: 'block' }
|
||||||
|
|
||||||
private renderTopicDeleteButton() {
|
private renderTopicDeleteButton() {
|
||||||
if (!this.props.node) {
|
if (!this.props.node || (!this.props.node.message || !this.props.node.message.value)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +114,7 @@ class Sidebar extends React.Component<Props, State> {
|
|||||||
private renderRecursiveTopicDeleteButton() {
|
private renderRecursiveTopicDeleteButton() {
|
||||||
const deleteLimit = 50
|
const deleteLimit = 50
|
||||||
const topicCount = this.props.node ? this.props.node.childTopicCount() : 0
|
const topicCount = this.props.node ? this.props.node.childTopicCount() : 0
|
||||||
if (!this.props.node || topicCount === 0) {
|
if ((!this.props.node || topicCount === 0) || (this.props.node.message && topicCount === 1)) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,7 +126,7 @@ class Sidebar extends React.Component<Props, State> {
|
|||||||
badgeContent={<span style={{ whiteSpace: 'nowrap' }}>{topicCount >= deleteLimit ? '50+' : topicCount}</span>}
|
badgeContent={<span style={{ whiteSpace: 'nowrap' }}>{topicCount >= deleteLimit ? '50+' : topicCount}</span>}
|
||||||
color="secondary"
|
color="secondary"
|
||||||
>
|
>
|
||||||
<DeleteForever color="action" />
|
<Delete color="action" />
|
||||||
</Badge>
|
</Badge>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</CustomIconButton>
|
</CustomIconButton>
|
||||||
@@ -170,11 +169,11 @@ class Sidebar extends React.Component<Props, State> {
|
|||||||
const deleteTopic = this.renderTopicDeleteButton()
|
const deleteTopic = this.renderTopicDeleteButton()
|
||||||
const deleteRecursiveTopic = this.renderRecursiveTopicDeleteButton()
|
const deleteRecursiveTopic = this.renderRecursiveTopicDeleteButton()
|
||||||
const copyValue = node && node.message ? <Copy value={node.message.value} /> : null
|
const copyValue = node && node.message ? <Copy value={node.message.value} /> : null
|
||||||
const summeryStyle = { minHeight: '0' }
|
const summaryStyle = { minHeight: '0' }
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<ExpansionPanel key="topic" defaultExpanded={true} disabled={!Boolean(this.props.node)}>
|
<ExpansionPanel key="topic" defaultExpanded={true} disabled={!Boolean(this.props.node)}>
|
||||||
<ExpansionPanelSummary expandIcon={<ExpandMore />} style={summeryStyle}>
|
<ExpansionPanelSummary expandIcon={<ExpandMore />} style={summaryStyle}>
|
||||||
<Typography className={classes.heading}>Topic {copyTopic} {deleteTopic} {deleteRecursiveTopic}</Typography>
|
<Typography className={classes.heading}>Topic {copyTopic} {deleteTopic} {deleteRecursiveTopic}</Typography>
|
||||||
</ExpansionPanelSummary>
|
</ExpansionPanelSummary>
|
||||||
<ExpansionPanelDetails style={this.detailsStyle}>
|
<ExpansionPanelDetails style={this.detailsStyle}>
|
||||||
@@ -182,7 +181,7 @@ class Sidebar extends React.Component<Props, State> {
|
|||||||
</ExpansionPanelDetails>
|
</ExpansionPanelDetails>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
<ExpansionPanel key="value" defaultExpanded={true}>
|
<ExpansionPanel key="value" defaultExpanded={true}>
|
||||||
<ExpansionPanelSummary expandIcon={<ExpandMore />} style={summeryStyle}>
|
<ExpansionPanelSummary expandIcon={<ExpandMore />} style={summaryStyle}>
|
||||||
<Typography className={classes.heading}>Value {copyValue}</Typography>
|
<Typography className={classes.heading}>Value {copyValue}</Typography>
|
||||||
</ExpansionPanelSummary>
|
</ExpansionPanelSummary>
|
||||||
<ExpansionPanelDetails style={this.detailsStyle}>
|
<ExpansionPanelDetails style={this.detailsStyle}>
|
||||||
@@ -196,7 +195,7 @@ class Sidebar extends React.Component<Props, State> {
|
|||||||
</ExpansionPanelDetails>
|
</ExpansionPanelDetails>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
<ExpansionPanel defaultExpanded={true}>
|
<ExpansionPanel defaultExpanded={true}>
|
||||||
<ExpansionPanelSummary expandIcon={<ExpandMore />} style={summeryStyle}>
|
<ExpansionPanelSummary expandIcon={<ExpandMore />} style={summaryStyle}>
|
||||||
<Typography className={classes.heading}>Publish</Typography>
|
<Typography className={classes.heading}>Publish</Typography>
|
||||||
</ExpansionPanelSummary>
|
</ExpansionPanelSummary>
|
||||||
<ExpansionPanelDetails style={this.detailsStyle}>
|
<ExpansionPanelDetails style={this.detailsStyle}>
|
||||||
@@ -206,7 +205,7 @@ class Sidebar extends React.Component<Props, State> {
|
|||||||
</ExpansionPanelDetails>
|
</ExpansionPanelDetails>
|
||||||
</ExpansionPanel>
|
</ExpansionPanel>
|
||||||
<ExpansionPanel defaultExpanded={Boolean(this.props.node)}>
|
<ExpansionPanel defaultExpanded={Boolean(this.props.node)}>
|
||||||
<ExpansionPanelSummary expandIcon={<ExpandMore />} style={summeryStyle}>
|
<ExpansionPanelSummary expandIcon={<ExpandMore />} style={summaryStyle}>
|
||||||
<Typography className={classes.heading}>Stats</Typography>
|
<Typography className={classes.heading}>Stats</Typography>
|
||||||
</ExpansionPanelSummary>
|
</ExpansionPanelSummary>
|
||||||
{this.renderNodeStats()}
|
{this.renderNodeStats()}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import * as React from 'react'
|
|
||||||
import * as q from '../../../../backend/src/Model'
|
import * as q from '../../../../backend/src/Model'
|
||||||
|
import * as React from 'react'
|
||||||
import { AppState } from '../../reducers'
|
|
||||||
import TreeNode from './TreeNode'
|
import TreeNode from './TreeNode'
|
||||||
|
import { AppState } from '../../reducers'
|
||||||
|
import { bindActionCreators } from 'redux'
|
||||||
import { connect } from 'react-redux'
|
import { connect } from 'react-redux'
|
||||||
import { TopicOrder } from '../../reducers/Settings'
|
import { TopicOrder } from '../../reducers/Settings'
|
||||||
import { TopicViewModel } from '../../TopicViewModel'
|
import { TopicViewModel } from '../../TopicViewModel'
|
||||||
import { treeActions } from '../../actions'
|
import { treeActions } from '../../actions'
|
||||||
import { bindActionCreators } from 'redux'
|
|
||||||
|
|
||||||
const MovingAverage = require('moving-average')
|
const MovingAverage = require('moving-average')
|
||||||
|
|
||||||
@@ -25,6 +24,7 @@ interface Props {
|
|||||||
topicOrder: TopicOrder
|
topicOrder: TopicOrder
|
||||||
autoExpandLimit: number
|
autoExpandLimit: number
|
||||||
highlightTopicUpdates: boolean
|
highlightTopicUpdates: boolean
|
||||||
|
selectTopicWithMouseOver: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
@@ -112,6 +112,7 @@ class Tree extends React.PureComponent<Props, State> {
|
|||||||
lastUpdate={tree.lastUpdate}
|
lastUpdate={tree.lastUpdate}
|
||||||
didSelectTopic={this.props.actions.selectTopic}
|
didSelectTopic={this.props.actions.selectTopic}
|
||||||
highlightTopicUpdates={this.props.highlightTopicUpdates}
|
highlightTopicUpdates={this.props.highlightTopicUpdates}
|
||||||
|
selectTopicWithMouseOver={this.props.selectTopicWithMouseOver}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -130,6 +131,7 @@ const mapStateToProps = (state: AppState) => {
|
|||||||
autoExpandLimit: state.settings.autoExpandLimit,
|
autoExpandLimit: state.settings.autoExpandLimit,
|
||||||
topicOrder: state.settings.topicOrder,
|
topicOrder: state.settings.topicOrder,
|
||||||
highlightTopicUpdates: state.settings.highlightTopicUpdates,
|
highlightTopicUpdates: state.settings.highlightTopicUpdates,
|
||||||
|
selectTopicWithMouseOver: state.settings.selectTopicWithMouseOver,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import * as React from 'react'
|
|
||||||
import * as q from '../../../../backend/src/Model'
|
import * as q from '../../../../backend/src/Model'
|
||||||
|
import * as React from 'react'
|
||||||
import { Theme, withStyles } from '@material-ui/core/styles'
|
|
||||||
|
|
||||||
import TreeNodeSubnodes from './TreeNodeSubnodes'
|
import TreeNodeSubnodes from './TreeNodeSubnodes'
|
||||||
import TreeNodeTitle from './TreeNodeTitle'
|
import TreeNodeTitle from './TreeNodeTitle'
|
||||||
|
import { Theme, withStyles } from '@material-ui/core/styles'
|
||||||
import { TopicOrder } from '../../reducers/Settings'
|
import { TopicOrder } from '../../reducers/Settings'
|
||||||
import { TopicViewModel } from '../../TopicViewModel'
|
import { TopicViewModel } from '../../TopicViewModel'
|
||||||
|
|
||||||
const debounce = require('lodash.debounce')
|
const debounce = require('lodash.debounce')
|
||||||
|
|
||||||
declare var performance: any
|
declare var performance: any
|
||||||
@@ -55,6 +54,7 @@ interface Props {
|
|||||||
lastUpdate: number
|
lastUpdate: number
|
||||||
didSelectTopic: any
|
didSelectTopic: any
|
||||||
highlightTopicUpdates: boolean
|
highlightTopicUpdates: boolean
|
||||||
|
selectTopicWithMouseOver: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
@@ -229,6 +229,9 @@ class TreeNode extends React.Component<Props, State> {
|
|||||||
private mouseOver = (event: React.MouseEvent) => {
|
private mouseOver = (event: React.MouseEvent) => {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
this.setHover(true)
|
this.setHover(true)
|
||||||
|
if (this.props.selectTopicWithMouseOver && this.props.treeNode && this.props.treeNode.message && this.props.treeNode.message.value) {
|
||||||
|
this.props.didSelectTopic(this.props.treeNode)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private mouseOut = (event: React.MouseEvent) => {
|
private mouseOut = (event: React.MouseEvent) => {
|
||||||
@@ -260,6 +263,7 @@ class TreeNode extends React.Component<Props, State> {
|
|||||||
lastUpdate={this.props.treeNode.lastUpdate}
|
lastUpdate={this.props.treeNode.lastUpdate}
|
||||||
didSelectTopic={this.props.didSelectTopic}
|
didSelectTopic={this.props.didSelectTopic}
|
||||||
highlightTopicUpdates={this.props.highlightTopicUpdates}
|
highlightTopicUpdates={this.props.highlightTopicUpdates}
|
||||||
|
selectTopicWithMouseOver={this.props.selectTopicWithMouseOver}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ export interface Props {
|
|||||||
autoExpandLimit: number
|
autoExpandLimit: number
|
||||||
didSelectTopic: any
|
didSelectTopic: any
|
||||||
highlightTopicUpdates: boolean
|
highlightTopicUpdates: boolean
|
||||||
|
selectTopicWithMouseOver: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
interface State {
|
interface State {
|
||||||
@@ -83,6 +84,7 @@ class TreeNodeSubnodes extends React.Component<Props, State> {
|
|||||||
lastUpdate={node.lastUpdate}
|
lastUpdate={node.lastUpdate}
|
||||||
didSelectTopic={this.props.didSelectTopic}
|
didSelectTopic={this.props.didSelectTopic}
|
||||||
highlightTopicUpdates={this.props.highlightTopicUpdates}
|
highlightTopicUpdates={this.props.highlightTopicUpdates}
|
||||||
|
selectTopicWithMouseOver={this.props.selectTopicWithMouseOver}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user