render thread

This commit is contained in:
towards-a-new-leftypol 2024-02-07 07:49:23 -05:00
parent 831c0ba096
commit 9269448477
10 changed files with 321 additions and 159 deletions

View File

@ -72,6 +72,9 @@ executable chandlr
Network.SiteType Network.SiteType
Network.PostType Network.PostType
Network.ThreadType Network.ThreadType
Component.ThreadView
Component.Thread.Files
Component.Thread.Intro
Routes Routes
Common.AttachmentType Common.AttachmentType

View File

@ -1 +1,19 @@
<div class="files"> <div class="file"> <p class="fileinfo"><span>File <small>(<a class="hide-image-link" href="javascript:void(0)" style="">hide</a>)</small>: </span><a href="/leftypol/src/1705665213107.png" target="_blank">1705665213107.png</a> <span class="details"> ( 1.88 MB , 1200x800 , <a download="south-african-representatives-at-the-international-court-of-justice.png" href="javascript:void(0)" title="Save as original filename (south-african-representatives-at-the-international-court-of-justice.png)">south-african-representati….png</a> ) </span></p> <a href="/leftypol/src/1705665213107.png" target="_blank"><img class="post-image" loading="lazy" src="https://leftychan.net/leftypol/thumb/1705665213107.png" style="width:255px;height:170px" alt=""></a> </div> </div> <div class="files">
<div class="file">
<p class="fileinfo">
<span>
File <small>(<a class="hide-image-link" href="javascript:void(0)" style="">hide</a>)</small>
:
</span>
<a href="/leftypol/src/1705665213107.png" target="_blank">1705665213107.png</a>
<span class="details">
(1.88 MB, 1200x800,
<a download="south-african-representatives-at-the-international-court-of-justice.png" href="javascript:void(0)" title="Save as original filename (south-african-representatives-at-the-international-court-of-justice.png)">south-african-representati….png</a>
)
</span>
</p>
<a href="/leftypol/src/1705665213107.png" target="_blank">
<img class="post-image" loading="lazy" src="https://leftychan.net/leftypol/thumb/1705665213107.png" style="width:255px;height:170px" alt="">
</a>
</div>
</div>

View File

@ -17,6 +17,10 @@
margin-left: .2em; margin-left: .2em;
margin-right: .2em; margin-right: .2em;
} }
.post.op.multifile {
clear: both;
}
</style> </style>
</head> </head>
<body> <body>

View File

@ -1,2 +1,2 @@
curl -v 'http://localhost:3000/sites?select=*,boards(*,threads(*,posts(*,attachments(*))))&name=eq.leftychan&boards.pathpart=eq.ga&boards.threads.board_thread_id=eq.11787' \ curl -v 'http://localhost:3000/sites?select=*,boards(*,threads(*,posts(*,attachments(*))))&name=eq.leftychan&boards.pathpart=eq.ga&boards.threads.board_thread_id=eq.11787&boards.threads.posts.order=board_post_id.asc' \
-H "Content-Type: application/json" -H "Content-Type: application/json"

View File

@ -108,7 +108,7 @@ gridItem iface m post =
body = map (rawHtml . toMisoString) $ maybeToList $ CatalogPost.body post body = map (rawHtml . toMisoString) $ maybeToList $ CatalogPost.body post
post_count_str :: MisoString post_count_str :: MisoString
post_count_str = "R: " `append` (toMisoString $ CatalogPost.estimated_post_count post) `append` "+" post_count_str = "R: " `append` (toMisoString $ (CatalogPost.estimated_post_count post) - 1) `append` "+"
thumb_url :: MisoString thumb_url :: MisoString
thumb_url = thumb_url =

View File

