1
1
mirror of https://github.com/aelve/guide.git synced 2024-12-23 21:02:13 +03:00

Split items into info and pros/cons

This commit is contained in:
Artyom 2016-02-20 16:03:08 +03:00
parent c515bd6a53
commit 88ad776ae4

View File

@ -156,9 +156,18 @@ main = runSpock 8080 $ spockT id $ do
lucid $ renderCategoryDescription renderMode category lucid $ renderCategoryDescription renderMode category
-- Item -- Item
Spock.get itemVar $ \itemId -> do Spock.get itemVar $ \itemId -> do
item <- withGlobal $ use (itemById itemId)
lucid $ renderItem item
-- Item info
Spock.get (itemVar <//> "info") $ \itemId -> do
item <- withGlobal $ use (itemById itemId) item <- withGlobal $ use (itemById itemId)
renderMode <- param' "mode" renderMode <- param' "mode"
lucid $ renderItem renderMode item lucid $ renderItemInfo renderMode item
-- Item pros-cons
Spock.get (itemVar <//> "pros-cons") $ \itemId -> do
item <- withGlobal $ use (itemById itemId)
renderMode <- param' "mode"
lucid $ renderItemProsCons renderMode item
-- Pro/con -- Pro/con
Spock.get (itemVar <//> "pro-con" <//> var) $ Spock.get (itemVar <//> "pro-con" <//> var) $
\itemId thingId -> do \itemId thingId -> do
@ -223,7 +232,7 @@ main = runSpock 8080 $ spockT id $ do
-- TODO: maybe do something if the category doesn't exist (e.g. has been -- TODO: maybe do something if the category doesn't exist (e.g. has been
-- already deleted) -- already deleted)
withGlobal $ categoryById catId . items %= (++ [newItem]) withGlobal $ categoryById catId . items %= (++ [newItem])
lucid $ renderItem Normal newItem lucid $ renderItem newItem
-- Pro (argument in favor of a library) -- Pro (argument in favor of a library)
Spock.post (itemVar <//> "pro") $ \itemId -> do Spock.post (itemVar <//> "pro") $ \itemId -> do
content' <- param' "content" content' <- param' "content"
@ -269,6 +278,8 @@ renderCategoryTitle editable category =
textButton "cancel" $ textButton "cancel" $
js_setCategoryTitleMode (titleNode, category^.uid, Editable) js_setCategoryTitleMode (titleNode, category^.uid, Editable)
-- TODO: render descriptions and pros/cons as Markdown
renderCategoryDescription :: Editable -> Category -> HtmlT IO () renderCategoryDescription :: Editable -> Category -> HtmlT IO ()
renderCategoryDescription editable category = renderCategoryDescription editable category =
p_ $ do p_ $ do
@ -291,60 +302,72 @@ renderCategory category =
renderCategoryTitle Editable category renderCategoryTitle Editable category
renderCategoryDescription Editable category renderCategoryDescription Editable category
itemsNode <- div_ [class_ "items"] $ do itemsNode <- div_ [class_ "items"] $ do
mapM_ (renderItem Normal) (category^.items) mapM_ renderItem (category^.items)
thisNode thisNode
let handler s = js_addLibrary (itemsNode, category^.uid, s) let handler s = js_addLibrary (itemsNode, category^.uid, s)
input_ [type_ "text", placeholder_ "new item", submitFunc handler] input_ [type_ "text", placeholder_ "new item", submitFunc handler]
renderItem renderItem :: Item -> HtmlT IO ()
:: Editable -- ^ Show edit buttons? renderItem item =
-> Item
-> HtmlT IO ()
renderItem editable item =
div_ [class_ "item"] $ do div_ [class_ "item"] $ do
itemNode <- thisNode renderItemInfo Normal item
h3_ $ do renderItemProsCons Normal item
-- If the library is on Hackage, the title links to its Hackage page;
-- otherwise, it doesn't link anywhere. Even if the link field is renderItemInfo :: Editable -> Item -> HtmlT IO ()
-- present, it's going to be rendered as “(site)”, not linked in the renderItemInfo editable item =
-- title. h3_ $ do
case item^.kind of this <- thisNode
HackageLibrary -> a_ [href_ hackageLink] (toHtml (item^.name)) -- If the library is on Hackage, the title links to its Hackage page;
_otherwise -> toHtml (item^.name) -- otherwise, it doesn't link anywhere. Even if the link field is
case item^.link of -- present, it's going to be rendered as “(site)”, not linked in the
Just l -> " (" >> a_ [href_ l] "site" >> ")" -- title.
Nothing -> return () case item^.kind of
case editable of HackageLibrary -> a_ [href_ hackageLink] (toHtml (item^.name))
Normal -> textButton "edit" $ _otherwise -> toHtml (item^.name)
js_setItemMode (itemNode, item^.uid, Editable) case item^.link of
Editable -> textButton "edit off" $ Just l -> " (" >> a_ [href_ l] "site" >> ")"
js_setItemMode (itemNode, item^.uid, Normal) Nothing -> return ()
div_ [class_ "pros-cons"] $ do case editable of
div_ [class_ "pros"] $ do Normal -> textButton "edit" $
p_ "Pros:" js_setItemInfoMode (this, item^.uid, Editable)
case editable of -- TODO: change to an actual button, “Submit”, etc.
Normal -> Editable -> textButton "edit off" $
ul_ $ mapM_ (renderProCon Normal (item^.uid)) (item^.pros) js_setItemInfoMode (this, item^.uid, Normal)
Editable -> do
listNode <- ul_ $ do
mapM_ (renderProCon Editable (item^.uid)) (item^.pros)
thisNode
let handler s = js_addPro (listNode, item^.uid, s)
input_ [type_ "text", placeholder_ "add pro", submitFunc handler]
div_ [class_ "cons"] $ do
p_ "Cons:"
case editable of
Normal ->
ul_ $ mapM_ (renderProCon Normal (item^.uid)) (item^.cons)
Editable -> do
listNode <- ul_ $ do
mapM_ (renderProCon Editable (item^.uid)) (item^.cons)
thisNode
let handler s = js_addCon (listNode, item^.uid, s)
input_ [type_ "text", placeholder_ "add con", submitFunc handler]
where where
hackageLink = "https://hackage.haskell.org/package/" <> item^.name hackageLink = "https://hackage.haskell.org/package/" <> item^.name
renderItemProsCons :: Editable -> Item -> HtmlT IO ()
renderItemProsCons editable item =
div_ [class_ "pros-cons"] $ do
this <- thisNode
case editable of
Normal -> textButton "edit" $
js_setItemProsConsMode (this, item^.uid, Editable)
Editable -> textButton "edit off" $
js_setItemProsConsMode (this, item^.uid, Normal)
div_ [class_ "pros"] $ do
p_ "Pros:"
case editable of
Normal ->
ul_ $ mapM_ (renderProCon Normal (item^.uid)) (item^.pros)
Editable -> do
listNode <- ul_ $ do
mapM_ (renderProCon Editable (item^.uid)) (item^.pros)
thisNode
let handler s = js_addPro (listNode, item^.uid, s)
input_ [type_ "text", placeholder_ "add pro", submitFunc handler]
div_ [class_ "cons"] $ do
p_ "Cons:"
case editable of
Normal ->
ul_ $ mapM_ (renderProCon Normal (item^.uid)) (item^.cons)
Editable -> do
listNode <- ul_ $ do
mapM_ (renderProCon Editable (item^.uid)) (item^.cons)
thisNode
let handler s = js_addCon (listNode, item^.uid, s)
input_ [type_ "text", placeholder_ "add con", submitFunc handler]
renderProCon :: Editable -> Uid -> ProCon -> HtmlT IO () renderProCon :: Editable -> Uid -> ProCon -> HtmlT IO ()
renderProCon Normal _ proCon = li_ (toHtml (proCon^.content)) renderProCon Normal _ proCon = li_ (toHtml (proCon^.content))
renderProCon Editable itemId proCon = li_ $ do renderProCon Editable itemId proCon = li_ $ do
@ -400,6 +423,8 @@ instance JSParams a => JSFunction (a -> JS) where
makeJSFunction fName _ = \args -> makeJSFunction fName _ = \args ->
fName <> "(" <> T.intercalate "," (jsParams args) <> ");" fName <> "(" <> T.intercalate "," (jsParams args) <> ");"
-- TODO: rename pros/cons to traits
allJSFunctions :: JSFunction a => [a] allJSFunctions :: JSFunction a => [a]
allJSFunctions = [ allJSFunctions = [
-- Utilities -- Utilities
@ -408,9 +433,8 @@ allJSFunctions = [
js_addLibrary, js_addCategory, js_addLibrary, js_addCategory,
js_addPro, js_addCon, js_addPro, js_addCon,
-- Render-as-editable methods -- Render-as-editable methods
js_setCategoryTitleMode, js_setCategoryTitleMode, js_setCategoryDescriptionMode,
js_setCategoryDescriptionMode, js_setItemInfoMode, js_setItemProsConsMode,
js_setItemMode,
js_setProConMode, js_setProConMode,
-- Set methods -- Set methods
js_submitCategoryTitleEdit, js_submitCategoryTitleEdit,
@ -507,11 +531,18 @@ js_addCon = makeJSFunction "addCon" [text|
} }
|] |]
-- | Add “[edit]” buttons to everything in an item, or remove them. js_setItemInfoMode :: JSFunction a => a
js_setItemMode :: JSFunction a => a js_setItemInfoMode = makeJSFunction "setItemInfoMode" [text|
js_setItemMode = makeJSFunction "setItemMode" [text| function setItemInfoMode(node, itemId, mode) {
function setItemMode(node, itemId, mode) { $.get("/render/item/"+itemId+"/info", {mode: mode})
$.get("/render/item/"+itemId, {mode: mode}) .done(replaceWithData(node));
}
|]
js_setItemProsConsMode :: JSFunction a => a
js_setItemProsConsMode = makeJSFunction "setItemProsConsMode" [text|
function setItemProsConsMode(node, itemId, mode) {
$.get("/render/item/"+itemId+"/pros-cons", {mode: mode})
.done(replaceWithData(node)); .done(replaceWithData(node));
} }
|] |]