From fa1b900f1db2fd0c668d9f25d72d2d18f44fce4c Mon Sep 17 00:00:00 2001 From: Lev Mishin Date: Sat, 9 Dec 2017 22:54:26 +0100 Subject: [PATCH 1/8] added buttons to scroll timelines --- .../actions/ScrollPositionActions.ts | 11 ++++ src/app.common/actions/index.ts | 3 +- src/app.common/components/TimeLine.tsx | 8 ++- src/app.common/models/ScrollPosition.ts | 6 +++ src/app.common/models/index.ts | 3 +- .../reducers/ScrollPositionReducer.ts | 17 ++++++ src/app.common/reducers/index.ts | 3 +- src/app.common/store.ts | 21 +++++++- src/app/components/Layout.tsx | 52 ++++++++++++++++--- src/manifest.json | 2 +- 10 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 src/app.common/actions/ScrollPositionActions.ts create mode 100644 src/app.common/models/ScrollPosition.ts create mode 100644 src/app.common/reducers/ScrollPositionReducer.ts diff --git a/src/app.common/actions/ScrollPositionActions.ts b/src/app.common/actions/ScrollPositionActions.ts new file mode 100644 index 0000000..b70491e --- /dev/null +++ b/src/app.common/actions/ScrollPositionActions.ts @@ -0,0 +1,11 @@ +import { ActionCreator } from "react-redux"; +import { Action } from "./Action"; +import { DisplaySettingsInfo, DSTSetting } from "../models"; +import * as moment from "moment-timezone"; + +export function changeScrollPostion(position: number): Action { + return { + type: "SCROLL_POSITION/SET", + payload: position + }; +} diff --git a/src/app.common/actions/index.ts b/src/app.common/actions/index.ts index a0ba6e8..8efb129 100644 --- a/src/app.common/actions/index.ts +++ b/src/app.common/actions/index.ts @@ -3,4 +3,5 @@ export * from "./TimeLineActions"; export * from "./TimeLineFormActions"; export * from "./DisplaySettingsActions"; export * from "./ThemeSettingsActions"; -export * from "./SelectedTimeSpanActions"; \ No newline at end of file +export * from "./SelectedTimeSpanActions"; +export * from "./ScrollPositionActions"; \ No newline at end of file diff --git a/src/app.common/components/TimeLine.tsx b/src/app.common/components/TimeLine.tsx index 3b9c038..c03fa60 100644 --- a/src/app.common/components/TimeLine.tsx +++ b/src/app.common/components/TimeLine.tsx @@ -5,7 +5,7 @@ import Typography from "material-ui/Typography"; import { withTheme, Theme } from "material-ui/styles"; const style = require("./TimeLine.css"); -import { TimeZoneInfo, getOffset, DisplaySettingsInfo } from "../models"; +import { TimeZoneInfo, getOffset, DisplaySettingsInfo, ScrollPosition } from "../models"; interface TimeLineProps { timeLine: TimeZoneInfo; @@ -13,6 +13,7 @@ interface TimeLineProps { hours: number[]; displaySettings: DisplaySettingsInfo; theme: Theme; + scrollPosition: number; } interface TimeLineState { @@ -54,15 +55,12 @@ class TimeLineImpl extends React.Component { // classes.push(style.timeLineBorderRight); } if (h < 8 || h > 21) { - // classes.push(style.nightHour); background = theme.palette.primary[100]; } if (h === 0) { - // classes.push(style.hourMidnight); background = theme.palette.primary[200]; } if (h === currentHour) { - // classes.push(style.currentHour); background = theme.palette.primary[700]; } const color = theme.palette.getContrastText(background); @@ -94,7 +92,7 @@ class TimeLineImpl extends React.Component { const uiOffset = (offset % 60) / 60; const oneDay = 100 / 3; const inlineStyle = { - transform: `translateX(${-oneDay - oneDay / 24 * uiOffset}%)` + transform: `translateX(${(this.props.scrollPosition || (-oneDay)) - oneDay / 24 * uiOffset}%)` }; return (
diff --git a/src/app.common/models/ScrollPosition.ts b/src/app.common/models/ScrollPosition.ts new file mode 100644 index 0000000..19698bf --- /dev/null +++ b/src/app.common/models/ScrollPosition.ts @@ -0,0 +1,6 @@ +export interface ScrollPosition { + minLimit: number; + maxLimit: number; + position: number; + step: number; +} \ No newline at end of file diff --git a/src/app.common/models/index.ts b/src/app.common/models/index.ts index 797136e..51c8003 100644 --- a/src/app.common/models/index.ts +++ b/src/app.common/models/index.ts @@ -3,4 +3,5 @@ export * from "./TimeZoneInfo"; export * from "./TimeZoneShort"; export * from "./DisplaySettingsInfo"; export * from "./CalendarEvent"; -export * from "./AppTheme"; \ No newline at end of file +export * from "./AppTheme"; +export * from "./ScrollPosition"; \ No newline at end of file diff --git a/src/app.common/reducers/ScrollPositionReducer.ts b/src/app.common/reducers/ScrollPositionReducer.ts new file mode 100644 index 0000000..0f010c7 --- /dev/null +++ b/src/app.common/reducers/ScrollPositionReducer.ts @@ -0,0 +1,17 @@ +import { Action } from "../actions"; +import { AppTheme, ScrollPosition } from "../models"; +import { getColorById } from "../themes/themes"; +import { updateState } from "./UpdateStateHelper"; + +export const scrollPosition = function (state: ScrollPosition = {} as ScrollPosition, action: Action): ScrollPosition { + switch (action.type) { + case "SCROLL_POSITION/SET": + if (action.payload > state.maxLimit || action.payload < state.minLimit) { + return state; + } else { + return updateState(state, { position: action.payload }); + } + default: + return state; + } +}; \ No newline at end of file diff --git a/src/app.common/reducers/index.ts b/src/app.common/reducers/index.ts index f02d30e..3322369 100644 --- a/src/app.common/reducers/index.ts +++ b/src/app.common/reducers/index.ts @@ -2,4 +2,5 @@ export * from "./TimeLineReducer"; export * from "./EditTimeLineFormReducer"; export * from "./DisplaySettingsReducer"; export * from "./ThemeReducer"; -export * from "./SelectedTimeSpanReducer"; \ No newline at end of file +export * from "./SelectedTimeSpanReducer"; +export * from "./ScrollPositionReducer"; \ No newline at end of file diff --git a/src/app.common/store.ts b/src/app.common/store.ts index e02b9db..ec281b1 100644 --- a/src/app.common/store.ts +++ b/src/app.common/store.ts @@ -3,8 +3,15 @@ import { createLogger } from "redux-logger"; import * as persistState from "redux-localstorage"; import * as moment from "moment"; -import { timeLines, editTimeLineForm, displaySettings, selectedTimeSpan, theme } from "./reducers"; -import { TimeZoneInfo, createTimeZoneInfo, DisplaySettingsInfo, TimeSpanInfo, AppTheme } from "../app.common/models"; +import { + timeLines, + editTimeLineForm, + displaySettings, + selectedTimeSpan, + theme, + scrollPosition +} from "./reducers"; +import { TimeZoneInfo, createTimeZoneInfo, DisplaySettingsInfo, TimeSpanInfo, AppTheme, ScrollPosition } from "../app.common/models"; import { initialPalette } from "./themes/themes"; @@ -14,6 +21,7 @@ export interface IAppState { displaySettings: DisplaySettingsInfo; selectedTimeSpan: TimeSpanInfo; theme: AppTheme; + scrollPosition: ScrollPosition; } export interface IAppStoreDispatcher extends ReducersMapObject { @@ -21,6 +29,8 @@ export interface IAppStoreDispatcher extends ReducersMapObject { editTimeLineForm: Reducer; displaySettings: Reducer; selectedTimeSpan: Reducer; + theme: Reducer; + scrollPosition: Reducer; } const initialState: IAppState = { @@ -49,6 +59,12 @@ const initialState: IAppState = { }, theme: { palette: initialPalette, + }, + scrollPosition: { + maxLimit: 0, + minLimit: -100 / 3 * 2 + 100 / 3 / 24, + position: -100 / 3, + step: 100 / 3 / 24 * 6, } } as IAppState; @@ -58,6 +74,7 @@ const reducers: IAppStoreDispatcher = { displaySettings, selectedTimeSpan, theme, + scrollPosition }; let enchancer: StoreEnhancer; diff --git a/src/app/components/Layout.tsx b/src/app/components/Layout.tsx index 3876c39..74141e5 100644 --- a/src/app/components/Layout.tsx +++ b/src/app/components/Layout.tsx @@ -6,13 +6,15 @@ import Button from "material-ui/Button"; import IconButton from "material-ui/IconButton"; import Icon from "material-ui/Icon"; import SettingsIcon from 'material-ui-icons/Settings'; +import KeyboardArrowLeftIcon from 'material-ui-icons/KeyboardArrowLeft'; +import KeyboardArrowRightIcon from 'material-ui-icons/KeyboardArrowRight'; import Paper from "material-ui/Paper"; import Typography from "material-ui/Typography"; import { withTheme, Theme } from "material-ui/styles"; import { TimeLine, Clock, Range, TimeSelector } from "../../app.common/components"; -import { changeSelectedTimeSpan } from "../../app.common/actions"; -import { getOffset, getHoursWithOffset, DisplaySettingsInfo, TimeSpanInfo, CalendarEvent } from "../../app.common/models"; +import { changeSelectedTimeSpan, changeScrollPostion } from "../../app.common/actions"; +import { getOffset, getHoursWithOffset, DisplaySettingsInfo, TimeSpanInfo, CalendarEvent, ScrollPosition } from "../../app.common/models"; import { IAppState } from "../../app.common/store"; const style = require("./Layout.css"); @@ -21,18 +23,40 @@ interface ILayoutStateProps { displaySettings?: DisplaySettingsInfo; selectedTimeSpan?: TimeSpanInfo; rangeColor?: string; + scrollPosition?: ScrollPosition; } interface ILayoutDispatchProps { - changeSelectedTimeSpan?: ActionCreator + changeSelectedTimeSpan?: ActionCreator, + changeScrollPostion?: ActionCreator, } type ILayoutProps = ILayoutStateProps & ILayoutDispatchProps; class LayoutImpl extends React.Component { + get maxPositionReached(): boolean { + const { position, step, maxLimit } = this.props.scrollPosition; + return position + step > maxLimit + } + + get minPositionReached(): boolean { + const { position, step, minLimit } = this.props.scrollPosition; + return position - step < minLimit + } + + incrementScrollPosition() { + const { position, step } = this.props.scrollPosition; + this.props.changeScrollPostion(position + step) + } + + decrementScrollPosition() { + const { position, step } = this.props.scrollPosition; + this.props.changeScrollPostion(position - step) + } + render(): React.ReactElement { - const { displaySettings, selectedTimeSpan, changeSelectedTimeSpan, timeLines, rangeColor } = this.props; + const { displaySettings, selectedTimeSpan, changeSelectedTimeSpan, timeLines, rangeColor, scrollPosition } = this.props; const valueMin = selectedTimeSpan.startHour * 2 + selectedTimeSpan.startMinute / 30; const valueMax = selectedTimeSpan.endHour * 2 + selectedTimeSpan.endMinute / 30; const startTime = moment().hours(selectedTimeSpan.startHour).minutes(selectedTimeSpan.startMinute); @@ -47,6 +71,18 @@ class LayoutImpl extends React.Component {
+ this.incrementScrollPosition()} + > + + + this.decrementScrollPosition()} + > + + @@ -56,7 +92,7 @@ class LayoutImpl extends React.Component {
{timeLines.map(tl => - + )}
@@ -102,6 +138,10 @@ export const Layout = connect Date: Sat, 9 Dec 2017 22:58:21 +0100 Subject: [PATCH 2/8] increment version --- src/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/manifest.json b/src/manifest.json index ce127cc..260ea46 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -2,7 +2,7 @@ "manifest_version": 2, "name": "Worldtime", "description": "All time zones in one click", - "version": "1.3.68", + "version": "1.3.69", "options_page": "options.html", "browser_action": { "default_icon": "icons/icon_19.png", From 81bece84566b96db0c404a4e7a8814e9f26c6331 Mon Sep 17 00:00:00 2001 From: Lev Mishin Date: Sun, 10 Dec 2017 11:43:46 +0100 Subject: [PATCH 3/8] refactored store fixed merge operation for initial value added center position button --- .../actions/ScrollPositionActions.ts | 7 + .../actions/SelectedTimeSpanActions.ts | 6 +- src/app.common/components/Range.tsx | 25 ++- src/app.common/components/TimeLine.tsx | 4 +- src/app.common/components/TimeSelector.tsx | 10 +- src/app.common/localstorage-enchancer.ts | 27 +++ src/app.common/models/DisplaySettingsInfo.ts | 1 + .../reducers/DisplaySettingsReducer.ts | 18 +- .../reducers/EditTimeLineFormReducer.ts | 9 +- .../reducers/ScrollPositionReducer.ts | 13 +- .../reducers/SelectedTimeSpanReducer.ts | 12 +- src/app.common/reducers/ThemeReducer.ts | 10 +- src/app.common/reducers/TimeLineReducer.ts | 19 +- src/app.common/reducers/index.ts | 52 ++++- src/app.common/store.ts | 99 ++------- src/app.common/themes/themes.ts | 4 +- .../components/DisplaySettings.tsx | 189 +++++++++--------- src/app/components/Layout.tsx | 90 +++++++-- src/manifest.json | 2 +- 19 files changed, 368 insertions(+), 229 deletions(-) create mode 100644 src/app.common/localstorage-enchancer.ts diff --git a/src/app.common/actions/ScrollPositionActions.ts b/src/app.common/actions/ScrollPositionActions.ts index b70491e..e13bf9d 100644 --- a/src/app.common/actions/ScrollPositionActions.ts +++ b/src/app.common/actions/ScrollPositionActions.ts @@ -9,3 +9,10 @@ export function changeScrollPostion(position: number): Action { payload: position }; } + +export function resetScrollPostion(): Action { + return { + type: "SCROLL_POSITION/RESET", + payload: 0 + }; +} diff --git a/src/app.common/actions/SelectedTimeSpanActions.ts b/src/app.common/actions/SelectedTimeSpanActions.ts index af71dfa..439b504 100644 --- a/src/app.common/actions/SelectedTimeSpanActions.ts +++ b/src/app.common/actions/SelectedTimeSpanActions.ts @@ -45,11 +45,7 @@ export function changeEndMinute(minute: number) { }; } -export function changeSelectedTimeSpan(start: number, end: number): Action { - const startHour = Math.floor(start / 2); - const startMinute = (start % 2) * 30; - const endHour = Math.floor(end / 2); - const endMinute = (end % 2) * 30; +export function changeSelectedTimeSpan(startHour: number, startMinute: number, endHour: number, endMinute: number): Action { return { type: "SELECTED_TIMESPAN/CHANGE_SELECTED_TIMESPAN", payload: { startHour, startMinute, endHour, endMinute } diff --git a/src/app.common/components/Range.tsx b/src/app.common/components/Range.tsx index 5247f43..33b3428 100644 --- a/src/app.common/components/Range.tsx +++ b/src/app.common/components/Range.tsx @@ -23,13 +23,28 @@ export class Range extends React.Component { constructor(props: IRangeProps) { super(props); + const { rangeSize, valueMin, valueMax } = props; this.state = { - valueMin: props.rangeSize ? props.valueMin / props.rangeSize * 100 : props.valueMin, - valueMax: props.rangeSize ? props.valueMax / props.rangeSize * 100 : props.valueMax, + valueMin: rangeSize ? valueMin / rangeSize * 100 : valueMin, + valueMax: rangeSize ? valueMax / rangeSize * 100 : valueMax, hold: false }; } + componentWillReceiveProps(props: IRangeProps) { + if (props) { + this.updateState(props); + } + } + + updateState(props: IRangeProps) { + const { valueMax, valueMin, rangeSize } = props; + this.setState({ + valueMin: rangeSize ? valueMin / rangeSize * 100 : valueMin, + valueMax: rangeSize ? valueMax / rangeSize * 100 : valueMax, + }); + } + onChange(valueMin: number, valueMax: number) { if (this.props.onChange) { this.props.onChange(this.convertValues(valueMin, valueMax)); @@ -122,9 +137,9 @@ export class Range extends React.Component {
this.onRangeBaseClick(event)}>
-
this.onHold("min")}>
-
-
this.onHold("max")}>
+
this.onHold("min")}>
+
+
this.onHold("max")}>
diff --git a/src/app.common/components/TimeLine.tsx b/src/app.common/components/TimeLine.tsx index c03fa60..312d759 100644 --- a/src/app.common/components/TimeLine.tsx +++ b/src/app.common/components/TimeLine.tsx @@ -91,8 +91,10 @@ class TimeLineImpl extends React.Component { const currentHour = +moment().utcOffset(offset).format("HH"); const uiOffset = (offset % 60) / 60; const oneDay = 100 / 3; + const oneHour = oneDay / 24; + const position = this.props.scrollPosition; const inlineStyle = { - transform: `translateX(${(this.props.scrollPosition || (-oneDay)) - oneDay / 24 * uiOffset}%)` + transform: `translateX(${-oneDay + oneHour * position - oneHour * uiOffset}%)` }; return (
diff --git a/src/app.common/components/TimeSelector.tsx b/src/app.common/components/TimeSelector.tsx index c188a80..225f61e 100644 --- a/src/app.common/components/TimeSelector.tsx +++ b/src/app.common/components/TimeSelector.tsx @@ -5,15 +5,17 @@ const style = require("./TimeSelector.css"); import { TimeZoneInfo, TimeSpanInfo } from "../models"; interface TimeSelectorProps { - selectedTimeSpan: TimeSpanInfo; + valueMin: number; + valueMax: number; + rangeSize: number; color: string; } export class TimeSelector extends React.Component { render() { - const { selectedTimeSpan, color } = this.props; - const left = (selectedTimeSpan.startHour * 2 + selectedTimeSpan.startMinute / 30) / 48 * 100; - const right = (selectedTimeSpan.endHour * 2 + selectedTimeSpan.endMinute / 30) / 48 * 100; + const { valueMin, valueMax, rangeSize, color } = this.props; + const left = valueMin / rangeSize * 100; + const right = valueMax / rangeSize * 100; const visibilityLeft = left <= 0.001 ? "hidden" : "visible"; const visibilityRight = right >= 99.999 ? "hidden" : "visible"; return ( diff --git a/src/app.common/localstorage-enchancer.ts b/src/app.common/localstorage-enchancer.ts new file mode 100644 index 0000000..1583962 --- /dev/null +++ b/src/app.common/localstorage-enchancer.ts @@ -0,0 +1,27 @@ +import { compose } from "redux"; +import * as persistState from "redux-localstorage"; +import * as _ from "lodash"; +import { IAppState } from "./reducers"; + +function merge(initialState: IAppState, persistedState: IAppState) { + const mergedState = _.cloneDeep(initialState); + if (!persistedState) { + return initialState; + } + if (persistedState.timeLines) { + mergedState.timeLines = persistedState.timeLines; + } + if (persistedState.displaySettings) { + mergedState.displaySettings = _.merge(mergedState.displaySettings, persistedState.displaySettings); + } + if (persistedState.theme) { + mergedState.theme = _.merge(mergedState.theme, persistedState.theme); + } + return mergedState; +} + +export const localStorageEnchancer = [ + persistState("timeLines", { key: "timeLines@0.0.259", merge }), + persistState("displaySettings", { key: "displaySettings@0.1.265", merge }), + persistState("theme", { key: "theme@1.2.45", merge }), +]; \ No newline at end of file diff --git a/src/app.common/models/DisplaySettingsInfo.ts b/src/app.common/models/DisplaySettingsInfo.ts index 3920e74..bfa592a 100644 --- a/src/app.common/models/DisplaySettingsInfo.ts +++ b/src/app.common/models/DisplaySettingsInfo.ts @@ -5,6 +5,7 @@ export interface DisplaySettingsInfo { showControlPanel: boolean; useDarkTheme: boolean; use24HoursTime: boolean; + selectionStep: number; } export type DSTSetting = "hide" | "DST" | "Summer/Winter"; \ No newline at end of file diff --git a/src/app.common/reducers/DisplaySettingsReducer.ts b/src/app.common/reducers/DisplaySettingsReducer.ts index 904768c..547919d 100644 --- a/src/app.common/reducers/DisplaySettingsReducer.ts +++ b/src/app.common/reducers/DisplaySettingsReducer.ts @@ -2,9 +2,21 @@ import { updateState } from "./UpdateStateHelper"; import { DisplaySettingsInfo } from "../models"; import { Action } from "../actions"; -export const displaySettings = function (state: DisplaySettingsInfo = {} as DisplaySettingsInfo, action: Action): DisplaySettingsInfo { - switch(action.type) { - case "DISPLAY_SETTINGS/SHOW_DST":{ +export type State = DisplaySettingsInfo; + +export const initialState: State = { + showDST: "hide", + showTimeZoneId: false, + showUTCOffset: true, + showControlPanel: true, + useDarkTheme: false, + use24HoursTime: true, + selectionStep: 30, +} + +export const reducer = function (state: State = initialState, action: Action): State { + switch (action.type) { + case "DISPLAY_SETTINGS/SHOW_DST": { return updateState(state, { showDST: action.payload }); } case "DISPLAY_SETTINGS/SHOW_UTC_OFFSET": { diff --git a/src/app.common/reducers/EditTimeLineFormReducer.ts b/src/app.common/reducers/EditTimeLineFormReducer.ts index 4bf82bb..2546ae4 100644 --- a/src/app.common/reducers/EditTimeLineFormReducer.ts +++ b/src/app.common/reducers/EditTimeLineFormReducer.ts @@ -2,7 +2,14 @@ import { updateState } from "./UpdateStateHelper"; import { TimeZoneInfo } from "../models"; import { Action } from "../actions"; -export const editTimeLineForm = function (state: TimeZoneInfo = {} as TimeZoneInfo, action: Action): TimeZoneInfo { +export type State = TimeZoneInfo; + +export const initialState: State = { + name: "", + timeZoneId: "" +} as State; + +export const reducer = function (state: State = initialState, action: Action): State { switch(action.type) { case "EDIT_TIMELINE/CHANGE_DISPLAY_NAME": return updateState(state, { name: action.payload }) diff --git a/src/app.common/reducers/ScrollPositionReducer.ts b/src/app.common/reducers/ScrollPositionReducer.ts index 0f010c7..3b924a5 100644 --- a/src/app.common/reducers/ScrollPositionReducer.ts +++ b/src/app.common/reducers/ScrollPositionReducer.ts @@ -3,8 +3,19 @@ import { AppTheme, ScrollPosition } from "../models"; import { getColorById } from "../themes/themes"; import { updateState } from "./UpdateStateHelper"; -export const scrollPosition = function (state: ScrollPosition = {} as ScrollPosition, action: Action): ScrollPosition { +export type State = ScrollPosition; + +export const initialState: State = { + maxLimit: 23, + minLimit: -23, + position: 0, + step: 6, +}; + +export const reducer = function (state: State = initialState, action: Action): State { switch (action.type) { + case "SCROLL_POSITION/RESET": + return updateState(state, { position: 0 }); case "SCROLL_POSITION/SET": if (action.payload > state.maxLimit || action.payload < state.minLimit) { return state; diff --git a/src/app.common/reducers/SelectedTimeSpanReducer.ts b/src/app.common/reducers/SelectedTimeSpanReducer.ts index 9b6487c..cfab175 100644 --- a/src/app.common/reducers/SelectedTimeSpanReducer.ts +++ b/src/app.common/reducers/SelectedTimeSpanReducer.ts @@ -1,8 +1,18 @@ import { updateState } from "./UpdateStateHelper"; import { TimeSpanInfo } from "../models"; import { Action } from "../actions"; +import * as moment from "moment"; -export const selectedTimeSpan = function (state: TimeSpanInfo = {} as TimeSpanInfo, action: Action): TimeSpanInfo { +export type State = TimeSpanInfo; + +export const initialState: State = { + startHour: moment().hours(), + startMinute: moment().minutes(), + endHour: 24, + endMinute: 0 +}; + +export const reducer = function (state: State = initialState, action: Action): State { switch(action.type) { case "SELECTED_TIMESPAN/CHANGE_SELECTED_TIMESPAN": { return updateState(state, action.payload) diff --git a/src/app.common/reducers/ThemeReducer.ts b/src/app.common/reducers/ThemeReducer.ts index 101a71c..9e981cc 100644 --- a/src/app.common/reducers/ThemeReducer.ts +++ b/src/app.common/reducers/ThemeReducer.ts @@ -1,8 +1,14 @@ import { Action } from "../actions"; import { AppTheme } from "../models"; -import { getColorById } from "../themes/themes"; +import { getColorById, initialPalette } from "../themes/themes"; -export const theme = function (state: AppTheme = {} as AppTheme, action: Action): AppTheme { +export type State = AppTheme; + +export const initialState: State = { + palette: initialPalette, +}; + +export const reducer = function (state: State = initialState, action: Action): State { switch (action.type) { case "THEME/SET_PRIMARY_COLOR": const newState = Object.assign({}, state); diff --git a/src/app.common/reducers/TimeLineReducer.ts b/src/app.common/reducers/TimeLineReducer.ts index e6a0e19..e283881 100644 --- a/src/app.common/reducers/TimeLineReducer.ts +++ b/src/app.common/reducers/TimeLineReducer.ts @@ -1,8 +1,19 @@ -import { TimeZoneInfo } from "../models"; +import { TimeZoneInfo, createTimeZoneInfo } from "../models"; import { Action } from "../actions"; -export const timeLines = function (state: TimeZoneInfo[] = [], action: Action): TimeZoneInfo[] { - switch(action.type) { +export type State = TimeZoneInfo[]; + +export const initialState: State = [ + createTimeZoneInfo("Europe/Warsaw", "Kraków"), + createTimeZoneInfo("US/Pacific", "San Francisco"), + createTimeZoneInfo("Europe/Moscow", "Saint Petersburg"), + createTimeZoneInfo("Australia/Melbourne", "Melbourne"), + createTimeZoneInfo("Asia/Calcutta", "India") + // createTimeZoneInfo("Asia/Yekaterinburg", "Yekaterinburg") +]; + +export const reducer = function (state: State = initialState, action: Action): State { + switch (action.type) { case "REPLACE_TIMELINES": return action.payload; case "CREATE_OR_UPDATE": { @@ -13,7 +24,7 @@ export const timeLines = function (state: TimeZoneInfo[] = [], action: Action x.timeLineid === action.payload.timeLineid); const timeLines = i > -1 - ? state.slice(0, i).concat([ action.payload ]).concat(state.slice(i + 1)) + ? state.slice(0, i).concat([action.payload]).concat(state.slice(i + 1)) : state.concat([action.payload]); return timeLines; } diff --git a/src/app.common/reducers/index.ts b/src/app.common/reducers/index.ts index 3322369..af10586 100644 --- a/src/app.common/reducers/index.ts +++ b/src/app.common/reducers/index.ts @@ -1,6 +1,46 @@ -export * from "./TimeLineReducer"; -export * from "./EditTimeLineFormReducer"; -export * from "./DisplaySettingsReducer"; -export * from "./ThemeReducer"; -export * from "./SelectedTimeSpanReducer"; -export * from "./ScrollPositionReducer"; \ No newline at end of file +import { combineReducers, Reducer, ReducersMapObject } from "redux"; + +import * as displaySettings from "./DisplaySettingsReducer"; +import * as editTimeLineForm from "./EditTimeLineFormReducer"; +import * as scrollPosition from "./ScrollPositionReducer"; +import * as selectedTimeSpan from "./SelectedTimeSpanReducer"; +import * as theme from "./ThemeReducer"; +import * as timeLines from "./TimeLineReducer"; + +export interface IAppStoreDispatcher extends ReducersMapObject { + timeLines: Reducer; + editTimeLineForm: Reducer; + displaySettings: Reducer; + selectedTimeSpan: Reducer; + theme: Reducer; + scrollPosition: Reducer; +} + +export interface IAppState { + timeLines: timeLines.State; + editTimeLineForm: editTimeLineForm.State; + displaySettings: displaySettings.State; + selectedTimeSpan: selectedTimeSpan.State; + theme: theme.State; + scrollPosition: scrollPosition.State; +} + +const reducers: IAppStoreDispatcher = { + timeLines: timeLines.reducer, + editTimeLineForm: editTimeLineForm.reducer, + displaySettings: displaySettings.reducer, + selectedTimeSpan: selectedTimeSpan.reducer, + theme: theme.reducer, + scrollPosition: scrollPosition.reducer, +}; + +export const initialState: IAppState = { + timeLines: timeLines.initialState, + editTimeLineForm: editTimeLineForm.initialState, + displaySettings: displaySettings.initialState, + selectedTimeSpan: selectedTimeSpan.initialState, + theme: theme.initialState, + scrollPosition: scrollPosition.initialState, +}; + +export const rootReducer = combineReducers(reducers); \ No newline at end of file diff --git a/src/app.common/store.ts b/src/app.common/store.ts index ec281b1..5b81bc3 100644 --- a/src/app.common/store.ts +++ b/src/app.common/store.ts @@ -1,106 +1,41 @@ -import { createStore, applyMiddleware, combineReducers, compose, Store, Reducer, ReducersMapObject, StoreEnhancer } from "redux"; -import { createLogger } from "redux-logger"; -import * as persistState from "redux-localstorage"; import * as moment from "moment"; +import { applyMiddleware, compose, createStore, Store, StoreEnhancer } from "redux"; +import { createLogger } from "redux-logger"; import { - timeLines, - editTimeLineForm, - displaySettings, - selectedTimeSpan, - theme, - scrollPosition -} from "./reducers"; -import { TimeZoneInfo, createTimeZoneInfo, DisplaySettingsInfo, TimeSpanInfo, AppTheme, ScrollPosition } from "../app.common/models"; + AppTheme, + createTimeZoneInfo, + DisplaySettingsInfo, + ScrollPosition, + TimeSpanInfo, + TimeZoneInfo, +} from "../app.common/models"; +import { localStorageEnchancer } from "./localstorage-enchancer"; +import { rootReducer, initialState, IAppState } from "./reducers"; import { initialPalette } from "./themes/themes"; - -export interface IAppState { - timeLines: TimeZoneInfo[]; - editTimeLineForm: TimeZoneInfo; - displaySettings: DisplaySettingsInfo; - selectedTimeSpan: TimeSpanInfo; - theme: AppTheme; - scrollPosition: ScrollPosition; -} - -export interface IAppStoreDispatcher extends ReducersMapObject { - timeLines: Reducer; - editTimeLineForm: Reducer; - displaySettings: Reducer; - selectedTimeSpan: Reducer; - theme: Reducer; - scrollPosition: Reducer; -} - -const initialState: IAppState = { - timeLines: [ - createTimeZoneInfo("Europe/Warsaw", "Kraków"), - createTimeZoneInfo("US/Pacific", "San Francisco"), - createTimeZoneInfo("Europe/Moscow", "Saint Petersburg"), - createTimeZoneInfo("Australia/Melbourne", "Melbourne"), - createTimeZoneInfo("Asia/Calcutta", "India") - // createTimeZoneInfo("Asia/Yekaterinburg", "Yekaterinburg") - ], - editTimeLineForm: { name: "", timeZoneId: "" } as TimeZoneInfo, - displaySettings: { - showDST: "hide", - showTimeZoneId: false, - showUTCOffset: true, - showControlPanel: true, - useDarkTheme: false, - use24HoursTime: true, - }, - selectedTimeSpan: { - startHour: moment().hours(), - startMinute: moment().minutes(), - endHour: 24, - endMinute: 0 - }, - theme: { - palette: initialPalette, - }, - scrollPosition: { - maxLimit: 0, - minLimit: -100 / 3 * 2 + 100 / 3 / 24, - position: -100 / 3, - step: 100 / 3 / 24 * 6, - } -} as IAppState; - -const reducers: IAppStoreDispatcher = { - timeLines, - editTimeLineForm, - displaySettings, - selectedTimeSpan, - theme, - scrollPosition -}; +export { IAppState, IAppStoreDispatcher } from "./reducers"; let enchancer: StoreEnhancer; -const localStorageState = [ - persistState("timeLines", { key: "timeLines@0.0.259" }), - persistState("displaySettings", { key: "displaySettings@0.1.265" }), - persistState("theme", { key: "theme@1.2.45" }), -]; if (process.env.NODE_ENV === "development") { const devEnchansers = [ applyMiddleware((createLogger)()) ]; - const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; + const composeEnhancers = compose; + // const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; enchancer = composeEnhancers( ...devEnchansers, - ...localStorageState + ...localStorageEnchancer ) as any; } else { enchancer = compose( - ...localStorageState + ...localStorageEnchancer ) as any; } export const store: Store = createStore( - combineReducers(reducers), + rootReducer, initialState, enchancer ); \ No newline at end of file diff --git a/src/app.common/themes/themes.ts b/src/app.common/themes/themes.ts index cd73418..aafd005 100644 --- a/src/app.common/themes/themes.ts +++ b/src/app.common/themes/themes.ts @@ -32,8 +32,8 @@ function getPalette(dark: boolean, overridePalette: Partial): Partial

{

- changeDarkThemeSetting(value)} + User interface +
+
+ changeShowUTCOffsetSetting(value)} + /> + } + label="Show UTC offset" /> - } - label="Use dark theme" - /> -
-
-
-
- changeShowUTCOffsetSetting(value)} +
+
+
+
+ changeShowTimezoneIdSetting(value)} + /> + } + label="Show Timezone name" /> - } - label="Show UTC offset" - /> -
-
-
-
- changeShowTimezoneIdSetting(value)} +
+
+
+
+ changeShowControlPanelSetting(value)} + /> + } + label="Show bottom panel" /> - } - label="Show Timezone name" - /> -
-
-
-
- changeShowControlPanelSetting(value)} +
+
+
+
+ change24HoursTimeFormatSetting(value)} + /> + } + label="Use 24 hours format" /> - } - label="Show bottom panel" - /> +
+
+
+
+ + Show DST (daylight saving time) DST + } + > + Hide + DST + Summer/Winter + + +
+
-
-
- change24HoursTimeFormatSetting(value)} + Theme +
+
+ changeDarkThemeSetting(value)} + /> + } + label="Use dark theme" /> - } - label="Use 24 hours format" - /> -
-
-
-
- - Show DST (daylight saving time) DST - } - > - hide - DST - Summer/Winter - - -
-
-
-
- changePrimaryColorSetting(color.id)} - /> -
-
-
-
- changeSecondaryColorSetting(color.id)} - /> +
+
+
+
+ changePrimaryColorSetting(color.id)} + /> +
+
+
+
+ changeSecondaryColorSetting(color.id)} + /> +
+
diff --git a/src/app/components/Layout.tsx b/src/app/components/Layout.tsx index 74141e5..2240502 100644 --- a/src/app/components/Layout.tsx +++ b/src/app/components/Layout.tsx @@ -1,21 +1,21 @@ -import { formatTime } from "../../app.common/util/time"; -import * as React from "react"; -import { connect, ActionCreator } from "react-redux"; -import * as moment from "moment"; +import AdjustIcon from "material-ui-icons/Adjust"; +import KeyboardArrowLeftIcon from "material-ui-icons/KeyboardArrowLeft"; +import KeyboardArrowRightIcon from "material-ui-icons/KeyboardArrowRight"; +import SettingsIcon from "material-ui-icons/Settings"; import Button from "material-ui/Button"; import IconButton from "material-ui/IconButton"; -import Icon from "material-ui/Icon"; -import SettingsIcon from 'material-ui-icons/Settings'; -import KeyboardArrowLeftIcon from 'material-ui-icons/KeyboardArrowLeft'; -import KeyboardArrowRightIcon from 'material-ui-icons/KeyboardArrowRight'; import Paper from "material-ui/Paper"; import Typography from "material-ui/Typography"; -import { withTheme, Theme } from "material-ui/styles"; +import * as moment from "moment"; +import * as React from "react"; +import { ActionCreator, connect } from "react-redux"; -import { TimeLine, Clock, Range, TimeSelector } from "../../app.common/components"; -import { changeSelectedTimeSpan, changeScrollPostion } from "../../app.common/actions"; -import { getOffset, getHoursWithOffset, DisplaySettingsInfo, TimeSpanInfo, CalendarEvent, ScrollPosition } from "../../app.common/models"; +import { changeScrollPostion, changeSelectedTimeSpan, resetScrollPostion } from "../../app.common/actions"; +import { Clock, Range, TimeLine, TimeSelector } from "../../app.common/components"; +import { CalendarEvent, DisplaySettingsInfo, getOffset, ScrollPosition, TimeSpanInfo, getHoursWithOffset } from "../../app.common/models"; import { IAppState } from "../../app.common/store"; +import { formatTime } from "../../app.common/util/time"; + const style = require("./Layout.css"); interface ILayoutStateProps { @@ -29,36 +29,77 @@ interface ILayoutStateProps { interface ILayoutDispatchProps { changeSelectedTimeSpan?: ActionCreator, changeScrollPostion?: ActionCreator, + resetScrollPostion?: ActionCreator, } type ILayoutProps = ILayoutStateProps & ILayoutDispatchProps; class LayoutImpl extends React.Component { + get positionCentered(): boolean { + const { position } = this.props.scrollPosition; + return position === 0; + } + get maxPositionReached(): boolean { const { position, step, maxLimit } = this.props.scrollPosition; - return position + step > maxLimit + return position + step > maxLimit; + } + + get rangeValue(): { valueMin: number, valueMax: number, rangeSize: number } { + const { position } = this.props.scrollPosition; + const { startHour, startMinute, endHour, endMinute } = this.props.selectedTimeSpan; + const { selectionStep } = this.props.displaySettings; + const stepsInHour = 60 / selectionStep; + const rangeSize = stepsInHour * 24; + + return { + valueMin: Math.max(startHour * stepsInHour + startMinute / selectionStep, 0), + valueMax: Math.min(endHour * stepsInHour + endMinute / selectionStep, rangeSize), + rangeSize, + }; } get minPositionReached(): boolean { const { position, step, minLimit } = this.props.scrollPosition; - return position - step < minLimit + return position - step < minLimit; } incrementScrollPosition() { const { position, step } = this.props.scrollPosition; - this.props.changeScrollPostion(position + step) + this.props.changeScrollPostion(position + step); } decrementScrollPosition() { const { position, step } = this.props.scrollPosition; - this.props.changeScrollPostion(position - step) + this.props.changeScrollPostion(position - step); + } + + updateSelectedTimeRange(start: number, end: number) { + const { position } = this.props.scrollPosition; + const { selectionStep } = this.props.displaySettings; + const stepsInHour = 60 / selectionStep; + const startHour = Math.floor(start / stepsInHour) + position; + const startMinute = (start % stepsInHour) * selectionStep; + const endHour = Math.floor(end / stepsInHour) + position; + const endMinute = (end % stepsInHour) * selectionStep; + this.props.changeSelectedTimeSpan(startHour, startMinute, endHour, endMinute); + } + + resetScrollPosition() { + this.props.resetScrollPostion(); } render(): React.ReactElement { - const { displaySettings, selectedTimeSpan, changeSelectedTimeSpan, timeLines, rangeColor, scrollPosition } = this.props; - const valueMin = selectedTimeSpan.startHour * 2 + selectedTimeSpan.startMinute / 30; - const valueMax = selectedTimeSpan.endHour * 2 + selectedTimeSpan.endMinute / 30; + const { + displaySettings, + selectedTimeSpan, + timeLines, + rangeColor, + scrollPosition + } = this.props; + const { valueMin, valueMax, rangeSize } = this.rangeValue; + console.log("min, max", valueMin, valueMax); const startTime = moment().hours(selectedTimeSpan.startHour).minutes(selectedTimeSpan.startMinute); const endTime = moment().hours(selectedTimeSpan.endHour).minutes(selectedTimeSpan.endMinute); if (selectedTimeSpan.endHour === 24) { @@ -77,6 +118,12 @@ class LayoutImpl extends React.Component { > + this.resetScrollPosition()} + > + + this.decrementScrollPosition()} @@ -89,7 +136,7 @@ class LayoutImpl extends React.Component {
- +
{timeLines.map(tl => @@ -98,7 +145,7 @@ class LayoutImpl extends React.Component {
- changeSelectedTimeSpan(valueMin, valueMax)} /> + this.updateSelectedTimeRange(valueMin, valueMax)} />
{displaySettings.showControlPanel ? (
@@ -143,5 +190,6 @@ export const Layout = connect Date: Sun, 10 Dec 2017 11:50:52 +0100 Subject: [PATCH 4/8] added time selection step setting --- .../actions/DisplaySettingsActions.ts | 7 +++++++ .../reducers/DisplaySettingsReducer.ts | 3 +++ src/app.common/store.ts | 3 +-- .../components/DisplaySettings.tsx | 19 +++++++++++++++++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/app.common/actions/DisplaySettingsActions.ts b/src/app.common/actions/DisplaySettingsActions.ts index af00ccf..09f6759 100644 --- a/src/app.common/actions/DisplaySettingsActions.ts +++ b/src/app.common/actions/DisplaySettingsActions.ts @@ -43,4 +43,11 @@ export function change24HoursTimeFormatSetting(value: boolean): Action type: "DISPLAY_SETTINGS/TOGGLE_24_HOURS", payload: value }; +} + +export function changeTimeSelectionStepSetting(value: number): Action { + return { + type: "DISPLAY_SETTINGS/CHANGE_TIME_SELECTION_STEP", + payload: value + }; } \ No newline at end of file diff --git a/src/app.common/reducers/DisplaySettingsReducer.ts b/src/app.common/reducers/DisplaySettingsReducer.ts index 547919d..86c32b6 100644 --- a/src/app.common/reducers/DisplaySettingsReducer.ts +++ b/src/app.common/reducers/DisplaySettingsReducer.ts @@ -34,6 +34,9 @@ export const reducer = function (state: State = initialState, action: ActioncreateLogger)()) ]; - const composeEnhancers = compose; - // const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; + const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose; enchancer = composeEnhancers( ...devEnchansers, ...localStorageEnchancer diff --git a/src/app.options/components/DisplaySettings.tsx b/src/app.options/components/DisplaySettings.tsx index 2153987..c266100 100644 --- a/src/app.options/components/DisplaySettings.tsx +++ b/src/app.options/components/DisplaySettings.tsx @@ -17,6 +17,7 @@ import { changeShowTimezoneIdSetting, changeShowUTCOffsetSetting, change24HoursTimeFormatSetting, + changeTimeSelectionStepSetting, } from "../../app.common/actions"; import { DisplaySettingsInfo } from "../../app.common/models"; import { AppTheme } from "../../app.common/models/AppTheme"; @@ -33,6 +34,7 @@ interface DisplaySettingsDispatchProps { changePrimaryColorSetting?: ActionCreator; changeSecondaryColorSetting?: ActionCreator; change24HoursTimeFormatSetting?: ActionCreator; + changeTimeSelectionStepSetting?: ActionCreator; } interface DisplaySettingsStateProps { @@ -61,6 +63,7 @@ class DisplaySettingsImpl extends React.Component { changeDarkThemeSetting, changePrimaryColorSetting, changeSecondaryColorSetting, + changeTimeSelectionStepSetting, theme, } = this.props; @@ -140,6 +143,21 @@ class DisplaySettingsImpl extends React.Component {
+
+
+ + Time selection step + } + > + 15 + 30 + + +
+
Theme @@ -197,5 +215,6 @@ export const DisplaySettings = connect, changeSecondaryColorSetting: changeSecondaryColor as ActionCreator, change24HoursTimeFormatSetting: change24HoursTimeFormatSetting as ActionCreator, + changeTimeSelectionStepSetting: changeTimeSelectionStepSetting as ActionCreator, } )(DisplaySettingsImpl); From 03bdef211d529b8639b1e5278e6891029236382b Mon Sep 17 00:00:00 2001 From: Lev Mishin Date: Sun, 10 Dec 2017 12:03:36 +0100 Subject: [PATCH 5/8] fixed range behavior if max=min fixed scroll behavior --- src/app.common/components/Range.tsx | 11 +++++++++-- src/app/components/Layout.tsx | 8 ++++---- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/app.common/components/Range.tsx b/src/app.common/components/Range.tsx index 33b3428..8ab574b 100644 --- a/src/app.common/components/Range.tsx +++ b/src/app.common/components/Range.tsx @@ -80,7 +80,15 @@ export class Range extends React.Component { event.preventDefault(); const { valueMin, valueMax } = this.state; const x = this.getCoordinateInRange(event); - const hold = Math.abs(x - valueMin) <= Math.abs(x - valueMax) ? "min" : "max"; + const distToMin = Math.abs(x - valueMin); + const distToMax = Math.abs(x - valueMax); + const hold = distToMin == distToMax + ? x > valueMax + ? "max" + : "min" + : distToMin < distToMax + ? "min" + : "max"; this.onHold(hold); this.movePointer(x, hold); } @@ -123,7 +131,6 @@ export class Range extends React.Component { } getRangeRect() { - // tslint:disable-next-line:no-string-literal return ReactDOM.findDOMNode(this.refs["rangeBase"]).getBoundingClientRect(); } diff --git a/src/app/components/Layout.tsx b/src/app/components/Layout.tsx index 2240502..e045be4 100644 --- a/src/app/components/Layout.tsx +++ b/src/app/components/Layout.tsx @@ -54,8 +54,8 @@ class LayoutImpl extends React.Component { const rangeSize = stepsInHour * 24; return { - valueMin: Math.max(startHour * stepsInHour + startMinute / selectionStep, 0), - valueMax: Math.min(endHour * stepsInHour + endMinute / selectionStep, rangeSize), + valueMin: Math.min(rangeSize, Math.max((startHour + position) * stepsInHour + startMinute / selectionStep, 0)), + valueMax: Math.max(Math.min((endHour + position) * stepsInHour + endMinute / selectionStep, rangeSize), 0), rangeSize, }; } @@ -79,9 +79,9 @@ class LayoutImpl extends React.Component { const { position } = this.props.scrollPosition; const { selectionStep } = this.props.displaySettings; const stepsInHour = 60 / selectionStep; - const startHour = Math.floor(start / stepsInHour) + position; + const startHour = Math.floor(start / stepsInHour) - position; const startMinute = (start % stepsInHour) * selectionStep; - const endHour = Math.floor(end / stepsInHour) + position; + const endHour = Math.floor(end / stepsInHour) - position; const endMinute = (end % stepsInHour) * selectionStep; this.props.changeSelectedTimeSpan(startHour, startMinute, endHour, endMinute); } From 3b5d65d38e5ff5a443651db005d39ef01c6fb2e8 Mon Sep 17 00:00:00 2001 From: Lev Mishin Date: Sun, 10 Dec 2017 14:23:53 +0100 Subject: [PATCH 6/8] remove console.log --- src/app/components/Layout.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/src/app/components/Layout.tsx b/src/app/components/Layout.tsx index e045be4..8e1c390 100644 --- a/src/app/components/Layout.tsx +++ b/src/app/components/Layout.tsx @@ -99,7 +99,6 @@ class LayoutImpl extends React.Component { scrollPosition } = this.props; const { valueMin, valueMax, rangeSize } = this.rangeValue; - console.log("min, max", valueMin, valueMax); const startTime = moment().hours(selectedTimeSpan.startHour).minutes(selectedTimeSpan.startMinute); const endTime = moment().hours(selectedTimeSpan.endHour).minutes(selectedTimeSpan.endMinute); if (selectedTimeSpan.endHour === 24) { From 305fe50caac609fd19118d597e1d68c2a5d50427 Mon Sep 17 00:00:00 2001 From: Lev Mishin Date: Sun, 10 Dec 2017 14:40:32 +0100 Subject: [PATCH 7/8] added tootips --- src/app/components/Layout.tsx | 52 +++++++++++++++++++++-------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/src/app/components/Layout.tsx b/src/app/components/Layout.tsx index 8e1c390..7a2eb5d 100644 --- a/src/app/components/Layout.tsx +++ b/src/app/components/Layout.tsx @@ -6,6 +6,7 @@ import Button from "material-ui/Button"; import IconButton from "material-ui/IconButton"; import Paper from "material-ui/Paper"; import Typography from "material-ui/Typography"; +import Tooltip from "material-ui/Tooltip"; import * as moment from "moment"; import * as React from "react"; import { ActionCreator, connect } from "react-redux"; @@ -98,6 +99,7 @@ class LayoutImpl extends React.Component { rangeColor, scrollPosition } = this.props; + const scrollStep = scrollPosition.step; const { valueMin, valueMax, rangeSize } = this.rangeValue; const startTime = moment().hours(selectedTimeSpan.startHour).minutes(selectedTimeSpan.startMinute); const endTime = moment().hours(selectedTimeSpan.endHour).minutes(selectedTimeSpan.endMinute); @@ -111,27 +113,35 @@ class LayoutImpl extends React.Component {
- this.incrementScrollPosition()} - > - - - this.resetScrollPosition()} - > - - - this.decrementScrollPosition()} - > - - - - - + + this.incrementScrollPosition()} + > + + + + + this.resetScrollPosition()} + > + + + + + this.decrementScrollPosition()} + > + + + + + + + +
From 27cb09b37d81aa74a97ff47b5d6f04e9640f1a4a Mon Sep 17 00:00:00 2001 From: Lev Mishin Date: Sun, 10 Dec 2017 14:43:33 +0100 Subject: [PATCH 8/8] fixed tootip for reset button --- src/app/components/Layout.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/app/components/Layout.tsx b/src/app/components/Layout.tsx index 7a2eb5d..1cd2550 100644 --- a/src/app/components/Layout.tsx +++ b/src/app/components/Layout.tsx @@ -122,12 +122,14 @@ class LayoutImpl extends React.Component { - this.resetScrollPosition()} - > - - +
+ this.resetScrollPosition()} + > + + +