Add quick preview switch

This commit is contained in:
Thomas Nordquist
2019-03-03 02:21:05 +01:00
parent 91486718d8
commit 692054c540
5 changed files with 83 additions and 39 deletions

View File

@@ -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,
} }
} }

View File

@@ -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()}

View File

@@ -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,
} }
} }

View File

@@ -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}
/> />
) )
} }

View File

@@ -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}
/> />
) )
}) })