Add new deck source: JSON Against Humanity.
This commit is contained in:
@@ -88,7 +88,7 @@ init flags url key =
|
||||
, speech = speech
|
||||
, notifications = Notifications.init
|
||||
, remoteMode = remoteMode
|
||||
, sources = { builtIn = Nothing, manyDecks = Nothing }
|
||||
, sources = { builtIn = Nothing, manyDecks = Nothing, jsonAgainstHumanity = Nothing }
|
||||
}
|
||||
|
||||
( page, pageCmd ) =
|
||||
|
||||
@@ -21,6 +21,7 @@ import Html.Attributes as HtmlA
|
||||
import MassiveDecks.Card.Source.BuiltIn as BuiltIn
|
||||
import MassiveDecks.Card.Source.Custom as Player
|
||||
import MassiveDecks.Card.Source.Fake as Fake
|
||||
import MassiveDecks.Card.Source.JsonAgainstHumanity as JsonAgainstHumanity
|
||||
import MassiveDecks.Card.Source.ManyDecks as ManyDecks
|
||||
import MassiveDecks.Card.Source.Methods exposing (..)
|
||||
import MassiveDecks.Card.Source.Model exposing (..)
|
||||
@@ -71,6 +72,9 @@ generalMethods source =
|
||||
GManyDecks ->
|
||||
ManyDecks.generalMethods
|
||||
|
||||
GJsonAgainstHumanity ->
|
||||
JsonAgainstHumanity.generalMethods
|
||||
|
||||
|
||||
{-| Get an empty source of the given type.
|
||||
-}
|
||||
@@ -180,12 +184,13 @@ generalEditor shared existing currentValue update submit noOp =
|
||||
enabledSources =
|
||||
[ shared.sources.builtIn |> Maybe.map (\_ -> BuiltIn.generalMethods)
|
||||
, shared.sources.manyDecks |> Maybe.map (\_ -> ManyDecks.generalMethods)
|
||||
, shared.sources.jsonAgainstHumanity |> Maybe.map (\_ -> JsonAgainstHumanity.generalMethods)
|
||||
]
|
||||
|
||||
toItem source =
|
||||
{ id = source.id ()
|
||||
, icon = source.logo ()
|
||||
, primary = [ () |> source.name |> Lang.html shared ]
|
||||
, primary = [ () |> source.name |> Lang.string shared |> Html.text ]
|
||||
, secondary = Nothing
|
||||
, meta = Nothing
|
||||
}
|
||||
@@ -257,3 +262,6 @@ externalMethods external =
|
||||
|
||||
BuiltIn id ->
|
||||
BuiltIn.methods id
|
||||
|
||||
JsonAgainstHumanity id ->
|
||||
JsonAgainstHumanity.methods id
|
||||
|
||||
@@ -0,0 +1,154 @@
|
||||
module MassiveDecks.Card.Source.JsonAgainstHumanity exposing
|
||||
( generalMethods
|
||||
, methods
|
||||
)
|
||||
|
||||
import FontAwesome.Icon as Icon
|
||||
import FontAwesome.Solid as Icon
|
||||
import Html as Html exposing (Html)
|
||||
import Html.Attributes as HtmlA
|
||||
import List.Extra as List
|
||||
import MassiveDecks.Card.Source.JsonAgainstHumanity.Model exposing (..)
|
||||
import MassiveDecks.Card.Source.Methods as Source
|
||||
import MassiveDecks.Card.Source.Model as Source exposing (Source)
|
||||
import MassiveDecks.Components.Form.Message as Message exposing (Message)
|
||||
import MassiveDecks.Model exposing (..)
|
||||
import MassiveDecks.Pages.Lobby.Configure.Decks.Model exposing (DeckOrError)
|
||||
import MassiveDecks.Strings as Strings exposing (MdString)
|
||||
import MassiveDecks.Util.Html as Html
|
||||
import MassiveDecks.Util.Maybe as Maybe
|
||||
import Material.Select as Select
|
||||
|
||||
|
||||
methods : Id -> Source.ExternalMethods msg
|
||||
methods givenId =
|
||||
{ name = name
|
||||
, logo = logo
|
||||
, empty = empty
|
||||
, id = id
|
||||
, messages = messages
|
||||
, problems = problems givenId
|
||||
, defaultDetails = details givenId
|
||||
, tooltip = tooltip givenId
|
||||
, editor = editor givenId
|
||||
, equals = equals givenId
|
||||
}
|
||||
|
||||
|
||||
generalMethods : Source.ExternalGeneralMethods msg
|
||||
generalMethods =
|
||||
{ name = name
|
||||
, logo = logo
|
||||
, empty = empty
|
||||
, id = id
|
||||
, messages = messages
|
||||
}
|
||||
|
||||
|
||||
|
||||
{- Private -}
|
||||
|
||||
|
||||
id : () -> Source.General
|
||||
id () =
|
||||
Source.GJsonAgainstHumanity
|
||||
|
||||
|
||||
name : () -> MdString
|
||||
name () =
|
||||
Strings.JsonAgainstHumanity
|
||||
|
||||
|
||||
empty : Shared -> Source.External
|
||||
empty shared =
|
||||
shared.sources.jsonAgainstHumanity
|
||||
|> Maybe.andThen (.decks >> List.head)
|
||||
|> Maybe.map .id
|
||||
|> Maybe.withDefault (hardcoded "")
|
||||
|> Source.JsonAgainstHumanity
|
||||
|
||||
|
||||
equals : Id -> Source.External -> Bool
|
||||
equals givenId source =
|
||||
case source of
|
||||
Source.JsonAgainstHumanity other ->
|
||||
givenId == other
|
||||
|
||||
_ ->
|
||||
False
|
||||
|
||||
|
||||
messages : () -> List (Message msg)
|
||||
messages () =
|
||||
[ Strings.JsonAgainstHumanityAbout |> Message.info ]
|
||||
|
||||
|
||||
problems : Id -> () -> List (Message msg)
|
||||
problems givenId () =
|
||||
[]
|
||||
|
||||
|
||||
editor : Id -> Shared -> List DeckOrError -> (Source.External -> msg) -> Maybe msg -> msg -> Html msg
|
||||
editor selected shared existing update _ _ =
|
||||
case shared.sources.jsonAgainstHumanity of
|
||||
Just { decks } ->
|
||||
let
|
||||
deck d =
|
||||
let
|
||||
matches other =
|
||||
case other.source of
|
||||
Source.JsonAgainstHumanity o ->
|
||||
o == d.id
|
||||
|
||||
_ ->
|
||||
False
|
||||
in
|
||||
{ id = d.id
|
||||
, icon = Nothing
|
||||
, primary = [ Html.text d.name ]
|
||||
, secondary = Nothing
|
||||
, meta = Icon.check |> Icon.viewIcon |> Maybe.justIf (existing |> List.any matches)
|
||||
}
|
||||
in
|
||||
Html.span [ HtmlA.id "json-against-humanity-editor", HtmlA.class "primary" ]
|
||||
[ Select.view shared
|
||||
{ label = Strings.Deck
|
||||
, idToString = toString
|
||||
, idFromString = fromString shared.sources.jsonAgainstHumanity
|
||||
, selected = Just selected
|
||||
, wrap = Maybe.withDefault (hardcoded "") >> Source.JsonAgainstHumanity >> update
|
||||
}
|
||||
[ HtmlA.id "built-in-selector" ]
|
||||
(decks |> List.map deck)
|
||||
]
|
||||
|
||||
Nothing ->
|
||||
Html.nothing
|
||||
|
||||
|
||||
details : Id -> Shared -> Source.Details
|
||||
details givenId shared =
|
||||
{ name =
|
||||
shared.sources.jsonAgainstHumanity
|
||||
|> Maybe.andThen (.decks >> List.find (\d -> d.id == givenId))
|
||||
|> Maybe.map .name
|
||||
|> Maybe.withDefault (givenId |> toString)
|
||||
, url = Nothing
|
||||
, author = Nothing
|
||||
, translator = Nothing
|
||||
, language = Nothing
|
||||
}
|
||||
|
||||
|
||||
tooltip : Id -> (String -> List (Html msg) -> Html msg) -> Maybe ( String, Html msg )
|
||||
tooltip givenId tooltipRender =
|
||||
let
|
||||
forId =
|
||||
"json-against-humanity-" ++ toString givenId
|
||||
in
|
||||
( forId, [] |> tooltipRender forId ) |> Just
|
||||
|
||||
|
||||
logo : () -> Maybe (Html msg)
|
||||
logo () =
|
||||
Icon.code |> Icon.viewIcon |> Just
|
||||
@@ -0,0 +1,73 @@
|
||||
module MassiveDecks.Card.Source.JsonAgainstHumanity.Model exposing
|
||||
( Deck
|
||||
, Id
|
||||
, Info
|
||||
, fromString
|
||||
, hardcoded
|
||||
, idDecoder
|
||||
, toString
|
||||
)
|
||||
|
||||
{-| The id for a built-in deck.
|
||||
-}
|
||||
|
||||
import Json.Decode as Json
|
||||
import List.Extra as List
|
||||
|
||||
|
||||
type Id
|
||||
= Id String
|
||||
|
||||
|
||||
{-| Information about the source from the server.
|
||||
-}
|
||||
type alias Info =
|
||||
{ aboutUrl : String
|
||||
, decks : List Deck
|
||||
}
|
||||
|
||||
|
||||
{-| Information about a deck.
|
||||
-}
|
||||
type alias Deck =
|
||||
{ id : Id
|
||||
, name : String
|
||||
}
|
||||
|
||||
|
||||
{-| Get an id from a string.
|
||||
-}
|
||||
fromString : Maybe Info -> String -> Maybe Id
|
||||
fromString builtInInfo stringId =
|
||||
let
|
||||
matching got deck =
|
||||
case deck.id of
|
||||
Id str ->
|
||||
str == got
|
||||
|
||||
internal { decks } =
|
||||
decks |> List.find (matching stringId) |> Maybe.map .id
|
||||
in
|
||||
builtInInfo |> Maybe.andThen internal
|
||||
|
||||
|
||||
{-| Allows you to hard-code an Id for a deck. This means that the client and server could end up out of sync if the id
|
||||
doesn't actually exist.
|
||||
-}
|
||||
hardcoded : String -> Id
|
||||
hardcoded =
|
||||
Id
|
||||
|
||||
|
||||
{-| A decoder for ids.
|
||||
-}
|
||||
idDecoder : Json.Decoder Id
|
||||
idDecoder =
|
||||
Json.string |> Json.map Id
|
||||
|
||||
|
||||
{-| Convert an Id to it's string representation.
|
||||
-}
|
||||
toString : Id -> String
|
||||
toString (Id str) =
|
||||
str
|
||||
@@ -13,6 +13,7 @@ module MassiveDecks.Card.Source.Model exposing
|
||||
|
||||
import Json.Decode as Json
|
||||
import MassiveDecks.Card.Source.BuiltIn.Model as BuiltIn
|
||||
import MassiveDecks.Card.Source.JsonAgainstHumanity.Model as JsonAgainstHumanity
|
||||
import MassiveDecks.Card.Source.ManyDecks.Model as ManyDecks
|
||||
import MassiveDecks.Strings.Languages.Model exposing (Language)
|
||||
|
||||
@@ -22,6 +23,7 @@ import MassiveDecks.Strings.Languages.Model exposing (Language)
|
||||
type General
|
||||
= GBuiltIn
|
||||
| GManyDecks
|
||||
| GJsonAgainstHumanity
|
||||
|
||||
|
||||
{-| Details on where game data came from.
|
||||
@@ -46,6 +48,7 @@ sources are more limited and specific.
|
||||
type External
|
||||
= BuiltIn BuiltIn.Id
|
||||
| ManyDecks ManyDecks.DeckCode
|
||||
| JsonAgainstHumanity JsonAgainstHumanity.Id
|
||||
|
||||
|
||||
{-| A summary of the contents of the source deck.
|
||||
@@ -80,6 +83,7 @@ type LoadFailureReason
|
||||
type alias Info =
|
||||
{ builtIn : Maybe BuiltIn.Info
|
||||
, manyDecks : Maybe ManyDecks.Info
|
||||
, jsonAgainstHumanity : Maybe JsonAgainstHumanity.Info
|
||||
}
|
||||
|
||||
|
||||
@@ -94,6 +98,9 @@ generalToString source =
|
||||
GManyDecks ->
|
||||
"ManyDecks"
|
||||
|
||||
GJsonAgainstHumanity ->
|
||||
"JAH"
|
||||
|
||||
|
||||
{-| Get a general source by a string name.
|
||||
-}
|
||||
@@ -106,6 +113,9 @@ generalFromString sourceName =
|
||||
"ManyDecks" ->
|
||||
Just GManyDecks
|
||||
|
||||
"JAH" ->
|
||||
Just GJsonAgainstHumanity
|
||||
|
||||
_ ->
|
||||
Nothing
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ import MassiveDecks.Card.Model as Card exposing (Call, Response)
|
||||
import MassiveDecks.Card.Parts as Parts exposing (Part, Parts)
|
||||
import MassiveDecks.Card.Play as Play exposing (Play)
|
||||
import MassiveDecks.Card.Source.BuiltIn.Model as BuiltIn
|
||||
import MassiveDecks.Card.Source.JsonAgainstHumanity.Model as JsonAgianstHumanity
|
||||
import MassiveDecks.Card.Source.ManyDecks.Model as ManyDecks
|
||||
import MassiveDecks.Card.Source.Model as Source exposing (Source)
|
||||
import MassiveDecks.Cast.Model as Cast
|
||||
@@ -71,6 +72,7 @@ sourceInfo =
|
||||
Json.succeed Source.Info
|
||||
|> Json.optional "builtIn" (builtInInfo |> Json.map Just) Nothing
|
||||
|> Json.optional "manyDecks" (manyDecksInfo |> Json.map Just) Nothing
|
||||
|> Json.optional "jsonAgainstHumanity" (jsonAgainstHumanityInfo |> Json.map Just) Nothing
|
||||
|> Json.andThen atLeastOne
|
||||
|
||||
|
||||
@@ -86,6 +88,19 @@ manyDecksInfo =
|
||||
|> Json.required "baseUrl" Json.string
|
||||
|
||||
|
||||
jsonAgainstHumanityInfo : Json.Decoder JsonAgianstHumanity.Info
|
||||
jsonAgainstHumanityInfo =
|
||||
let
|
||||
jsonAgainstHumanityDeck =
|
||||
Json.succeed JsonAgianstHumanity.Deck
|
||||
|> Json.required "id" JsonAgianstHumanity.idDecoder
|
||||
|> Json.required "name" Json.string
|
||||
in
|
||||
Json.succeed JsonAgianstHumanity.Info
|
||||
|> Json.required "aboutUrl" Json.string
|
||||
|> Json.required "decks" (Json.list jsonAgainstHumanityDeck)
|
||||
|
||||
|
||||
builtInDeck : Json.Decoder BuiltIn.Deck
|
||||
builtInDeck =
|
||||
Json.succeed BuiltIn.Deck
|
||||
@@ -230,6 +245,9 @@ externalSourceByGeneral general =
|
||||
Source.GManyDecks ->
|
||||
Json.field "deckCode" (Json.string |> Json.map ManyDecks.deckCode) |> Json.map Source.ManyDecks
|
||||
|
||||
Source.GJsonAgainstHumanity ->
|
||||
Json.field "id" (JsonAgianstHumanity.idDecoder |> Json.map Source.JsonAgainstHumanity)
|
||||
|
||||
|
||||
tokenValidity : Json.Decoder (List Lobby.Token)
|
||||
tokenValidity =
|
||||
|
||||
@@ -24,6 +24,7 @@ module MassiveDecks.Models.Encoders exposing
|
||||
import Dict
|
||||
import Json.Encode as Json
|
||||
import MassiveDecks.Card.Source.BuiltIn.Model as BuiltIn
|
||||
import MassiveDecks.Card.Source.JsonAgainstHumanity.Model as JsonAgainstHumanity
|
||||
import MassiveDecks.Card.Source.ManyDecks.Model as ManyDecks
|
||||
import MassiveDecks.Card.Source.Model as Source exposing (Source)
|
||||
import MassiveDecks.Cast.Model as Cast
|
||||
@@ -343,14 +344,18 @@ source s =
|
||||
Source.ManyDecks deckCode ->
|
||||
Json.object
|
||||
[ ( "source", "ManyDecks" |> Json.string )
|
||||
, ( "deckCode"
|
||||
, deckCode |> ManyDecks.encode
|
||||
)
|
||||
, ( "deckCode", deckCode |> ManyDecks.encode )
|
||||
]
|
||||
|
||||
Source.BuiltIn id ->
|
||||
Json.object [ ( "source", "BuiltIn" |> Json.string ), ( "id", id |> BuiltIn.toString |> Json.string ) ]
|
||||
|
||||
Source.JsonAgainstHumanity id ->
|
||||
Json.object
|
||||
[ ( "source", "JAH" |> Json.string )
|
||||
, ( "id", id |> JsonAgainstHumanity.toString |> Json.string )
|
||||
]
|
||||
|
||||
|
||||
language : Language -> Json.Value
|
||||
language l =
|
||||
|
||||
@@ -201,7 +201,11 @@ view shared model =
|
||||
manyDecksAd { baseUrl } =
|
||||
Html.blankA
|
||||
[ HtmlA.href baseUrl, HtmlA.id "many-decks-ad", Strings.ManyDecksWhereToGet |> Lang.title shared ]
|
||||
[ Html.div [] [ Icon.boxOpen |> Icon.viewIcon, Strings.ManyDecks |> Lang.html shared ] ]
|
||||
[ Html.div []
|
||||
[ Icon.boxOpen |> Icon.viewIcon
|
||||
, Html.span [] [ Strings.ManyDecks |> Lang.string shared |> Html.text ]
|
||||
]
|
||||
]
|
||||
in
|
||||
[ Html.div [ HtmlA.class "page start" ]
|
||||
[ overlay shared model.overlay
|
||||
|
||||
@@ -217,6 +217,8 @@ type MdString
|
||||
| ManyDecksDeckCodeTitle -- A term referring to a deck code for Many Decks.
|
||||
| ManyDecksDeckCodeShort -- A description of the problem where a deck code must be at least five characters.
|
||||
| ManyDecksWhereToGet -- A description of how to get deck codes from Many Decks.
|
||||
| JsonAgainstHumanity -- The name of the JSON Against Humanity source.
|
||||
| JsonAgainstHumanityAbout -- A short description of the JSON Against Humanity source.
|
||||
| BuiltIn -- A term referring to decks of cards that are provided by this instance of the game.
|
||||
| APlayer -- A short description of a generic player in the game in the context of being the author of a card.
|
||||
| DeckAlreadyAdded -- A description of the problem of the deck already being added to the game configuration.
|
||||
|
||||
@@ -757,7 +757,13 @@ translate mdString =
|
||||
[ Text "A deck code must be at least five characters long." ]
|
||||
|
||||
ManyDecksWhereToGet ->
|
||||
[ Text "You can create decks to play with at Many Decks." ]
|
||||
[ Text "You can create and find decks to play with at ", Ref ManyDecks, Text "." ]
|
||||
|
||||
JsonAgainstHumanity ->
|
||||
[ Text "JSON Against Humanity" ]
|
||||
|
||||
JsonAgainstHumanityAbout ->
|
||||
[ Text "Decks provided by ", Ref JsonAgainstHumanity ]
|
||||
|
||||
BuiltIn ->
|
||||
[ Text "Built-in" ]
|
||||
|
||||
@@ -786,6 +786,14 @@ translate mdString =
|
||||
ManyDecksWhereToGet ->
|
||||
[ Missing ]
|
||||
|
||||
-- TODO: Translate
|
||||
JsonAgainstHumanity ->
|
||||
[ Missing ]
|
||||
|
||||
-- TODO: Translate
|
||||
JsonAgainstHumanityAbout ->
|
||||
[ Missing ]
|
||||
|
||||
-- TODO: Translate
|
||||
BuiltIn ->
|
||||
[ Missing ]
|
||||
|
||||
@@ -773,7 +773,15 @@ translate mdString =
|
||||
[ Text "Um código de deck deve ser de pelo menos cinco caracteres." ]
|
||||
|
||||
ManyDecksWhereToGet ->
|
||||
[ Text "Você pode criar decks para jogar usando o Many Decks." ]
|
||||
[ Text "Você pode criar decks para jogar usando o ", Ref ManyDecks, Text "." ]
|
||||
|
||||
-- TODO: Translate
|
||||
JsonAgainstHumanity ->
|
||||
[ Missing ]
|
||||
|
||||
-- TODO: Translate
|
||||
JsonAgainstHumanityAbout ->
|
||||
[ Missing ]
|
||||
|
||||
BuiltIn ->
|
||||
[ Text "Embutido" ]
|
||||
|
||||
@@ -243,7 +243,7 @@ enhanceHtml context mdString unenhanced =
|
||||
Played ->
|
||||
term context PlayedDescription Icon.check unenhanced
|
||||
|
||||
ManyDecksWhereToGet ->
|
||||
ManyDecks ->
|
||||
case context.shared.sources.manyDecks of
|
||||
Just { baseUrl } ->
|
||||
[ Html.blankA [ HtmlA.href baseUrl ] unenhanced ]
|
||||
@@ -251,6 +251,14 @@ enhanceHtml context mdString unenhanced =
|
||||
Nothing ->
|
||||
unenhanced
|
||||
|
||||
JsonAgainstHumanity ->
|
||||
case context.shared.sources.jsonAgainstHumanity of
|
||||
Just { aboutUrl } ->
|
||||
[ Html.blankA [ HtmlA.href aboutUrl ] unenhanced ]
|
||||
|
||||
Nothing ->
|
||||
unenhanced
|
||||
|
||||
_ ->
|
||||
unenhanced
|
||||
|
||||
|
||||
@@ -182,6 +182,8 @@
|
||||
left: -0.8em;
|
||||
top: -3em;
|
||||
|
||||
z-index: 11;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
align-items: center;
|
||||
|
||||
Reference in New Issue
Block a user