Skip to content

Commit 3facdd7

Browse files
authored
Merge pull request #23 from 414owen/rm-all-compiler-warnings
Remove all compiler warnings
2 parents fac08a3 + a0376a5 commit 3facdd7

File tree

1 file changed

+52
-33
lines changed

1 file changed

+52
-33
lines changed

src/Reflex/TodoMVC.hs

+52-33
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
{-# LANGUAGE TypeFamilies #-}
88
module Reflex.TodoMVC where
99

10-
import Prelude hiding (mapM, mapM_, all, sequence)
10+
import Prelude hiding (mapM, mapM_, sequence)
1111

1212
import Control.Monad hiding (mapM, mapM_, forM, forM_, sequence)
1313
import Control.Monad.Fix
@@ -23,7 +23,6 @@ import GHCJS.DOM.Types (JSM)
2323

2424
import Reflex
2525
import Reflex.Dom.Core
26-
import Data.Text.Encoding (encodeUtf8)
2726

2827
--------------------------------------------------------------------------------
2928
-- Model
@@ -115,21 +114,23 @@ taskEntry
115114
)
116115
=> m (Event t Task)
117116
taskEntry = el "header" $ do
118-
-- Create the textbox; it will be cleared whenever the user presses enter
119-
rec let newValueEntered = ffilter (keyCodeIs Enter . fromIntegral) (_textInput_keypress descriptionBox)
120-
descriptionBox <- textInput $ def
121-
& textInputConfig_setValue .~ fmap (const "") newValueEntered
122-
& textInputConfig_attributes .~ constDyn (mconcat [ "class" =: "new-todo"
123-
, "placeholder" =: "What needs to be done?"
124-
, "name" =: "newTodo"
125-
])
126-
-- -- Request focus on this element when the widget is done being built
127-
-- schedulePostBuild $ liftIO $ focus $ _textInput_element descriptionBox
128-
let -- | Get the current value of the textbox whenever the user hits enter
129-
newValue = tag (current $ _textInput_value descriptionBox) newValueEntered
130-
-- -- Set focus when the user enters a new Task
131-
-- performEvent_ $ fmap (const $ liftIO $ focus $ _textInput_element descriptionBox) newValueEntered
132-
return $ fmap (\d -> Task d False) $ fmapMaybe stripDescription newValue
117+
-- Create the textbox; it will be cleared whenever the user presses enter
118+
rec let newValueEntered = keypress Enter descriptionBox
119+
descriptionBox <- inputElement $ def
120+
& inputElementConfig_setValue .~ fmap (const "") newValueEntered
121+
& inputElementConfig_elementConfig . elementConfig_initialAttributes .~
122+
mconcat [ "class" =: "new-todo"
123+
, "placeholder" =: "What needs to be done?"
124+
, "name" =: "newTodo"
125+
, "type" =: "text"
126+
]
127+
-- -- Request focus on this element when the widget is done being built
128+
-- schedulePostBuild $ liftIO $ focus $ _textInput_element descriptionBox
129+
let -- | Get the current value of the textbox whenever the user hits enter
130+
newValue = tag (current $ value descriptionBox) newValueEntered
131+
-- -- Set focus when the user enters a new Task
132+
-- performEvent_ $ fmap (const $ liftIO $ focus $ _textInput_element descriptionBox) newValueEntered
133+
return $ fmap (\d -> Task d False) $ fmapMaybe stripDescription newValue
133134

