{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RankNTypes #-} module Shpadoinkle.Widgets.Types.Pagination ( CurrentScrollY (..) , Offset (..) , Length (..) , Page (..) ) where import Data.Aeson import qualified Data.Attoparsec.Text as A import Data.Either.Combinators (mapLeft) import Data.Text (pack) import GHC.Generics import Language.Javascript.JSaddle hiding (JSM, MonadJSM) import Servant.API (FromHttpApiData (..), ToHttpApiData (..)) import Shpadoinkle newtype CurrentScrollY = CurrentScrollY Int -- measured in pixels deriving (Eq, Ord, Generic, ToJSON, FromJSON, Read, Show, Num, Enum, Real, Integral, NFData) newtype Length = Length Int deriving (Eq, Ord, Generic, Read, Show, Num, Enum, Real, Integral, ToHttpApiData, FromHttpApiData) instance ToJSON Length instance FromJSON Length instance ToJSVal Length instance FromJSVal Length instance NFData Length newtype Offset = Offset Int deriving (Eq, Ord, Generic, Read, Show, Num, Enum, Real, Integral, ToHttpApiData, FromHttpApiData) instance ToJSON Offset instance FromJSON Offset instance ToJSVal Offset instance FromJSVal Offset instance NFData Offset data Page = Page { pageOffset :: Offset, pageLength :: Length } deriving (Eq, Ord, Generic, Read, Show) instance ToJSON Page instance FromJSON Page instance ToJSVal Page instance FromJSVal Page instance NFData Page instance ToHttpApiData Page where toUrlPiece (Page off len) = toUrlPiece off <> "," <> toUrlPiece len toQueryParam pg = toUrlPiece pg instance FromHttpApiData Page where parseUrlPiece = (mapLeft pack .) . A.parseOnly $ do off <- Offset <$> A.signed A.decimal _ <- A.char ',' len <- Length <$> A.signed A.decimal return $ Page off len