-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathStore.kt
More file actions
114 lines (102 loc) · 3.75 KB
/
Store.kt
File metadata and controls
114 lines (102 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
package com.chaidarun.chronofile
import android.util.Log
import com.jakewharton.rxrelay2.BehaviorRelay
import com.jakewharton.rxrelay2.PublishRelay
import io.reactivex.Observable
/** All actions must be immutable */
sealed class Action {
data class AddEntry(
val activity: String,
val note: String?,
val latLong: Pair<Double, Double>?
) : Action()
data class EditEntry(
val oldStartTime: Long,
val newStartTime: String,
val activity: String,
val note: String
) : Action()
data class RemoveEntry(val entry: Long) : Action()
data class SetConfigFromText(val text: String) : Action()
data class SetConfigFromFile(val config: Config) : Action()
data class SetGraphGrouping(val grouped: Boolean) : Action()
data class SetGraphMetric(val metric: Metric) : Action()
data class SetGraphRangeEnd(val timestamp: Long) : Action()
data class SetGraphRangeStart(val timestamp: Long) : Action()
data class SetGraphStacking(val stacked: Boolean) : Action()
data class SetHistory(val history: History) : Action()
}
/** This class must be deeply immutable and preferably printable */
data class State(
val config: Config? = null,
val history: History? = null,
val graphConfig: GraphConfig = GraphConfig()
)
private val reducer: (State, Action) -> State = { state, action ->
with(state) {
val start = System.currentTimeMillis()
val nextState = when (action) {
is Action.AddEntry -> copy(
history = history?.withNewEntry(
action.activity, action.note, action.latLong
)
)
is Action.EditEntry -> copy(
history = history?.withEditedEntry(
action.oldStartTime, action.newStartTime, action.activity, action.note
)
)
is Action.RemoveEntry -> copy(history = history?.withoutEntry(action.entry))
is Action.SetConfigFromText ->
try {
val config = Config.fromText(action.text)
App.toast("Saved config")
copy(config = config)
} catch (e: Throwable) {
App.toast("Failed to save invalid config")
this
}
is Action.SetConfigFromFile -> copy(config = action.config)
is Action.SetGraphGrouping -> copy(
graphConfig = graphConfig.copy(grouped = action.grouped)
)
is Action.SetGraphMetric -> copy(graphConfig = graphConfig.copy(metric = action.metric))
is Action.SetGraphRangeEnd -> {
val timestamp = action.timestamp
val newSettings = if (timestamp >= state.graphConfig.startTime ?: 0) {
graphConfig.copy(endTime = timestamp)
} else {
graphConfig.copy(endTime = timestamp, startTime = timestamp)
}
copy(graphConfig = newSettings)
}
is Action.SetGraphRangeStart -> {
val timestamp = action.timestamp
val newSettings = if (timestamp <= state.graphConfig.endTime ?: Long.MAX_VALUE) {
graphConfig.copy(startTime = timestamp)
} else {
graphConfig.copy(endTime = timestamp, startTime = timestamp)
}
copy(graphConfig = newSettings)
}
is Action.SetGraphStacking -> copy(
graphConfig = graphConfig.copy(stacked = action.stacked)
)
is Action.SetHistory -> copy(history = action.history)
}
Log.i(TAG, "Reduced $action in ${System.currentTimeMillis() - start} ms")
nextState
}
}
/** API heavily inspired by Redux */
object Store {
private val stateRelay: BehaviorRelay<State> = BehaviorRelay.create()
private val actionRelay = PublishRelay.create<Action>().apply {
scan(State(), reducer).distinctUntilChanged().subscribe { stateRelay.accept(it) }
}
val state: State
get() = stateRelay.value
val observable: Observable<State>
get() = stateRelay
fun dispatch(action: Action) = actionRelay.accept(action)
}