@ -0,0 +1,176 @@
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Component.Thread.Files where
import Miso
( View
, div_
, href_
, a_
, class_
, title_
, alt_
, src_
, style_
, img_
, span_
, loading_
, download_
, p_
, Attribute
, text
)
import Data.Foldable (toList)
import qualified Data.Text as Text
import Miso.String (append, toMisoString)
import qualified Data.Map as Map
import GHCJS.DOM.Types (JSString)
import Network.SiteType (Site)
import qualified Network.SiteType as Site
import qualified Network.BoardType as Board
import qualified Network.ThreadType as Thread
import qualified Network.PostType as Post
import Network.PostType (Post)
import Common.AttachmentType (Attachment, Dimension (..))
import qualified Common.AttachmentType as Attachment
import Network.Units (bytesToHumanReadable)
max_thumbnail_width :: Int
max_thumbnail_width = 255
max_thumbnail_height :: Int
max_thumbnail_height = 255
max_original_filename_display_length :: Int
max_original_filename_display_length = 25
files :: JSString -> Site -> Post -> View a
files media_root site post = div_
[ class_ "files" ]
( map (file media_root site multi) as )
where
multi = length as > 1
as = Post.attachments post
file :: JSString -> Site -> Bool -> Attachment -> View a
file media_root site multifile a = div_
( [ class_ "file" ] ++
if multifile then
[ class_ "multifile" ] ++ file_elem_size_attr
else []
)
[ p_
[ class_ "fileinfo" ]
[ span_ [] [ "File: " ]
, a_
[ href_ file_url
][ text $ toMisoString board_filename]
, text " "
, span_
[ class_ "details" ]
[ text $ "(" `append` size `append` ", 1280x720, "
, a_
[ download_ orig_file_name
, href_ file_url
, title_ $ "Save as original filename (" `append` orig_file_name `append` ")"
][ text filename_text ]
, ")"
]
]
, a_
[ href_ file_url
]
[ img_
(
[ class_ "post-image"
, loading_ "lazy"
, src_ thumb_url
, alt_ ""
] ++ size_style_attr
)
]
]
where
orig_file_name :: JSString
orig_file_name = toMisoString fname
size :: JSString
size = toMisoString $
bytesToHumanReadable (Attachment.file_size_bytes a) True
filename_text :: JSString
filename_text
| Text.length fname > max_original_filename_display_length =
toMisoString (Text.take max_original_filename_display_length fname)
`append` "" `append` toMisoString file_ext
| otherwise = toMisoString fname
fname :: Text.Text
fname = maybe board_filename id $ Attachment.original_filename a
file_ext :: Text.Text
file_ext = maybe "" ((<>) ".") $ Attachment.file_extension a
board_filename :: Text.Text
board_filename = Attachment.board_filename a <> file_ext
thumb_url :: JSString
thumb_url = img_url_path
`append` "/thumbnail_" `append` toMisoString (Attachment.board_filename a)
`append` toMisoString (maybe "" ((<>) ".") $ Attachment.thumb_extension a)
file_url :: JSString
file_url = img_url_path
`append` "/" `append` toMisoString (Attachment.board_filename a)
`append` toMisoString file_ext
img_url_path :: JSString
img_url_path
= media_root
`append` "/" `append` toMisoString (Site.name site)
`append` "/" `append` toMisoString (Board.pathpart board)
`append` "/" `append` toMisoString
(show $ Thread.board_thread_id
(head (Board.threads board)))
board :: Board.Board
board = head $ Site.boards site
size_style_attr :: [ Attribute a ]
size_style_attr = map (mk_size_style_attr . thumb_dimensions) $ toList $ Attachment.resolution a
file_elem_size_attr :: [ Attribute a ]
file_elem_size_attr = map (mk_file_elem_width_style . thumb_dimensions) $ toList $ Attachment.resolution a
mk_file_elem_width_style :: Dimension -> Attribute a
mk_file_elem_width_style Dimension {..} =
style_ $ Map.singleton "width" $ toPx (width + 40)
mk_size_style_attr :: Dimension -> Attribute a
mk_size_style_attr Dimension {..} = style_ $ Map.fromList
[
( "width"
, toPx width
)
,
( "height"
, toPx height
)
]
toPx :: Int -> JSString
toPx i = (toMisoString $ show i) `append` "px"
thumb_dimensions :: Dimension -> Dimension
thumb_dimensions Dimension {..}
| width > height = Dimension mw (round $ fromIntegral mw / fromIntegral width * (fromIntegral height :: Double))
| otherwise = Dimension (round $ fromIntegral mh / fromIntegral height * (fromIntegral width :: Double)) mh
where
mw = min max_thumbnail_width width
mh = min max_thumbnail_height height

View File

