Skip to content
This repository was archived by the owner on May 26, 2022. It is now read-only.

Commit d09b098

Browse files
author
Adam Haglund
authored
only cache parts of state we want (#16)
1 parent b49cda8 commit d09b098

File tree

4 files changed

+75
-45
lines changed

4 files changed

+75
-45
lines changed

src/state/epics/cacheEpics.ts

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,34 @@ import { isActionOf } from 'typesafe-actions'
44

55
import { IRootActions, IRootState } from '@state/index'
66
import { setTime } from '@state/actions/timerActions'
7-
import { addUser, removeUser, setActive, setOrder } from '@state/actions/usersActions'
7+
import {
8+
addUser,
9+
removeUser,
10+
setActive,
11+
setOrder,
12+
} from '@state/actions/usersActions'
813

914
type EpicType = Epic<IRootActions, IRootActions, IRootState>
1015
const SAVE_TIMEOUT = 1000
1116
let saveTimer: number | null
1217

18+
export interface ICachedState {
19+
timer: {
20+
timeLeft: {
21+
minutes: number
22+
seconds: number
23+
}
24+
duration: {
25+
minutes: number
26+
seconds: number
27+
}
28+
}
29+
users: {
30+
list: string[]
31+
activeUser: number
32+
}
33+
}
34+
1335
export const cacheSaveSettingsEpic: EpicType = (action$, state$) =>
1436
action$.pipe(
1537
filter(isActionOf([setTime, addUser, removeUser, setOrder, setActive])), // More?
@@ -18,9 +40,19 @@ export const cacheSaveSettingsEpic: EpicType = (action$, state$) =>
1840
clearTimeout(saveTimer)
1941
}
2042

21-
const stateToSave: any = JSON.parse(JSON.stringify(state$.value))
22-
stateToSave.timer.timeLeft = stateToSave.timer.duration
23-
stateToSave.timer.timerLoop = null
43+
const state = state$.value
44+
const stateToSave: ICachedState = {
45+
timer: {
46+
// Set time left to duration so when people refresh page
47+
// the timer has reset
48+
timeLeft: state.timer.duration,
49+
duration: state.timer.duration,
50+
},
51+
users: {
52+
list: state.users.list as string[],
53+
activeUser: state.users.activeUser,
54+
},
55+
}
2456

2557
saveTimer = window.setTimeout(() => {
2658
localStorage.setItem('cache', JSON.stringify(stateToSave))

src/state/reducers/timerReducers.ts

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Reducer } from 'redux'
22

33
import { IRootActions } from '@state/index'
4+
import { ICachedState } from '@state/epics/cacheEpics'
45
import {
56
COUNT_DOWN_ONE_SECOND,
67
SET_TIME,
@@ -12,10 +13,10 @@ import {
1213
import { Time } from '../../time'
1314

1415
export interface IStateTimer {
15-
readonly counting: boolean
16-
readonly timeLeft: Time
17-
readonly duration: Time
18-
readonly notifications: ReadonlyArray<Notification>
16+
counting: boolean
17+
timeLeft: Time
18+
duration: Time
19+
notifications: ReadonlyArray<Notification>
1920
}
2021

2122
const initialState: IStateTimer = {
@@ -25,18 +26,23 @@ const initialState: IStateTimer = {
2526
notifications: [],
2627
}
2728

28-
const cachedSettings = JSON.parse(
29+
const { timer: cachedTimer } = JSON.parse(
2930
localStorage.getItem('cache') || '{ "timer": null }'
30-
).timer
31-
32-
if (cachedSettings) {
33-
cachedSettings.timeLeft = Time.fromTime(cachedSettings.timeLeft)
34-
35-
cachedSettings.duration = Time.fromTime(cachedSettings.duration)
31+
) as ICachedState
32+
33+
if (cachedTimer) {
34+
initialState.timeLeft = new Time(
35+
initialState.timeLeft.minutes,
36+
initialState.timeLeft.seconds
37+
)
38+
initialState.duration = new Time(
39+
cachedTimer.duration.minutes,
40+
cachedTimer.duration.seconds
41+
)
3642
}
3743

3844
export const timerReducers: Reducer<IStateTimer, IRootActions> = (
39-
state = { ...initialState, ...cachedSettings },
45+
state = { ...initialState },
4046
action
4147
) => {
4248
switch (action.type) {
@@ -75,13 +81,9 @@ export const timerReducers: Reducer<IStateTimer, IRootActions> = (
7581
case ADD_NOTIFICATION:
7682
return {
7783
...state,
78-
notifications: [
79-
action.payload,
80-
...state.notifications,
81-
],
84+
notifications: [action.payload, ...state.notifications],
8285
}
8386

84-
8587
default:
8688
return state
8789
}

src/state/reducers/usersReducers.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { Reducer } from 'redux'
22

33
import { IRootActions } from '@state/index'
4+
import { ICachedState } from '@state/epics/cacheEpics'
45
import {
56
ADD_USER,
67
REMOVE_USER,
@@ -11,9 +12,9 @@ import {
1112
} from '@state/actions/constants'
1213

1314
export interface IStateUsers {
14-
readonly list: ReadonlyArray<string>
15-
readonly activeUser: number
16-
readonly hideUserList: boolean
15+
list: ReadonlyArray<string>
16+
activeUser: number
17+
hideUserList: boolean
1718
}
1819

1920
const initialState: IStateUsers = {
@@ -22,12 +23,17 @@ const initialState: IStateUsers = {
2223
hideUserList: true,
2324
}
2425

25-
const cachedSettings = JSON.parse(
26+
const { users: cachedUsers } = JSON.parse(
2627
localStorage.getItem('cache') || '{ "users": null }'
27-
).users
28+
) as ICachedState
29+
30+
if (cachedUsers) {
31+
initialState.list = cachedUsers.list
32+
initialState.activeUser = cachedUsers.activeUser
33+
}
2834

2935
export const usersReducers: Reducer<IStateUsers, IRootActions> = (
30-
state = { ...initialState, ...cachedSettings },
36+
state = { ...initialState },
3137
action
3238
) => {
3339
switch (action.type) {

src/time.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,8 @@ export class Time {
33
public readonly seconds: number
44

55
constructor(minutes: number = 0, seconds: number = 0) {
6-
this.minutes = this.clamp(minutes, 0, 99)
7-
this.seconds = this.clamp(seconds, 0, 59)
8-
}
9-
10-
private clamp(x: number, min: number, max: number) {
11-
return Math.max(min, Math.min(x, max))
6+
this.minutes = Time.clamp(minutes, 0, 99)
7+
this.seconds = Time.clamp(seconds, 0, 59)
128
}
139

1410
public toString() {
@@ -32,21 +28,15 @@ export class Time {
3228
return new Time(newMinutes, newSeconds)
3329
}
3430

35-
public static fromTime = (time: Time) => new Time(time.minutes, time.seconds)
36-
37-
public static fromString = (str: string) => {
38-
const match = str.match(/^(\d{2}):(\d{2})$/)
39-
40-
if (!match || !match[1] || !match[2] || match[3]) {
41-
throw new Error('Invalid Time String')
42-
}
43-
44-
return new Time(Number(match[1]), Number(match[2]))
45-
}
46-
4731
public equals(other: Time) {
4832
return this.minutes === other.minutes && this.seconds === other.seconds
4933
}
5034

5135
public toSeconds = () => this.minutes * 60 + this.seconds
36+
37+
private static clamp(x: number, min: number, max: number) {
38+
return Math.max(min, Math.min(x, max))
39+
}
40+
41+
public static fromTime = (time: Time) => new Time(time.minutes, time.seconds)
5242
}

0 commit comments

Comments
 (0)