aboutsummaryrefslogtreecommitdiff
path: root/src/Main.elm
diff options
context:
space:
mode:
Diffstat (limited to 'src/Main.elm')
-rw-r--r--src/Main.elm137
1 files changed, 7 insertions, 130 deletions
diff --git a/src/Main.elm b/src/Main.elm
index 9a35631..a91e12b 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -1,12 +1,15 @@
1module Main exposing (..) 1module Main exposing (..)
2 2
3import Array exposing (..) 3import Array exposing (..)
4import Base exposing (..)
4import Browser 5import Browser
5import Html exposing (..) 6import Html exposing (..)
6import Html.Attributes exposing (..) 7import Html.Attributes exposing (..)
7import Html.Events exposing (onInput) 8import Html.Events exposing (onInput)
8import Task 9import Task
9import Time 10import Time
11import Utils exposing (isJust, isNothing)
12import Views exposing (..)
10 13
11 14
12main = 15main =
@@ -18,30 +21,6 @@ main =
18 } 21 }
19 22
20 23
21type WordStatus
22 = Correct
23 | Wrong
24 | Todo
25 | CurrentWord
26
27
28type alias Word =
29 { content : String
30 , status : WordStatus
31 }
32
33
34type alias Model =
35 { begin : Maybe Time.Posix
36 , end : Maybe Time.Posix
37 , words : Array Word
38 , accuracy : Maybe Float
39 , length : Int
40 , currentWord : Int
41 , inputBox : String
42 }
43
44
45type Msg 24type Msg
46 = Started Time.Posix 25 = Started Time.Posix
47 | Finished Time.Posix 26 | Finished Time.Posix
@@ -137,26 +116,6 @@ handleWordEnded model =
137 ( newModel, cmd ) 116 ( newModel, cmd )
138 117
139 118
140isNothing : Maybe a -> Bool
141isNothing p =
142 case p of
143 Nothing ->
144 True
145
146 Just a ->
147 False
148
149
150isJust : Maybe a -> Bool
151isJust p =
152 not (isNothing p)
153
154
155flip : (a -> b -> c) -> (b -> a -> c)
156flip f =
157 \x y -> f y x
158
159
160update : Msg -> Model -> ( Model, Cmd Msg ) 119update : Msg -> Model -> ( Model, Cmd Msg )
161update msg model = 120update msg model =
162 case msg of 121 case msg of
@@ -199,21 +158,6 @@ update msg model =
199 ) 158 )
200 159
201 160
202displayTime : Time.Posix -> String
203displayTime t =
204 let
205 hh =
206 Time.toHour Time.utc t
207
208 mm =
209 Time.toMinute Time.utc t
210
211 ss =
212 Time.toSecond Time.utc t
213 in
214 String.join ":" (List.map String.fromInt [ hh, mm, ss ])
215
216
217wordStyle : WordStatus -> Attribute msg 161wordStyle : WordStatus -> Attribute msg
218wordStyle w = 162wordStyle w =
219 case w of 163 case w of
@@ -246,83 +190,16 @@ currentContents model =
246 |> Maybe.withDefault "" 190 |> Maybe.withDefault ""
247 191
248 192
249diffDuration : Time.Posix -> Time.Posix -> Float
250diffDuration t1 t2 =
251 let
252 m1 =
253 Time.posixToMillis t1
254
255 m2 =
256 Time.posixToMillis t2
257 in
258 toFloat (m2 - m1) / 1000
259
260
261viewWpm : Model -> String
262viewWpm model =
263 let
264 t1 =
265 model.begin
266
267 t2 =
268 model.end
269
270 duration =
271 Maybe.map2 diffDuration t1 t2
272
273 correctWords =
274 wordCount model.words ((==) Correct)
275
276 wpm =
277 Maybe.map (String.fromInt << truncate << (*) 60 << (/) (toFloat correctWords)) duration
278 in
279 Maybe.withDefault "XX" wpm
280
281
282wordCount : Array Word -> (WordStatus -> Bool) -> Int
283wordCount words predicate =
284 words |> Array.map .status |> Array.filter predicate |> Array.length
285
286
287viewProgress : Model -> String
288viewProgress model =
289 String.fromInt model.currentWord ++ "/" ++ String.fromInt model.length
290
291
292viewAccuracy : Model -> String
293viewAccuracy model =
294 let
295 wordsAttempted =
296 toFloat <| wordCount model.words ((/=) Todo)
297
298 correctCount =
299 toFloat <| wordCount model.words ((==) Correct)
300
301 accuracy =
302 if wordsAttempted == 0.0 then
303 Nothing
304
305 else
306 Just <| correctCount / wordsAttempted * 100
307 in
308 case accuracy of
309 Nothing ->
310 "XX"
311
312 Just a ->
313 String.fromInt <| truncate a
314
315
316view : Model -> Html Msg 193view : Model -> Html Msg
317view model = 194view model =
318 div [] 195 pre []
319 [ p [] [ text (String.fromInt model.currentWord) ] 196 [ toPara model.words model.currentWord (currentContents model)
320 , toPara model.words model.currentWord (currentContents model)
321 197
322 -- , p [] [ text (Maybe.withDefault "XX" (Maybe.map displayTime model.begin)) ] 198 -- , p [] [ text (Maybe.withDefault "XX" (Maybe.map displayTime model.begin)) ]
323 -- , p [] [ text (Maybe.withDefault "XX" (Maybe.map displayTime model.end)) ] 199 -- , p [] [ text (Maybe.withDefault "XX" (Maybe.map displayTime model.end)) ]
200 , p [] [ text ("POS: " ++ viewProgress (model.currentWord + 1) model.length) ]
324 , p [] [ text ("WPM: " ++ viewWpm model) ] 201 , p [] [ text ("WPM: " ++ viewWpm model) ]
325 , p [] [ text ("ACC: " ++ viewAccuracy model) ] 202 , p [] [ text ("ACC: " ++ viewAccuracy model.words) ]
326 , input [ onInput handleInputChanged, value model.inputBox ] [] 203 , input [ onInput handleInputChanged, value model.inputBox ] []
327 ] 204 ]
328 205