Add time locale selection
This commit is contained in:
@@ -54,6 +54,14 @@ export const setAutoExpandLimit = (autoExpandLimit: number = 0) => (dispatch: Di
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const setTimeLocale = (timeLocale: string) => (dispatch: Dispatch<any>) => {
|
||||||
|
dispatch({
|
||||||
|
timeLocale,
|
||||||
|
type: ActionTypes.SETTINGS_SET_TIME_LOCALE,
|
||||||
|
})
|
||||||
|
dispatch(storeSettings())
|
||||||
|
}
|
||||||
|
|
||||||
export const selectTopicWithMouseOver = (doSelect: boolean) => (dispatch: Dispatch<any>) => {
|
export const selectTopicWithMouseOver = (doSelect: boolean) => (dispatch: Dispatch<any>) => {
|
||||||
dispatch({
|
dispatch({
|
||||||
selectTopicWithMouseOver: doSelect,
|
selectTopicWithMouseOver: doSelect,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
Typography,
|
Typography,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
} from '@material-ui/core'
|
} from '@material-ui/core'
|
||||||
|
import TimeLocale from './TimeLocale';
|
||||||
|
|
||||||
export const autoExpandLimitSet = [{
|
export const autoExpandLimitSet = [{
|
||||||
limit: 0,
|
limit: 0,
|
||||||
@@ -188,6 +189,7 @@ class Settings extends React.Component<Props, {}> {
|
|||||||
<div>
|
<div>
|
||||||
{this.renderAutoExpand()}
|
{this.renderAutoExpand()}
|
||||||
{this.renderNodeOrder()}
|
{this.renderNodeOrder()}
|
||||||
|
<TimeLocale />
|
||||||
{this.renderHighlightTopicUpdates()}
|
{this.renderHighlightTopicUpdates()}
|
||||||
{this.selectTopicsOnMouseOver()}
|
{this.selectTopicsOnMouseOver()}
|
||||||
{this.toggleTheme()}
|
{this.toggleTheme()}
|
||||||
|
|||||||
79
app/src/components/SettingsDrawer/TimeLocale.tsx
Normal file
79
app/src/components/SettingsDrawer/TimeLocale.tsx
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
import * as React from 'react'
|
||||||
|
import DateFormatter from '../helper/DateFormatter'
|
||||||
|
import { AppState } from '../../reducers'
|
||||||
|
import { bindActionCreators } from 'redux'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
import {
|
||||||
|
Input,
|
||||||
|
InputLabel,
|
||||||
|
MenuItem,
|
||||||
|
Select,
|
||||||
|
StyleRulesCallback
|
||||||
|
} from '@material-ui/core'
|
||||||
|
import { settingsActions } from '../../actions'
|
||||||
|
import { withStyles } from '@material-ui/styles'
|
||||||
|
const moment = require('moment/min/moment-with-locales')
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
actions: {
|
||||||
|
settings: typeof settingsActions
|
||||||
|
},
|
||||||
|
timeLocale: string
|
||||||
|
classes: any
|
||||||
|
}
|
||||||
|
|
||||||
|
function TimeLocaleSettings(props: Props) {
|
||||||
|
const { classes, timeLocale, actions } = props
|
||||||
|
const locales = moment.locales()
|
||||||
|
const date = new Date()
|
||||||
|
const localeMenuItems = locales.map((l: string) => (
|
||||||
|
<MenuItem key={l} value={l}>
|
||||||
|
<div>Locale: <b>{l}</b>, Format: <b><DateFormatter date={date} overrideLocale={l} /></b></div>
|
||||||
|
</MenuItem>
|
||||||
|
))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div style={{ padding: '8px', display: 'flex' }}>
|
||||||
|
<InputLabel htmlFor="time-locale" style={{ flex: '1', marginTop: '8px' }}>Time Locale</InputLabel>
|
||||||
|
<Select
|
||||||
|
value={timeLocale}
|
||||||
|
onChange={e => actions.settings.setTimeLocale(e.target.value)}
|
||||||
|
input={<Input name="time-locale" id="time-locale-label-placeholder" />}
|
||||||
|
name="time-locale"
|
||||||
|
className={classes.input}
|
||||||
|
renderValue={(v) => <span>{v}</span>}
|
||||||
|
style={{ flex: '1' }}
|
||||||
|
>
|
||||||
|
{localeMenuItems}
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapStateToProps = (state: AppState) => {
|
||||||
|
return {
|
||||||
|
timeLocale: state.settings.get('timeLocale'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const mapDispatchToProps = (dispatch: any) => {
|
||||||
|
return {
|
||||||
|
actions: {
|
||||||
|
settings: bindActionCreators(settingsActions, dispatch),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles: StyleRulesCallback = theme => ({
|
||||||
|
input: {
|
||||||
|
minWidth: '150px',
|
||||||
|
margin: `auto ${theme.spacing(1)} auto ${theme.spacing(2)}px`,
|
||||||
|
},
|
||||||
|
selected: {
|
||||||
|
'& div': {
|
||||||
|
display: 'none'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
export default withStyles(styles)(connect(mapStateToProps, mapDispatchToProps)(TimeLocaleSettings))
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
import * as React from 'react'
|
|
||||||
import * as moment from 'moment'
|
import * as moment from 'moment'
|
||||||
|
import * as React from 'react'
|
||||||
|
import { AppState } from '../../reducers'
|
||||||
|
import { connect } from 'react-redux'
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
date: Date
|
date: Date
|
||||||
|
overrideLocale?: string
|
||||||
|
locale?: string
|
||||||
intervalSince?: Date
|
intervalSince?: Date
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -13,7 +17,6 @@ const unitMapping = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DateFormatter extends React.Component<Props, {}> {
|
class DateFormatter extends React.Component<Props, {}> {
|
||||||
|
|
||||||
private intervalSince(intervalSince: Date) {
|
private intervalSince(intervalSince: Date) {
|
||||||
const interval = intervalSince.getTime() - this.props.date.getTime()
|
const interval = intervalSince.getTime() - this.props.date.getTime()
|
||||||
const unit = this.unitForInterval(interval)
|
const unit = this.unitForInterval(interval)
|
||||||
@@ -28,22 +31,23 @@ class DateFormatter extends React.Component<Props, {}> {
|
|||||||
return moment(this.props.date).locale(locale).format('L LTS')
|
return moment(this.props.date).locale(locale).format('L LTS')
|
||||||
}
|
}
|
||||||
|
|
||||||
private unitForInterval(millis: number) {
|
private unitForInterval(milliseconds: number) {
|
||||||
const oneMinute = 1000 * 60
|
const oneMinute = 1000 * 60
|
||||||
const oneHour = oneMinute * 60
|
const oneHour = oneMinute * 60
|
||||||
|
|
||||||
if (millis > oneHour * 2) {
|
if (milliseconds > oneHour * 2) {
|
||||||
return 'h'
|
return 'h'
|
||||||
}
|
}
|
||||||
|
|
||||||
if (millis > oneMinute * 2) {
|
if (milliseconds > oneMinute * 2) {
|
||||||
return 'm'
|
return 'm'
|
||||||
}
|
}
|
||||||
|
|
||||||
return 's'
|
return 's'
|
||||||
}
|
}
|
||||||
|
|
||||||
public render() {
|
public render() {
|
||||||
const locale = window.navigator.language
|
const locale = this.props.overrideLocale || this.props.locale
|
||||||
if (this.props.intervalSince) {
|
if (this.props.intervalSince) {
|
||||||
return <span>{this.intervalSince(this.props.intervalSince)}</span>
|
return <span>{this.intervalSince(this.props.intervalSince)}</span>
|
||||||
}
|
}
|
||||||
@@ -51,4 +55,10 @@ class DateFormatter extends React.Component<Props, {}> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default DateFormatter
|
const mapStateToProps = (state: AppState) => {
|
||||||
|
return {
|
||||||
|
locale: state.settings.get('timeLocale'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default connect(mapStateToProps)(DateFormatter)
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import * as moment from 'moment'
|
||||||
import { createReducer } from './lib'
|
import { createReducer } from './lib'
|
||||||
import { Record } from 'immutable'
|
import { Record } from 'immutable'
|
||||||
|
|
||||||
@@ -12,6 +13,7 @@ export type ValueRendererDisplayMode = 'diff' | 'raw'
|
|||||||
|
|
||||||
export interface SettingsState {
|
export interface SettingsState {
|
||||||
autoExpandLimit: number
|
autoExpandLimit: number
|
||||||
|
timeLocale: string
|
||||||
topicOrder: TopicOrder
|
topicOrder: TopicOrder
|
||||||
topicFilter?: string
|
topicFilter?: string
|
||||||
highlightTopicUpdates: boolean
|
highlightTopicUpdates: boolean
|
||||||
@@ -28,6 +30,7 @@ export type Actions = SetAutoExpandLimitAction
|
|||||||
& SetValueRendererDisplayModeAction
|
& SetValueRendererDisplayModeAction
|
||||||
& SetTheme
|
& SetTheme
|
||||||
& SetSelectTopicWithMouseOverAction
|
& SetSelectTopicWithMouseOverAction
|
||||||
|
& SetTimeLocale
|
||||||
|
|
||||||
export enum ActionTypes {
|
export enum ActionTypes {
|
||||||
SETTINGS_SET_AUTO_EXPAND_LIMIT = 'SETTINGS_SET_AUTO_EXPAND_LIMIT',
|
SETTINGS_SET_AUTO_EXPAND_LIMIT = 'SETTINGS_SET_AUTO_EXPAND_LIMIT',
|
||||||
@@ -39,9 +42,11 @@ export enum ActionTypes {
|
|||||||
SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER = 'SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER',
|
SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER = 'SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER',
|
||||||
SETTINGS_SET_THEME_LIGHT = 'SETTINGS_SET_THEME_LIGHT',
|
SETTINGS_SET_THEME_LIGHT = 'SETTINGS_SET_THEME_LIGHT',
|
||||||
SETTINGS_SET_THEME_DARK = 'SETTINGS_SET_THEME_DARK',
|
SETTINGS_SET_THEME_DARK = 'SETTINGS_SET_THEME_DARK',
|
||||||
|
SETTINGS_SET_TIME_LOCALE = 'SETTINGS_SET_TIME_LOCALE',
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialState = Record<SettingsState>({
|
const initialState = Record<SettingsState>({
|
||||||
|
timeLocale: window.navigator.language,
|
||||||
autoExpandLimit: 0,
|
autoExpandLimit: 0,
|
||||||
topicOrder: TopicOrder.none,
|
topicOrder: TopicOrder.none,
|
||||||
highlightTopicUpdates: true,
|
highlightTopicUpdates: true,
|
||||||
@@ -65,6 +70,7 @@ const reducerActions: {[s: string]: (state: Record<SettingsState>, action: Actio
|
|||||||
SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER: setSelectTopicWithMouseOver,
|
SETTINGS_SET_SELECT_TOPIC_WITH_MOUSE_OVER: setSelectTopicWithMouseOver,
|
||||||
SETTINGS_SET_THEME_LIGHT: setTheme('light'),
|
SETTINGS_SET_THEME_LIGHT: setTheme('light'),
|
||||||
SETTINGS_SET_THEME_DARK: setTheme('dark'),
|
SETTINGS_SET_THEME_DARK: setTheme('dark'),
|
||||||
|
SETTINGS_SET_TIME_LOCALE: setTimeLocale,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const settingsReducer = createReducer(initialState(), reducerActions)
|
export const settingsReducer = createReducer(initialState(), reducerActions)
|
||||||
@@ -92,6 +98,15 @@ export function setSelectTopicWithMouseOver(state: Record<SettingsState>, action
|
|||||||
return state.set('selectTopicWithMouseOver', !state.get('selectTopicWithMouseOver'))
|
return state.set('selectTopicWithMouseOver', !state.get('selectTopicWithMouseOver'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SetTimeLocale {
|
||||||
|
type: ActionTypes.SETTINGS_SET_TIME_LOCALE
|
||||||
|
timeLocale: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function setTimeLocale(state: Record<SettingsState>, action: SetTimeLocale): Record<SettingsState> {
|
||||||
|
return state.set('timeLocale', action.timeLocale)
|
||||||
|
}
|
||||||
|
|
||||||
export interface SetValueRendererDisplayModeAction {
|
export interface SetValueRendererDisplayModeAction {
|
||||||
type: ActionTypes.SETTINGS_SET_VALUE_RENDERER_DISPLAY_MODE
|
type: ActionTypes.SETTINGS_SET_VALUE_RENDERER_DISPLAY_MODE
|
||||||
valueRendererDisplayMode: ValueRendererDisplayMode
|
valueRendererDisplayMode: ValueRendererDisplayMode
|
||||||
|
|||||||
Reference in New Issue
Block a user