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>) => {
|
||||
dispatch({
|
||||
selectTopicWithMouseOver: doSelect,
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
Typography,
|
||||
Tooltip,
|
||||
} from '@material-ui/core'
|
||||
import TimeLocale from './TimeLocale';
|
||||
|
||||
export const autoExpandLimitSet = [{
|
||||
limit: 0,
|
||||
@@ -188,6 +189,7 @@ class Settings extends React.Component<Props, {}> {
|
||||
<div>
|
||||
{this.renderAutoExpand()}
|
||||
{this.renderNodeOrder()}
|
||||
<TimeLocale />
|
||||
{this.renderHighlightTopicUpdates()}
|
||||
{this.selectTopicsOnMouseOver()}
|
||||
{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 React from 'react'
|
||||
import { AppState } from '../../reducers'
|
||||
import { connect } from 'react-redux'
|
||||
|
||||
interface Props {
|
||||
date: Date
|
||||
overrideLocale?: string
|
||||
locale?: string
|
||||
intervalSince?: Date
|
||||
}
|
||||
|
||||
@@ -13,7 +17,6 @@ const unitMapping = {
|
||||
}
|
||||
|
||||
class DateFormatter extends React.Component<Props, {}> {
|
||||
|
||||
private intervalSince(intervalSince: Date) {
|
||||
const interval = intervalSince.getTime() - this.props.date.getTime()
|
||||
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')
|
||||
}
|
||||
|
||||
private unitForInterval(millis: number) {
|
||||
private unitForInterval(milliseconds: number) {
|
||||
const oneMinute = 1000 * 60
|
||||
const oneHour = oneMinute * 60
|
||||
|
||||
if (millis > oneHour * 2) {
|
||||
if (milliseconds > oneHour * 2) {
|
||||
return 'h'
|
||||
}
|
||||
|
||||
if (millis > oneMinute * 2) {
|
||||
if (milliseconds > oneMinute * 2) {
|
||||
return 'm'
|
||||
}
|
||||
|
||||
return 's'
|
||||
}
|
||||
|
||||
public render() {
|
||||
const locale = window.navigator.language
|
||||
const locale = this.props.overrideLocale || this.props.locale
|
||||
if (this.props.intervalSince) {
|
||||
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 { Record } from 'immutable'
|
||||
|
||||
@@ -12,6 +13,7 @@ export type ValueRendererDisplayMode = 'diff' | 'raw'
|
||||
|
||||
export interface SettingsState {
|
||||
autoExpandLimit: number
|
||||
timeLocale: string
|
||||
topicOrder: TopicOrder
|
||||
topicFilter?: string
|
||||
highlightTopicUpdates: boolean
|
||||
@@ -28,6 +30,7 @@ export type Actions = SetAutoExpandLimitAction
|
||||
& SetValueRendererDisplayModeAction
|
||||
& SetTheme
|
||||
& SetSelectTopicWithMouseOverAction
|
||||
& SetTimeLocale
|
||||
|
||||
export enum ActionTypes {
|
||||
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_THEME_LIGHT = 'SETTINGS_SET_THEME_LIGHT',
|
||||
SETTINGS_SET_THEME_DARK = 'SETTINGS_SET_THEME_DARK',
|
||||
SETTINGS_SET_TIME_LOCALE = 'SETTINGS_SET_TIME_LOCALE',
|
||||
}
|
||||
|
||||
const initialState = Record<SettingsState>({
|
||||
timeLocale: window.navigator.language,
|
||||
autoExpandLimit: 0,
|
||||
topicOrder: TopicOrder.none,
|
||||
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_THEME_LIGHT: setTheme('light'),
|
||||
SETTINGS_SET_THEME_DARK: setTheme('dark'),
|
||||
SETTINGS_SET_TIME_LOCALE: setTimeLocale,
|
||||
}
|
||||
|
||||
export const settingsReducer = createReducer(initialState(), reducerActions)
|
||||
@@ -92,6 +98,15 @@ export function setSelectTopicWithMouseOver(state: Record<SettingsState>, action
|
||||
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 {
|
||||
type: ActionTypes.SETTINGS_SET_VALUE_RENDERER_DISPLAY_MODE
|
||||
valueRendererDisplayMode: ValueRendererDisplayMode
|
||||
|
||||
Reference in New Issue
Block a user