diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Main.elm | 2 | ||||
-rw-r--r-- | src/Model/Edition/Edition.elm | 34 | ||||
-rw-r--r-- | src/Model/Edition/NameEdition.elm | 15 | ||||
-rw-r--r-- | src/Model/Edition/TimeEdition.elm (renamed from src/Model/TimerEdition.elm) | 29 | ||||
-rw-r--r-- | src/Model/Model.elm | 9 | ||||
-rw-r--r-- | src/Model/Timer.elm | 8 | ||||
-rw-r--r-- | src/Update/Update.elm | 77 | ||||
-rw-r--r-- | src/Update/UpdateEdition.elm | 30 | ||||
-rw-r--r-- | src/Update/UpdateTimer.elm | 5 | ||||
-rw-r--r-- | src/Update/UpdateTimerEdition.elm | 34 | ||||
-rw-r--r-- | src/View/Timer.elm | 120 |
11 files changed, 217 insertions, 146 deletions
diff --git a/src/Main.elm b/src/Main.elm index 48c7320..4fab1e9 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -30,7 +30,7 @@ input = Signal.mergeMany [ Signal.subscribe updates , Signal.map DeltaTime (fps 30) - , Signal.map (\_ -> ReadOnly) clickAway + , Signal.map (\_ -> ClickAway) clickAway , Signal.map KeyPressed Keyboard.lastPressed ] diff --git a/src/Model/Edition/Edition.elm b/src/Model/Edition/Edition.elm new file mode 100644 index 0000000..89a0b52 --- /dev/null +++ b/src/Model/Edition/Edition.elm @@ -0,0 +1,34 @@ +module Model.Edition.Edition + ( Edition + , Kind(..) + , newEdition + , keyCodeToChar + ) where + +import Keyboard (KeyCode) + +import Model.Id (..) +import Model.Edition.NameEdition as NameEdition +import Model.Edition.TimeEdition as TimeEdition + +type alias Edition = + { id : Id + , kind : Kind + , chars : List Char + } + +type Kind = + Name + | Time + +newEdition id kind = + { id = id + , kind = kind + , chars = [] + } + +keyCodeToChar : Kind -> KeyCode -> Maybe Char +keyCodeToChar kind = + case kind of + Name -> NameEdition.keyCodeToChar + Time -> TimeEdition.keyCodeToChar diff --git a/src/Model/Edition/NameEdition.elm b/src/Model/Edition/NameEdition.elm new file mode 100644 index 0000000..18224ea --- /dev/null +++ b/src/Model/Edition/NameEdition.elm @@ -0,0 +1,15 @@ +module Model.Edition.NameEdition + ( keyCodeToChar + , renderNameEdition + ) where + +import Char +import Keyboard (KeyCode) +import String +import List + +keyCodeToChar : KeyCode -> Maybe Char +keyCodeToChar = Just << Char.fromCode + +renderNameEdition : List Char -> String +renderNameEdition = String.fromList << List.reverse diff --git a/src/Model/TimerEdition.elm b/src/Model/Edition/TimeEdition.elm index 2ec98b7..6999b25 100644 --- a/src/Model/TimerEdition.elm +++ b/src/Model/Edition/TimeEdition.elm @@ -1,8 +1,5 @@ -module Model.TimerEdition - ( TimerEdition - , Numbers - , newTimerEdition - , keyCodeToNumberChar +module Model.Edition.TimeEdition + ( keyCodeToChar , toTime , toMinutesAndSeconds ) where @@ -13,25 +10,11 @@ import Array import String import Keyboard (KeyCode) -import Model.Id (..) - import Utils.List (..) import Utils.Maybe (..) -type alias TimerEdition = - { id : Id - , numbers : Numbers - } - -type alias Numbers = List Char - -newTimerEdition id = - { id = id - , numbers = [] - } - -keyCodeToNumberChar : KeyCode -> Maybe Char -keyCodeToNumberChar code = +keyCodeToChar : KeyCode -> Maybe Char +keyCodeToChar code = List.map (flip keyCodeToCharFromZero code) zeroKeyCodes |> List.foldl orElse Nothing @@ -46,14 +29,14 @@ keyCodeToCharFromZero zero code = |> Array.get (code - zero) else Nothing -toTime : Numbers -> Time +toTime : List Char -> Time toTime numbers = numbers |> toMinutesAndSeconds |> \(a, b) -> (stringToInt a, stringToInt b) |> \(minutes, seconds) -> (toFloat minutes) * 60 * 1000 + (toFloat seconds) * 1000 -toMinutesAndSeconds : Numbers -> (String, String) +toMinutesAndSeconds : List Char -> (String, String) toMinutesAndSeconds numbers = numbers |> List.take 4 diff --git a/src/Model/Model.elm b/src/Model/Model.elm index b929261..c45300b 100644 --- a/src/Model/Model.elm +++ b/src/Model/Model.elm @@ -10,7 +10,7 @@ import Time (Time) import List import Model.Timer (..) -import Model.TimerEdition (..) +import Model.Edition.Edition (..) import Model.Id (..) import Model.IdGenerator (..) @@ -18,17 +18,16 @@ type alias Model = { currentTime : Time , timers : Dict Id Timer , timerIdGenerator : IdGenerator - , timerEdition : Maybe TimerEdition + , edition : Maybe Edition } initialModel : Time -> Model initialModel initialTime = let (id, idGenerator) = getId initialIdGenerator - timerName = "Timer " ++ (toString id) in { currentTime = initialTime - , timers = Dict.insert id (initialTimer initialTime timerName) Dict.empty + , timers = Dict.insert id (initialTimer initialTime) Dict.empty , timerIdGenerator = idGenerator - , timerEdition = Nothing + , edition = Nothing } numberOfTimers : Model -> Int diff --git a/src/Model/Timer.elm b/src/Model/Timer.elm index f05c487..35850fc 100644 --- a/src/Model/Timer.elm +++ b/src/Model/Timer.elm @@ -11,17 +11,17 @@ import Model.TimerState (..) type alias Timer = { creationTime : Time - , name : String + , name : Maybe String , initialTime : Time , currentTime : Time , state : TimerState } -initialTimer : Time -> String -> Timer -initialTimer creationTime name = +initialTimer : Time -> Timer +initialTimer creationTime = let initialTime = 5 * 60 * 1000 in { creationTime = creationTime - , name = name + , name = Nothing , initialTime = initialTime , currentTime = initTime initialTime , state = Idle diff --git a/src/Update/Update.elm b/src/Update/Update.elm index fabe0e8..5a4b12a 100644 --- a/src/Update/Update.elm +++ b/src/Update/Update.elm @@ -16,12 +16,14 @@ import List import Model.Model (..) import Model.Timer (..) -import Model.TimerEdition (..) +import Model.Edition.Edition (..) +import Model.Edition.NameEdition (..) +import Model.Edition.TimeEdition (..) import Model.Id (..) import Model.IdGenerator (..) import Update.UpdateTimer (..) -import Update.UpdateTimerEdition (..) +import Update.UpdateEdition (..) import Utils.Maybe (..) @@ -32,9 +34,9 @@ type Action = | DeltaTime Time | UpdateTimer Id TimerAction | RemoveTimer Id - | EditTimer Id - | ValidTimerEdition - | ReadOnly + | Edit Id Kind + | ValidEdition + | ClickAway | KeyPressed KeyCode updates : Signal.Channel Action @@ -54,9 +56,8 @@ update action model = initialModel model.currentTime AddNewTimer -> let (id, newTimerIdGenerator) = getId model.timerIdGenerator - timerName = "Timer " ++ (toString id) in { model - | timers <- Dict.insert id (initialTimer model.currentTime timerName) model.timers + | timers <- Dict.insert id (initialTimer model.currentTime) model.timers , timerIdGenerator <- newTimerIdGenerator } DeltaTime delta -> @@ -65,14 +66,12 @@ update action model = , timers <- Dict.map (\id timer -> updateTimer (SubstractTime delta) timer) model.timers } UpdateTimer id action -> - let maybeTimerEdition = filterMaybe (\timerEdition -> timerEdition.id == id) model.timerEdition - in case maybeTimerEdition of - Just timerEdition -> + let maybeEdition = filterMaybe (\edition -> edition.id == id) model.edition + in case maybeEdition of + Just edition -> { model - | timers <- - updateTimerTime timerEdition model.timers - |> Dict.update id (Maybe.map (updateTimer action)) - , timerEdition <- Nothing + | timers <- Dict.update id (Maybe.map (updateTimer action)) model.timers + , edition <- Nothing } Nothing -> { model | timers <- Dict.update id (Maybe.map (updateTimer action)) model.timers } @@ -82,36 +81,42 @@ update action model = { model | timers <- Dict.remove id model.timers } else model - EditTimer id -> + Edit id kind -> { model - | timerEdition <- Just (newTimerEdition id) + | edition <- Just (newEdition id kind) , timers <- Dict.update id (Maybe.map (updateTimer Pause)) model.timers } - ValidTimerEdition -> - case model.timerEdition of - Just timerEdition -> - { model - | timers <- updateTimerTime timerEdition model.timers - , timerEdition <- Nothing - } - Nothing -> - { model | timerEdition <- Nothing } - ReadOnly -> - { model | timerEdition <- Nothing } + ValidEdition -> + validEdition model + ClickAway -> + { model | edition <- Nothing } KeyPressed keyCode -> if isRemoveKeyCode keyCode then - { model | timerEdition <- Maybe.map (updateTimerEdition DeleteLast) model.timerEdition } + { model | edition <- Maybe.map (updateEdition DeleteLast) model.edition } else - { model | timerEdition <- Maybe.map (updateTimerEdition (AddNumber keyCode)) model.timerEdition } + { model | edition <- Maybe.map (updateEdition (AddChar keyCode)) model.edition } -updateTimerTime : TimerEdition -> Dict Id Timer -> Dict Id Timer -updateTimerTime timerEdition = - if List.isEmpty timerEdition.numbers - then - identity - else - Dict.update timerEdition.id (Maybe.map (updateTimer (SetTime (toTime timerEdition.numbers)))) +validEdition : Model -> Model +validEdition model = + case model.edition of + Just edition -> + if List.isEmpty edition.chars + then + model + else + let action = + case edition.kind of + Name -> + Rename (renderNameEdition edition.chars) + Time -> + SetTime (toTime edition.chars) + in { model + | timers <- Dict.update edition.id (Maybe.map (updateTimer action)) model.timers + , edition <- Nothing + } + Nothing -> + model isRemoveKeyCode : KeyCode -> Bool isRemoveKeyCode = (==) 8 diff --git a/src/Update/UpdateEdition.elm b/src/Update/UpdateEdition.elm new file mode 100644 index 0000000..911a4c1 --- /dev/null +++ b/src/Update/UpdateEdition.elm @@ -0,0 +1,30 @@ +module Update.UpdateEdition + ( updateEdition + , EditionAction(..) + ) where + +import Char (..) + +import Model.Edition.Edition (..) + +import Utils.List (..) + +type EditionAction = + DeleteLast + | AddChar KeyCode + +updateEdition : EditionAction -> Edition -> Edition +updateEdition action edition = + case action of + DeleteLast -> + case maybeTail edition.chars of + Just tailChars -> + { edition | chars <- tailChars } + Nothing -> + edition + AddChar keyCode -> + case keyCodeToChar edition.kind keyCode of + Just char -> + { edition | chars <- char :: edition.chars } + Nothing -> + edition diff --git a/src/Update/UpdateTimer.elm b/src/Update/UpdateTimer.elm index 2e0d9af..30603cd 100644 --- a/src/Update/UpdateTimer.elm +++ b/src/Update/UpdateTimer.elm @@ -10,7 +10,8 @@ import Model.TimerState (..) import Model.Id (..) type TimerAction = - Pause + Rename String + | Pause | ToggleRunning | Stop | SetTime Time @@ -19,6 +20,8 @@ type TimerAction = updateTimer : TimerAction -> Timer -> Timer updateTimer action timer = case action of + Rename name -> + { timer | name <- Just name } Pause -> { timer | state <- Idle } ToggleRunning -> diff --git a/src/Update/UpdateTimerEdition.elm b/src/Update/UpdateTimerEdition.elm deleted file mode 100644 index e9493eb..0000000 --- a/src/Update/UpdateTimerEdition.elm +++ /dev/null @@ -1,34 +0,0 @@ -module Update.UpdateTimerEdition - ( updateTimerEdition - , TimerEditionAction(..) - ) where - -import Char (..) - -import Model.TimerEdition (..) - -import Utils.List (..) - -type TimerEditionAction = - DeleteLast - | AddNumber KeyCode - -updateTimerEdition : TimerEditionAction -> TimerEdition -> TimerEdition -updateTimerEdition action timerEdition = - case action of - DeleteLast -> - case maybeTail timerEdition.numbers of - Just tailNumbers -> - { timerEdition | numbers <- tailNumbers } - Nothing -> - timerEdition - AddNumber keyCode -> - case keyCodeToNumberChar keyCode of - Just char -> - if isDigit char - then - { timerEdition | numbers <- char :: timerEdition.numbers } - else - timerEdition - Nothing -> - timerEdition diff --git a/src/View/Timer.elm b/src/View/Timer.elm index 604b045..100514a 100644 --- a/src/View/Timer.elm +++ b/src/View/Timer.elm @@ -5,15 +5,17 @@ module View.Timer import Html (..) import Html.Attributes (..) import Html.Events (..) -import String import Time (Time) import Signal import Maybe import List +import String import Model.Model (..) import Model.Timer (..) -import Model.TimerEdition (..) +import Model.Edition.Edition (..) +import Model.Edition.NameEdition (..) +import Model.Edition.TimeEdition (..) import Model.TimerState (..) import Model.Id (..) @@ -28,54 +30,75 @@ timerView : Model -> (Id, Timer) -> Html timerView model (id, timer) = div [ class "timer" ] - [ nameBlock (id, timer) - , timeBlock model (id, timer) + [ renderMaybeEdition model id Name (nameBlockReadOnly id timer) (nameBlockEdition id timer) + , renderMaybeEdition model id Time (timeBlockReadOnly id timer) (timeBlockEdition timer) , playPauseBlock (id, timer) , stopBlock (id, timer) , removeBlock (id, timer) ] -nameBlock : (Id, Timer) -> Html -nameBlock (id, timer) = +nameBlockReadOnly : Id -> Timer -> Html +nameBlockReadOnly id timer = button - [ class "name block" ] - [ text timer.name ] + [ class "name block" + , onClick (Signal.send updates (Edit id Name)) + ] + [ text (timerName id timer) ] -timeBlock : Model -> (Id, Timer) -> Html -timeBlock model (id, timer) = - let maybeEdition = filterMaybe (\te -> te.id == id) model.timerEdition - in case maybeEdition of - Just edition -> - let isEmptyEdition = List.isEmpty edition.numbers - in button - [ [ (True, "time block edition") - , (isEmptyEdition, "empty") - ] - |> activatedClasses - , onClick (Signal.send updates ValidTimerEdition) - ] - [ if isEmptyEdition - then - timeWithProgressBar timer - else - text (editionView edition.numbers) - ] +nameBlockEdition : Id -> Timer -> Edition -> Html +nameBlockEdition id timer edition = + button + [ [ (True, "name block edition") + , (List.isEmpty edition.chars, "empty") + ] + |> activatedClasses + , onClick (Signal.send updates ValidEdition) + ] + [ if List.isEmpty edition.chars + then + text (timerName id timer) + else + edition.chars + |> renderNameEdition + |> text + ] - Nothing -> - button - [ [ (True, "time block") - , (timer.state == Ringing, "isRinging") - , (timer.state == Running, "isRunning") - ] - |> activatedClasses - , onClick - <| if timer.state == Ringing - then Signal.send updates (UpdateTimer id Stop) - else Signal.send updates (EditTimer id) - ] - [ timeWithProgressBar timer ] - -editionView : Numbers -> String +timerName : Id -> Timer -> String +timerName id = Maybe.withDefault ("Timer " ++ toString id) << .name + +timeBlockReadOnly : Id -> Timer -> Html +timeBlockReadOnly id timer = + button + [ [ (True, "time block") + , (timer.state == Ringing, "isRinging") + , (timer.state == Running, "isRunning") + ] + |> activatedClasses + , onClick + <| if timer.state == Ringing + then Signal.send updates (UpdateTimer id Stop) + else Signal.send updates (Edit id Time) + ] + [ timeWithProgressBar timer ] + +timeBlockEdition : Timer -> Edition -> Html +timeBlockEdition timer edition = + let isEmptyEdition = List.isEmpty edition.chars + in button + [ [ (True, "time block edition") + , (isEmptyEdition, "empty") + ] + |> activatedClasses + , onClick (Signal.send updates ValidEdition) + ] + [ if isEmptyEdition + then + timeWithProgressBar timer + else + text (editionView edition.chars) + ] + +editionView : List Char -> String editionView numbers = let (minutes, seconds) = toMinutesAndSeconds numbers in minutes ++ " : " ++ seconds @@ -134,3 +157,16 @@ removeBlock (id, timer) = , onClick (Signal.send updates (RemoveTimer id)) ] [ i [ class "fa fa-fw fa-remove" ] [] ] + +renderMaybeEdition : Model -> Id -> Kind -> Html -> (Edition -> Html) -> Html +renderMaybeEdition model id kind readOnlyView editionView = + let maybeEdition = filterMaybe (\edition -> edition.id == id) model.edition + in case maybeEdition of + Just edition -> + if edition.kind == kind + then + editionView edition + else + readOnlyView + Nothing -> + readOnlyView |