summaryrefslogtreecommitdiff
path: root/elm3/VNEdit/General.elm
diff options
context:
space:
mode:
Diffstat (limited to 'elm3/VNEdit/General.elm')
-rw-r--r--elm3/VNEdit/General.elm155
1 files changed, 155 insertions, 0 deletions
diff --git a/elm3/VNEdit/General.elm b/elm3/VNEdit/General.elm
new file mode 100644
index 00000000..f98bf5c2
--- /dev/null
+++ b/elm3/VNEdit/General.elm
@@ -0,0 +1,155 @@
+module VNEdit.General exposing (..)
+
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (..)
+import File exposing (File)
+import Json.Decode as JD
+import Lib.Html exposing (..)
+import Lib.Gen exposing (..)
+import Lib.Util exposing (..)
+import Lib.Api as Api
+
+
+type alias Model =
+ { desc : String
+ , image : Int
+ , imgState : Api.State
+ , img_nsfw : Bool
+ , length : Int
+ , l_renai : String
+ , l_wp : String
+ , anime : String
+ , animeList : List { aid : Int }
+ , animeDuplicates : Bool
+ }
+
+
+init : VNEdit -> Model
+init d =
+ { desc = d.desc
+ , image = d.image
+ , imgState = Api.Normal
+ , img_nsfw = d.img_nsfw
+ , length = d.length
+ , l_renai = d.l_renai
+ , l_wp = d.l_wp
+ , anime = String.join " " (List.map (.aid >> String.fromInt) d.anime)
+ , animeList = d.anime
+ , animeDuplicates = False
+ }
+
+
+new : Model
+new =
+ { desc = ""
+ , image = 0
+ , imgState = Api.Normal
+ , img_nsfw = False
+ , length = 0
+ , l_renai = ""
+ , l_wp = ""
+ , anime = ""
+ , animeList = []
+ , animeDuplicates = False
+ }
+
+
+type Msg
+ = Desc String
+ | Image String
+ | ImgNSFW Bool
+ | Length String
+ | LWP String
+ | LRenai String
+ | Anime String
+ | ImgUpload (List File)
+ | ImgDone Api.Response
+
+
+update : Msg -> Model -> (Model, Cmd Msg)
+update msg model =
+ case msg of
+ Desc s -> ({ model | desc = s }, Cmd.none)
+ Image s -> ({ model | image = if s == "" then 0 else Maybe.withDefault model.image (String.toInt s) }, Cmd.none)
+ ImgNSFW b -> ({ model | img_nsfw = b }, Cmd.none)
+ Length s -> ({ model | length = Maybe.withDefault 0 (String.toInt s) }, Cmd.none)
+ LWP s -> ({ model | l_wp = s }, Cmd.none)
+ LRenai s -> ({ model | l_renai = s }, Cmd.none)
+
+ Anime s ->
+ let lst = List.map (\e -> { aid = Maybe.withDefault 0 (String.toInt e) }) (String.words s)
+ in ({ model | anime = s, animeList = lst, animeDuplicates = hasDuplicates <| List.map .aid lst }, Cmd.none)
+
+ ImgUpload [i] -> ({ model | imgState = Api.Loading }, Api.postImage Api.Cv i ImgDone)
+ ImgUpload _ -> (model, Cmd.none)
+
+ ImgDone (Api.Image id _ _) -> ({ model | image = id, imgState = Api.Normal }, Cmd.none)
+ ImgDone r -> ({ model | image = 0, imgState = Api.Error r }, Cmd.none)
+
+
+view : Model -> (Msg -> a) -> List (Html a) -> Html a
+view model wrap titles = card "general" "General info" [] <|
+ titles ++ List.map (Html.map wrap)
+ [ cardRow "Description" (Just "English please!") <| formGroup
+ [ inputTextArea "desc" model.desc Desc [rows 8]
+ , div [class "form-group__help"]
+ [ text "Short description of the main story. Please do not include untagged spoilers,"
+ , text " and don't forget to list the source in case you didn't write the description yourself."
+ , text " Formatting codes are allowed."
+ ]
+ ]
+ , cardRow "Image" Nothing
+ [ div [class "row"]
+ [ div [class "col-md col-md--1"]
+ [ div [style "max-width" "200px", style "margin-bottom" "8px"]
+ [ dbImg "cv" (if model.imgState == Api.Loading then -1 else model.image) [] Nothing ]
+ ]
+ , div [class "col-md col-md--2"] <| formGroups
+ [ [ label [for "img"] [ text "Upload new image" ]
+ , input [type_ "file", class "text", name "img", id "img", Api.onFileChange ImgUpload, disabled (model.imgState == Api.Loading) ] []
+ , case model.imgState of
+ Api.Error r -> div [class "invalid-feedback"] [text <| Api.showResponse r]
+ _ -> text ""
+ , div [class "form-group__help"]
+ [ text "Preferably the cover of the CD/DVD/package. Image must be in JPEG or PNG format and at most 5MB. Images larger than 256x400 will automatically be resized." ]
+ ]
+ , [ label [for "img_id"] [ text "Image ID" ]
+ , inputText "img_id" (String.fromInt model.image) Image [pattern "^[0-9]+$", disabled (model.imgState == Api.Loading)]
+ , div [class "form-group__help"]
+ [ text "Use a VN image that is already on the server. Set to '0' to remove the current image." ]
+ ]
+ , [ label [for "img_nsfw"] [ text "NSFW" ]
+ , label [class "checkbox"]
+ [ inputCheck "img_nsfw" model.img_nsfw ImgNSFW
+ , text " Not safe for work" ]
+ , div [class "form-group__help"]
+ [ text "Please check this option if the image contains nudity, gore, or is otherwise not safe in a work-friendly environment." ]
+ ]
+ ]
+ ]
+ ]
+ , cardRow "Properties" Nothing <| formGroups
+ [ [ label [for "length"] [ text "Length" ]
+ , inputSelect [id "length", name "length", onInput Length]
+ (String.fromInt model.length)
+ (List.map (\(a,b) -> (String.fromInt a, b)) vnLengths)
+ ]
+ , [ label [] [ text "External links" ]
+ , p [] [ text "http://en.wikipedia.org/wiki/", inputText "l_wp" model.l_wp LWP [class "form-control--inline", maxlength 100] ]
+ , p [] [ text "http://renai.us/game/", inputText "l_renai" model.l_renai LRenai [class "form-control--inline", maxlength 100], text ".shtml" ]
+ ]
+ -- TODO: Nicer list-editing and search suggestions for anime
+ , [ label [ for "anime" ] [ text "Anime" ]
+ , inputText "anime" model.anime Anime [pattern "^[ 0-9]*$"]
+ , if model.animeDuplicates
+ then div [class "invalid-feedback"] [ text "There are duplicate anime." ]
+ else text ""
+ , div [class "form-group__help"]
+ [ text "Whitespace separated list of AniDB anime IDs. E.g. \"1015 3348\" will add Shingetsutan Tsukihime and Fate/stay night as related anime."
+ , br [] []
+ , text "Note: It can take a few minutes for the anime titles to appear on the VN page."
+ ]
+ ]
+ ]
+ ]