diff options
-rw-r--r-- | elm/VNEdit.elm | 81 | ||||
-rw-r--r-- | lib/VNWeb/VN/Edit.pm | 35 |
2 files changed, 113 insertions, 3 deletions
diff --git a/elm/VNEdit.elm b/elm/VNEdit.elm index 54247622..0764c167 100644 --- a/elm/VNEdit.elm +++ b/elm/VNEdit.elm @@ -60,11 +60,15 @@ type alias Model = , image : Img.Image , staff : List GVE.RecvStaff , staffSearch : A.Model GApi.ApiStaffResult + , seiyuu : List GVE.RecvSeiyuu + , seiyuuSearch: A.Model GApi.ApiStaffResult + , seiyuuDef : Int -- character id for newly added seiyuu , screenshots : List (Int,Img.Image,Maybe Int) -- internal id, img, rel , scrUplRel : Maybe Int , scrUplNum : Maybe Int , scrId : Int -- latest used internal id , releases : List GVE.RecvReleases + , chars : List GVE.RecvChars , id : Maybe Int } @@ -88,11 +92,15 @@ init d = , image = Img.info d.image_info , staff = d.staff , staffSearch = A.init "" + , seiyuu = d.seiyuu + , seiyuuSearch= A.init "" + , seiyuuDef = Maybe.withDefault 0 <| List.head <| List.map (\c -> c.id) d.chars , screenshots = List.indexedMap (\n i -> (n, Img.info (Just i.info), i.rid)) d.screenshots , scrUplRel = Nothing , scrUplNum = Nothing , scrId = 100 , releases = d.releases + , chars = d.chars , id = d.id } @@ -114,6 +122,7 @@ encode model = , anime = List.map (\a -> { aid = a.aid }) model.anime , image = model.image.id , staff = List.map (\s -> { aid = s.aid, role = s.role, note = s.note }) model.staff + , seiyuu = List.map (\s -> { aid = s.aid, cid = s.cid, note = s.note }) model.seiyuu , screenshots = List.map (\(_,i,r) -> { scr = Maybe.withDefault "" i.id, rid = r }) model.screenshots } @@ -126,6 +135,9 @@ animeConfig = { wrap = AnimeSearch, id = "animeadd", source = A.animeSource } staffConfig : A.Config Msg GApi.ApiStaffResult staffConfig = { wrap = StaffSearch, id = "staffadd", source = A.staffSource } +seiyuuConfig : A.Config Msg GApi.ApiStaffResult +seiyuuConfig = { wrap = SeiyuuSearch, id = "seiyuuadd", source = A.staffSource } + type Msg = Editsum Editsum.Msg | Tab Tab @@ -152,6 +164,11 @@ type Msg | StaffRole Int String | StaffNote Int String | StaffSearch (A.Msg GApi.ApiStaffResult) + | SeiyuuDef Int + | SeiyuuDel Int + | SeiyuuChar Int Int + | SeiyuuNote Int String + | SeiyuuSearch (A.Msg GApi.ApiStaffResult) | ScrUplRel (Maybe Int) | ScrUplSel | ScrUpl File (List File) @@ -209,6 +226,16 @@ update msg model = Nothing -> ({ model | staffSearch = nm }, c) Just s -> ({ model | staffSearch = A.clear nm "", staff = model.staff ++ [{ id = s.id, aid = s.aid, name = s.name, original = s.original, role = "staff", note = "" }] }, Cmd.none) + SeiyuuDef c -> ({ model | seiyuuDef = c }, Cmd.none) + SeiyuuDel idx -> ({ model | seiyuu = delidx idx model.seiyuu }, Cmd.none) + SeiyuuChar idx v -> ({ model | seiyuu = modidx idx (\s -> { s | cid = v }) model.seiyuu }, Cmd.none) + SeiyuuNote idx v -> ({ model | seiyuu = modidx idx (\s -> { s | note = v }) model.seiyuu }, Cmd.none) + SeiyuuSearch m -> + let (nm, c, res) = A.update seiyuuConfig m model.seiyuuSearch + in case res of + Nothing -> ({ model | seiyuuSearch = nm }, c) + Just s -> ({ model | seiyuuSearch = A.clear nm "", seiyuu = model.seiyuu ++ [{ id = s.id, aid = s.aid, name = s.name, original = s.original, cid = model.seiyuuDef, note = "" }] }, Cmd.none) + ScrUplRel s -> ({ model | scrUplRel = s }, Cmd.none) ScrUplSel -> (model, FSel.files ["image/png", "image/jpg"] ScrUpl) ScrUpl f1 fl -> @@ -242,6 +269,7 @@ isValid model = not || not (Img.isValid model.image) || List.any (\(_,i,r) -> r == Nothing || not (Img.isValid i)) model.screenshots || hasDuplicates (List.map (\s -> (s.aid, s.role)) model.staff) + || hasDuplicates (List.map (\s -> (s.aid, s.cid)) model.seiyuu) ) @@ -364,6 +392,55 @@ view model = ] in table [] <| head ++ [ foot ] ++ List.indexedMap item model.staff + cast = + let + chars = List.map (\c -> (c.id, c.name ++ " (c" ++ String.fromInt c.id ++ ")")) model.chars + head = + if List.isEmpty model.seiyuu then [] else [ + thead [] [ tr [] + [ td [] [ text "Character" ] + , td [] [ text "Cast" ] + , td [] [ text "Note" ] + , td [] [] + ] ] ] + foot = + tfoot [] [ tr [] [ td [ colspan 4 ] + [ br [] [] + , b [] [ text "Add cast" ] + , br [] [] + , if hasDuplicates (List.map (\s -> (s.aid, s.cid)) model.seiyuu) + then b [ class "standout" ] [ text "List contains duplicate cast roles.", br [] [] ] + else text "" + , inputSelect "" model.seiyuuDef SeiyuuDef [] chars + , text " voiced by " + , div [ style "display" "inline-block" ] [ A.view seiyuuConfig model.seiyuuSearch [] ] + , br [] [] + , text "Can't find the person you're looking for? You can " + , a [ href "/s/new" ] [ text "create a new entry" ] + , text ", but " + , a [ href "/s/all" ] [ text "please check for aliasses first." ] + ] ] ] + item n s = tr [] + [ td [] [ inputSelect "" s.cid (SeiyuuChar n) [] + <| chars ++ if List.any (\c -> c.id == s.cid) model.chars then [] else [(s.cid, "[deleted/moved character: c" ++ String.fromInt s.cid ++ "]")] ] + , td [] + [ b [ class "grayedout" ] [ text <| "s" ++ String.fromInt s.id ++ ":" ] + , a [ href <| "/s" ++ String.fromInt s.id ] [ text s.name ] ] + , td [] [ inputText "" s.note (SeiyuuNote n) (style "width" "300px" :: GVE.valSeiyuuNote) ] + , td [] [ inputButton "remove" (SeiyuuDel n) [] ] + ] + in + if model.id == Nothing + then text <| "Voice actors can be added to this visual novel once it has character entries associated with it. " + ++ "To do so, first create this entry without cast, then create the appropriate character entries, and finally come back to this form by editing the visual novel." + else if List.isEmpty model.chars && List.isEmpty model.seiyuu + then p [] + [ text "This visual novel does not have any characters associated with it (yet). Please " + , a [ href <| "/v" ++ Maybe.withDefault "" (Maybe.map String.fromInt model.id) ++ "/addchar" ] [ text "add the appropriate character entries" ] + , text " first and then come back to this form to assign voice actors." + ] + else table [] <| head ++ [ foot ] ++ List.indexedMap item model.seiyuu + screenshots = let showrel r = "[" ++ (RDate.format (RDate.expand r.released)) ++ " " ++ (String.join "," r.lang) ++ "] " ++ r.title ++ " (r" ++ String.fromInt r.id ++ ")" @@ -432,7 +509,7 @@ view model = ] in if model.id == Nothing - then text <| "Screenshots can be uploaded when this visual novel once it has a release entry associated with it. " + then text <| "Screenshots can be uploaded to this visual novel once it has a release entry associated with it. " ++ "To do so, first create this entry without screenshots, then create the appropriate release entries, and finally come back to this form by editing the visual novel." else if List.isEmpty model.releases then p [] @@ -458,7 +535,7 @@ view model = , div [ class "mainbox", classList [("hidden", model.tab /= General && model.tab /= All)] ] [ h1 [] [ text "General info" ], table [ class "formtable" ] geninfo ] , div [ class "mainbox", classList [("hidden", model.tab /= Image && model.tab /= All)] ] [ h1 [] [ text "Image" ], image ] , div [ class "mainbox", classList [("hidden", model.tab /= Staff && model.tab /= All)] ] [ h1 [] [ text "Staff" ], staff ] - , div [ class "mainbox", classList [("hidden", model.tab /= Cast && model.tab /= All)] ] [ h1 [] [ text "Cast" ] ] + , div [ class "mainbox", classList [("hidden", model.tab /= Cast && model.tab /= All)] ] [ h1 [] [ text "Cast" ], cast ] , div [ class "mainbox", classList [("hidden", model.tab /= Screenshots && model.tab /= All)] ] [ h1 [] [ text "Screenshots" ], screenshots ] , div [ class "mainbox" ] [ fieldset [ class "submit" ] [ Html.map Editsum (Editsum.view model.editsum) diff --git a/lib/VNWeb/VN/Edit.pm b/lib/VNWeb/VN/Edit.pm index cf3e7fba..e7a9e3ff 100644 --- a/lib/VNWeb/VN/Edit.pm +++ b/lib/VNWeb/VN/Edit.pm @@ -35,6 +35,15 @@ my $FORM = { name => { _when => 'out' }, original => { _when => 'out', required => 0, default => '' }, } }, + seiyuu => { sort_keys => ['aid','cid'], aoh => { + aid => { id => 1 }, + cid => { id => 1 }, + note => { required => 0, default => '', maxlength => 250 }, + # Staff info + id => { _when => 'out', id => 1 }, + name => { _when => 'out' }, + original => { _when => 'out', required => 0, default => '' }, + } }, screenshots=> { sort_keys => 'scr', aoh => { scr => { vndbid => 'sf' }, rid => { required => 0, id => 1 }, @@ -46,6 +55,11 @@ my $FORM = { authmod => { _when => 'out', anybool => 1 }, editsum => { _when => 'in out', editsum => 1 }, releases => { _when => 'out', $VNWeb::Elm::apis{Releases}[0]->%* }, + chars => { _when => 'out', aoh => { + id => { id => 1 }, + name => {}, + original => { required => 0, default => '' }, + } }, }; my $FORM_OUT = form_compile out => $FORM; @@ -73,7 +87,12 @@ TUWF::get qr{/$RE{vrev}/edit} => sub { enrich_merge vid => 'SELECT id AS vid, title, original FROM vn WHERE id IN', $e->{relations}; enrich_merge aid => 'SELECT id AS aid, title_romaji AS title, title_kanji AS original FROM anime WHERE id IN', $e->{anime}; - enrich_merge aid => 'SELECT id, aid, name, original FROM staff_alias WHERE aid IN', $e->{staff}; + enrich_merge aid => 'SELECT id, aid, name, original FROM staff_alias WHERE aid IN', $e->{staff}, $e->{seiyuu}; + + # It's possible for older revisions to link to aliases that have been removed. + # Let's exclude those to make sure the form will at least load. + $e->{staff} = [ grep $_->{id}, $e->{staff}->@* ]; + $e->{seiyuu} = [ grep $_->{id}, $e->{seiyuu}->@* ]; $e->{releases} = tuwf->dbAlli(' SELECT rv.vid, r.id, r.title, r.original, r.released, r.type as rtype, r.reso_x, r.reso_y @@ -85,6 +104,12 @@ TUWF::get qr{/$RE{vrev}/edit} => sub { enrich_flatten lang => id => id => sub { sql('SELECT id, lang FROM releases_lang WHERE id IN', $_, 'ORDER BY lang') }, $e->{releases}; enrich_flatten platforms => id => id => sub { sql('SELECT id, platform FROM releases_platforms WHERE id IN', $_, 'ORDER BY platform') }, $e->{releases}; + $e->{chars} = tuwf->dbAlli(' + SELECT id, name, original FROM chars + WHERE NOT hidden AND id IN(SELECT id FROM chars_vns WHERE vid =', \$e->{id},') + ORDER BY name, id' + ); + framework_ title => "Edit $e->{title}", type => 'v', dbobj => $e, tab => 'edit', sub { editmsg_ v => $e, "Edit $e->{title}"; @@ -123,6 +148,7 @@ elm_api VNEdit => $FORM_OUT, $FORM_IN, sub { validate_dbid 'SELECT id FROM images WHERE id IN', $data->{image} if $data->{image}; validate_dbid 'SELECT id FROM images WHERE id IN', map $_->{scr}, $data->{screenshots}->@*; validate_dbid 'SELECT aid FROM staff_alias WHERE aid IN', map $_->{aid}, $data->{staff}->@*; + validate_dbid 'SELECT aid FROM staff_alias WHERE aid IN', map $_->{aid}, $data->{seiyuu}->@*; $data->{relations} = [] if $data->{hidden}; validate_dbid 'SELECT id FROM vn WHERE id IN', map $_->{vid}, $data->{relations}->@*; @@ -137,6 +163,13 @@ elm_api VNEdit => $FORM_OUT, $FORM_IN, sub { SELECT rid FROM vn_screenshots WHERE id =', \$e->{id}, 'AND rid IN', $_ }, map $_->{rid}, $data->{screenshots}->@*; + # Likewise, allow linking to deleted or moved characters. + validate_dbid sub { ' + SELECT c.id FROM chars c JOIN chars_vns cv ON c.id = cv.id WHERE NOT c.hidden AND cv.vid =', \$e->{id}, ' AND c.id IN', $_, ' + UNION + SELECT cid FROM vn_seiyuu WHERE id =', \$e->{id}, 'AND cid IN', $_ + }, map $_->{cid}, $data->{seiyuu}->@*; + $data->{image_nsfw} = $e->{image_nsfw}||0; my %oldscr = map +($_->{scr}, $_->{nsfw}), @{ $e->{screenshots}||[] }; $_->{nsfw} = $oldscr{$_->{scr}}||0 for $data->{screenshots}->@*; |