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