2024-05-31 10:42:26 +02:00
|
|
|
module Main where
|
|
|
|
|
|
|
|
|
|
#ifndef ghcjs_HOST_OS
|
|
|
|
|
import Language.Javascript.JSaddle.Warp as JSaddle
|
|
|
|
|
#endif
|
|
|
|
|
|
2024-06-04 14:36:26 +02:00
|
|
|
import Data.Bifunctor
|
2024-06-03 11:22:10 +02:00
|
|
|
import Data.Default
|
|
|
|
|
import Data.Function
|
|
|
|
|
import GHC.Generics (Generic)
|
|
|
|
|
import Miso
|
|
|
|
|
import Miso.String (toMisoString)
|
2024-06-04 12:32:59 +02:00
|
|
|
import NeatInterpolation qualified as Q
|
2024-06-04 14:36:26 +02:00
|
|
|
import Page (Page, initialPage, updatePage, viewPage)
|
|
|
|
|
import Page qualified as Page
|
|
|
|
|
import Route (parseURI)
|
2024-06-03 11:22:10 +02:00
|
|
|
|
|
|
|
|
data Model = Model
|
2024-06-04 14:36:26 +02:00
|
|
|
{ page :: Maybe (Either String Page)
|
2024-06-03 11:22:10 +02:00
|
|
|
}
|
|
|
|
|
deriving (Show, Eq, Generic, Default)
|
|
|
|
|
|
2024-05-31 10:42:26 +02:00
|
|
|
data Action
|
2024-06-03 11:22:10 +02:00
|
|
|
= NoOp
|
2024-06-04 14:36:26 +02:00
|
|
|
| Init URI
|
|
|
|
|
| HandleURI URI
|
|
|
|
|
| HandlePage Page.Action
|
|
|
|
|
| SetPage (Either String Page)
|
2024-05-31 10:42:26 +02:00
|
|
|
deriving (Show, Eq)
|
|
|
|
|
|
|
|
|
|
#ifndef ghcjs_HOST_OS
|
|
|
|
|
runApp :: JSM () -> IO ()
|
|
|
|
|
runApp f = JSaddle.debugOr 8080 (f >> syncPoint) JSaddle.jsaddleApp
|
|
|
|
|
#else
|
|
|
|
|
runApp :: IO () -> IO ()
|
|
|
|
|
runApp app = app
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
main :: IO ()
|
2024-06-04 14:36:26 +02:00
|
|
|
main = runApp $ do
|
|
|
|
|
uri <- getCurrentURI
|
|
|
|
|
startApp App {initialAction = Init uri, ..}
|
2024-05-31 10:42:26 +02:00
|
|
|
where
|
2024-06-03 11:22:10 +02:00
|
|
|
model = def
|
2024-05-31 10:42:26 +02:00
|
|
|
update = updateModel
|
|
|
|
|
view = viewModel
|
|
|
|
|
events = defaultEvents
|
2024-06-04 14:36:26 +02:00
|
|
|
subs = [uriSub HandleURI]
|
2024-05-31 10:42:26 +02:00
|
|
|
mountPoint = Nothing
|
|
|
|
|
logLevel = Off
|
|
|
|
|
|
|
|
|
|
updateModel :: Action -> Model -> Effect Action Model
|
2024-06-04 14:36:26 +02:00
|
|
|
updateModel NoOp m = noEff m
|
|
|
|
|
updateModel (Init uri) m =
|
|
|
|
|
m <# do
|
|
|
|
|
SetPage <$> initialPage (parseURI uri)
|
|
|
|
|
updateModel (HandleURI uri) m =
|
|
|
|
|
m <# do
|
|
|
|
|
let route = parseURI uri
|
|
|
|
|
SetPage <$> initialPage route
|
|
|
|
|
updateModel (SetPage page) m = noEff m {page = Just page}
|
|
|
|
|
updateModel (HandlePage action) m =
|
|
|
|
|
case m.page of
|
|
|
|
|
Just (Right page) ->
|
|
|
|
|
updatePage action page
|
|
|
|
|
& bimap HandlePage (\page -> m {page = Just (Right page)})
|
|
|
|
|
_ -> noEff m
|
2024-05-31 10:42:26 +02:00
|
|
|
|
|
|
|
|
viewModel :: Model -> View Action
|
2024-06-03 11:22:10 +02:00
|
|
|
viewModel model =
|
2024-06-04 14:36:26 +02:00
|
|
|
div_ [] $
|
|
|
|
|
[ viewCss,
|
|
|
|
|
viewHeader,
|
|
|
|
|
nav_ [] [viewCollections],
|
|
|
|
|
main_ [] $
|
|
|
|
|
[ HandlePage
|
|
|
|
|
<$> maybe
|
|
|
|
|
(text "..")
|
|
|
|
|
(either err viewPage)
|
|
|
|
|
model.page
|
2024-06-04 09:59:10 +02:00
|
|
|
]
|
2024-06-04 14:36:26 +02:00
|
|
|
]
|
2024-06-03 11:22:10 +02:00
|
|
|
|
2024-06-04 12:32:59 +02:00
|
|
|
viewCss :: View Action
|
|
|
|
|
viewCss =
|
|
|
|
|
node
|
|
|
|
|
HTML
|
|
|
|
|
"style"
|
|
|
|
|
Nothing
|
|
|
|
|
[type_ "text/css"]
|
|
|
|
|
[ text
|
|
|
|
|
( toMisoString
|
|
|
|
|
[Q.text|
|
|
|
|
|
/* normalize */
|
|
|
|
|
* {
|
|
|
|
|
box-sizing: border-box; }
|
|
|
|
|
body {
|
|
|
|
|
margin: 0;
|
|
|
|
|
min-height: 100vh; }
|
|
|
|
|
|
|
|
|
|
/* typography */
|
|
|
|
|
html {
|
|
|
|
|
font: Iosevka; }
|
|
|
|
|
|
|
|
|
|
/* layout */
|
|
|
|
|
body > div {
|
|
|
|
|
display: flex;
|
|
|
|
|
flex-flow: row nowrap;
|
|
|
|
|
min-height: 100vh;
|
|
|
|
|
padding-top: 64px;
|
|
|
|
|
align-items: stretch; }
|
|
|
|
|
header {
|
|
|
|
|
position: fixed;
|
|
|
|
|
top: 0; left: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 64px; }
|
|
|
|
|
nav, main {
|
|
|
|
|
min-height: 100%; }
|
|
|
|
|
nav {
|
|
|
|
|
flex: 0 0 200px; }
|
|
|
|
|
main {
|
|
|
|
|
flex: 1 1 auto; }
|
|
|
|
|
|
|
|
|
|
/* borders */
|
|
|
|
|
header {
|
|
|
|
|
border-bottom: 1px solid gray; }
|
|
|
|
|
nav {
|
|
|
|
|
border-right: 1px solid gray; }
|
|
|
|
|
|
|
|
|
|
/* padding */
|
|
|
|
|
nav, header, main {
|
|
|
|
|
padding: 16px; }
|
|
|
|
|
|
|
|
|
|
/* scrolling */
|
|
|
|
|
body > div {
|
|
|
|
|
overflow: visible; }
|
|
|
|
|
header {
|
|
|
|
|
overflow: visible; }
|
|
|
|
|
nav, main {
|
|
|
|
|
overflow: auto; }
|
|
|
|
|
|
|
|
|
|
/* header */
|
|
|
|
|
header {
|
|
|
|
|
display: flex;
|
|
|
|
|
align-items: center; }
|
|
|
|
|
header section {
|
|
|
|
|
margin-left: auto; }
|
|
|
|
|
header section:first-child {
|
|
|
|
|
margin-left: 0; }
|
2024-06-04 15:42:33 +02:00
|
|
|
|
|
|
|
|
/* table layout */
|
|
|
|
|
th, td {
|
|
|
|
|
text-align: left;
|
|
|
|
|
padding: 0 16px;
|
|
|
|
|
line-height: 52px;
|
|
|
|
|
text-overflow: ellipsis;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* table borders */
|
|
|
|
|
table {
|
|
|
|
|
border-collapse: collapse;
|
|
|
|
|
border-left: 1px solid gray;
|
|
|
|
|
border-right: 1px solid gray; }
|
|
|
|
|
th, td {
|
|
|
|
|
border-top: 1px solid gray;
|
|
|
|
|
border-bottom: 1px solid gray; }
|
2024-06-04 12:32:59 +02:00
|
|
|
|]
|
|
|
|
|
)
|
|
|
|
|
]
|
|
|
|
|
|
2024-06-04 14:36:26 +02:00
|
|
|
err :: String -> View action
|
2024-06-03 11:22:10 +02:00
|
|
|
err = text . toMisoString . ("err! " <>)
|
|
|
|
|
|
2024-06-04 12:32:59 +02:00
|
|
|
viewHeader :: View Action
|
|
|
|
|
viewHeader =
|
|
|
|
|
header_ [] $
|
2024-06-04 14:36:26 +02:00
|
|
|
[ section_ [] [h1_ [] [a_ [href_ "#"] [text "acms"]]],
|
2024-06-04 12:32:59 +02:00
|
|
|
section_ [] [viewBranch]
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
viewBranch :: View Action
|
|
|
|
|
viewBranch =
|
|
|
|
|
select_ [] [option_ [] [text "main"]]
|
|
|
|
|
|
|
|
|
|
viewCollections :: View Action
|
|
|
|
|
viewCollections =
|
|
|
|
|
section_ [] $
|
|
|
|
|
[ span_ [] [text "collections"],
|
2024-06-03 11:22:10 +02:00
|
|
|
ol_ [] $
|
2024-06-04 14:36:26 +02:00
|
|
|
[ li_ [] [a_ [href_ "#collection/posts"] [text "posts"]],
|
|
|
|
|
li_ [] [a_ [href_ "#collection/posts1"] [text "posts1"]]
|
|
|
|
|
]
|
|
|
|
|
]
|