summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elm/VNEdit.elm46
-rw-r--r--lib/VNWeb/DB.pm2
-rw-r--r--lib/VNWeb/Elm.pm1
-rw-r--r--lib/VNWeb/VN/Edit.pm49
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;