@@ -4,44 +4,31 @@
5module Obelisk.Snap where
5module Obelisk.Snap where
7−import Obelisk.Asset.Serve
7+import Obelisk.Asset.Serve.Snap
8+import Obelisk.Snap.Extras
9import Snap
10import Snap
11import Control.Lens
12import Control.Lens
12import Data.ByteString (ByteString)
13import Data.ByteString (ByteString)
13import Data.Default
14import Data.Default
15import Data.Monoid
15import Data.Monoid
17−import Data.Text (Text)
18import qualified Data.Text as T
16import qualified Data.Text as T
19−import Diagrams.Prelude (Diagram, renderDia, mkWidth)
20−import Diagrams.Backend.SVG
21−import qualified Graphics.Svg as SVG
22−import Graphics.Svg.Attributes
23import Lucid
17import Lucid
24import System.FilePath
18import System.FilePath
25−import Text.RawString.QQ
26import Control.Monad.IO.Class
19import Control.Monad.IO.Class
28-- Data type for web app configuration
21-- Data type for web app configuration
29data AppConfig m
22data AppConfig m
30− = AppConfig { _appConfig_logo :: Diagram SVG
31− , _appConfig_extraHeadMarkup :: Html ()
32− , _appConfig_initialStyles :: Maybe Text
33− , _appConfig_initialBody :: Maybe (m ByteString)
23+ = AppConfig { _appConfig_initialBody :: m ByteString
34− , _appConfig_initialHead :: Maybe ByteString
24+ , _appConfig_initialHead :: ByteString
35 , _appConfig_serveJsexe :: Bool
25 , _appConfig_serveJsexe :: Bool
36 , _appConfig_jsexe :: FilePath
26 , _appConfig_jsexe :: FilePath
39-- Default instance for app configuration
29-- Default instance for app configuration
40−instance Default (AppConfig m) where
30+instance Monad m => Default (AppConfig m) where
41− def = AppConfig { _appConfig_logo = mempty
42− , _appConfig_extraHeadMarkup = mempty
43− , _appConfig_initialStyles = mempty
44− , _appConfig_initialBody = Nothing
31+ def = AppConfig { _appConfig_initialBody = return mempty
45 , _appConfig_initialHead = mempty
32 , _appConfig_initialHead = mempty
46 , _appConfig_serveJsexe = True
33 , _appConfig_serveJsexe = True
47 , _appConfig_jsexe = "frontend.jsexe"
34 , _appConfig_jsexe = "frontend.jsexe"
@@ -83,28 +70,18 @@ frontendJsAssetsPath (AppConfig { _appConfig_jsexe = jsexe }) = "frontendJs.asse
83-- Helper funtion used in 'serveAppAt', writes a lazy bytestring to the body of Http response
70-- Helper funtion used in 'serveAppAt', writes a lazy bytestring to the body of Http response
84serveStaticIndex :: MonadSnap m => AppConfig m -> m ()
71serveStaticIndex :: MonadSnap m => AppConfig m -> m ()
85serveStaticIndex cfg = do
72serveStaticIndex cfg = do
86− -- Decode, pack, and append asset target to file path
73+ -- Decode, pack, and append asset target to file path
87 appJsPath <- liftIO $ getAssetPath (frontendJsAssetsPath cfg) "/all.js"
74 appJsPath <- liftIO $ getAssetPath (frontendJsAssetsPath cfg) "/all.js"
88− -- extract initial body from 'AppConfig' or return empty string
89− initialBody <- fromMaybe (return "") $ _appConfig_initialBody cfg
75+ initialBody <- _appConfig_initialBody cfg
90− -- extract inital head from 'AppConfig' or return empty string
91− let initialHead = fromMaybe "" $ _appConfig_initialHead cfg
92− -- extract initial styles from 'AppConfig' or return empty string
93− let initialStyles = fromMaybe "" $ _appConfig_initialStyles cfg
95− -- Render and write html head and body to response
76+ -- Render and write html head and body to response
96 writeLBS $ renderBS $ doctypehtml_ $ do
77 writeLBS $ renderBS $ doctypehtml_ $ do
97 head_ $ do
78 head_ $ do
98 meta_ [charset_ "utf-8"] -- meta-data charset description
79 meta_ [charset_ "utf-8"] -- meta-data charset description
99 meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1.0"] -- meta-data viewport description
80 meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1.0"] -- meta-data viewport description
100− _appConfig_extraHeadMarkup cfg -- any additional <head> html from 'AppConfig' type
81+ toHtmlRaw $ _appConfig_initialHead cfg
101− toHtmlRaw initialHead -- HtmlT monad wrapper
102− style_ initialStyles -- generate style element/attribute
103 body_ $ do -- <body>
82 body_ $ do -- <body>
104 toHtmlRaw initialBody -- HtmlT monad wrapper
83 toHtmlRaw initialBody -- HtmlT monad wrapper
105− script_ [type_ "text/javascript", src_ (maybe "/all.js" T.pack appJsPath), defer_ "defer"] ("" :: String)
84+ script_ [type_ "application/javascript", src_ (maybe "/all.js" T.pack appJsPath), defer_ "defer"] ("" :: String)
106− -- create <script> element
109{- | Takes an AppConfig monad and uses it to generate & write Lazy ByteString
86{- | Takes an AppConfig monad and uses it to generate & write Lazy ByteString
110 to the body of the https response. This one comes with hard coded values
87 to the body of the https response. This one comes with hard coded values
@@ -116,43 +93,7 @@ serveIndex cfg = do
116 head_ $ do
93 head_ $ do
117 meta_ [charset_ "utf-8"]
94 meta_ [charset_ "utf-8"]
118 meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1.0"]
95 meta_ [name_ "viewport", content_ "width=device-width, initial-scale=1.0"]
119− _appConfig_extraHeadMarkup cfg
127− -webkit-animation: fadein 2s; /* Safari, Chrome and Opera > 12.1 */
128− -moz-animation: fadein 2s; /* Firefox < 16 */
129− -ms-animation: fadein 2s; /* Internet Explorer */
130− -o-animation: fadein 2s; /* Opera < 12.1 */
131− animation: fadein 2s;
134− from { opacity: 0; }
138− @-moz-keyframes fadein {
139− from { opacity: 0; }
142− /* Safari, Chrome and Opera > 12.1 */
143− @-webkit-keyframes fadein {
144− from { opacity: 0; }
147− /* Internet Explorer */
148− @-ms-keyframes fadein {
149− from { opacity: 0; }
153 body_ $ do
96 body_ $ do
154− let svgOpts = SVGOptions (mkWidth 400) Nothing "preload-logo-" [bindAttr Id_ "preload-logo"] False
155− toHtml $ SVG.renderBS $ renderDia SVG svgOpts $ _appConfig_logo cfg
156− script_ [type_ "text/javascript", src_ (maybe "/all.js" T.pack appJsPath), defer_ "defer"] ("" :: String)
97+ script_ [type_ "application/javascript", src_ (maybe "/all.js" T.pack appJsPath), defer_ "defer"] ("" :: String)
158makeLenses ''AppConfig
99makeLenses ''AppConfig