summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--elm/AdvSearch/Fields.elm6
-rw-r--r--elm/AdvSearch/Set.elm23
-rw-r--r--elm/VNEdit.elm7
-rw-r--r--lib/VNDB/Types.pm5
-rw-r--r--lib/VNWeb/AdvSearch.pm1
-rw-r--r--lib/VNWeb/Elm.pm1
-rw-r--r--lib/VNWeb/VN/Edit.pm1
-rw-r--r--lib/VNWeb/VN/Page.pm19
-rw-r--r--sql/schema.sql6
-rw-r--r--util/updates/2022-07-31-vn-devstatus.sql24
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;