diff options
Diffstat (limited to 'elm3/VNEdit/General.elm')
-rw-r--r-- | elm3/VNEdit/General.elm | 155 |
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." + ] + ] + ] + ] |