Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kittykatattack/f05b42efc6ecf09ddf244bbafd18edb3 to your computer and use it in GitHub Desktop.
Save kittykatattack/f05b42efc6ecf09ddf244bbafd18edb3 to your computer and use it in GitHub Desktop.
port module Main exposing(..)
import Html exposing (..)
import Html.App as Html
import Html.Events exposing (..)
import Html.Attributes exposing (src, style)
import Json.Decode as Json
import String
import String.Extra
import Regex
import Material
import Material.Textfield as Textfield
import Material.Options as Options exposing (css)
import Material.Options exposing (css)
import Material.Button as Button
import Material.Grid exposing (grid, cell, size, offset, Device(..))
import Material.Card as Card
import Material.Elevation as Elevation
import StoryTemplates
import Animation
import Animation.Messenger exposing (State)
-- DEFAULTS
type alias Defaults =
{ imagesLocation : String
, titleFont : String
, storyFont : String
, fontFamily : String
}
defaults : Defaults
defaults =
{ imagesLocation = "images/"
, titleFont = "SuisseIntl-Thin"
, storyFont = "LibreBaskerville-Regular, serif"
, fontFamily = "Helvetica, Arial, sans-serif"
}
-- MODEL
type alias Model =
{ content : String
, mdl : Material.Model
, logo : String
, storyOutput : String
, input : String
, words : Words
, places : String
, livingThings : String
, objects : String
, actions : String
, moods : String
, storyTextStyle : Animation.Messenger.State Msg
}
model : (Model, Cmd Msg)
model =
{ content = "test"
, mdl = Material.model
, logo = defaults.imagesLocation ++ "logo_WritersDeskLong_48.png"
, storyOutput = "(Your story will appear here.)"
, input = ""
, words = initialWords
, places = "forest city mountain ocean castle"
, livingThings = "sorcerer cat tree pilot flamingo goldfish"
, objects = "hat apple axe fork basket"
, actions = "fly sing dance jump sail"
, moods = "adventurous boring uncomfortable whistful sleepy"
, storyTextStyle =
Animation.style
[ Animation.opacity 1.0
]
}
! []
type alias Words =
{ places : List String
, livingThings : List String
, objects : List String
, actions : List String
, moods : List String
}
initialWords =
{ places = [""]
, livingThings = [""]
, objects = [""]
, actions = [""]
, moods = [""]
}
-- UPDATE
type Msg
= MDL (Material.Msg Msg)
| SendStoryComponents
| UpdateLivingThings String
| UpdateObjects String
| UpdatePlaces String
| UpdateActions String
| UpdateMoods String
| Animate Animation.Msg
--| LoadPartsOfSpeech PartsOfSpeech
| LoadStory String
| CreateStory
--| DoneFadingOutOldTextPleaseSwitchModelToNewText String
| FadeInOut
| NoOp
port sendStoryComponents : (Words, List String) -> Cmd msg
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
SendStoryComponents ->
let
_ = Debug.crash "crash"
words =
model.words
toList string =
String.Extra.clean string
|> String.split " "
words' =
{ places = toList model.places
, livingThings = toList model.livingThings
, objects = toList model.objects
, actions = toList model.actions
, moods = toList model.moods
}
model' =
{ model
| words = words'
}
in
(model', sendStoryComponents(model'.words, StoryTemplates.stories))
LoadStory storyOutput' ->
let
model' =
{ model
| storyOutput = storyOutput'
}
in
model' ! []
UpdateLivingThings input' ->
{ model
| livingThings = input'
}
! [ ]
UpdateObjects input' ->
{ model
| objects = input'
}
! [ ]
UpdatePlaces input' ->
{ model
| places = input'
}
! [ ]
UpdateActions input' ->
{ model
| actions = input'
}
! [ ]
UpdateMoods input' ->
{ model
| moods = input'
}
! [ ]
Animate animMsg ->
let
(newStyle, cmds) =
Animation.Messenger.update
animMsg
model.storyTextStyle
in
({ model
| storyTextStyle = newStyle
}
, cmds
)
FadeInOut ->
let
newStyle =
Animation.interrupt
[ Animation.to [Animation.opacity 0]
, Animation.Messenger.send SendStoryComponents
, Animation.to [Animation.opacity 1]
]
model.storyTextStyle
in
{ model
| storyTextStyle = newStyle
}
! [ ]
{-
LoadPartsOfSpeech partsOfSpeech' ->
let
model' =
{ model
| partsOfSpeech = partsOfSpeech'
}
in
update CreateStory model'
-}
{-
UpdateField input' ->
{ model
| input = input'
}
! []
-}
MDL msg' ->
Material.update msg' model
CreateStory ->
model ! []
NoOp ->
model ! []
-- Helper functions
{-
stripPunctuation : String -> String
stripPunctuation =
Regex.replace Regex.All (Regex.regex "/[.,\/#!$%\^&\*;:{}=\-_`~()]/g") (\_ -> "")
-}
-- VIEW
(=>) : a -> b -> ( a, b )
(=>) = (,)
view : Model -> Html Msg
view model =
let
titleStyle =
style
[ "font-size" => "2.5em"
, "font-family" => defaults.titleFont
, "padding-top" => "1em"
, "padding-bottom" => "1em"
, "margin-bottom" => "0em"
]
mainContainerStyle =
style
[ "margin" => "0"
, "padding" => "2vh 5vw 2vh 5vw"
, "width" => "90vw"
, "height" => "94vh"
]
labelStyle =
style
[ "padding-bottom" => "0"
, "margin-bottom" => "0"
, "padding-top" => "1em"
, "line-height" => "1.2em"
]
instructionsStyle =
style
[ "line-height" => "1.2em"
]
labelHeadingStyle =
style
[ "font-weight" => "bold"
]
exampleWordsStyle =
style
[ "display" => "inline-block"
, "background-color" => "whiteSmoke"
, "border-radius" => "3px"
, "padding" => "0.1em 0.5em 0.1em 0.5em"
]
buttonLabelStyle =
style
[ "float" => "right"
, "font-weight" => "bold"
]
storyCardStyle =
style
[ "width" => "90%"
, "height" => "70%"
, "padding" => "5%"
, "background-image" => ("url(" ++ defaults.imagesLocation ++ "paper.png" ++ ")")
, "-webkit-box-shadow" => "1px 3px 3px 0px rgba(50, 50, 50, 0.3)"
, "-moz-box-shadow" => "1px 3px 3px 0px rgba(50, 50, 50, 0.3)"
, "box-shadow" => "1px 3px 3px 0px rgba(50, 50, 50, 0.3)"
]
storyParagraphStyle =
style
[ "font-family" => defaults.storyFont
, "font-size" => "1.4em"
, "line-height" => "1.5em"
, "color" => "black"
]
mdlTextfield id msg =
Textfield.render MDL [ id ] model.mdl
[ Textfield.label ""
, Textfield.autofocus
, Textfield.maxlength 1000
, Textfield.label "Enter words here..."
, Textfield.on "input" (Json.map msg targetValue)
, Textfield.style
[ -- css "font-size" "1.3em"
]
--, Textfield.value question.answer
--, Textfield.on "input" (Json.map (UpdateField question) targetValue)
-- Assign a unique html `id` attribute that matches the `question.id`. This is used
-- by the `SetFocus` message to set the input focus to the first question
-- in the tab list when a tab is clicked or the `next paragraph` button is clicked
--, Textfield.style [ Options.attribute <| Html.Attributes.id ("question" ++ toString (question.id)) ]
--, css "width" "90%"
--, Textfield.text' question.answer
]
generateButton id =
Button.render MDL [ id ] model.mdl
[ Button.ripple
, Button.raised
, Button.colored
, Button.onClick FadeInOut --SendStoryComponents --FadeInOut
--, css "margin-top" "0.5em"
, css "display" "block"
, css "margin-bottom" "2em"
, css "clear" "both"
, css "float" "right"
]
[ text "Create" ]
{-
storyCard id =
Card.view
[ css "width" "100%"
, css "height" "80%"
, css "background-image" ("url(" ++ defaults.imagesLocation ++ "paper.png" ++ ")")
--, Color.background (Color.color Color.LightBlue Color.S400)
, Elevation.e3
]
[ Card.text
[ Card.expand
, css "font-family" defaults.storyFont
, css "font-size" "1.4em"
, css "line-height" "1.6em"
, css "color" "black"
]
[ text model.storyOutput ]
]
-}
{-
crossFadeTextTo text =
Animation.interrupt
[ Animation.to [Animation.opacity 0]
, Animation.Messenger.send (DoneFadingOutOldTextPleaseSwitchModelToNewText text)
, Animation.to [Animation.opacity 1]
]
-}
in
div [ mainContainerStyle ]
[
img [ src model.logo ] []
, h1 [ titleStyle ] [ text "Story Idea Helper" ]
, grid []
[ cell [ size Tablet 6, size Desktop 6, size Phone 12 ]
[ --h4 [ ] [text "1. Enter words"]
p [ instructionsStyle ] [ text "Enter lists of single words, separated by spaces, into the text fields below. After you've filled them all in, press the Create button to generate your story idea. Just enter the first words that spontaneously come to mind. The more words you enter, the better your story will be. If your generated story idea doesn't make sense, change your existing words or add some new words, and press the Create button again until you find an idea that interests you." ]
-- Living things
, p [ labelStyle ]
[ span [ labelHeadingStyle ] [ text "A. LIVING THINGS: " ]
, text "Enter any words that describe living things (like people or animals), such as: "
, span [ exampleWordsStyle ] [ text "sorcerer cat tree pilot flamingo goldfish" ]
]
, mdlTextfield 0 UpdateLivingThings
-- Objects
, p [ labelStyle ]
[ span [ labelHeadingStyle ] [ text "B. OBJECTS: " ]
, text "Enter any words that describe non-living objects, such as: "
, span [ exampleWordsStyle ] [ text "hat apple axe fork basket" ]
]
, mdlTextfield 2 UpdateObjects
-- Places
, p [ labelStyle ]
[ span [ labelHeadingStyle ] [ text "C. PLACES: " ]
, text "Enter any words that refer to places, such as: "
, span [ exampleWordsStyle ] [ text "forest city mountain ocean castle" ]
]
, mdlTextfield 3 UpdatePlaces
-- Actions
, p [ labelStyle ]
[ span [ labelHeadingStyle ] [ text "D. ACTIONS: " ]
, text "Enter any expressive action words, such as: "
, span [ exampleWordsStyle ] [ text "fly sing dance jump sail" ]
]
, mdlTextfield 4 UpdateActions
-- Moods
, p [ labelStyle ]
[ span [ labelHeadingStyle ] [ text "E. MOODS: " ]
, text "Enter words that describe moods or feelings, such as: "
, span [ exampleWordsStyle ] [ text "adventurous boring uncomfortable whistful sleepy" ]
]
, mdlTextfield 5 UpdateMoods
]
, cell [ size Tablet 5, size Desktop 5, size Phone 12, offset Desktop 1 ]
[ --h4 [] [text "2. Generate your story"]
--storyCard 200
div [ storyCardStyle ]
[ p ( Animation.render model.storyTextStyle ++ [ storyParagraphStyle ]) [ text model.storyOutput ] ]
]
-- The generate button
, cell [ size Tablet 6, size Desktop 6, size Phone 12 ]
[ p [ buttonLabelStyle ] [text "Press the Create button to generate a story idea."]
, generateButton 100
]
]
]
-- SUBSCRIPTIONS
port loadStory : (String -> msg) -> Sub msg
subscriptions : Model -> Sub Msg
subscriptions model =
loadStory LoadStory
-- APP
main =
Html.program
{ init = model
, view = view
, update = update
, subscriptions = subscriptions
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment