aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAkshay <[email protected]>2020-11-23 14:01:15 +0000
committerAkshay <[email protected]>2020-11-23 14:01:15 +0000
commit615f4398f2b118a0142d752433d7eb1fc77f2301 (patch)
tree8b63898317c63d854cfdd22404b69375f417f0a5
parent86bd94ec91e88f3a50a02daf051fcca316db09a5 (diff)
fix layouting, finish styling
-rw-r--r--src/Base.elm1
-rw-r--r--src/Main.elm59
-rw-r--r--src/Styles.elm87
-rw-r--r--src/Views.elm83
4 files changed, 149 insertions, 81 deletions
diff --git a/src/Base.elm b/src/Base.elm
index 480147a..1d19723 100644
--- a/src/Base.elm
+++ b/src/Base.elm
@@ -25,6 +25,7 @@ type alias Model =
25 , config : Config 25 , config : Config
26 , currentWord : Int 26 , currentWord : Int
27 , inputBox : String 27 , inputBox : String
28 , inputCorrect : Bool
28 } 29 }
29 30
30 31
diff --git a/src/Main.elm b/src/Main.elm
index 4ca4934..2b1cc67 100644
--- a/src/Main.elm
+++ b/src/Main.elm
@@ -4,14 +4,14 @@ import Array exposing (..)
4import Base exposing (..) 4import Base exposing (..)
5import Browser 5import Browser
6import Css 6import Css
7import Css.Global exposing (everything, global, selector) 7import Css.Global exposing (body, everything, global, selector)
8import Data exposing (..) 8import Data exposing (..)
9import Html 9import Html
10import Html.Styled exposing (..) 10import Html.Styled exposing (..)
11import Html.Styled.Attributes exposing (..) 11import Html.Styled.Attributes exposing (..)
12import Html.Styled.Events exposing (onClick, onInput) 12import Html.Styled.Events exposing (onClick, onInput)
13import Random 13import Random
14import Styles exposing (styledButton, styledInput, styledTextBox) 14import Styles exposing (styledButton, styledInput, styledTextBox, wordStyle)
15import Task 15import Task
16import Time 16import Time
17import Utils exposing (isJust, isNothing) 17import Utils exposing (isJust, isNothing)
@@ -44,7 +44,7 @@ generateWords config =
44 44
45defaultModel : Model 45defaultModel : Model
46defaultModel = 46defaultModel =
47 Model Nothing Nothing Array.empty Nothing defaultConfig 0 "" 47 Model Nothing Nothing Array.empty Nothing defaultConfig 0 "" False
48 48
49 49
50init : () -> ( Model, Cmd Msg ) 50init : () -> ( Model, Cmd Msg )
@@ -143,8 +143,11 @@ update msg model =
143 143
144 else 144 else
145 Cmd.none 145 Cmd.none
146
147 inpStat =
148 String.startsWith s (currentContents model)
146 in 149 in
147 ( { model | inputBox = s } 150 ( { model | inputBox = s, inputCorrect = inpStat }
148 , cmd 151 , cmd
149 ) 152 )
150 153
@@ -183,28 +186,13 @@ update msg model =
183 ) 186 )
184 187
185 188
186wordStyle : WordStatus -> Attribute msg
187wordStyle w =
188 case w of
189 Correct ->
190 style "color" "green"
191
192 Wrong ->
193 style "color" "red"
194
195 Todo ->
196 style "color" "black"
197
198 CurrentWord ->
199 style "color" "magenta"
200
201
202toPara : Array Word -> Int -> String -> Html Msg 189toPara : Array Word -> Int -> String -> Html Msg
203toPara words current content = 190toPara words current content =
204 words 191 words
205 |> Array.map (\w -> span [ wordStyle w.status ] [ text (w.content ++ " ") ]) 192 |> Array.map (\w -> span [ css [ wordStyle w.status ] ] [ text w.content ])
206 |> Array.set current (span [ wordStyle CurrentWord ] [ text (content ++ " ") ]) 193 |> Array.set current (span [ css [ wordStyle CurrentWord ] ] [ text content ])
207 |> Array.toList 194 |> Array.toList
195 |> List.intersperse (span [] [ text " " ])
208 |> styledTextBox [] 196 |> styledTextBox []
209 197
210 198
@@ -217,20 +205,33 @@ currentContents model =
217 205
218view : Model -> Html Msg 206view : Model -> Html Msg
219view model = 207view model =
220 div [] 208 div
221 [ div [] 209 [ style "width" "95%"
210 , style "max-width" "650px"
211 , style "margin" "auto"
212 , style "padding-top" "15%"
213 ]
214 [ div
215 [ style "width" "100%"
216 ]
222 [ viewWordLengthOptions 217 [ viewWordLengthOptions
223 , viewStats model 218 , div
219 [ style "float" "right" ]
220 [ styledButton [ onClick Redo ] [ text "redo" ] ]
224 ] 221 ]
225 , div [] 222 , div []
226 [ toPara model.words model.currentWord (currentContents model) 223 [ toPara model.words model.currentWord (currentContents model)
227 , div [] 224 , div []
228 [ styledInput [ onInput handleInputChanged, value model.inputBox ] [] 225 [ text "> "
229 , styledButton [ onClick Redo ] [ text "redo" ] 226 , styledInput model.inputCorrect [ onInput handleInputChanged, value model.inputBox ] []
230 ] 227 ]
231 ] 228 ]
232 , global [ selector "li:not(:last-child)::after" [ Css.property "content" "' / '" ] ] 229 , div [] [ viewStats model ]
233 , global [ everything [ Css.fontFamily Css.monospace ] ] 230
231 -- , global [ selector "li:not(:last-child)::after" [ Css.property "content" "' · '" ] ]
232 , global [ everything [ Css.fontFamily Css.monospace, Css.fontSize (Css.px 18) ] ]
233
234 -- , global [ body [ Css.backgroundColor (Css.hex "#000"), Css.color (Css.hex "#fff") ] ]
234 ] 235 ]
235 236
236 237
diff --git a/src/Styles.elm b/src/Styles.elm
index 36bd1a3..db5b0ce 100644
--- a/src/Styles.elm
+++ b/src/Styles.elm
@@ -1,5 +1,6 @@
1module Styles exposing (..) 1module Styles exposing (..)
2 2
3import Base exposing (WordStatus(..))
3import Css exposing (..) 4import Css exposing (..)
4import Css.Global exposing (global, selector) 5import Css.Global exposing (global, selector)
5import Html 6import Html
@@ -10,27 +11,43 @@ styledButton : List (Attribute msg) -> List (Html msg) -> Html msg
10styledButton = 11styledButton =
11 styled 12 styled
12 button 13 button
13 [ margin (px 12) 14 [ marginTop (px 12)
14 , color (hex "#000") 15 , marginBottom (px 12)
16 , paddingTop (px 12)
17 , paddingBottom (px 12)
18 , paddingLeft (px 0)
19 , paddingRight (px 12)
15 , fontFamily monospace 20 , fontFamily monospace
16 , backgroundColor (hex "#ddd")
17 , border (px 0) 21 , border (px 0)
22 , backgroundColor (hex "#fff")
18 , borderRadius (px 4) 23 , borderRadius (px 4)
19 , padding (px 12)
20 ] 24 ]
21 25
22 26
23styledInput : List (Attribute msg) -> List (Html msg) -> Html msg 27correctInputStyle : Style
24styledInput = 28correctInputStyle =
29 color (hex "#000")
30
31
32wrongInputStyle : Style
33wrongInputStyle =
34 wrongWordStyle
35
36
37styledInput : Bool -> List (Attribute msg) -> List (Html msg) -> Html msg
38styledInput inputStatus =
25 styled 39 styled
26 input 40 input
27 [ margin (px 12) 41 [ fontFamily monospace
28 , color (hex "#000") 42 , if inputStatus then
29 , fontFamily monospace 43 correctInputStyle
30 , backgroundColor (hex "#eee") 44
31 , border (px 0) 45 else
32 , borderRadius (px 4) 46 wrongInputStyle
33 , padding (px 12) 47 , border zero
48 , paddingTop (px 12)
49 , paddingBottom (px 12)
50 , width (pct 95)
34 ] 51 ]
35 52
36 53
@@ -55,14 +72,12 @@ styledTextBox : List (Attribute msg) -> List (Html msg) -> Html msg
55styledTextBox = 72styledTextBox =
56 styled 73 styled
57 div 74 div
58 [ margin (px 12) 75 [ color (hex "#000")
59 , color (hex "#000")
60 , fontFamily monospace 76 , fontFamily monospace
61 , backgroundColor (hex "#eee")
62 , border (px 0) 77 , border (px 0)
63 , borderRadius (px 4) 78 , borderRadius (px 4)
64 , padding (px 12) 79 , paddingTop (px 12)
65 , width (px 500) 80 , paddingBottom (px 12)
66 , display inlineBlock 81 , display inlineBlock
67 ] 82 ]
68 83
@@ -74,3 +89,39 @@ actionContainer =
74 [ padding (px 12) 89 [ padding (px 12)
75 , width (pct 100) 90 , width (pct 100)
76 ] 91 ]
92
93
94wrongWordStyle : Style
95wrongWordStyle =
96 color (hex "#f07178")
97
98
99correctWordStyle : Style
100correctWordStyle =
101 color (hex "#13CA91")
102
103
104todoWordStyle : Style
105todoWordStyle =
106 color (hex "#787878")
107
108
109currentWordStyle : Style
110currentWordStyle =
111 textDecoration underline
112
113
114wordStyle : WordStatus -> Style
115wordStyle w =
116 case w of
117 Correct ->
118 correctWordStyle
119
120 Wrong ->
121 wrongWordStyle
122
123 Todo ->
124 todoWordStyle
125
126 CurrentWord ->
127 currentWordStyle
diff --git a/src/Views.elm b/src/Views.elm
index b56a945..b54fc93 100644
--- a/src/Views.elm
+++ b/src/Views.elm
@@ -5,10 +5,11 @@ import Base exposing (..)
5import Css exposing (..) 5import Css exposing (..)
6import Html 6import Html
7import Html.Styled exposing (..) 7import Html.Styled exposing (..)
8import Html.Styled.Attributes exposing (css)
8import Html.Styled.Events exposing (onClick) 9import Html.Styled.Events exposing (onClick)
9import Styles exposing (styledListItem, styledUnorderedList) 10import Styles exposing (styledButton, styledListItem, styledUnorderedList)
10import Time exposing (Posix, toHour, toMinute, toSecond, utc) 11import Time exposing (Posix, toHour, toMinute, toSecond, utc)
11import Utils exposing (diffDuration, wordCountWith) 12import Utils exposing (diffDuration, isNothing, wordCountWith)
12 13
13 14
14viewTime : Posix -> String 15viewTime : Posix -> String
@@ -26,7 +27,7 @@ viewTime t =
26 String.join ":" (List.map String.fromInt [ hh, mm, ss ]) 27 String.join ":" (List.map String.fromInt [ hh, mm, ss ])
27 28
28 29
29viewWpm : Model -> String 30viewWpm : Model -> Maybe String
30viewWpm model = 31viewWpm model =
31 let 32 let
32 t1 = 33 t1 =
@@ -40,11 +41,8 @@ viewWpm model =
40 41
41 correctWords = 42 correctWords =
42 wordCountWith model.words ((==) Correct) 43 wordCountWith model.words ((==) Correct)
43
44 wpm =
45 Maybe.map (String.fromInt << truncate << (*) 60 << (/) (toFloat correctWords)) duration
46 in 44 in
47 Maybe.withDefault "XX" wpm 45 Maybe.map (String.fromInt << truncate << (*) 60 << (/) (toFloat correctWords)) duration
48 46
49 47
50viewProgress : Model -> String 48viewProgress : Model -> String
@@ -59,28 +57,30 @@ viewProgress model =
59 String.fromInt soFar ++ ":" ++ String.fromInt total 57 String.fromInt soFar ++ ":" ++ String.fromInt total
60 58
61 59
62viewAccuracy : Array Word -> String 60viewAccuracy : Model -> Maybe String
63viewAccuracy words = 61viewAccuracy model =
64 let 62 if isNothing model.end then
65 wordsAttempted = 63 Nothing
66 toFloat <| wordCountWith words ((/=) Todo)
67 64
68 correctCount = 65 else
69 toFloat <| wordCountWith words ((==) Correct) 66 let
67 words =
68 model.words
70 69
71 accuracy = 70 wordsAttempted =
72 if wordsAttempted == 0.0 then 71 toFloat <| wordCountWith words ((/=) Todo)
73 Nothing
74 72
75 else 73 correctCount =
76 Just <| correctCount / wordsAttempted * 100 74 toFloat <| wordCountWith words ((==) Correct)
77 in 75
78 case accuracy of 76 accuracy =
79 Nothing -> 77 if wordsAttempted == 0.0 then
80 "XX" 78 Nothing
81 79
82 Just a -> 80 else
83 String.fromInt <| truncate a 81 Just <| String.fromInt <| truncate <| correctCount / wordsAttempted * 100
82 in
83 accuracy
84 84
85 85
86viewWordLengthOptions : Html Msg 86viewWordLengthOptions : Html Msg
@@ -89,12 +89,20 @@ viewWordLengthOptions =
89 wl = 89 wl =
90 [ 10, 25, 50, 100 ] 90 [ 10, 25, 50, 100 ]
91 in 91 in
92 styledUnorderedList [] 92 ul
93 [ css
94 [ margin zero
95 , listStyle Css.none
96 , display inlineBlock
97 , paddingLeft (px 0)
98 ]
99 ]
93 (List.map 100 (List.map
94 (\len -> 101 (\len ->
95 styledListItem 102 li [ css [ display inline ] ]
96 [ onClick (Base.WordLengthChanged len) ] 103 [ styledButton [ onClick (Base.WordLengthChanged len) ]
97 [ text <| String.fromInt len ] 104 [ text <| String.fromInt len ]
105 ]
98 ) 106 )
99 wl 107 wl
100 ) 108 )
@@ -102,8 +110,15 @@ viewWordLengthOptions =
102 110
103viewStats : Model -> Html Msg 111viewStats : Model -> Html Msg
104viewStats model = 112viewStats model =
105 styledUnorderedList [] 113 let
106 [ styledListItem [] [ text ("WPM " ++ viewWpm model) ] 114 wpm =
107 , styledListItem [] [ text ("ACC " ++ viewAccuracy model.words) ] 115 viewWpm model
108 , styledListItem [] [ text ("POS " ++ viewProgress model) ] 116
109 ] 117 acc =
118 viewAccuracy model
119
120 stats =
121 Maybe.map2 (\w a -> w ++ " words per minute · " ++ a ++ "% accuracy") wpm acc
122 in
123 p []
124 [ text (Maybe.withDefault "" stats) ]