summaryrefslogtreecommitdiff
path: root/Hero
diff options
context:
space:
mode:
Diffstat (limited to 'Hero')
-rw-r--r--Hero/Core.hs67
-rw-r--r--Hero/Host.hs157
-rw-r--r--Hero/Keep.hs40
-rw-r--r--Hero/Look.hs93
-rw-r--r--Hero/Look/Typography.hs2
-rw-r--r--Hero/Node.hs136
-rw-r--r--Hero/Part.hs2
7 files changed, 255 insertions, 242 deletions
diff --git a/Hero/Core.hs b/Hero/Core.hs
index 8f865da..86b0638 100644
--- a/Hero/Core.hs
+++ b/Hero/Core.hs
@@ -77,12 +77,11 @@ comicSlug Comic {..} = snake comicName <> "-" <> comicIssue
-- * user
-data User
- = User
- { userEmail :: Text,
- userName :: Text,
- userLibrary :: [Comic]
- }
+data User = User
+ { userEmail :: Text,
+ userName :: Text,
+ userLibrary :: [Comic]
+ }
deriving (Show, Eq, Generic, Data, Ord)
instance Semigroup User where
@@ -158,7 +157,7 @@ instance Elemental Button where
[ img_ [src_ <| ms <| Pack.icon <> "save.svg"],
span_ [] [text "saved"]
]
- else-- not in library
+ else -- not in library
a_
[class_ "wrs-button", onClick <| ToggleInLibrary c]
@@ -173,7 +172,7 @@ instance Elemental Button where
onClick <| ToggleInLibrary c
]
[img_ [src_ <| ms <| Pack.demo <> "library-add.png"]]
- else-- not in library
+ else -- not in library
button_
[ class_ "button is-large has-background-black-bis",
@@ -231,16 +230,15 @@ findComic id = List.find (\c -> comicId c == id)
--
-- Try to prefix component-specific state with the component initials: 'd' for
-- discover, 'cp' for comic player.
-data Form
- = Form
- { uri :: Api.URI,
- appComics :: RemoteData MisoString [Comic],
- user :: User,
- dMediaInfo :: Maybe Comic,
- cpState :: ComicReaderState,
- cpAudioState :: AudioState,
- magnification :: Magnification
- }
+data Form = Form
+ { uri :: Api.URI,
+ appComics :: RemoteData MisoString [Comic],
+ user :: User,
+ dMediaInfo :: Maybe Comic,
+ cpState :: ComicReaderState,
+ cpAudioState :: AudioState,
+ magnification :: Magnification
+ }
deriving (Show, Eq)
initForm :: Api.URI -> Form
@@ -323,6 +321,7 @@ pubRoutes :: Proxy PubRoutes
pubRoutes = Proxy
-- * pages
+
--
-- TODO: consider making a typeclass, something like:
--
@@ -334,6 +333,7 @@ pubRoutes = Proxy
-- link :: Api.URI
-- ** home
+
--
-- this is the unauthenticated page that you see when you first visit
@@ -481,15 +481,14 @@ discoverFooter =
-- ** comic
-data Comic
- = Comic
- { comicId :: ComicId,
- comicPages :: Integer,
- comicName :: Text,
- -- | Ideally this would be a dynamic number-like type
- comicIssue :: Text,
- comicDescription :: Text
- }
+data Comic = Comic
+ { comicId :: ComicId,
+ comicPages :: Integer,
+ comicName :: Text,
+ -- | Ideally this would be a dynamic number-like type
+ comicIssue :: Text,
+ comicDescription :: Text
+ }
deriving (Show, Eq, Generic, Data, Ord)
instance ToJSON Comic where
@@ -534,11 +533,11 @@ instance IsMediaObject Comic where
<| Pack.demo <> comicSlug comic <> "-logo.png"
]
],
- div_ [class_ "comic-action-menu"] <|
- el </ [Watch comic, Read comic, Save comic lib],
+ div_ [class_ "comic-action-menu"]
+ <| el </ [Watch comic, Read comic, Save comic lib],
p_
[class_ "description"]
- [ text . ms <| comicDescription comic
+ [ text <. ms <| comicDescription comic
]
]
]
@@ -800,7 +799,7 @@ comicVideo _ _ _ =
]
]
--- * general page components & utils
+-- * general page components |> utils
-- | If 'View' had a 'Monoid' instance, then '(text "")' could just be 'mempty'
maybeView :: (a -> View action) -> Maybe a -> View action
@@ -899,9 +898,9 @@ comicControls comic page form =
]
]
where
- leftPage = ms . Legacy.show <| page
- rightPage = ms . Legacy.show <| 1 + page
- totalpages = ms . Legacy.show <| comicPages comic
+ leftPage = ms <. Legacy.show <| page
+ rightPage = ms <. Legacy.show <| 1 + page
+ totalpages = ms <. Legacy.show <| comicPages comic
topbar :: View Move
topbar =
diff --git a/Hero/Host.hs b/Hero/Host.hs
index d547fa5..9d10f02 100644
--- a/Hero/Host.hs
+++ b/Hero/Host.hs
@@ -9,7 +9,6 @@
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE NoImplicitPrelude #-}
-
{-# OPTIONS_GHC -fno-warn-orphans #-}
-- | Hero web app
@@ -83,57 +82,59 @@ main = bracket startup shutdown run
where
run (cfg, app, _) = Warp.run (heroPort cfg) app
prn = IO.hPutStrLn IO.stderr
- startup = Envy.decodeEnv >>= \case
- Left e -> Exit.die e
- Right cfg ->
- do
- keep <- Keep.open (heroKeep cfg)
- skey <- upsertKey (heroSkey cfg)
- say "hero"
- prn <| "port: " ++ show (heroPort cfg)
- prn <| "keep: " ++ heroKeep cfg
- prn <| "node: " ++ heroNode cfg
- prn <| "skey: " ++ heroSkey cfg
- let jwts = Auth.defaultJWTSettings skey
- cs =
- Auth.defaultCookieSettings
- { -- uncomment this for insecure dev
- Auth.cookieIsSecure = Auth.NotSecure,
- Auth.cookieXsrfSetting = Nothing
- }
- ctx = cs :. jwts :. EmptyContext
- proxy = Proxy @(AllRoutes '[Auth.JWT, Auth.Cookie])
- static = serveDirectoryWith <| defaultWebAppSettings <| heroNode cfg
- server =
- -- assets, auth, and the homepage is public
- static
- :<|> cssHandlers
- :<|> pure heroManifest
- :<|> pubHostHandlers
- :<|> authHandler cs jwts
- -- app and api are private
- :<|> wrapAuth (jsonHandlers keep)
- :<|> wrapAuth appHostHandlers
- -- fall through to 404
- :<|> Tagged handle404
- return
- ( cfg,
- serveWithContext
- proxy
- ctx
- server,
- keep
- )
+ startup =
+ Envy.decodeEnv >>= \case
+ Left e -> Exit.die e
+ Right cfg ->
+ do
+ keep <- Keep.open (heroKeep cfg)
+ skey <- upsertKey (heroSkey cfg)
+ say "hero"
+ prn <| "port: " ++ show (heroPort cfg)
+ prn <| "keep: " ++ heroKeep cfg
+ prn <| "node: " ++ heroNode cfg
+ prn <| "skey: " ++ heroSkey cfg
+ let jwts = Auth.defaultJWTSettings skey
+ cs =
+ Auth.defaultCookieSettings
+ { -- uncomment this for insecure dev
+ Auth.cookieIsSecure = Auth.NotSecure,
+ Auth.cookieXsrfSetting = Nothing
+ }
+ ctx = cs :. jwts :. EmptyContext
+ proxy = Proxy @(AllRoutes '[Auth.JWT, Auth.Cookie])
+ static = serveDirectoryWith <| defaultWebAppSettings <| heroNode cfg
+ server =
+ -- assets, auth, and the homepage is public
+ static
+ :<|> cssHandlers
+ :<|> pure heroManifest
+ :<|> pubHostHandlers
+ :<|> authHandler cs jwts
+ -- app and api are private
+ :<|> wrapAuth (jsonHandlers keep)
+ :<|> wrapAuth appHostHandlers
+ -- fall through to 404
+ :<|> Tagged handle404
+ return
+ ( cfg,
+ serveWithContext
+ proxy
+ ctx
+ server,
+ keep
+ )
shutdown :: App -> IO ()
shutdown (_, _, keep) = do
Keep.close keep
return ()
upsertKey :: FilePath -> IO Crypto.JWK
-upsertKey fp = Directory.doesFileExist fp >>= \exists ->
- if exists
- then Auth.readKey fp
- else Auth.writeKey fp >> Auth.readKey fp
+upsertKey fp =
+ Directory.doesFileExist fp >>= \exists ->
+ if exists
+ then Auth.readKey fp
+ else Auth.writeKey fp >> Auth.readKey fp
-- This part is a little confusing. I have:
--
@@ -150,13 +151,12 @@ upsertKey fp = Directory.doesFileExist fp >>= \exists ->
-- | This can be generalized I think, put in Biz.App, or something
type App = (Config, Application, AcidState Keep.HeroKeep)
-data Config
- = Config
- { heroPort :: Warp.Port,
- heroNode :: FilePath,
- heroKeep :: FilePath,
- heroSkey :: FilePath
- }
+data Config = Config
+ { heroPort :: Warp.Port,
+ heroNode :: FilePath,
+ heroKeep :: FilePath,
+ heroSkey :: FilePath
+ }
deriving (Generic, Show)
instance Envy.DefConfig Config where
@@ -206,12 +206,13 @@ type CssRoute = "css" :> "main.css" :> Get '[CSS] Text
cssHandlers :: Server CssRoute
cssHandlers =
- return . Lazy.toStrict . Clay.render <| Typography.main <> Look.main
+ return <. Lazy.toStrict <. Clay.render <| Typography.main <> Look.main
type AuthRoute =
"auth"
:> ReqBody '[JSON] LoginForm
- :> Post '[JSON]
+ :> Post
+ '[JSON]
( Headers
'[ Header "Set-Cookie" Auth.SetCookie,
Header "Set-Cookie" Auth.SetCookie
@@ -291,37 +292,37 @@ instance L.ToHtml a => L.ToHtml (Templated a) where
L.link_
[ L.rel_ "apple-touch-icon",
L.sizes_ "180x180",
- L.href_ <|
- Pack.cdnEdge
- <> "/old-assets/images/favicons/apple-touch-icon.png"
+ L.href_
+ <| Pack.cdnEdge
+ <> "/old-assets/images/favicons/apple-touch-icon.png"
]
L.link_
[ L.rel_ "icon",
L.type_ "image/png",
L.sizes_ "32x32",
- L.href_ <|
- Pack.cdnEdge
- <> "/old-assets/images/favicons/favicon-32x32.png"
+ L.href_
+ <| Pack.cdnEdge
+ <> "/old-assets/images/favicons/favicon-32x32.png"
]
L.link_
[ L.rel_ "icon",
L.type_ "image/png",
L.sizes_ "16x16",
- L.href_ <|
- Pack.cdnEdge
- <> "/old-assets/images/favicons/favicon-16x16.png"
+ L.href_
+ <| Pack.cdnEdge
+ <> "/old-assets/images/favicons/favicon-16x16.png"
]
L.link_
[ L.rel_ "manifest",
- L.href_ <|
- Pack.cdnEdge
- <> "/old-assets/images/favicons/manifest.json"
+ L.href_
+ <| Pack.cdnEdge
+ <> "/old-assets/images/favicons/manifest.json"
]
L.link_
[ L.rel_ "mask-icon",
- L.href_ <|
- Pack.cdnEdge
- <> "/old-assets/images/favicons/safari-pinned-tab.svg"
+ L.href_
+ <| Pack.cdnEdge
+ <> "/old-assets/images/favicons/safari-pinned-tab.svg"
]
L.meta_ [L.charset_ "utf-8"]
L.meta_ [L.name_ "theme-color", L.content_ "#000"]
@@ -373,30 +374,30 @@ bulmaRef =
"https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css"
homeHandler :: Handler (Templated (View Move))
-homeHandler = pure . Templated . home <| initForm homeLink
+homeHandler = pure <. Templated <. home <| initForm homeLink
comicCoverHandler :: ComicId -> Handler (Templated (View Move))
comicCoverHandler id =
- pure . Templated . comicCover id . initForm <| comicLink id
+ pure <. Templated <. comicCover id <. initForm <| comicLink id
comicPageHandler :: ComicId -> PageNumber -> Handler (Templated (View Move))
comicPageHandler id n =
- pure . Templated . comicReader id n . initForm <| comicReaderSpreadLink id n
+ pure <. Templated <. comicReader id n <. initForm <| comicReaderSpreadLink id n
comicPageFullHandler :: ComicId -> PageNumber -> Handler (Templated (View Move))
comicPageFullHandler id n =
- pure . Templated . comicReader id n . initForm <| comicReaderFullLink id n
+ pure <. Templated <. comicReader id n <. initForm <| comicReaderFullLink id n
comicVideoHandler :: ComicId -> PageNumber -> Handler (Templated (View Move))
comicVideoHandler id n =
- pure . Templated . comicReader id n . initForm <| comicVideoLink id n
+ pure <. Templated <. comicReader id n <. initForm <| comicVideoLink id n
discoverHandler :: Handler (Templated (View Move))
-discoverHandler = pure . Templated . discover <| initForm discoverLink
+discoverHandler = pure <. Templated <. discover <| initForm discoverLink
chooseExperienceHandler :: ComicId -> PageNumber -> Handler (Templated (View Move))
chooseExperienceHandler id n =
- pure . Templated . comicReader id n . initForm <| chooseExperienceLink id n
+ pure <. Templated <. comicReader id n <. initForm <| chooseExperienceLink id n
loginHandler :: Handler (Templated (View Move))
-loginHandler = pure . Templated . login <| initForm loginLink
+loginHandler = pure <. Templated <. login <| initForm loginLink
diff --git a/Hero/Keep.hs b/Hero/Keep.hs
index 72bd6c2..744313b 100644
--- a/Hero/Keep.hs
+++ b/Hero/Keep.hs
@@ -16,11 +16,11 @@ module Hero.Keep
where
import Alpha
-import qualified Data.Acid as Acid
import Data.Acid (Update, makeAcidic)
+import qualified Data.Acid as Acid
import Data.Data (Data, Typeable)
-import qualified Data.IxSet as IxSet
import Data.IxSet (Indexable (..), IxSet, ixFun, ixSet)
+import qualified Data.IxSet as IxSet
import Data.SafeCopy (base, deriveSafeCopy)
import qualified Data.Text as Text
import Hero.Core
@@ -28,11 +28,10 @@ import Hero.Core
-- * Keep
-- | Main database.
-data HeroKeep
- = HeroKeep
- { _comics :: (IxSet Comic),
- _users :: (IxSet User)
- }
+data HeroKeep = HeroKeep
+ { _comics :: IxSet Comic,
+ _users :: IxSet User
+ }
deriving (Data, Typeable)
$(deriveSafeCopy 0 'base ''HeroKeep)
@@ -48,25 +47,25 @@ $(deriveSafeCopy 0 'base ''ComicId)
instance Indexable Comic where
empty =
ixSet
- [ ixFun $ \c -> [comicId c],
- ixFun $ \c -> [comicPages c],
- ixFun $ \c -> [comicName c],
- ixFun $ \c -> [comicIssue c],
- ixFun $ \c -> [comicDescription c]
+ [ ixFun <| \c -> [comicId c],
+ ixFun <| \c -> [comicPages c],
+ ixFun <| \c -> [comicName c],
+ ixFun <| \c -> [comicIssue c],
+ ixFun <| \c -> [comicDescription c]
]
instance Indexable User where
empty =
ixSet
- [ ixFun $ \u -> [userEmail u],
- ixFun $ \u -> [userName u],
- ixFun $ \u -> [userLibrary u]
+ [ ixFun <| \u -> [userEmail u],
+ ixFun <| \u -> [userName u],
+ ixFun <| \u -> [userLibrary u]
]
newComic :: Comic -> Update HeroKeep Comic
newComic c = do
keep <- get
- put $ keep {_comics = IxSet.insert c (_comics keep)}
+ put <| keep {_comics = IxSet.insert c (_comics keep)}
return c
getComics :: Int -> Acid.Query HeroKeep [Comic]
@@ -80,10 +79,11 @@ initialHeroKeep :: HeroKeep
initialHeroKeep =
HeroKeep
{ _comics = IxSet.fromList [theRed],
- _users = IxSet.fromList
- [ User "a" "micheal" [],
- User "b" "ben" []
- ]
+ _users =
+ IxSet.fromList
+ [ User "a" "micheal" [],
+ User "b" "ben" []
+ ]
}
where
theRed =
diff --git a/Hero/Look.hs b/Hero/Look.hs
index 03f64b3..e3958d5 100644
--- a/Hero/Look.hs
+++ b/Hero/Look.hs
@@ -2,12 +2,15 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE NoImplicitPrelude #-}
+{- HLINT ignore "Use |>" -}
+
-- | Styles
--
-- Eventually move make this mostly well-typed. Use this EDSL:
-- http://fvisser.nl/clay/
module Hero.Look where
+import Alpha hiding (rem, (**), (|>))
import Clay
import qualified Clay.Flexbox as Flexbox
import qualified Clay.Media as Media
@@ -16,9 +19,8 @@ import qualified Clay.Stylesheet as Stylesheet
import qualified Data.Map as Map
import qualified Data.Text.Lazy as L
import Hero.Look.Typography as Typo
-import Miso ((=:), Attribute, style_)
+import Miso (Attribute, style_, (=:))
import Miso.String (MisoString, toMisoString)
-import Protolude hiding ((&), (**), rem)
main :: Css
main = do
@@ -33,8 +35,8 @@ main = do
textDecoration none
".loading" ? do
centered
- height $ vh 100
- width $ vw 100
+ height <| vh 100
+ width <| vw 100
-- animations
".grow" ? do
transition "all" (sec 0.2) easeInOut (sec 0.2)
@@ -51,13 +53,13 @@ main = do
forwards
keyframes
"blur"
- [ (0, Clay.filter $ blur (px 0)),
- (50, Clay.filter $ blur (px 0)),
- (100, Clay.filter $ blur (px 10))
+ [ (0, Clay.filter <| blur (px 0)),
+ (50, Clay.filter <| blur (px 0)),
+ (100, Clay.filter <| blur (px 10))
]
html <> body ? do
background nite
- mobile $ do
+ mobile <| do
overflowX hidden
width (vw 100)
-- general app wrapper stuf
@@ -85,19 +87,19 @@ main = do
borderBottom solid (px 3) grai
wide
top (px 0)
- mobile $ noBorder <> width (vw 100)
+ mobile <| noBorder <> width (vw 100)
"#app-body" ? do
display flex
- desktop $ width (vw 93)
+ desktop <| width (vw 93)
alignContent center
alignItems flexStart
justifyContent flexStart
flexDirection column
flexShrink 0
padding (px 0) 0 0 0
- marginY $ px 74
- mobile $ flexDirection column
- "#discover #app-body" ? do desktop $ marginLeft appmenuWidth
+ marginY <| px 74
+ mobile <| flexDirection column
+ "#discover #app-body" ? do desktop <| marginLeft appmenuWidth
"#app-head-right" ? do
display flex
justifyContent spaceBetween
@@ -137,7 +139,7 @@ main = do
zIndex 1
height (vh 100)
width (px 400)
- mobile $ width (vw 90)
+ mobile <| width (vw 90)
"#login" ** ".help" ** a ? do
color white
display flex
@@ -159,17 +161,17 @@ main = do
euro <> wide
flexCenter
width (pct 100)
- desktop $ marginLeft appmenuWidth <> height (vh 90)
- mobile $ marginX (rem 0) <> marginTop (rem 0) <> minHeight (vh 90)
+ desktop <| marginLeft appmenuWidth <> height (vh 90)
+ mobile <| marginX (rem 0) <> marginTop (rem 0) <> minHeight (vh 90)
h2 ? do
thicc <> wide <> smol <> lower <> coat 2
textAlign center
- mobile $ coat 0.8
+ mobile <| coat 0.8
p ? do
thicc <> coat 0.8 <> textAlign center
maxWidth (px 900)
marginAll (rem 1)
- mobile $ coat 0.6
+ mobile <| coat 0.6
ul ? do
display flex
flexDirection row
@@ -181,7 +183,7 @@ main = do
display flex
flexDirection column
textAlign center
- mobile $ coat 0.6
+ mobile <| coat 0.6
coat 0.8 <> clickable
divv <? do
position relative
@@ -207,7 +209,7 @@ main = do
justifyContent center
alignItems center
display flex
- ".comic-video" |> iframe ? do
+ ".comic-video" & iframe ? do
position absolute
height (pct 93)
width (pct 100)
@@ -219,8 +221,8 @@ main = do
fontSize z
lineHeight z
let m = 24 :: Double
- top $ px $ navbarHeight + m
- left $ px m
+ top <| px <| navbarHeight + m
+ left <| px m
zIndex 999
-- zoom button and slider
"#zoom-button" ? do
@@ -229,15 +231,15 @@ main = do
let sliderYY = 250
euro <> wide
input ? do
- transform $ Clay.rotate (deg (-90))
+ transform <| Clay.rotate (deg (-90))
margin 0 0 (px sliderYY) 0
position absolute
- height $ px sliderY
- width $ px 200
+ height <| px sliderY
+ width <| px 200
hide
label ? do
coat 0.9
- marginBottom $ px $ 2 * sliderYY
+ marginBottom <| px <| 2 * sliderYY
position absolute
hide
":hover" & ".ctrl" ? visibility visible
@@ -252,7 +254,7 @@ main = do
borderBottom solid (px 1) white
flexDirection row
centerJustify
- mobile $ do
+ mobile <| do
margin (rem 2) 0 (rem 2) 0
padding 0 0 0 (rem 0)
noBorder
@@ -263,7 +265,7 @@ main = do
display flex
flexDirection row
divv # lastChild <? paddingLeft (rem 1)
- mobile $ do
+ mobile <| do
width (vw 90) -- this line can be commented if you want to center the meta
img ? width (px 150)
order (-1)
@@ -271,7 +273,7 @@ main = do
".media-info-summary" ? do
Flexbox.flex 2 1 (px 0)
paddingRight (rem 3)
- mobile $ do
+ mobile <| do
marginAll (rem 1)
padding 0 0 0 (rem 0)
".media-info-actions" ? do
@@ -280,7 +282,7 @@ main = do
display flex
flexDirection column
justifyContent spaceAround
- mobile $ do
+ mobile <| do
maxWidth (vw 100)
flexDirection row
order 1
@@ -308,8 +310,8 @@ main = do
a |> img ? do
width (px 22)
height (px 22)
- desktop $ a |> span ? remove
- mobile $ do
+ desktop <| a |> span ? remove
+ mobile <| do
order 2
flexDirection row
position fixed
@@ -329,14 +331,14 @@ main = do
flexDirection column
Typo.euro
height (px 411)
- mobile $ do
+ mobile <| do
padding (px 0) 0 0 0
margin 0 0 (px 50) 0
after & do
display block
position relative
- background $
- linearGradient
+ background
+ <| linearGradient
(straight sideTop)
[ (setA 0 nite, pct 0),
(nite, pct 100)
@@ -356,13 +358,13 @@ main = do
position relative
minHeight (px 411)
minWidth (px 1214)
- mobile $ marginLeft (px (-310))
+ mobile <| marginLeft (px (-310))
"#featured-content" ? do
position absolute
width (pct 100)
zIndex 9
top (px 200) -- b/c Firefox & WebKit autocalc "top" differently
- mobile $ do
+ mobile <| do
marginTop (px 200)
alignItems center
display flex
@@ -382,7 +384,7 @@ main = do
fontSize (rem 0.8)
fontVariant smallCaps
euro <> thicc <> wide
- mobile $ do
+ mobile <| do
height (px 26)
width (px 100)
margin 0 (px 5) 0 (px 5)
@@ -393,7 +395,7 @@ main = do
img ? do
marginRight (px 7)
height (px 15)
- mobile $ height (px 10)
+ mobile <| height (px 10)
--
".comic-action-menu" ? display flex <> justifyContent (JustifyContentValue "left")
-- shelving
@@ -402,7 +404,7 @@ main = do
flexDirection column
justifyContent flexStart
alignItems flexStart
- mobile $ do
+ mobile <| do
padding (rem 0.5) (rem 0.5) (rem 0.5) (rem 0.5)
width (vw 100)
".comic" ? do
@@ -518,15 +520,16 @@ grai = rgb 221 221 221 -- #dddddd
-- dynamically as JavaScript object properties. The implementation is a bit
-- hacky, but works.
css :: Clay.Css -> Attribute action
-css = Miso.style_ . Map.fromList . f . Clay.renderWith Clay.htmlInline []
+css = Miso.style_ <. Map.fromList <. f <. Clay.renderWith Clay.htmlInline []
where
f :: L.Text -> [(MisoString, MisoString)]
- f t = L.splitOn ";" t
- <&> L.splitOn ":"
- <&> \(x : y) -> (toMisoString x, toMisoString $ L.intercalate ":" y)
+ f t =
+ L.splitOn ";" t
+ <&> L.splitOn ":"
+ <&> \(x : y) -> (toMisoString x, toMisoString <| L.intercalate ":" y)
inlineCss :: Css -> MisoString
-inlineCss = toMisoString . render
+inlineCss = toMisoString <. render
type Style = Map MisoString MisoString
diff --git a/Hero/Look/Typography.hs b/Hero/Look/Typography.hs
index 7c28f21..603e78b 100644
--- a/Hero/Look/Typography.hs
+++ b/Hero/Look/Typography.hs
@@ -44,7 +44,7 @@ upper = textTransform uppercase
-- | apparently "coat" is a synonym for "size"
coat :: Double -> Css
-coat = fontSize . Clay.rem
+coat = fontSize <. Clay.rem
fontRoot :: Text
fontRoot = Pack.cdnEdge <> "/old-assets/fonts/eurostile/Eurostile"
diff --git a/Hero/Node.hs b/Hero/Node.hs
index 70b8217..38f540d 100644
--- a/Hero/Node.hs
+++ b/Hero/Node.hs
@@ -26,13 +26,13 @@ import qualified Data.Set as Set
import qualified GHC.Show as Legacy
import GHCJS.Types (JSVal)
import Hero.Core
- ( Move (..),
- AudioState (..),
+ ( AudioState (..),
Comic (..),
ComicReaderState (..),
ComicReaderView (..),
- LoginForm (..),
Form (..),
+ LoginForm (..),
+ Move (..),
User (..),
audioId,
chooseExperienceLink,
@@ -57,7 +57,7 @@ import Protolude
-- | Entry point for a miso application
main :: IO ()
-main = miso $ \currentURI -> App {model = initForm currentURI, ..}
+main = miso <| \currentURI -> App {model = initForm currentURI, ..}
where
update = move
view = see
@@ -97,38 +97,42 @@ foreign import javascript unsafe "$1.value"
-- | Updates form, optionally introduces side effects
move :: Move -> Form -> Effect Move Form
move NoOp form = noEff form
-move Dumpform form = form <# do
- jslog $ ms $ Legacy.show form
- pure NoOp
-move (SelectExperience comic) form = form {cpState = ChooseExperience (comicId comic) 1}
- <# do pure $ ChangeURI $ chooseExperienceLink (comicId comic) 1
-move (StartReading comic) form = form {cpState = Reading Spread (comicId comic) 1}
- <# do pure $ ChangeURI $ comicReaderSpreadLink (comicId comic) 1
-move (StartWatching comic) form = form {cpState = Watching (comicId comic)}
- <# do pure $ ChangeURI $ comicVideoLink (comicId comic) 1
+move Dumpform form =
+ form <# do
+ jslog <| ms <| Legacy.show form
+ pure NoOp
+move (SelectExperience comic) form =
+ form {cpState = ChooseExperience (comicId comic) 1}
+ <# do pure <| ChangeURI <| chooseExperienceLink (comicId comic) 1
+move (StartReading comic) form =
+ form {cpState = Reading Spread (comicId comic) 1}
+ <# do pure <| ChangeURI <| comicReaderSpreadLink (comicId comic) 1
+move (StartWatching comic) form =
+ form {cpState = Watching (comicId comic)}
+ <# do pure <| ChangeURI <| comicVideoLink (comicId comic) 1
move NextPage form = case cpState form of
Reading Spread id pg ->
form {cpState = Reading Spread id (pg + 2)} <# do
- pure $ ChangeURI $ comicReaderSpreadLink id (pg + 2)
+ pure <| ChangeURI <| comicReaderSpreadLink id (pg + 2)
Reading Full id pg ->
form {cpState = Reading Full id (pg + 1)} <# do
- pure $ ChangeURI $ comicReaderFullLink id (pg + 1)
+ pure <| ChangeURI <| comicReaderFullLink id (pg + 1)
Cover id ->
form {cpState = Reading Spread id 1} <# do
- pure $ ChangeURI $ comicReaderSpreadLink id 1
+ pure <| ChangeURI <| comicReaderSpreadLink id 1
_ -> noEff form
move PrevPage form = case cpState form of
Reading Spread id pg ->
form {cpState = Reading Spread id (pg -2)} <# do
- pure $ ChangeURI $ comicReaderSpreadLink id (pg -2)
+ pure <| ChangeURI <| comicReaderSpreadLink id (pg -2)
Reading Full id pg ->
form {cpState = Reading Full id (pg -1)} <# do
- pure $ ChangeURI $ comicReaderFullLink id (pg -1)
+ pure <| ChangeURI <| comicReaderFullLink id (pg -1)
Cover _ -> noEff form
_ -> noEff form
move (ToggleZoom c pg) m = m {cpState = newState} <# pure act
where
- goto lnk = ChangeURI $ lnk (comicId c) pg
+ goto lnk = ChangeURI <| lnk (comicId c) pg
reading v = Reading v (comicId c) pg
(newState, act) = case cpState m of
Reading Full _ _ -> (reading Spread, goto comicReaderSpreadLink)
@@ -138,45 +142,50 @@ move (ToggleInLibrary c) form = form {user = newUser} <# pure NoOp
where
newUser = (user form) {userLibrary = newLib}
newLib
- | c `elem` (userLibrary $ user form) =
- Protolude.filter (/= c) $ userLibrary $ user form
- | otherwise = c : (userLibrary $ user form)
+ | c `elem` (userLibrary <| user form) =
+ Protolude.filter (/= c) <| userLibrary <| user form
+ | otherwise = c : (userLibrary <| user form)
move (HandleURI u) form = form {uri = u} <# pure NoOp
-move (ChangeURI u) form = form <# do
- pushURI u
- pure NoOp
+move (ChangeURI u) form =
+ form <# do
+ pushURI u
+ pure NoOp
move FetchComics form = form <# (SetComics <$> fetchComics)
move (SetComics cs) form = noEff form {appComics = cs}
-move (ToggleAudio i) form = form {cpAudioState = newState} <# do
- el <- Document.getElementById i
- toggle el
- pure NoOp
+move (ToggleAudio i) form =
+ form {cpAudioState = newState} <# do
+ el <- Document.getElementById i
+ toggle el
+ pure NoOp
where
(newState, toggle) = case cpAudioState form of
Playing -> (Paused, Audio.pause)
Paused -> (Playing, Audio.play)
-move ToggleFullscreen form = form {cpState = newState} <# do
- el <- Document.querySelector "body"
- -- TODO: check Document.fullscreenEnabled
- -- https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenEnabled
- _ <- toggle el
- pure NoOp
+move ToggleFullscreen form =
+ form {cpState = newState} <# do
+ el <- Document.querySelector "body"
+ -- TODO: check Document.fullscreenEnabled
+ -- https://developer.mozilla.org/en-US/docs/Web/API/Document/fullscreenEnabled
+ _ <- toggle el
+ pure NoOp
where
(toggle, newState) = case cpState form of
Reading Full c n -> (const Fullscreen.exit, Reading Full c n)
Reading Spread c n -> (Fullscreen.request, Reading Spread c n)
-- otherwise, do nothing:
x -> (pure, x)
-move (SetMediaInfo x) form = form {dMediaInfo = x}
- <# case x of
- Just Comic {comicId = id} ->
- pure $ ScrollIntoView $ "comic-" <> ms id
- Nothing ->
- pure NoOp
-move (ScrollIntoView id) form = form <# do
- jslog $ ms $ Legacy.show id
- scrollIntoView id
- pure NoOp
+move (SetMediaInfo x) form =
+ form {dMediaInfo = x}
+ <# case x of
+ Just Comic {comicId = id} ->
+ pure <| ScrollIntoView <| "comic-" <> ms id
+ Nothing ->
+ pure NoOp
+move (ScrollIntoView id) form =
+ form <# do
+ jslog <| ms <| Legacy.show id
+ scrollIntoView id
+ pure NoOp
move ValidateUserPassword form =
batchEff
form
@@ -193,15 +202,16 @@ move ValidateUserPassword form =
Network.NotAsked -> pure NoOp
fetchComics :: IO (Network.RemoteData MisoString [Comic])
-fetchComics = Ajax.xhrByteString req /> Ajax.contents >>= \case
- Nothing ->
- pure $ Network.Failure "Could not fetch comics from server."
- Just json ->
- json
- |> Aeson.eitherDecodeStrict
- |> either (Left . ms) pure
- |> Network.fromEither
- |> pure
+fetchComics =
+ Ajax.xhrByteString req /> Ajax.contents >>= \case
+ Nothing ->
+ pure <| Network.Failure "Could not fetch comics from server."
+ Just json ->
+ json
+ |> Aeson.eitherDecodeStrict
+ |> either (Left <. ms) pure
+ |> Network.fromEither
+ |> pure
where
req =
Ajax.Request
@@ -217,16 +227,18 @@ sendLogin ::
Auth.Username ->
Auth.Password ->
IO
- ( Network.RemoteData MisoString
+ ( Network.RemoteData
+ MisoString
User
)
-sendLogin u p = Ajax.xhrByteString req /> Ajax.contents >>= \case
- Nothing ->
- pure $ Network.Failure "Could not send login request."
- Just json ->
- pure $ Network.fromEither
- $ either (Left . ms) pure
- $ Aeson.eitherDecodeStrict json
+sendLogin u p =
+ Ajax.xhrByteString req /> Ajax.contents >>= \case
+ Nothing ->
+ pure <| Network.Failure "Could not send login request."
+ Just json ->
+ pure <| Network.fromEither
+ <| either (Left <. ms) pure
+ <| Aeson.eitherDecodeStrict json
where
req =
Ajax.Request
diff --git a/Hero/Part.hs b/Hero/Part.hs
index fb34fff..4244721 100644
--- a/Hero/Part.hs
+++ b/Hero/Part.hs
@@ -1,3 +1 @@
module Hero.Part () where
-
-