summaryrefslogtreecommitdiff
path: root/elm3/VNEdit/Screenshots.elm
diff options
context:
space:
mode:
Diffstat (limited to 'elm3/VNEdit/Screenshots.elm')
-rw-r--r--elm3/VNEdit/Screenshots.elm182
1 files changed, 182 insertions, 0 deletions
diff --git a/elm3/VNEdit/Screenshots.elm b/elm3/VNEdit/Screenshots.elm
new file mode 100644
index 00000000..7505fc15
--- /dev/null
+++ b/elm3/VNEdit/Screenshots.elm
@@ -0,0 +1,182 @@
+module VNEdit.Screenshots exposing (Model, Msg, loading, init, update, view)
+
+import Html exposing (..)
+import Html.Attributes exposing (..)
+import Html.Events exposing (..)
+import File exposing (File)
+import Lib.Html exposing (..)
+import Lib.Util exposing (..)
+import Lib.Api as Api
+import Lib.Gen exposing (resolutions, VNEditScreenshots, VNEditReleases)
+import Lib.Util exposing (lookup, isJust)
+
+
+type alias Model =
+ { screenshots : List VNEditScreenshots
+ , releases : List VNEditReleases
+ , state : List Api.State
+ , id : Int -- Temporary negative internal screenshot identifier, until the image has been uploaded and the actual ID is known
+ , rel : Int
+ , nsfw : Bool
+ , files : List File
+ }
+
+
+init : List VNEditScreenshots -> List VNEditReleases -> Model
+init scr rels =
+ { screenshots = scr
+ , releases = rels
+ , state = List.map (always Api.Normal) scr
+ , id = -1
+ , rel = Maybe.withDefault 0 <| Maybe.map .id <| List.head rels
+ , nsfw = False
+ , files = []
+ }
+
+
+loading : Model -> Bool
+loading model = List.any (\s -> s /= Api.Normal) model.state
+
+
+type Msg
+ = Del Int
+ | SetNSFW Int Bool
+ | SetRel Int String
+ | DefNSFW Bool
+ | DefRel String
+ | DefFiles (List File)
+ | Upload
+ | Done Int Api.Response
+
+
+update : Msg -> Model -> (Model, Cmd Msg)
+update msg model =
+ case msg of
+ Del i -> ({ model | screenshots = delidx i model.screenshots, state = delidx i model.state }, Cmd.none)
+ SetNSFW i b -> ({ model | screenshots = modidx i (\e -> { e | nsfw = b }) model.screenshots }, Cmd.none)
+ SetRel i s -> ({ model | screenshots = modidx i (\e -> { e | rid = Maybe.withDefault e.rid (String.toInt s) }) model.screenshots }, Cmd.none)
+ DefNSFW b -> ({ model | nsfw = b }, Cmd.none)
+ DefRel s -> ({ model | rel = Maybe.withDefault 0 (String.toInt s) }, Cmd.none)
+ DefFiles l -> ({ model | files = l }, Cmd.none)
+
+ Upload ->
+ let
+ st = model.state ++ List.map (always Api.Loading) model.files
+ scr i _ = { scr = model.id - i, rid = model.rel, nsfw = model.nsfw, width = 0, height = 0 }
+ alst = List.indexedMap scr model.files
+ lst = model.screenshots ++ alst
+ nid = model.id - List.length model.files
+ cmd f i = Api.postImage Api.Sf f (Done i.scr)
+ cmds = List.map2 cmd model.files alst
+ in ({ model | screenshots = lst, id = nid, state = st, files = [] }, Cmd.batch cmds)
+
+ Done id r ->
+ case List.head <| List.filter (\(_,i) -> i.scr == id) <| List.indexedMap (\a b -> (a,b)) model.screenshots of
+ Nothing -> (model, Cmd.none)
+ Just (n,_) ->
+ let
+ st _ = case r of
+ Api.Image _ _ _ -> Api.Normal
+ re -> Api.Error re
+ scr s = case r of
+ Api.Image nid width height -> { s | scr = nid, width = width, height = height }
+ _ -> s
+ in ({ model | screenshots = modidx n scr model.screenshots, state = modidx n st model.state }, Cmd.none)
+
+
+
+view : Model -> Maybe Int -> Html Msg
+view model vid =
+ let
+ row image remove titl opts after = div [class "screenshot-edit__row"]
+ [ div [ class "screenshot-edit__screenshot" ] [ image ]
+ , div [ class "screenshot-edit__fields" ] <|
+ [ remove
+ , div [ class "screenshot-edit__title" ] [ text titl ]
+ , div [ class "screenshot-edit__options" ] opts
+ ] ++ after
+ ]
+
+ rm n = div [ class "screenshot-edit__remove" ] [ removeButton (Del n) ]
+ img n f = dbImg "st" n [class "vn-image-placeholder--wide"] f
+
+ commonRes res =
+ -- NDS resolution, not in the database
+ res == "256x384" || isJust (lookup res resolutions)
+
+ resWarn e =
+ let res = String.fromInt e.width ++ "x" ++ String.fromInt e.height
+ in case List.filter (\r -> r.id == e.rid) model.releases |> List.head of
+ Nothing -> text "" -- Shouldn't happen
+ Just r ->
+ -- If the release resolution is known and does *not* match the image resolution, warn about that
+ if r.resolution /= "unknown" && r.resolution /= "nonstandard" && r.resolution /= res
+ then div [ class "invalid-feedback" ]
+ [ text <| "Screenshot resolution is not the same as that of the selected release (" ++ r.resolution ++ "). Please make sure take screenshots in that *exact* resolution!" ]
+ -- Otherwise, if this isn't a non-standard resolution, check for common ones
+ else if r.resolution == "nonstandard" || commonRes res
+ then text ""
+ else div [ class "invalid-feedback" ]
+ [ text <| "Odd screenshot resolution. Please make sure take screenshots in the correct resolution!" ]
+
+ entry n (s,e) = case s of
+ Api.Loading -> row (img -1 Nothing) (rm n) "Uploading screenshot" [] []
+ Api.Error r -> row
+ (img 0 Nothing) (rm n) "Upload failed"
+ [ div [ class "invalid-feedback" ] [ text <| Api.showResponse r ] ]
+ []
+ Api.Normal -> row
+ (img e.scr <| Just { width = e.width, height = e.height, id = "scr" })
+ (rm n) ("Screenshot #" ++ String.fromInt e.scr)
+ [ span [ class "muted" ] [ text <| String.fromInt e.width ++ "x" ++ String.fromInt e.height ]
+ , label [ class "checkbox" ]
+ [ inputCheck "" e.nsfw (SetNSFW n)
+ , text " Not safe for work"
+ ]
+ ]
+ [ resWarn e
+ , releaseSelect e.rid (SetRel n) ]
+
+ add = if List.length model.screenshots == 10 then text "" else row
+ (text "")
+ (text "")
+ "Add screenshot"
+ [ span [ class "muted" ] [ text "Image must be smaller than 5MB and in PNG or JPEG format. No more than 10 screenshots can be uploaded." ] ]
+ [ releaseSelect model.rel DefRel
+ , div [ class "screenshot-edit__upload-options" ]
+ [ div [ class "screenshot-edit__upload-option" ] [ input [ type_ "file", id "addscr", tabindex 10, multiple True, Api.onFileChange DefFiles ] [] ]
+ , div [ class "screenshot-edit__upload-option" ]
+ [ label [ class "checkbox screenshot-edit__upload-nsfw-label" ]
+ [ inputCheck "" model.nsfw DefNSFW
+ , text " Not safe for work" ] ]
+ , div [ class "flex-expand" ] []
+ , div [ class "screenshot-edit__upload-option" ]
+ [ button
+ [ type_ "button", class "btn screenshot-edit__upload-btn", tabindex 10, onClick Upload
+ , disabled <| List.isEmpty model.files || (List.length model.files + List.length model.screenshots) > 10
+ ] [ text "Upload!" ] ]
+ ]
+ ]
+
+ releaseSelect rid msg = inputSelect [onInput msg] (String.fromInt rid)
+ <| List.map (\s -> (String.fromInt s.id, s.display)) model.releases
+
+ norel =
+ case vid of
+ Nothing -> [ text "Screenshots can be uploaded after adding releases to this visual novel." ]
+ Just i ->
+ [ text "Screenshots can be added after "
+ , a [ href <| "/v" ++ (String.fromInt i) ++ "/add", target "_blank" ] [ text "adding a release entry" ]
+ , text "."
+ ]
+
+ in if List.isEmpty model.releases
+ then card "screenshots" "Screenshots" [ div [class "card__subheading"] norel ] []
+ else card "screenshots" "Screenshots"
+ [ div [class "card__subheading"]
+ [ text "Keep in mind that all screenshots must conform to "
+ , a [href "/d2#6", target "blank"] [ text "strict guidelines" ]
+ , text ", read those carefully!"
+ ]
+ ]
+ [ div [class "screenshot-edit"] <| List.indexedMap entry (List.map2 (\a b -> (a,b)) model.state model.screenshots) ++ [ add ] ]