diff options
-rw-r--r-- | elm/AdvSearch/Fields.elm | 6 | ||||
-rw-r--r-- | elm/AdvSearch/Set.elm | 23 | ||||
-rw-r--r-- | elm/VNEdit.elm | 7 | ||||
-rw-r--r-- | lib/VNDB/Types.pm | 5 | ||||
-rw-r--r-- | lib/VNWeb/AdvSearch.pm | 1 | ||||
-rw-r--r-- | lib/VNWeb/Elm.pm | 1 | ||||
-rw-r--r-- | lib/VNWeb/VN/Edit.pm | 1 | ||||
-rw-r--r-- | lib/VNWeb/VN/Page.pm | 19 | ||||
-rw-r--r-- | sql/schema.sql | 6 | ||||
-rw-r--r-- | util/updates/2022-07-31-vn-devstatus.sql | 24 |
10 files changed, 83 insertions, 10 deletions
diff --git a/elm/AdvSearch/Fields.elm b/elm/AdvSearch/Fields.elm index d0a02d51..fa08f585 100644 --- a/elm/AdvSearch/Fields.elm +++ b/elm/AdvSearch/Fields.elm @@ -290,6 +290,7 @@ type FieldModel | FMRPlatform (AS.Model String) | FMVPlatform (AS.Model String) | FMLength (AS.Model Int) + | FMDevStatus (AS.Model Int) | FMRole (AS.Model String) | FMBlood (AS.Model String) | FMSex (AS.SexModel) @@ -335,6 +336,7 @@ type FieldMsg | FSRPlatform (AS.Msg String) | FSVPlatform (AS.Msg String) | FSLength (AS.Msg Int) + | FSDevStatus (AS.Msg Int) | FSRole (AS.Msg String) | FSBlood (AS.Msg String) | FSSex AS.SexMsg @@ -431,6 +433,7 @@ fields = , f V "My Labels" 0 FMLabel AS.init AS.labelFromQuery , l V "My List" 0 [(QInt 65 Eq 1, "On my list"), (QInt 65 Ne 1, "Not on my list")] , f V "Length" 0 FMLength AS.init AS.lengthFromQuery + , f V "Development status" 0 FMDevStatus AS.init AS.devStatusFromQuery , f V "Release date" 0 FMRDate AD.init AD.fromQuery , f V "Popularity" 0 FMPopularity AR.popularityInit AR.popularityFromQuery , f V "Rating" 0 FMRating AR.ratingInit AR.ratingFromQuery @@ -554,6 +557,7 @@ fieldUpdate dat msg_ (num, dd, model) = (FSRPlatform msg,FMRPlatform m)-> maps FMRPlatform(AS.update msg m) (FSVPlatform msg,FMVPlatform m)-> maps FMVPlatform(AS.update msg m) (FSLength msg, FMLength m) -> maps FMLength (AS.update msg m) + (FSDevStatus msg,FMDevStatus m)-> maps FMDevStatus(AS.update msg m) (FSRole msg, FMRole m) -> maps FMRole (AS.update msg m) (FSBlood msg, FMBlood m) -> maps FMBlood (AS.update msg m) (FSSex msg, FMSex m) -> maps FMSex (AS.sexUpdate msg m) @@ -622,6 +626,7 @@ fieldView dat (_, dd, model) = FMVPlatform m -> f FSVPlatform (AS.platformView False m) FMRPlatform m -> f FSRPlatform (AS.platformView True m) FMLength m -> f FSLength (AS.lengthView m) + FMDevStatus m -> f FSDevStatus (AS.devStatusView m) FMRole m -> f FSRole (AS.roleView m) FMBlood m -> f FSBlood (AS.bloodView m) FMSex m -> f FSSex (AS.sexView m) @@ -671,6 +676,7 @@ fieldToQuery dat (_, _, model) = FMRPlatform m-> AS.toQuery (QStr 4) m FMVPlatform m-> AS.toQuery (QStr 4) m FMLength m -> AS.toQuery (QInt 5) m + FMDevStatus m-> AS.toQuery (QInt 66) m FMRole m -> AS.toQuery (QStr 2) m FMBlood m -> AS.toQuery (QStr 3) m FMSex (s,m) -> AS.toQuery (QStr (if s then 5 else 4)) m diff --git a/elm/AdvSearch/Set.elm b/elm/AdvSearch/Set.elm index b787b7e4..68984fcc 100644 --- a/elm/AdvSearch/Set.elm +++ b/elm/AdvSearch/Set.elm @@ -216,6 +216,29 @@ lengthFromQuery = fromQuery (\q -> +-- Development status + +devStatusView model = + ( case Set.toList model.sel of + [] -> b [ class "grayedout" ] [ text "Status" ] + [v] -> span [ class "nowrap" ] [ lblPrefix model, text <| Maybe.withDefault "" (lookup v GT.devStatus) ] + l -> span [] [ lblPrefix model, text <| "Length (" ++ String.fromInt (List.length l) ++ ")" ] + , \() -> + [ div [ class "advheader" ] + [ h3 [] [ text "Development status" ] + , opts model False True ] + , ul [] <| List.map (\(l,t) -> li [] [ linkRadio (Set.member l model.sel) (Sel l) [ text t ] ]) GT.devStatus + ] + ) + +devStatusFromQuery = fromQuery (\q -> + case q of + QInt 66 op v -> Just (op, v) + _ -> Nothing) + + + + -- Character role roleView model = diff --git a/elm/VNEdit.elm b/elm/VNEdit.elm index fe2808ac..18d1faf2 100644 --- a/elm/VNEdit.elm +++ b/elm/VNEdit.elm @@ -55,6 +55,7 @@ type alias Model = , titles : List GVE.RecvTitles , alias : String , desc : TP.Model + , devStatus : Int , olang : String , length : Int , lWikidata : Maybe Int @@ -91,6 +92,7 @@ init d = , titles = d.titles , alias = d.alias , desc = TP.bbcode d.desc + , devStatus = d.devstatus , olang = d.olang , length = d.length , lWikidata = d.l_wikidata @@ -126,6 +128,7 @@ encode model = , locked = model.editsum.locked , titles = model.titles , alias = model.alias + , devstatus = model.devStatus , desc = model.desc.data , olang = model.olang , length = model.length @@ -161,6 +164,7 @@ type Msg | Submitted GApi.Response | Alias String | Desc TP.Msg + | DevStatus Int | Length Int | LWikidata (Maybe Int) | LRenai String @@ -224,6 +228,7 @@ update msg model = InvalidEnable -> ({ model | invalidDis = False }, Cmd.none) Alias s -> ({ model | alias = s, dupVNs = [] }, Cmd.none) Desc m -> let (nm,nc) = TP.update m model.desc in ({ model | desc = nm }, Cmd.map Desc nc) + DevStatus b-> ({ model | devStatus = b }, Cmd.none) Length n -> ({ model | length = n }, Cmd.none) LWikidata n-> ({ model | lWikidata = n }, Cmd.none) LRenai s -> ({ model | lRenai = s }, Cmd.none) @@ -398,6 +403,8 @@ view model = [ TP.view "desc" model.desc Desc 600 (style "height" "180px" :: onInvalid (Invalid General) :: GVE.valDesc) [ b [ class "standout" ] [ text "English please!" ] ] , text "Short description of the main story. Please do not include spoilers, and don't forget to list the source in case you didn't write the description yourself." ] + , formField "devstatus::Development status" + [ inputSelect "devstatus" model.devStatus DevStatus [] GT.devStatus ] , formField "length::Length" [ inputSelect "length" model.length Length [] GT.vnLengths , text " (only displayed if there are no length votes)" ] diff --git a/lib/VNDB/Types.pm b/lib/VNDB/Types.pm index 9a4ab892..684c3602 100644 --- a/lib/VNDB/Types.pm +++ b/lib/VNDB/Types.pm @@ -134,6 +134,11 @@ hash VN_RELATION => orig => { reverse => 'fan', pref => 0, txt => 'Original game' }; +hash DEVSTATUS => + 0 => 'Finished', + 1 => 'In development', + 2 => 'Cancelled'; + # SQL: ENUM producer_relation # "Pref" relations are considered the "preferred" relation to show (as opposed to their reverse) diff --git a/lib/VNWeb/AdvSearch.pm b/lib/VNWeb/AdvSearch.pm index 8b5343d7..f322c433 100644 --- a/lib/VNWeb/AdvSearch.pm +++ b/lib/VNWeb/AdvSearch.pm @@ -323,6 +323,7 @@ f v => 62 => 'has-anime', { uint => 1, range => [1,1] }, '=' => sub { 'EXI f v => 63 => 'has-screenshot', { uint => 1, range => [1,1] }, '=' => sub { 'EXISTS(SELECT 1 FROM vn_screenshots vs WHERE vs.id = v.id)' }; f v => 64 => 'has-review', { uint => 1, range => [1,1] }, '=' => sub { 'EXISTS(SELECT 1 FROM reviews r WHERE r.vid = v.id AND NOT r.c_flagged)' }; f v => 65 => 'on-list', { uint => 1, range => [1,1] }, '=' => sub { auth ? sql 'v.id IN(SELECT vid FROM ulist_vns WHERE uid =', \auth->uid, ')' : '1=0' }; +f v => 66 => 'devstatus', { uint => 1, enum => \%DEVSTATUS }, '=' => sub { 'v.devstatus =', \$_ }; f v => 8 => 'tag', { type => 'any', func => \&_validate_tag }, compact => sub { my $id = ($_->[0] =~ s/^g//r)*1; $_->[1] == 0 && $_->[2] == 0 ? $id : [ $id, int($_->[2]*5)*3 + $_->[1] ] }, diff --git a/lib/VNWeb/Elm.pm b/lib/VNWeb/Elm.pm index f6ee14a2..08029680 100644 --- a/lib/VNWeb/Elm.pm +++ b/lib/VNWeb/Elm.pm @@ -452,6 +452,7 @@ sub write_types { $data .= def boardTypes => 'List (String, String)' => list map tuple(string $_, string $BOARD_TYPE{$_}{txt}), keys %BOARD_TYPE; $data .= def ratings => 'List String' => list map string(fmtrating $_), 1..10; $data .= def ageRatings => 'List (Int, String)' => list map tuple($_, string $AGE_RATING{$_}{txt}.($AGE_RATING{$_}{ex}?" ($AGE_RATING{$_}{ex})":'')), keys %AGE_RATING; + $data .= def devStatus => 'List (Int, String)' => list map tuple($_, string $DEVSTATUS{$_}), keys %DEVSTATUS; $data .= def voiced => 'List (Int, String)' => list map tuple($_, string $VOICED{$_}{txt}), keys %VOICED; $data .= def animated => 'List (Int, String)' => list map tuple($_, string $ANIMATED{$_}{txt}), keys %ANIMATED; $data .= def genders => 'List (String, String)' => list map tuple(string $_, string $GENDER{$_}), keys %GENDER; diff --git a/lib/VNWeb/VN/Edit.pm b/lib/VNWeb/VN/Edit.pm index 204e965d..0cacbb0f 100644 --- a/lib/VNWeb/VN/Edit.pm +++ b/lib/VNWeb/VN/Edit.pm @@ -15,6 +15,7 @@ my $FORM = { } }, alias => { required => 0, default => '', maxlength => 500 }, desc => { required => 0, default => '', maxlength => 10240 }, + devstatus => { uint => 1, enum => \%DEVSTATUS }, olang => { enum => \%LANGUAGE, default => 'ja' }, length => { uint => 1, enum => \%VN_LENGTH }, l_wikidata => { required => 0, uint => 1, max => (1<<31)-1 }, diff --git a/lib/VNWeb/VN/Page.pm b/lib/VNWeb/VN/Page.pm index 72fc852a..439db889 100644 --- a/lib/VNWeb/VN/Page.pm +++ b/lib/VNWeb/VN/Page.pm @@ -97,6 +97,7 @@ sub rev_ { [ alias => 'Alias' ], [ olang => 'Original language', fmt => \%LANGUAGE ], [ desc => 'Description' ], + [ devstatus => 'Development status',fmt => \%DEVSTATUS ], [ length => 'Length', fmt => \%VN_LENGTH ], [ staff => 'Credits', fmt => sub { a_ href => "/$_->{sid}", title => $_->{original}||$_->{name}, $_->{name} if $_->{sid}; @@ -162,14 +163,8 @@ sub infobox_relations_ { sub infobox_length_ { my($v) = @_; - my $today = strftime('%Y%m%d', gmtime); - - # Length is only relevant if this VN has been released. Some VNs have been - # cancelled and only have a trial, but we allow votes on those as well. - my $hastrial = grep $_->{rtype} eq 'trial' && $_->{released} <= $today, $v->{releases}->@*; - my $hasnontba = grep $_->{rtype} ne 'trial' && $_->{released} <= $today, $v->{releases}->@*; - my $hastba = grep $_->{rtype} ne 'trial' && $_->{released} > $today, $v->{releases}->@*; - return if !($hasnontba || ($hastrial && !$hastba)); + # Length is only relevant if this VN is finalized in some form. + return if $v->{devstatus} == 1; return if !$v->{length} && !$v->{c_lengthnum} && !VNWeb::VN::Length::can_vote(); @@ -431,6 +426,14 @@ sub infobox_ { td_ $v->{alias} =~ s/\n/, /gr; } if $v->{alias}; + tr_ sub { + td_ 'Status'; + td_ sub { + txt_ 'In development' if $v->{devstatus} == 1; + txt_ 'Unfinished, no ongoing development' if $v->{devstatus} == 2; + }; + } if $v->{devstatus}; + infobox_length_ $v; infobox_producers_ $v; infobox_relations_ $v; diff --git a/sql/schema.sql b/sql/schema.sql index f9156de3..31a706ef 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -1136,7 +1136,8 @@ CREATE TABLE vn ( -- dbentry_type=v c_developers vndbid[] NOT NULL DEFAULT '{}', c_average smallint, -- [pub], decimal vote*100, i.e. 100 - 1000 c_length smallint, - c_lengthnum smallint NOT NULL DEFAULT 0 + c_lengthnum smallint NOT NULL DEFAULT 0, + devstatus smallint NOT NULL DEFAULT 0 -- [pub] (0/finished 1/ongoing 2/cancelled) ); -- vn_hist @@ -1151,7 +1152,8 @@ CREATE TABLE vn_hist ( l_wp varchar(150) NOT NULL DEFAULT '', l_encubed varchar(100) NOT NULL DEFAULT '', l_renai varchar(100) NOT NULL DEFAULT '', - "desc" text NOT NULL DEFAULT '' + "desc" text NOT NULL DEFAULT '', + devstatus smallint NOT NULL DEFAULT 0 ); -- vn_anime diff --git a/util/updates/2022-07-31-vn-devstatus.sql b/util/updates/2022-07-31-vn-devstatus.sql new file mode 100644 index 00000000..7bc709a0 --- /dev/null +++ b/util/updates/2022-07-31-vn-devstatus.sql @@ -0,0 +1,24 @@ +ALTER TABLE vn ADD COLUMN devstatus smallint NOT NULL DEFAULT 0; +ALTER TABLE vn_hist ADD COLUMN devstatus smallint NOT NULL DEFAULT 0; +\i sql/editfunc.sql + +UPDATE vn SET devstatus = 0 WHERE devstatus <> 0; + +-- Heuristic: VN is considered cancelled if it meets all of the following criteria: +-- * doesn't have a complete release +-- * doesn't have any release after 2020 +-- * doesn't have multiple partial releases +-- * doesn't have both a trial and partial release (weird heuristic, but there's many matching in-dev games) +UPDATE vn SET devstatus = 2 WHERE + id NOT IN(SELECT vid FROM releases_vn rv JOIN releases r ON r.id = rv.id WHERE NOT r.hidden AND rtype = 'complete' OR released > 20200000) + AND id NOT IN(SELECT vid FROM releases_vn rv JOIN releases r ON r.id = rv.id WHERE NOT r.hidden AND rtype = 'partial' GROUP BY vid HAVING COUNT(r.id) > 1) + AND id NOT IN(SELECT vid FROM releases_vn rv JOIN releases r ON r.id = rv.id WHERE NOT r.hidden AND rtype IN('partial','trial') GROUP BY vid HAVING COUNT(DISTINCT rtype) = 2); + +-- Heuristic: VN is considerd in development if it's not cancelled and meets one of the following: +-- * Has a future release date +-- * Has no complete releases and only a single partial release +UPDATE vn SET devstatus = 1 WHERE devstatus = 0 AND (c_released > 22020731 OR ( + id NOT IN(SELECT vid FROM releases_vn rv JOIN releases r ON r.id = rv.id WHERE NOT r.hidden AND rtype = 'complete') + AND id IN(SELECT vid FROM releases_vn rv JOIN releases r ON r.id = rv.id WHERE NOT r.hidden AND rtype = 'partial' GROUP BY vid HAVING COUNT(r.id) = 1))); + +UPDATE vn_hist SET devstatus = v.devstatus FROM changes c JOIN vn v ON c.itemid = v.id WHERE vn_hist.chid = c.id AND v.devstatus <> vn_hist.devstatus; |