module State exposing (..)
import Date exposing (Date)
import Set exposing (Set)
import Task
import Time exposing (Weekday(..))
type alias WeekdayLabel =
String
type alias HabitLabel =
String
type Msg
= DoNothing
| SetView View
| ReceiveDate Date
| ToggleHabit WeekdayLabel HabitLabel
| MaybeAdjustWeekday
| ViewToday
| ViewPrevious
| ViewNext
| ClearAll
| ToggleMorning
| ToggleEvening
type View
= Habits
type HabitType
= Morning
| Evening
| DayOfWeek
| Payday
| FirstOfTheMonth
| FirstOfTheYear
type alias Habit =
{ label : HabitLabel
, habitType : HabitType
, minutesDuration : Int
}
type alias CompletedHabits =
Set ( WeekdayLabel, HabitLabel )
type alias Model =
{ isLoading : Bool
, view : View
, today : Maybe Date
, completed : CompletedHabits
, visibleDayOfWeek : Maybe Weekday
, includeMorning : Bool
, includeEvening : Bool
}
previousDay : Weekday -> Weekday
previousDay weekday =
case weekday of
Mon ->
Sun
Tue ->
Mon
Wed ->
Tue
Thu ->
Wed
Fri ->
Thu
Sat ->
Fri
Sun ->
Sat
nextDay : Weekday -> Weekday
nextDay weekday =
case weekday of
Mon ->
Tue
Tue ->
Wed
Wed ->
Thu
Thu ->
Fri
Fri ->
Sat
Sat ->
Sun
Sun ->
Mon
{-| The initial state for the application.
-}
init : ( Model, Cmd Msg )
init =
( { isLoading = False
, view = Habits
, today = Nothing
, completed = Set.empty
, visibleDayOfWeek = Nothing
, includeMorning = True
, includeEvening = True
}
, Date.today |> Task.perform ReceiveDate
)
{-| Now that we have state, we need a function to change the state.
-}
update : Msg -> Model -> ( Model, Cmd Msg )
update msg ({ today, visibleDayOfWeek, completed } as model) =
case msg of
DoNothing ->
( model, Cmd.none )
SetView x ->
( { model
| view = x
, isLoading = True
}
, Cmd.none
)
ReceiveDate x ->
( { model
| today = Just x
, visibleDayOfWeek = Just (Date.weekday x)
}
, Cmd.none
)
ToggleHabit weekdayLabel habitLabel ->
( { model
| completed =
if Set.member ( weekdayLabel, habitLabel ) completed then
Set.remove ( weekdayLabel, habitLabel ) completed
else
Set.insert ( weekdayLabel, habitLabel ) completed
}
, Cmd.none
)
MaybeAdjustWeekday ->
( model, Date.today |> Task.perform ReceiveDate )
ViewToday ->
( { model | visibleDayOfWeek = today |> Maybe.map Date.weekday }, Cmd.none )
ViewPrevious ->
( { model
| visibleDayOfWeek = visibleDayOfWeek |> Maybe.map previousDay
}
, Cmd.none
)
ViewNext ->
( { model
| visibleDayOfWeek = visibleDayOfWeek |> Maybe.map nextDay
}
, Cmd.none
)
ClearAll ->
( { model | completed = Set.empty }, Cmd.none )
ToggleMorning ->
( { model | includeMorning = not model.includeMorning }, Cmd.none )
ToggleEvening ->
( { model | includeEvening = not model.includeEvening }, Cmd.none )