-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathMain.hs
106 lines (88 loc) · 3.5 KB
/
Main.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
module Main where
import qualified Common
import Data.Proxy
import qualified Lucid as L
import qualified Lucid.Base as L
import qualified Network.HTTP.Types as HTTP
import qualified Network.Wai as Wai
import qualified Network.Wai.Handler.Warp as Wai
import qualified Network.Wai.Middleware.Gzip as Wai
import qualified Network.Wai.Middleware.RequestLogger as Wai
import qualified Servant
import Servant ( (:>), (:<|>)(..) )
import qualified System.IO as IO
import qualified Miso
import Miso ( View )
main :: IO ()
main = do
IO.hPutStrLn IO.stderr "Running on port 3003..."
Wai.run 3003 $ Wai.logStdout $ compress app
where
compress :: Wai.Middleware
compress = Wai.gzip Wai.def { Wai.gzipFiles = Wai.GzipCompress }
app :: Wai.Application
app =
Servant.serve (Proxy @ServerAPI)
( static
:<|> serverHandlers
:<|> Servant.Tagged page404
)
where
static :: Servant.Server StaticAPI
static = Servant.serveDirectoryFileServer "static"
serverHandlers :: Servant.Server ServerRoutes
serverHandlers = homeServer :<|> flippedServer
-- Alternative type:
-- Servant.Server (ToServerRoutes Common.Home HtmlPage Common.Action)
-- Handles the route for the home page, rendering Common.homeView.
homeServer :: Servant.Handler (HtmlPage (View Common.Action))
homeServer =
pure $ HtmlPage $
Common.viewModel $
Common.initialModel Common.homeLink
-- Alternative type:
-- Servant.Server (ToServerRoutes Common.Flipped HtmlPage Common.Action)
-- Renders the /flipped page.
flippedServer :: Servant.Handler (HtmlPage (View Common.Action))
flippedServer =
pure $ HtmlPage $
Common.viewModel $
Common.initialModel Common.flippedLink
-- The 404 page is a Wai application because the endpoint is Raw.
-- It just renders the page404View and sends it to the client.
page404 :: Wai.Application
page404 _ respond = respond $ Wai.responseLBS
HTTP.status404 [("Content-Type", "text/html")] $
L.renderBS $ L.toHtml Common.page404View
-- | Represents the top level Html code. Its value represents the body of the
-- page.
newtype HtmlPage a = HtmlPage a
deriving (Show, Eq)
instance L.ToHtml a => L.ToHtml (HtmlPage a) where
toHtmlRaw = L.toHtml
toHtml (HtmlPage x) = do
L.doctype_
L.head_ $ do
L.title_ "Miso isomorphic example"
L.meta_ [L.charset_ "utf-8"]
L.with (L.script_ mempty)
[ L.makeAttribute "src" "/static/all.js"
, L.makeAttribute "async" mempty
, L.makeAttribute "defer" mempty
]
L.body_ (L.toHtml x)
-- Converts the ClientRoutes (which are a servant tree of routes leading to
-- some `View action`) to lead to `Get '[Html] (HtmlPage (View Common.Action))`
type ServerRoutes
= Miso.ToServerRoutes Common.ViewRoutes HtmlPage Common.Action
-- The server serves static files besides the ServerRoutes, among which is the
-- javascript file of the client.
type ServerAPI =
StaticAPI
:<|> (ServerRoutes
:<|> Servant.Raw) -- This will show the 404 page for any unknown route
type StaticAPI = "static" :> Servant.Raw