module ServerCommunication ( Communication(..) , sendRequest , serverCommunications ) where import Signal import Task as Task exposing (Task) import Http import Json.Decode exposing (..) import Date import Model.Message exposing (messageDecoder) import Model.Payment exposing (PaymentId, perPage, paymentsDecoder) import Update as U import Update.SignIn exposing (..) import Update.Payment as UP type Communication = NoCommunication | SignIn String | AddPayment String String Int | DeletePayment PaymentId String Int Int | UpdatePage Int | SignOut serverCommunications : Signal.Mailbox Communication serverCommunications = Signal.mailbox NoCommunication sendRequest : Communication -> Task Http.RawError U.Action sendRequest communication = case getRequest communication of Nothing -> Task.succeed U.NoOp Just request -> (Http.send Http.defaultSettings request) `Task.andThen` (serverResult communication) getRequest : Communication -> Maybe Http.Request getRequest communication = case communication of NoCommunication -> Nothing SignIn login -> Just (simple "post" ("/signIn?login=" ++ login)) AddPayment userName paymentName cost -> Just (simple "post" ("/payment/add?name=" ++ paymentName ++ "&cost=" ++ (toString cost))) DeletePayment paymentId _ _ _ -> Just (simple "post" ("payment/delete?id=" ++ paymentId)) UpdatePage page -> Just (updatePageRequest page) SignOut -> Just (simple "post" "/signOut") updatePageRequest : Int -> Http.Request updatePageRequest page = simple "get" ("payments?page=" ++ toString page ++ "&perPage=" ++ toString perPage) simple : String -> String -> Http.Request simple method url = { verb = method , headers = [] , url = url , body = Http.empty } serverResult : Communication -> Http.Response -> Task Http.RawError U.Action serverResult communication response = if response.status == 200 then case communication of NoCommunication -> Task.succeed U.NoOp SignIn login -> Task.succeed (U.UpdateSignIn (ValidLogin login)) AddPayment userName paymentName cost -> Http.send Http.defaultSettings (updatePageRequest 1) |> Task.map (\response -> if response.status == 200 then decodeResponse response paymentsDecoder (\payments -> U.UpdatePayment (UP.AddPayment userName cost payments)) else U.NoOp ) DeletePayment id userName cost currentPage -> Http.send Http.defaultSettings (updatePageRequest currentPage) |> Task.map (\response -> if response.status == 200 then decodeResponse response paymentsDecoder (\payments -> U.UpdatePayment (UP.Remove userName cost payments)) else U.NoOp ) UpdatePage page -> decodeResponse response paymentsDecoder (\payments -> U.UpdatePayment (UP.UpdatePage page payments)) |> Task.succeed SignOut -> Task.succeed (U.GoSignInView) else decodeResponse response messageDecoder (\error -> case communication of SignIn _ -> U.UpdateSignIn (ErrorLogin error) _ -> U.NoOp ) |> Task.succeed decodeResponse : Http.Response -> Decoder a -> (a -> U.Action) -> U.Action decodeResponse response decoder responseToAction = case response.value of Http.Text text -> case decodeString decoder text of Ok x -> responseToAction x Err _ -> U.NoOp Http.Blob _ -> U.NoOp