website/frontend/src/Pages/Blog.elm

321 lines
8.5 KiB
Elm
Raw Normal View History

2024-12-16 00:12:23 -06:00
module Pages.Blog exposing (Model, Msg, page)
2024-12-09 19:53:09 -06:00
import Config.Data.Identity exposing (pageNames)
2024-12-18 20:11:04 -06:00
import Config.Helpers.Articles.Article exposing (extractFirstWords)
2024-12-15 02:31:26 -06:00
import Config.Helpers.CardFormat
exposing
( cardContentSpacing
, cardFormatter
, cardMaker
, cardTitleMaker
, desktopCardMaker
, desktopImageBoxSize
, desktopImageSize
, fieldSpacer
, mobileCardMaker
, mobileImageBoxSize
, mobileImageSize
, topLevelBox
2024-12-15 02:33:01 -06:00
, underConstructionMaker
2024-12-15 02:31:26 -06:00
)
2024-12-16 04:19:13 -06:00
import Config.Helpers.Converters
exposing
( formatName
, wordCount
)
import Config.Helpers.Format
exposing
2024-12-18 20:11:04 -06:00
( headerFontSizeSmall
, paragraphFontSize
2024-12-16 04:19:13 -06:00
, paragraphSpacing
)
2024-12-18 20:11:04 -06:00
import Config.Helpers.Headers.Header exposing (headerMaker)
import Config.Helpers.Headers.Types exposing (Header)
import Config.Helpers.Markdown
exposing
( renderDeviceMarkdown
, renderDeviceMarkdownNoToc
)
2024-12-11 03:48:49 -06:00
import Config.Helpers.Response
2024-12-09 19:53:09 -06:00
exposing
2024-12-09 20:30:04 -06:00
( pageList
2024-12-09 19:53:09 -06:00
, topLevelContainer
)
import Config.Helpers.Viewport exposing (resetViewport)
2024-12-18 02:04:31 -06:00
import Config.Pages.Blog.Records.BigFatSurprise exposing (articleBigFatSurprise)
2024-12-17 19:50:50 -06:00
import Config.Pages.Blog.Records.EverettVegans exposing (articleEverettVegans)
2024-12-17 02:17:06 -06:00
import Config.Pages.Blog.Records.HunterGatherers exposing (articleHunterGatherers)
2024-12-17 19:50:50 -06:00
import Config.Pages.Blog.Records.MeatApologetics exposing (articleMeatApologetics)
2024-12-17 02:17:06 -06:00
import Config.Pages.Blog.Records.NagraGoodrich exposing (articleNagraGoodrich)
2024-12-18 02:04:31 -06:00
import Config.Pages.Blog.Records.PlantBasedMeta exposing (articlePlantBasedMeta)
2024-12-17 03:24:17 -06:00
import Config.Pages.Blog.Records.QuackSmashing exposing (articleQuackSmashing)
2024-12-17 02:17:06 -06:00
import Config.Pages.Blog.Records.SapienDiet exposing (articleSapienDiet)
2024-12-16 04:19:13 -06:00
import Config.Pages.Blog.Records.SeedOils exposing (articleSeedOils)
2024-12-18 02:04:31 -06:00
import Config.Pages.Blog.Records.Shenangians exposing (articleShenanigans)
import Config.Pages.Blog.Records.SweetDeception exposing (articleSweetDeception)
2024-12-16 04:19:13 -06:00
import Config.Pages.Blog.Types exposing (..)
2024-12-09 19:53:09 -06:00
import Config.Style.Colour as T exposing (..)
2024-12-11 03:48:49 -06:00
import Config.Style.Icons.Icons exposing (construction)
import Effect exposing (Effect)
2024-12-09 19:53:09 -06:00
import Element as E exposing (..)
2024-12-16 04:19:13 -06:00
import Element.Background as B
import Element.Border as D
import Element.Font as F
import Html.Attributes as H exposing (style)
import Layouts
import Page exposing (Page)
import Route exposing (Route)
2024-12-16 04:19:13 -06:00
import Route.Path as Path
import Shared exposing (..)
import View exposing (View)
2024-12-08 21:35:48 -06:00
page : Shared.Model -> Route () -> Page Model Msg
page shared route =
Page.new
{ init = init
, update = update
, subscriptions = subscriptions
2024-12-08 21:35:48 -06:00
, view = view shared
}
2024-12-01 02:56:13 -06:00
|> Page.withLayout toLayout
toLayout : Model -> Layouts.Layout Msg
toLayout model =
2024-12-06 22:03:24 -06:00
Layouts.Navbar {}
-- INIT
type alias Model =
{}
init : () -> ( Model, Effect Msg )
init () =
( {}
2024-12-03 04:59:27 -06:00
, Effect.map
(\_ -> NoOp)
(Effect.sendCmd resetViewport)
)
-- UPDATE
type Msg
= NoOp
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
NoOp ->
( model
, Effect.none
)
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- VIEW
2024-12-08 21:35:48 -06:00
view : Shared.Model -> Model -> View Msg
view shared model =
2024-12-14 23:59:50 -06:00
{ title = pageNames.pageHyperBlog
2024-12-01 02:56:13 -06:00
, attributes = []
2024-12-16 04:19:13 -06:00
, element = blogContainer shared.device
2024-12-01 02:56:13 -06:00
}
2024-12-08 21:35:48 -06:00
2024-12-16 04:19:13 -06:00
blogContainer : Device -> Element msg
blogContainer device =
topLevelContainer (blogList device)
2024-12-08 21:35:48 -06:00
2024-12-16 04:19:13 -06:00
blogList : Device -> Element msg
blogList device =
column
(case ( device.class, device.orientation ) of
_ ->
pageList
)
<|
2024-12-08 21:35:48 -06:00
List.concat
2024-12-16 04:19:13 -06:00
[ List.map headerMaker
[ blogHeader ]
, (case ( device.class, device.orientation ) of
( Phone, Portrait ) ->
List.map mobileBlogMaker
( Tablet, Portrait ) ->
List.map mobileBlogMaker
2024-12-08 21:35:48 -06:00
_ ->
2024-12-16 04:19:13 -06:00
List.map desktopBlogMaker
)
2024-12-18 02:04:31 -06:00
[ articleShenanigans
, articleSweetDeception
, articleEverettVegans
2024-12-17 19:50:50 -06:00
, articleQuackSmashing
2024-12-17 02:17:06 -06:00
, articleSapienDiet
2024-12-17 19:50:50 -06:00
, articleNagraGoodrich
, articleMeatApologetics
2024-12-17 02:17:06 -06:00
, articleSeedOils
, articleHunterGatherers
2024-12-18 02:04:31 -06:00
, articlePlantBasedMeta
, articleBigFatSurprise
2024-12-17 02:17:06 -06:00
]
2024-12-16 04:19:13 -06:00
]
2024-12-15 03:01:13 -06:00
2024-12-16 04:19:13 -06:00
blogHeader : Header
blogHeader =
2024-12-15 03:01:13 -06:00
let
name =
"Blog"
in
{ headerTitle = String.toUpper name
2024-12-16 04:19:13 -06:00
, headerBody = "This page features blog articles written by me, along with contributions from guest authors, covering topics primarily related to nutrition science, health science, and debate."
}
desktopBlogMaker : BlogArticle -> Element msg
desktopBlogMaker article =
row
topLevelBox
[ desktopCardMaker desktopImageBoxSize desktopImageSize (articleImage article) article.articleLink
, cardMaker
[ cardTitleMaker article.articleName
, cardFormatter
[ cardContentSpacing
[ column
fieldSpacer
2024-12-17 02:17:06 -06:00
[ articleMaker article ]
2024-12-16 04:19:13 -06:00
]
]
]
]
mobileBlogMaker : BlogArticle -> Element msg
mobileBlogMaker article =
row
topLevelBox
[ column [] []
, cardMaker
[ cardTitleMaker article.articleName
, cardFormatter
[ cardContentSpacing
[ column
fieldSpacer
[ row [ width fill, spacing 10 ]
[ mobileCardMaker mobileImageBoxSize mobileImageSize (articleImage article) article.articleLink
, column
[ width fill ]
2024-12-17 02:17:06 -06:00
[ articleMaker article ]
2024-12-16 04:19:13 -06:00
]
]
]
]
]
]
articleImage :
BlogArticle
->
{ src : String
, description : String
}
articleImage article =
2024-12-17 02:17:06 -06:00
{ src = "blog/" ++ article.articleImage ++ "thumb.png"
2024-12-16 04:19:13 -06:00
, description = article.articleName
2024-12-15 03:01:13 -06:00
}
2024-12-16 04:19:13 -06:00
2024-12-17 02:17:06 -06:00
articleMaker : BlogArticle -> Element msg
articleMaker article =
2024-12-16 04:19:13 -06:00
column
[ E.width fill
, centerX
]
[ column [ width fill ]
2024-12-17 02:17:06 -06:00
(articleRows article
2024-12-16 04:19:13 -06:00
++ [ row []
[ paragraph
[ F.color colourTheme.textLightGrey
, paragraphSpacing
, paragraphFontSize
, spacing 3
, F.regular
, F.alignLeft
, paddingEach
{ top = 8
, bottom = 0
, left = 0
, right = 0
}
]
2024-12-18 20:11:04 -06:00
[ renderDeviceMarkdownNoToc (extractFirstWords article.articleBody) ]
2024-12-16 04:19:13 -06:00
]
]
)
]
infoRow : String -> String -> Element msg
infoRow label value =
row [ width fill ]
2024-12-18 20:11:04 -06:00
[ el [ width <| px 88 ] <|
el
2024-12-16 04:19:13 -06:00
[ F.color colourTheme.textLightOrange
, paragraphSpacing
, F.bold
2024-12-18 20:11:04 -06:00
, headerFontSizeSmall
2024-12-16 04:19:13 -06:00
, E.width fill
]
2024-12-18 20:11:04 -06:00
<|
text label
2024-12-16 04:19:13 -06:00
, el [ width fill ] <|
paragraph
[ F.color colourTheme.textLightGrey
, F.regular
, paragraphFontSize
, width fill
]
[ text value ]
]
2024-12-17 02:17:06 -06:00
articleRows : BlogArticle -> List (Element msg)
articleRows article =
2024-12-18 20:11:04 -06:00
let
referenceCount =
List.length article.articleReferences
in
[ infoRow "Published:" article.articlePublished
, infoRow "Author:" article.articleAuthor
2024-12-17 02:17:06 -06:00
, infoRow "Duration:" (String.fromInt (wordCount article.articleBody // 225) ++ " minutes")
2024-12-17 03:24:17 -06:00
, infoRow "Words:" (String.fromInt (wordCount article.articleBody))
2024-12-16 04:19:13 -06:00
]
2024-12-19 01:43:02 -06:00
++ (if referenceCount >= 2 then
2024-12-18 20:11:04 -06:00
[ infoRow "Sources:" (String.fromInt referenceCount) ]
else
[]
)