website/frontend/src/Pages/Debate/Arguments.elm

621 lines
19 KiB
Elm
Raw Normal View History

2024-12-11 02:38:42 -06:00
module Pages.Debate.Arguments exposing (Model, Msg, page)
2024-11-12 19:23:16 -06:00
2025-01-02 02:33:57 -06:00
import Browser.Events as Events
2024-12-09 19:53:09 -06:00
import Config.Data.Identity exposing (pageNames)
2025-01-02 02:33:57 -06:00
import Config.Data.ImageFolders as M
2024-12-27 01:30:21 -06:00
exposing
2025-01-02 02:33:57 -06:00
( ImageFolder(..)
, imagePathMaker
)
import Config.Helpers.Cards.Inner.StrengthBar exposing (barMaker)
import Config.Helpers.Cards.Inner.Text
exposing
( bodyFormat
, detailBodyLink
2024-12-27 01:30:21 -06:00
, detailBodyMaker
, detailFormat
, detailSpacing
, detailTitleMaker
2025-01-02 02:33:57 -06:00
, generalButton
, getHoverColours
2024-12-27 01:30:21 -06:00
)
import Config.Helpers.Cards.Inner.ToolTip
exposing
( ToolTipPosition(..)
, tooltip
)
2024-12-27 01:30:21 -06:00
import Config.Helpers.Cards.Outer.Helpers exposing (cardMaker)
2025-01-02 02:33:57 -06:00
import Config.Helpers.Cards.Outer.Types as C exposing (Cardable(..))
2024-12-20 00:13:27 -06:00
import Config.Helpers.Converters exposing (toTitleCase)
2025-01-02 02:33:57 -06:00
import Config.Helpers.Headers.Helpers exposing (headerMaker)
2024-12-22 04:36:03 -06:00
import Config.Helpers.Headers.Records exposing (argumentHeader)
2025-01-02 02:33:57 -06:00
import Config.Helpers.Headers.Types as R exposing (Headerable(..))
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-15 02:31:26 -06:00
import Config.Pages.Debate.Arguments.List
exposing
( argumentList
)
2025-01-02 02:33:57 -06:00
import Config.Pages.Debate.Arguments.Types exposing (Argument)
2024-12-27 01:30:21 -06:00
import Config.Style.Colour.Helpers
exposing
( ThemeColor(..)
2025-01-02 02:33:57 -06:00
, getThemeColor
)
import Config.Style.Icons.Icons
exposing
( code
, copyLink
, thumbsDown
2024-12-27 01:30:21 -06:00
)
2025-01-02 02:33:57 -06:00
import Config.Style.Icons.Types as TySvg
2024-12-15 02:31:26 -06:00
exposing
2025-01-02 02:33:57 -06:00
( InnerPart
, OuterPart
2024-12-15 02:31:26 -06:00
)
2025-01-03 16:47:17 -06:00
import Config.Style.Images
exposing
( ElementSize(..)
, imageSquareMaker
)
2024-12-15 02:31:26 -06:00
import Config.Style.Transitions exposing (transitionStyleSlow)
2024-11-12 19:23:16 -06:00
import Effect exposing (Effect)
2025-01-02 02:33:57 -06:00
import Element as E
exposing
( Attribute
, Device
, DeviceClass(..)
, Element
, Orientation(..)
, alignLeft
, alignRight
, alignTop
, centerX
, centerY
, clip
, column
, el
, fill
, focused
, height
, htmlAttribute
, maximum
, none
, paddingEach
, paddingXY
, paragraph
, rgba
, row
, spacing
, text
, width
)
import Element.Background as B exposing (color)
2024-12-15 02:31:26 -06:00
import Element.Border as D
2025-01-02 02:33:57 -06:00
exposing
( color
, rounded
, shadow
)
2024-12-15 02:31:26 -06:00
import Element.Font as F
2025-01-02 02:33:57 -06:00
exposing
( bold
, center
, color
)
import Element.Input as Input
import Html.Attributes as H exposing (style)
2024-11-12 19:23:16 -06:00
import Layouts
import Page exposing (Page)
2025-01-02 02:33:57 -06:00
import Ports
import Process
2024-11-12 19:23:16 -06:00
import Route exposing (Route)
2024-12-28 20:50:11 -06:00
import Route.Path as Path
2024-11-12 19:23:16 -06:00
import Shared
2025-01-02 02:33:57 -06:00
import Svg.Attributes as SvgAttr
import Task
2024-11-12 19:23:16 -06:00
import View exposing (View)
page : Shared.Model -> Route () -> Page Model Msg
page shared route =
Page.new
{ init = init
, update = update
, subscriptions = subscriptions
, view = view shared
2024-11-12 19:23:16 -06:00
}
|> Page.withLayout toLayout
toLayout : Model -> Layouts.Layout Msg
toLayout model =
2024-12-07 15:43:26 -06:00
Layouts.Navbar {}
2024-11-12 19:23:16 -06:00
-- INIT
type alias Model =
2025-01-02 02:33:57 -06:00
{ hasBeenCopied : List Bool }
2024-11-12 19:23:16 -06:00
init : () -> ( Model, Effect Msg )
init () =
2025-01-02 03:41:57 -06:00
( { hasBeenCopied = List.repeat (List.length argumentList) False }
, Effect.batch
[ Effect.map
(\_ -> NoOp)
(Effect.sendCmd resetViewport)
, Effect.none
]
2024-11-12 19:23:16 -06:00
)
-- UPDATE
type Msg
2025-01-02 02:33:57 -06:00
= CopyText String Int
| ResetCopyState Int
| NoOp
2024-11-12 19:23:16 -06:00
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
2025-01-02 02:33:57 -06:00
let
urlLinkClickUpdate : Int -> Model
urlLinkClickUpdate index =
{ model
| hasBeenCopied =
List.take index model.hasBeenCopied
++ (case List.head (List.drop index model.hasBeenCopied) of
Just isCLicked ->
[ not isCLicked ]
Nothing ->
[]
-- shouldn't happen
)
++ List.drop (index + 1) model.hasBeenCopied
}
in
2024-11-27 15:11:21 -06:00
case msg of
2025-01-02 02:33:57 -06:00
CopyText text index ->
( urlLinkClickUpdate index
, Effect.batch
[ Effect.sendCmd (Ports.copyToClipboard text)
, Effect.sendCmd (Process.sleep 700 |> Task.perform (\_ -> ResetCopyState index))
]
)
ResetCopyState index ->
( urlLinkClickUpdate index
-- wrong lol
, Effect.none
)
2024-11-27 15:11:21 -06:00
NoOp ->
( model
, Effect.none
)
-- SUBSCRIPTIONS
2024-11-12 19:23:16 -06:00
subscriptions : Model -> Sub Msg
subscriptions model =
2024-11-27 15:11:21 -06:00
Sub.none
2024-11-12 19:23:16 -06:00
-- VIEW
view : Shared.Model -> Model -> View Msg
view shared model =
2024-12-08 02:18:36 -06:00
{ title = "debate (" ++ pageNames.pageArguments ++ ")"
2024-11-12 19:23:16 -06:00
, attributes = []
2025-01-02 02:33:57 -06:00
, element = debateContainer shared model
2024-11-12 19:23:16 -06:00
}
2025-01-02 02:33:57 -06:00
debateContainer : Shared.Model -> Model -> Element Msg
debateContainer shared model =
topLevelContainer (debateList shared model)
2025-01-02 02:33:57 -06:00
debateList : Shared.Model -> Model -> Element Msg
debateList shared model =
column
2024-12-28 22:30:45 -06:00
(case ( shared.device.class, shared.device.orientation ) of
2024-12-07 15:43:26 -06:00
_ ->
2024-12-28 22:30:45 -06:00
pageList shared.device
)
<|
List.concat
2024-12-22 04:36:03 -06:00
[ [ headerMaker (R.Arguments argumentHeader) ]
2025-01-02 02:33:57 -06:00
, List.map3
(\argument dummy index ->
cardMaker shared.device
(C.Argument argument)
(contentList shared model dummy index argument)
2024-12-21 23:23:59 -06:00
)
2024-12-08 02:18:36 -06:00
argumentList
2025-01-02 02:33:57 -06:00
model.hasBeenCopied
(List.range 0 (List.length argumentList))
]
2024-12-15 02:31:26 -06:00
2025-01-02 02:33:57 -06:00
contentList : Shared.Model -> Model -> Bool -> Int -> Argument -> List (Element Msg)
contentList shared model isLinkClicked index argument =
2024-12-24 03:08:39 -06:00
let
2025-01-03 16:47:17 -06:00
image : ElementSize -> Element msg
2024-12-24 03:08:39 -06:00
image size =
el
[ alignLeft
, alignTop
, paddingEach
{ top = 0
2024-12-27 01:30:21 -06:00
, right = 10
2024-12-24 03:08:39 -06:00
, bottom = 0
2024-12-27 01:30:21 -06:00
, left = 0
2024-12-24 03:08:39 -06:00
}
]
<|
2024-12-28 22:30:45 -06:00
imageSquareMaker shared.device (imagePathMaker M.Argument argument.argumentImage) True size
2024-12-24 03:08:39 -06:00
in
2024-12-23 03:15:35 -06:00
[ row
[ width fill
, paddingEach
{ top =
2024-12-28 22:30:45 -06:00
case ( shared.device.class, shared.device.orientation ) of
2024-12-23 03:15:35 -06:00
( Phone, Portrait ) ->
8
( Tablet, Portrait ) ->
8
_ ->
0
, right = 0
, bottom = 0
, left = 0
}
]
2024-12-27 01:30:21 -06:00
[ detailFormat column
[ detailFormat paragraph
2024-12-28 22:30:45 -06:00
[ case ( shared.device.class, shared.device.orientation ) of
2024-12-27 01:30:21 -06:00
( Phone, Portrait ) ->
none
2024-12-15 02:31:26 -06:00
2024-12-27 01:30:21 -06:00
( Tablet, Portrait ) ->
none
2024-12-15 02:31:26 -06:00
2024-12-27 01:30:21 -06:00
_ ->
2025-01-03 16:47:17 -06:00
image Medium
2024-12-27 01:30:21 -06:00
, el ([ height fill ] ++ bodyFormat TextLightGrey) <| text argument.propositionSummary
2024-12-15 02:31:26 -06:00
]
2024-12-27 01:30:21 -06:00
, detailFormat row
2024-12-28 22:30:45 -06:00
[ strengthMaker shared
2025-01-03 18:29:59 -06:00
, barMaker shared getConfidenceTooltip argument.argumentCertainty
2024-12-15 02:31:26 -06:00
]
]
]
2024-12-28 22:30:45 -06:00
, tableMaker shared.device argument
, formalizationMaker shared.device argument
, el [ alignRight ] <|
2024-12-28 20:50:11 -06:00
row [ width fill, spacing 20 ]
2025-01-02 02:33:57 -06:00
[ generalButton shared (Path.toString Path.Contact_Criticism) thumbsDown
, generalButton shared argument.proofLink code
, copyButton shared model isLinkClicked index argument
2024-12-28 20:50:11 -06:00
]
2024-12-27 01:30:21 -06:00
]
2024-12-15 02:31:26 -06:00
2025-01-02 02:33:57 -06:00
copyButton : Shared.Model -> Model -> Bool -> Int -> Argument -> Element Msg
copyButton shared model isLinkClicked index argument =
Input.button
[ focused
[ D.color (rgba 0 0 0 0)
2025-01-03 16:47:17 -06:00
, D.shadow
{ blur = 0
, color = rgba 0 0 0 0
, offset = ( 0, 0 )
, size = 0
}
2025-01-02 02:33:57 -06:00
]
]
{ onPress = Just (CopyText ("https://uprootnutrition.com" ++ Path.toString Path.Debate_Arguments ++ "#" ++ argument.argumentImage) index)
, label =
el
(if isLinkClicked then
[ transitionStyleSlow
, tooltip IsRight "Copied!"
2025-01-02 02:33:57 -06:00
, case ( shared.device.class, shared.device.orientation ) of
( Phone, Portrait ) ->
B.color (getThemeColor BackgroundDarkGrey)
( Tablet, Portrait ) ->
B.color (getThemeColor BackgroundDarkGrey)
_ ->
B.color (getThemeColor BackgroundDeepDarkGrey)
, paddingXY 7 7
, D.rounded 10
, F.color (getThemeColor TextLightOrange)
]
else
[ transitionStyleSlow
, B.color (getThemeColor Transparent)
, paddingXY 7 7
, D.rounded 10
, F.color (getThemeColor TextLightOrange)
]
++ getHoverColours TextLightOrange
)
<|
copyLink
{ elementAttributes =
[]
, sharedModel = shared
, svgAttributes = [ SvgAttr.width "20" ]
}
}
2024-12-28 22:30:45 -06:00
strengthMaker : Shared.Model -> Element msg
strengthMaker shared =
2024-12-27 01:30:21 -06:00
el
2025-01-03 18:29:59 -06:00
(case ( shared.device.class, shared.device.orientation ) of
( Phone, Portrait ) ->
[]
( Tablet, Portrait ) ->
[]
_ ->
if not shared.isNavbarExpanded then
[ tooltip IsRight
2025-01-03 18:29:59 -06:00
"This represents my confidence that the argument is sound."
]
2024-12-28 22:30:45 -06:00
2025-01-03 18:29:59 -06:00
else
[]
2024-12-28 22:30:45 -06:00
)
2024-12-27 01:30:21 -06:00
<|
detailTitleMaker TextLightOrange "Confidence:"
2024-12-15 02:31:26 -06:00
getConfidenceTooltip : Int -> String
getConfidenceTooltip num =
case num of
0 ->
"Extremely low. Speculative reasoning."
1 ->
"Very low. Extremely weak reasoning."
2 ->
"Low. Weak reasoning."
3 ->
"Kinda low. Somewhat weak reasoning."
4 ->
"Below average. More weak than strong."
5 ->
"Moderate. OK reasoning."
6 ->
"Above average. More strong than weak."
7 ->
"Kinda high. Somewhat strong reasoning."
8 ->
"High. Robust reasoning."
9 ->
"Very high. Extremely robust reasoning."
10 ->
"Extremely high. Air tight reasoning."
_ ->
"Confidence level out of expected range."
2024-12-23 03:15:35 -06:00
tableMaker : Device -> Argument -> Element msg
tableMaker device argument =
2024-12-22 04:36:03 -06:00
let
cellPadding : Attribute msg
cellPadding =
paddingXY 10 5
in
2024-12-15 02:31:26 -06:00
column
[ centerX
, E.width fill
]
2024-12-22 04:36:03 -06:00
[ el
2024-12-27 01:30:21 -06:00
[ E.width fill
2024-12-22 04:36:03 -06:00
, htmlAttribute <| H.style "position" "relative"
]
<|
E.table
2024-12-23 03:15:35 -06:00
([ D.rounded 10
, D.width 2
2025-01-02 02:33:57 -06:00
, D.color (getThemeColor TextDarkGrey)
2024-12-23 03:15:35 -06:00
, clip
]
++ (case ( device.class, device.orientation ) of
( Phone, Portrait ) ->
2025-01-02 02:33:57 -06:00
[ B.color (getThemeColor BackgroundSpreadsheet) ]
2024-12-23 03:15:35 -06:00
( Tablet, Portrait ) ->
2025-01-02 02:33:57 -06:00
[ B.color (getThemeColor BackgroundSpreadsheet) ]
2024-12-23 03:15:35 -06:00
_ ->
[]
)
)
2024-12-15 02:31:26 -06:00
{ data = argument.definitionTable
, columns =
[ { header =
el
[ F.bold
, D.widthEach
{ bottom = 1
, top = 1
, left = 1
, right = 1
}
2025-01-02 02:33:57 -06:00
, D.color (getThemeColor TextDarkGrey)
2024-12-22 04:36:03 -06:00
, cellPadding
2024-12-15 02:31:26 -06:00
, E.width fill
]
2024-12-22 04:36:03 -06:00
<|
2024-12-27 01:30:21 -06:00
detailTitleMaker
TextLightOrange
"Definiendum"
2024-12-22 04:36:03 -06:00
, width = fill |> maximum 30
2024-12-15 02:31:26 -06:00
, view =
\definition ->
2024-12-22 04:36:03 -06:00
el
2024-12-27 01:30:21 -06:00
[ D.widthEach
2024-12-15 02:31:26 -06:00
{ bottom = 1
, top = 0
, left = 1
, right = 1
}
2025-01-02 02:33:57 -06:00
, D.color (getThemeColor TextDarkGrey)
2024-12-22 04:36:03 -06:00
, cellPadding
2024-12-15 02:31:26 -06:00
, E.height fill
]
2024-12-22 04:36:03 -06:00
<|
2024-12-27 01:30:21 -06:00
el
[ centerX
, centerY
]
<|
paragraph [] [ detailTitleMaker TextLightOrange definition.definiendum ]
2024-12-15 02:31:26 -06:00
}
, { header =
el
2024-12-27 01:30:21 -06:00
[ D.widthEach
2024-12-15 02:31:26 -06:00
{ bottom = 1
, top = 1
, left = 0
, right = 1
}
2025-01-02 02:33:57 -06:00
, D.color (getThemeColor TextDarkGrey)
2024-12-22 04:36:03 -06:00
, cellPadding
2024-12-15 02:31:26 -06:00
, E.width fill
]
2024-12-22 04:36:03 -06:00
<|
2024-12-27 01:30:21 -06:00
detailTitleMaker TextLightOrange "Definiens"
2024-12-15 02:31:26 -06:00
, width = fill
, view =
\definition ->
2024-12-22 04:36:03 -06:00
el
2024-12-27 01:30:21 -06:00
[ D.widthEach
2024-12-15 02:31:26 -06:00
{ bottom = 1
, top = 0
, left = 0
, right = 1
}
2025-01-02 02:33:57 -06:00
, D.color (getThemeColor TextDarkGrey)
2024-12-22 04:36:03 -06:00
, cellPadding
2024-12-15 02:31:26 -06:00
, E.height fill
]
2024-12-22 04:36:03 -06:00
<|
el [] <|
2024-12-27 01:30:21 -06:00
paragraph [] [ detailBodyMaker TextLightGrey (text definition.definiens) ]
2024-12-15 02:31:26 -06:00
}
]
}
]
2024-12-28 18:42:47 -06:00
formalizationMaker : Device -> Argument -> Element msg
formalizationMaker device argument =
2024-12-15 02:31:26 -06:00
column
[ centerX
, E.width fill
, spacing 10
]
(List.indexedMap
(\index argumentEntry ->
column
2024-12-28 18:42:47 -06:00
[ paddingXY
(case ( device.class, device.orientation ) of
( Phone, Portrait ) ->
0
( Tablet, Portrait ) ->
0
_ ->
2024-12-28 20:50:11 -06:00
40
2024-12-28 18:42:47 -06:00
)
3
2024-12-22 04:36:03 -06:00
]
2024-12-15 02:31:26 -06:00
(List.indexedMap
(\entryIndex entryWithNotation ->
column
[ centerX
, F.center
2024-12-27 01:30:21 -06:00
, detailSpacing
2024-12-15 02:31:26 -06:00
, E.width fill
]
[ paragraph
2024-12-27 01:30:21 -06:00
[ width fill ]
[ detailTitleMaker
TextLightOrange
2024-12-15 02:31:26 -06:00
(if entryIndex < List.length argumentEntry.premises then
"P" ++ String.fromInt (entryIndex + 1) ++ ") "
else
"C) "
)
2024-12-27 01:30:21 -06:00
, detailBodyMaker TextLightGrey
(text
(if entryIndex < List.length argumentEntry.premises then
entryWithNotation.premise
else
argumentEntry.conclusion
)
2024-12-15 02:31:26 -06:00
)
|> el
2024-12-27 01:30:21 -06:00
[]
2024-12-15 02:31:26 -06:00
]
, paragraph
2024-12-27 01:30:21 -06:00
[]
[ detailTitleMaker
TextLightOrange
2024-12-15 02:31:26 -06:00
(if entryIndex < List.length argumentEntry.premises then
"(" ++ entryWithNotation.notation ++ ")"
else
"(" ++ argumentEntry.conclusionNotation ++ ")"
)
]
]
)
(argumentEntry.premises ++ [ { premise = argumentEntry.conclusion, notation = argumentEntry.conclusionNotation } ])
)
)
argument.argumentFormalization
)