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.User exposing (UserId) import Model.Payment exposing (..) import Model.View.Payment.Add exposing (Frequency) import Update as U import Update.SignIn exposing (..) import Update.LoggedView as UL type Communication = NoCommunication | SignIn String | AddPayment UserId String Int Frequency | DeletePayment PaymentId UserId 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 |> flip 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 userId name cost frequency -> Just (simple "post" ("/payment/add?name=" ++ name ++ "&cost=" ++ (toString cost) ++ "&frequency=" ++ (toString frequency))) DeletePayment paymentId _ _ _ -> Just (simple "post" ("payment/delete?id=" ++ (toString 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 userId name cost frequency -> decodeResponse response ("id" := paymentIdDecoder) (\paymentId -> Http.send Http.defaultSettings (updatePageRequest 1) |> flip Task.andThen (\response2 -> if response2.status == 200 then decodeResponse response2 paymentsDecoder (\payments -> Task.succeed <| U.UpdateLoggedView (UL.AddPayment userId paymentId name cost frequency payments)) else Task.succeed U.NoOp ) ) DeletePayment id userId cost currentPage -> Http.send Http.defaultSettings (updatePageRequest currentPage) |> flip Task.andThen (\response -> if response.status == 200 then decodeResponse response paymentsDecoder (\payments -> Task.succeed <| U.UpdateLoggedView (UL.Remove userId cost payments)) else Task.succeed U.NoOp ) UpdatePage page -> decodeResponse response paymentsDecoder (\payments -> Task.succeed <| U.UpdateLoggedView (UL.UpdatePage page payments)) SignOut -> Task.succeed (U.GoSignInView) else decodeResponse response messageDecoder (\error -> case communication of SignIn _ -> Task.succeed <| U.UpdateSignIn (ErrorLogin error) _ -> Task.succeed <| U.NoOp ) decodeResponse : Http.Response -> Decoder a -> (a -> Task b U.Action) -> Task b U.Action decodeResponse response decoder responseToAction = case response.value of Http.Text text -> case decodeString decoder text of Ok x -> responseToAction x Err _ -> Task.succeed U.NoOp Http.Blob _ -> Task.succeed U.NoOp