summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elm/VNEdit.elm81
-rw-r--r--lib/VNWeb/VN/Edit.pm35
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}->@*;