Add time locale selection

This commit is contained in:
Thomas Nordquist
2019-04-16 12:48:10 +02:00
parent a901f2b90b
commit c2885c4829
5 changed files with 121 additions and 7 deletions

View File

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

View File

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

View 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))

View File

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

View File

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