@ -0,0 +1,57 @@
{-# LANGUAGE OverloadedStrings #-}
module Component.Thread.Intro where
import Miso
( View
, text
, href_
, a_
, class_
, id_
, textProp
, title_
, span_
, time_
)
import GHCJS.DOM.Types (JSString)
import Data.Foldable (toList)
import Miso.String (toMisoString)
import Network.PostType (Post)
import qualified Network.PostType as Post
intro :: Post -> View a
intro post = span_
[ class_ "intro" ]
( subject ++
[ span_
[ class_ "name" ][ "Anonymous" ]
-- TODO: Add flags (don't have that data in the db yet)
, time_
[ textProp "datetime" "2024-01-19T11:53:33Z"
, textProp "data-local" "true"
, title_ "14 days ago"
][ "2024-01-19 (Fri) 06:53:33" ]
, " "
, a_
[ class_ "post_no"
, id_ "post_no_477700"
, href_ "/leftypol/res/477700.html#477700"
][ "No." ]
, a_
[ class_ "post_no"
, href_ "/leftypol/res/477700.html#q477700"
][ "477700" ]
]
)
where
subject :: [ View a ]
subject = map (mkSubject . toMisoString) $ toList $ Post.subject post
mkSubject :: JSString -> View a
mkSubject s = span_
[ class_ "subject" ]
[ text s ]

View File

@ -15,30 +15,15 @@ import Miso
, text , text
, h1_ , h1_
, noEff , noEff
, href_
, a_
, class_ , class_
, id_ , id_
, textProp , textProp
, title_
, alt_
, src_
, style_
, img_
, span_
, time_
, h2_ , h2_
, rawHtml , rawHtml
, loading_ , Attribute
, download_
, small_
, p_
, for_
, label_
) )
import Data.Maybe (maybeToList) import Data.Maybe (maybeToList)
import qualified Data.Map as Map
import Miso.String (toMisoString) import Miso.String (toMisoString)
import GHCJS.DOM.Types (JSString) import GHCJS.DOM.Types (JSString)
@ -48,6 +33,8 @@ import Network.PostType (Post)
import qualified Network.PostType as Post import qualified Network.PostType as Post
import qualified Network.BoardType as Board import qualified Network.BoardType as Board
import qualified Network.ThreadType as Thread import qualified Network.ThreadType as Thread
import Component.Thread.Files (files)
import Component.Thread.Intro (intro)
data Model = Model data Model = Model
{ site :: Site { site :: Site
@ -70,10 +57,13 @@ view m =
div_ div_
[] []
( (
[ h1_ [] [ text $ toMisoString $ Site.name $ site m ] [ h1_ [] [ text title ]
, op_post thread_posts , div_
[ class_ "thread" ]
( (op_post thread_posts)
++ map (reply m) (drop 1 thread_posts)
)
] ]
++ map reply (drop 1 thread_posts)
) )
where where
@ -83,64 +73,43 @@ view m =
concatMap (Board.threads) $ concatMap (Board.threads) $
Site.boards (site m) Site.boards (site m)
op_post :: [ Post ] -> View a op_post :: [ Post ] -> [ View a ]
op_post [] = h2_ [] [ "There's nothing here" ] op_post [] = [ h2_ [] [ "There's nothing here" ] ]
op_post (x:_) = op x op_post (x:_) = op m x
title :: JSString
title = toMisoString $ (Site.name $ site m) <> " /" <> board <> "/"
board = Board.pathpart $ head $ Site.boards (site m)
body :: Post -> [ View a ] body :: Post -> [ View a ]
body post = map (rawHtml . toMisoString) $ maybeToList $ Post.body post body post = map (rawHtml . toMisoString) $ maybeToList $ Post.body post
op :: Post -> View a op :: Model -> Post -> [ View a ]
op op_post = div_ op m op_post =
[ files (media_root m) (site m) op_post
, div_
(
[ class_ "post op" [ class_ "post op"
, id_ "op_477700" , id_ "op_477700"
] ] ++ multi
[ span_
[ class_ "intro" ]
[ span_
[ class_ "subject" ][ "Israel 'at war' as Hamas gunmen launch surprise attack from Gaza Thread Pt. II" ]
, span_
[ class_ "name" ][ "Anonymous" ]
, img_
[ style_ $ Map.fromList
[
( "max-height"
, "16px"
) )
, [ intro op_post
( "width"
, "auto"
)
]
, class_ "flag"
, src_ "/static/flags/acceleration.png"
, alt_ "Acceleration"
, title_ "Acceleration"
]
, time_
[ textProp "datetime" "2024-01-19T11:53:33Z"
, textProp "data-local" "true"
, title_ "14 days ago"
][ "2024-01-19 (Fri) 06:53:33" ]
]
, " "
, a_
[ class_ "post_no"
, id_ "post_no_477700"
, href_ "/leftypol/res/477700.html#477700"
][ "No." ]
, a_
[ class_ "post_no"
, href_ "/leftypol/res/477700.html#q477700"
][ "477700" ]
, div_ , div_
[ class_ "body" ] [ class_ "body" ]
(body op_post) (body op_post)
] ]
]
reply :: Post -> View a where
reply post = div_ multi :: [ Attribute a ]
multi
| length (Post.attachments op_post) > 1 = [ class_ "multifile" ]
| otherwise = []
reply :: Model -> Post -> View a
reply m post = div_
[ class_ "postcontainer" [ class_ "postcontainer"
, id_ "pc477702" , id_ "pc477702"
, textProp "data-board" "leftypol" , textProp "data-board" "leftypol"
@ -149,93 +118,8 @@ reply post = div_
[ class_ "post reply" [ class_ "post reply"
, id_ "reply_477702" , id_ "reply_477702"
] ]
[ p_ [ intro post
[ class_ "intro" ] , files (media_root m) (site m) post
[ label_
[ for_ "delete_477702" ]
[ span_
[ class_ "name" ][ "Anonymous" ]
, time_
[ textProp "datetime" "2024-01-19T11:58:26Z"
, textProp "data-local" "true"
, title_ "17 days ago"
][ "2024-01-19 (Fri) 06:58:26" ]
]
, "&nbsp;"
, a_
[ class_ "post_no"
, id_ "post_no_477702"
-- , onclick_ "highlightReply(477702)"
, href_ "/leftypol/res/477700.html#477702"
][ "No." ]
, a_
[ class_ "post_no"
-- , onclick_ "citeReply(477702)"
, href_ "/leftypol/res/477700.html#q477702"
][ "477702" ]
, span_
[ class_ "mentioned unimportant" ]
[ a_
[ class_ "mentioned-477703"
-- , onclick_ "highlightReply('477703');"
, href_ "#477703"
][ "&gt;&gt;477703" ]
]
]
, div_
[ class_ "files" ]
[ div_
[ class_ "file" ]
[ p_
[ class_ "fileinfo" ]
[ span_ []
[ "File"
, small_ []
[ "("
, a_
[ class_ "hide-image-link"
, href_ "javascript:void(0)"
][ "hide" ]
, ")"
]
, ":"
]
, a_
[ href_ "/leftypol/src/1705665505794.jpeg"
][ "1705665505794.jpeg" ]
, span_
[ class_ "details" ]
[ "( 403.8 KB, 1280x720,"
, a_
[ download_ "Aerial-shot-Washington-DC-Palestine.jpeg"
, href_ "javascript:void(0)"
, title_ "Save as original filename (Aerial-shot-Washington-DC-Palestine.jpeg)"
][ "Aerial-shot-Washington-DC….jpeg" ]
, ")"
]
]
, a_
[ href_ "/leftypol/src/1705665505794.jpeg"
]
[ img_
[ style_ $ Map.fromList
[
( "height"
, "143px"
)
,
( "width"
, "255px"
)
]
, class_ "post-image"
, loading_ "lazy"
, src_ "/leftypol/thumb/1705665505794.png"
, alt_ ""
]
]
]
]
, div_ , div_
[ class_ "body" ] [ class_ "body" ]
(body post) (body post)

View File

@ -90,3 +90,4 @@ getThread m iface A.GetThreadArgs {..} =
<> "&name=eq." <> toMisoString website <> "&name=eq." <> toMisoString website
<> "&boards.pathpart=eq." <> toMisoString board_pathpart <> "&boards.pathpart=eq." <> toMisoString board_pathpart
<> "&boards.threads.board_thread_id=eq." <> toMisoString (show board_thread_id) <> "&boards.threads.board_thread_id=eq." <> toMisoString (show board_thread_id)
<> "&boards.threads.posts.order=board_post_id.asc"

19
src/Network/Units.hs Normal file
View File

@ -0,0 +1,19 @@
module Network.Units where
import Text.Printf (printf)
data Unit = KiB | MiB | GiB | TiB | PiB | EiB | ZiB | YiB
| KB | MB | GB | TB | PB | EB | ZB | YB
deriving (Enum, Show, Bounded)
bytesToHumanReadable :: Integral a => a -> Bool -> String
bytesToHumanReadable bytes binaryPrefix = printf "%.2f %s" size (show unit)
where
(factor, units) = if binaryPrefix
then (1024.0, enumFrom KiB) -- Binary prefix, 1024 base, explicitly Double
else (1000.0, enumFrom KB) -- Decimal prefix, 1000 base, explicitly Double
(size, unit) = foldl (\(accSize, accUnit) u ->
if accSize < factor then (accSize, accUnit)
else (accSize / factor, u))
(fromIntegral bytes :: Double, if binaryPrefix then KiB else KB) -- Explicitly Double
units