aboutsummaryrefslogtreecommitdiff
path: root/client/src/Component/Pages.hs
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/Component/Pages.hs')
-rw-r--r--client/src/Component/Pages.hs86
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