diff options
Diffstat (limited to 'client/src/Component/Pages.hs')
-rw-r--r-- | client/src/Component/Pages.hs | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/client/src/Component/Pages.hs b/client/src/Component/Pages.hs new file mode 100644 index 0000000..d54cd3d --- /dev/null +++ b/client/src/Component/Pages.hs @@ -0,0 +1,86 @@ +module Component.Pages + ( view + , In(..) + , Out(..) + ) where + +import qualified Data.Text as T +import Reflex.Dom (Dynamic, Event, MonadWidget) +import qualified Reflex.Dom as R + +import qualified Component.Button as Button + +import qualified Util.Reflex as ReflexUtil +import qualified View.Icon as Icon + +data In t = In + { _in_total :: Dynamic t Int + , _in_perPage :: Int + , _in_page :: Int + } + +data Out t = Out + { _out_newPage :: Event t Int + } + +view :: forall t m. MonadWidget t m => In t -> m (Out t) +view input = do + newPage <- ReflexUtil.divVisibleIf ((> 0) <$> (_in_total input)) $ pageButtons input + + return $ Out + { _out_newPage = newPage + } + +pageButtons + :: forall t m. MonadWidget t m + => In t + -> m (Event t Int) +pageButtons input = do + R.divClass "pages" $ do + rec + let newPage = R.leftmost + [ firstPageClic + , previousPageClic + , pageClic + , nextPageClic + , lastPageClic + ] + + currentPage <- R.holdDyn (_in_page input) newPage + + firstPageClic <- pageButton noCurrentPage (R.constDyn 1) Icon.doubleLeftBar + + previousPageClic <- pageButton noCurrentPage (fmap (\x -> max (x - 1) 1) currentPage) Icon.doubleLeft + + pageClic <- pageEvent <$> (R.simpleList (range <$> currentPage <*> maxPage) $ \p -> + pageButton (Just <$> currentPage) p (R.dynText $ fmap (T.pack . show) p)) + + nextPageClic <- pageButton noCurrentPage ((\c m -> min (c + 1) m) <$> currentPage <*> maxPage) Icon.doubleRight + + lastPageClic <- pageButton noCurrentPage maxPage Icon.doubleRightBar + + return newPage + + where maxPage = R.ffor (_in_total input) (\t -> ceiling $ toRational t / toRational (_in_perPage input)) + pageEvent = R.switch . R.current . fmap R.leftmost + noCurrentPage = R.constDyn Nothing + +range :: Int -> Int -> [Int] +range currentPage maxPage = [start..end] + where sidePages = 2 + start = max 1 (min (currentPage - sidePages) (maxPage - sidePages * 2)) + end = min maxPage (start + sidePages * 2) + +pageButton :: forall t m. MonadWidget t m => Dynamic t (Maybe Int) -> Dynamic t Int -> m () -> m (Event t Int) +pageButton currentPage page content = do + clic <- Button._out_clic <$> (Button.view $ Button.In + { Button._in_class = do + cp <- currentPage + p <- page + if cp == Just p then "page current" else "page" + , Button._in_content = content + , Button._in_waiting = R.never + , Button._in_tabIndex = Nothing + , Button._in_submit = False + }) + return . fmap fst $ R.attach (R.current page) clic |