{-# LANGUAGE TransformListComp #-} module GalleryPage (make) where import Data.Foldable import Data.Function (on, (&)) import qualified Data.HashMap.Strict as HashMap import Data.HashSet (HashSet) import qualified Data.HashSet as HashSet import Data.List (intersperse, groupBy, sortOn) import qualified Data.Text.Lazy as Lazy import qualified Data.Time as Time import System.FilePath (takeDirectory, joinPath, splitPath) import GHC.Exts (Down (..), the) import BuilderQQ import Info make :: Text -> GalleryInfo -> [(FilePath, Info)] -> Lazy.Text make root ginfo infos = toLazyText $ make' root ginfo infos make' :: Text -> GalleryInfo -> [(FilePath, Info)] -> Builder make' root (GalleryInfo {title, desc, prefix, filters, hidden}) infos = [b|@0 $title

$title

rss

|] where items = map (uncurry $ makeYearItems nsfw) infosByYear infosByYear = [(the year, infopath) | infopath@(_, info) <- infos, then sortOn by Down info, let year = #year info, then group by Down year using groupBy'] groupBy' f = groupBy ((==) `on` f) undir = joinPath (replicate (length (splitPath prefix)) "..") allTags = infos & concatMap (map (,1) . tagsFor nsfw . #second) & HashMap.fromListWith (+) & HashMap.toList & sortOn (\(tag, count) -> (Down count, tag)) requireFilters = map (uncurry $ makeFilter "require" mempty) allTags excludeFilters = map (uncurry $ makeFilter "exclude" hidden) allTags nsfw = #nsfw filters /= NoNsfw url = [b|$root/$prefix|] imagepath0 | (_, (p0, i0) : _) : _ <- infosByYear = getThumb (takeDirectory p0) i0 | otherwise = "/style/card.png" makeFilter :: Text -> HashSet Text -> Text -> Int -> Builder makeFilter prefix initial tag count = [b|@8
  • |] where id' = [b|$prefix$&_$tag'|] tag' = escId tag checked = if HashSet.member tag initial then [b| checked|] else "" makeYearItems :: Bool -- ^ nsfw -> Integer -- ^ year -> [(FilePath, Info)] -> Builder makeYearItems nsfw year infos = [b|@4
  • $year' $4.items |] where items = map (uncurry $ makeItem nsfw) infos year' = show year & foldMap \c -> [b|$c|] makeItem :: Bool -> FilePath -> Info -> Builder makeItem nsfw file info@(Info {title, bg, date}) = [b|@4
  • $title
    |] where dir = takeDirectory file thumb = getThumb dir info nsfw' = if nsfw && #anyNsfw info then [b| nsfw|] else "" tags' = fold $ intersperse ";" $ map fromText $ tagsFor nsfw info date' = formatDateShort date bgStyle = ifJust bg \col -> [b| style="background: $col"|] formatDateShort :: Time.Day -> Builder formatDateShort date = [b|$day $month|] where (_, m, day) = Time.toGregorian date month = words "jan feb mar apr may jun jul aug sep oct nov dec" !! (m - 1)