134135
-- | Display the user's Tasks, subject to a Filter; return requested modifications to the Task list
135136
taskList
@@ -144,10 +145,9 @@ taskList
144145
-> Dynamic t (Map k Task)
145146
-> m (Event t (Map k Task -> Map k Task))
146147
taskList activeFilter tasks = elAttr "section" ("class" =: "main") $ do
147-
-- Create "toggle all" button
148148
let toggleAllState = all taskCompleted . Map.elems <$> tasks
149149
toggleAllAttrs = ffor tasks $ \t -> "class" =: "toggle-all" <> "name" =: "toggle" <> if Map.null t then "style" =: "visibility:hidden" else mempty
150-
toggleAll <- checkboxView toggleAllAttrs toggleAllState
150+
toggleAll <- toggleInput toggleAllAttrs toggleAllState
151151
elAttr "label" ("for" =: "toggle-all") $ text "Mark all as complete"
152152
-- Filter the item list
153153
let visibleTasks = zipDynWith (Map.filter . satisfiesFilter) activeFilter tasks
@@ -162,11 +162,29 @@ taskList activeFilter tasks = elAttr "section" ("class" =: "main") $ do
162162
let combineItemChanges = fmap (foldl' (.) id) . mergeList . map (\(k, v) -> fmap (flip Map.update k) v) . Map.toList
163163
itemChangeEvent = fmap combineItemChanges items
164164
itemChanges = switch $ current itemChangeEvent
165-
-- Change all items' completed state when the toggleAll button is clicked
166-
toggleAllChanges = fmap (\oldAllCompletedState -> fmap (\t -> t { taskCompleted = not oldAllCompletedState })) $ tag (current toggleAllState) toggleAll
167-
return $ mergeWith (.) [ itemChanges
168-
, toggleAllChanges
169-
]
165+
return itemChanges
166+
167+
toggleInput
168+
:: ( DomBuilder t m
169+
, DomBuilderSpace m ~ GhcjsDomSpace
170+
, MonadFix m
171+
, MonadHold t m
172+
, PostBuild t m
173+
)
174+
=> Dynamic t (Map AttributeName Text)
175+
-> Dynamic t Bool
176+
-> m (Event t ())
177+
toggleInput dynAttrs dynChecked = do
178+
let attrs = (<> "class" =: "toggle") . ("type" =: "checkbox" <>) <$> dynAttrs
179+
updatedAttrs = fmap Just <$> updated dynAttrs
180+
updatedChecked = updated dynChecked
181+
initialAttrs <- sample $ current attrs
182+
initialChecked <- sample $ current dynChecked
183+
domEvent Click <$> inputElement (def
184+
& inputElementConfig_initialChecked .~ initialChecked
185+
& inputElementConfig_setChecked .~ updatedChecked
186+
& inputElementConfig_elementConfig . elementConfig_modifyAttributes .~ updatedAttrs
187+
& inputElementConfig_elementConfig . elementConfig_initialAttributes .~ initialAttrs)
170188

171189
buildCompletedCheckbox
172190
:: ( DomBuilder t m
@@ -181,8 +199,8 @@ buildCompletedCheckbox
181199
buildCompletedCheckbox todo description = elAttr "div" ("class" =: "view") $ do
182200
-- Display the todo item's completed status, and allow it to be set
183201
completed <- holdUniqDyn $ fmap taskCompleted todo
184-
completedCheckbox <- checkboxView (constDyn $ "class" =: "toggle") completed
185-
let setCompleted = fmap not $ tag (current completed) completedCheckbox
202+
checkboxClicked <- toggleInput (constDyn mempty) completed
203+
let setCompleted = fmap not $ tag (current completed) checkboxClicked
186204
-- Display the todo item's name for viewing purposes
187205
(descriptionLabel, _) <- el' "label" $ dynText description
188206
-- Display the button for deleting the todo item
@@ -213,16 +231,17 @@ todoItem todo = do
213231
(setCompleted, destroy, startEditing) <- buildCompletedCheckbox todo description
214232
-- Set the current value of the editBox whenever we start editing (it's not visible in non-editing mode)
215233
let setEditValue = tag (current description) $ ffilter id $ updated editing'
216-
editBox <- textInput $ def
217-
& textInputConfig_setValue .~ setEditValue
218-
& textInputConfig_attributes .~ constDyn ("class" =: "edit" <> "name" =: "title")
234+
editBox <- inputElement $ def
235+
& inputElementConfig_setValue .~ setEditValue
236+
& inputElementConfig_elementConfig . elementConfig_initialAttributes
237+
.~ ("class" =: "edit" <> "name" =: "title")
219238
let -- Set the todo item's description when the user leaves the textbox or presses enter in it
220-
setDescription = tag (current $ _textInput_value editBox) $ leftmost
221-
[ void $ ffilter (keyCodeIs Enter . fromIntegral) $ _textInput_keypress editBox
222-
, void $ ffilter not $ updated $ _textInput_hasFocus editBox
239+
setDescription = tag (current $ value editBox) $ leftmost
240+
[ keypress Enter editBox
241+
, domEvent Blur editBox
223242
]
224243
-- Cancel editing (without changing the item's description) when the user presses escape in the textbox
225-
cancelEdit = void $ ffilter (keyCodeIs Escape . fromIntegral) $ _textInput_keydown editBox
244+
cancelEdit = keypress Escape editBox
226245
-- Put together all the ways the todo item can change itself
227246
changeSelf = mergeWith (>=>) [ fmap (\c t -> Just $ t { taskCompleted = c }) setCompleted
228247
, fmap (const $ const Nothing) destroy

0 commit comments

Comments
 (0)