diff options
-rw-r--r-- | elm/VNEdit.elm | 46 | ||||
-rw-r--r-- | lib/VNWeb/DB.pm | 2 | ||||
-rw-r--r-- | lib/VNWeb/Elm.pm | 1 | ||||
-rw-r--r-- | lib/VNWeb/VN/Edit.pm | 49 |
4 files changed, 93 insertions, 5 deletions
diff --git a/elm/VNEdit.elm b/elm/VNEdit.elm index 8266fc5b..35b6d688 100644 --- a/elm/VNEdit.elm +++ b/elm/VNEdit.elm @@ -39,7 +39,6 @@ type Tab | Image | Staff | Cast - | Relations | Screenshots | All @@ -57,6 +56,8 @@ type alias Model = , anime : List GVE.RecvAnime , animeSearch : A.Model GApi.ApiAnimeResult , image : Img.Image + , vns : List GVE.RecvRelations + , vnSearch : A.Model GApi.ApiVNResult , screenshots : List (Int,Img.Image,Maybe Int) -- internal id, img, rel , scrUplRel : Maybe Int , scrUplNum : Maybe Int @@ -78,6 +79,8 @@ init d = , length = d.length , lWikidata = d.l_wikidata , lRenai = d.l_renai + , vns = d.relations + , vnSearch = A.init "" , anime = d.anime , animeSearch = A.init "" , image = Img.info d.image_info @@ -103,6 +106,7 @@ encode model = , length = model.length , l_wikidata = model.lWikidata , l_renai = model.lRenai + , relations = List.map (\v -> { vid = v.vid, relation = v.relation, official = v.official }) model.vns , anime = List.map (\a -> { aid = a.aid }) model.anime , image = model.image.id , screenshots = List.map (\(_,i,r) -> { scr = Maybe.withDefault "" i.id, rid = r }) model.screenshots @@ -111,6 +115,9 @@ encode model = animeConfig : A.Config Msg GApi.ApiAnimeResult animeConfig = { wrap = AnimeSearch, id = "animeadd", source = A.animeSource } +vnConfig : A.Config Msg GApi.ApiVNResult +vnConfig = { wrap = VNSearch, id = "relationadd", source = A.vnSource } + type Msg = Editsum Editsum.Msg | Tab Tab @@ -123,6 +130,10 @@ type Msg | Length Int | LWikidata (Maybe Int) | LRenai String + | VNDel Int + | VNRel Int String + | VNOfficial Int Bool + | VNSearch (A.Msg GApi.ApiVNResult) | AnimeDel Int | AnimeSearch (A.Msg GApi.ApiAnimeResult) | ImageSet String Bool @@ -150,6 +161,18 @@ update msg model = LWikidata n-> ({ model | lWikidata = n }, Cmd.none) LRenai s -> ({ model | lRenai = s }, Cmd.none) + VNDel idx -> ({ model | vns = delidx idx model.vns }, Cmd.none) + VNRel idx rel -> ({ model | vns = modidx idx (\v -> { v | relation = rel }) model.vns }, Cmd.none) + VNOfficial idx o -> ({ model | vns = modidx idx (\v -> { v | official = o }) model.vns }, Cmd.none) + VNSearch m -> + let (nm, c, res) = A.update vnConfig m model.vnSearch + in case res of + Nothing -> ({ model | vnSearch = nm }, c) + Just v -> + if List.any (\l -> l.vid == v.id) model.vns + then ({ model | vnSearch = A.clear nm "" }, c) + else ({ model | vnSearch = A.clear nm "", vns = model.vns ++ [{ vid = v.id, title = v.title, original = v.original, relation = "seq", official = True }] }, Cmd.none) + AnimeDel i -> ({ model | anime = delidx i model.anime }, Cmd.none) AnimeSearch m -> let (nm, c, res) = A.update animeConfig m model.animeSearch @@ -226,6 +249,25 @@ view model = , formField "length::Length" [ inputSelect "length" model.length Length [] GT.vnLengths ] , formField "l_wikidata::Wikidata ID" [ inputWikidata "l_wikidata" model.lWikidata LWikidata ] , formField "l_renai::Renai.us link" [ text "http://renai.us/game/", inputText "l_renai" model.lRenai LRenai [], text ".shtml" ] + + , tr [ class "newpart" ] [ td [ colspan 2 ] [ text "Database relations" ] ] + , formField "Related VNs" + [ if List.isEmpty model.vns then text "" + else table [] <| List.indexedMap (\i v -> tr [] + [ td [ style "text-align" "right" ] [ b [ class "grayedout" ] [ text <| "v" ++ String.fromInt v.vid ++ ":" ] ] + , td [ style "text-align" "right"] [ a [ href <| "/v" ++ String.fromInt v.vid ] [ text v.title ] ] + , td [] + [ text "is an " + , label [] [ inputCheck "" v.official (VNOfficial i), text " official" ] + , inputSelect "" v.relation (VNRel i) [] GT.vnRelations + , text " of this VN" + ] + , td [] [ inputButton "remove" (VNDel i) [] ] + ] + ) model.vns + , A.view vnConfig model.vnSearch [placeholder "Add visual novel..."] + ] + , tr [ class "newpart" ] [ td [ colspan 2 ] [] ] , formField "Related anime" [ if List.isEmpty model.anime then text "" else table [] <| List.indexedMap (\i e -> tr [] @@ -349,7 +391,6 @@ view model = , li [ classList [("tabselected", model.tab == Image )] ] [ a [ href "#", onClickD (Tab Image ) ] [ text "Image" ] ] , li [ classList [("tabselected", model.tab == Staff )] ] [ a [ href "#", onClickD (Tab Staff ) ] [ text "Staff" ] ] , li [ classList [("tabselected", model.tab == Cast )] ] [ a [ href "#", onClickD (Tab Cast ) ] [ text "Cast" ] ] - , li [ classList [("tabselected", model.tab == Relations )] ] [ a [ href "#", onClickD (Tab Relations ) ] [ text "Relations" ] ] , li [ classList [("tabselected", model.tab == Screenshots)] ] [ a [ href "#", onClickD (Tab Screenshots) ] [ text "Screenshots" ] ] , li [ classList [("tabselected", model.tab == All )] ] [ a [ href "#", onClickD (Tab All ) ] [ text "All items" ] ] ] @@ -358,7 +399,6 @@ view model = , 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" ] ] , div [ class "mainbox", classList [("hidden", model.tab /= Cast && model.tab /= All)] ] [ h1 [] [ text "Cast" ] ] - , div [ class "mainbox", classList [("hidden", model.tab /= Relations && model.tab /= All)] ] [ h1 [] [ text "Relations" ] ] , 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/DB.pm b/lib/VNWeb/DB.pm index b597a21c..2cc6421e 100644 --- a/lib/VNWeb/DB.pm +++ b/lib/VNWeb/DB.pm @@ -331,7 +331,7 @@ sub db_edit { my $base = $t->{base}{name} =~ s/_hist$//r; tuwf->dbExeci("UPDATE edit_${base} SET ", sql_comma( map sql(sql_identifier($_->{name}), ' = ', val $data->{$_->{name}}, $_), - grep exists $data->{$_->{name}}, $t->{base}{cols}->@* + grep $_->{name} ne 'chid' && exists $data->{$_->{name}}, $t->{base}{cols}->@* )); } diff --git a/lib/VNWeb/Elm.pm b/lib/VNWeb/Elm.pm index d07a19d6..a2fdddb3 100644 --- a/lib/VNWeb/Elm.pm +++ b/lib/VNWeb/Elm.pm @@ -404,6 +404,7 @@ sub write_types { $data .= def bloodTypes => 'List (String, String)' => list map tuple(string $_, string $BLOOD_TYPE{$_}), keys %BLOOD_TYPE; $data .= def charRoles => 'List (String, String)' => list map tuple(string $_, string $CHAR_ROLE{$_}{txt}), keys %CHAR_ROLE; $data .= def vnLengths => 'List (Int, String)' => list map tuple($_, string $VN_LENGTH{$_}{txt}.($VN_LENGTH{$_}{time}?" ($VN_LENGTH{$_}{time})":'')), keys %VN_LENGTH; + $data .= def vnRelations=> 'List (String, String)' => list map tuple(string $_, string $VN_RELATION{$_}{txt}), keys %VN_RELATION; $data .= def curYear => Int => (gmtime)[5]+1900; write_module Types => $data; diff --git a/lib/VNWeb/VN/Edit.pm b/lib/VNWeb/VN/Edit.pm index 625d477d..7182d8d3 100644 --- a/lib/VNWeb/VN/Edit.pm +++ b/lib/VNWeb/VN/Edit.pm @@ -13,13 +13,20 @@ my $FORM = { length => { uint => 1, enum => \%VN_LENGTH }, l_wikidata => { required => 0, uint => 1, max => (1<<31)-1 }, l_renai => { required => 0, default => '', maxlength => 100 }, - anime => { sort_keys => 'id', aoh => { + anime => { sort_keys => 'aid', aoh => { aid => { id => 1 }, title => { _when => 'out' }, original => { _when => 'out', required => 0, default => '' }, } }, image => { required => 0, vndbid => 'cv' }, image_info => { _when => 'out', required => 0, type => 'hash', keys => $VNWeb::Elm::apis{ImageResult}[0]{aoh} }, + relations => { sort_keys => 'vid', aoh => { + vid => { id => 1 }, + relation => { enum => \%VN_RELATION }, + official => { anybool => 1 }, + title => { _when => 'out' }, + original => { _when => 'out', required => 0, default => '' }, + } }, screenshots=> { sort_keys => 'scr', aoh => { scr => { vndbid => 'sf' }, rid => { required => 0, id => 1 }, @@ -57,6 +64,8 @@ TUWF::get qr{/$RE{vrev}/edit} => sub { enrich_merge aid => 'SELECT id AS aid, title_romaji AS title, title_kanji AS original FROM anime WHERE id IN', $e->{anime}; + enrich_merge vid => 'SELECT id AS vid, title, original FROM vn WHERE id IN', $e->{relations}; + $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 FROM releases r @@ -105,6 +114,10 @@ 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}->@*; + $data->{relations} = [] if $data->{hidden}; + validate_dbid 'SELECT id FROM vn WHERE id IN', map $_->{vid}, $data->{relations}->@*; + die "Relation with self" if grep $_->{vid} == $e->{id}, $data->{relations}->@*; + die "Screenshot without releases assigned" if grep !$_->{rid}, $data->{screenshots}->@*; # This is only the case for *very* old revisions, form disallows this now. # Allow linking to deleted or moved releases only if the previous revision also had that. # (The form really should encourage the user to fix that, but disallowing the edit seems a bit overkill) @@ -120,7 +133,41 @@ elm_api VNEdit => $FORM_OUT, $FORM_IN, sub { return elm_Unchanged if !$new && !form_changed $FORM_CMP, $data, $e; my($id,undef,$rev) = db_edit v => $e->{id}, $data; + update_reverse($id, $rev, $e, $data); elm_Redirect "/v$id.$rev"; }; + +sub update_reverse { + my($id, $rev, $old, $new) = @_; + + my %old = map +($_->{vid}, $_), $old->{relations} ? $old->{relations}->@* : (); + my %new = map +($_->{vid}, $_), $new->{relations}->@*; + + # Updates to be performed, vid => { vid => x, relation => y, official => z } or undef if the relation should be removed. + my %upd; + + for my $i (keys %old, keys %new) { + if($old{$i} && !$new{$i}) { + $upd{$i} = undef; + } elsif(!$old{$i} || $old{$i}{relation} ne $new{$i}{relation} || !$old{$i}{official} != !$new{$i}{official}) { + $upd{$i} = { + vid => $id, + relation => $VN_RELATION{ $new{$i}{relation} }{reverse}, + official => $new{$i}{official} + }; + } + } + + for my $i (keys %upd) { + my $v = db_entry v => $i; + $v->{relations} = [ + $upd{$i} ? $upd{$i} : (), + grep $_->{vid} != $id, $v->{relations}->@* + ]; + $v->{editsum} = "Reverse relation update caused by revision v$id.$rev"; + db_edit v => $i, $v, 1; + } +} + 1; |