diff options
-rw-r--r-- | Dockerfile | 2 | ||||
-rw-r--r-- | elm/TableOpts.elm | 33 | ||||
-rw-r--r-- | lib/VNWeb/Chars/List.pm | 4 | ||||
-rw-r--r-- | lib/VNWeb/TableOpts.pm | 27 | ||||
-rw-r--r-- | sql/perms.sql | 4 | ||||
-rw-r--r-- | sql/schema.sql | 3 | ||||
-rw-r--r-- | util/updates/2021-02-22-tableopts-char.sql | 2 |
7 files changed, 62 insertions, 13 deletions
@@ -1,7 +1,7 @@ FROM alpine:3.13 MAINTAINER Yorhel <contact@vndb.org> -ENV VNDB_DOCKER_VERSION=6 +ENV VNDB_DOCKER_VERSION=7 CMD /var/www/util/docker-init.sh RUN apk add --no-cache \ diff --git a/elm/TableOpts.elm b/elm/TableOpts.elm index 65814185..7dcfec2a 100644 --- a/elm/TableOpts.elm +++ b/elm/TableOpts.elm @@ -8,6 +8,7 @@ import Bitwise as B import Lib.DropDown as DD import Lib.Api as Api import Lib.Html exposing (..) +import Gen.Api as GApi import Gen.TableOptsSave as GTO @@ -21,6 +22,8 @@ main = Browser.element type alias Model = { opts : GTO.Recv + , state : Api.State + , saved : Bool , dd : DD.Config Msg , view : Int , results : Int @@ -32,6 +35,8 @@ type alias Model = init : GTO.Recv -> Model init opts = { opts = opts + , state = Api.Normal + , saved = False , dd = DD.init "tableopts" Open , view = B.and 3 opts.value , results = B.and 7 (B.shiftRightBy 2 opts.value) @@ -45,14 +50,22 @@ type Msg = Open Bool | View Int Bool | Results Int Bool + | Save + | Saved GApi.Response update : Msg -> Model -> (Model, Cmd Msg) update msg model = case msg of - Open b -> ({ model | dd = DD.toggle model.dd b }, Cmd.none) - View n _ -> ({ model | view = n }, Cmd.none) - Results n _ -> ({ model | results = n }, Cmd.none) + Open b -> ({ model | saved = False, dd = DD.toggle model.dd b }, Cmd.none) + View n _ -> ({ model | saved = False, view = n }, Cmd.none) + Results n _ -> ({ model | saved = False, results = n }, Cmd.none) + Save -> ( { model | saved = False, state = Api.Loading } + , GTO.send { save = Maybe.withDefault "" model.opts.save + , value = if encInt model == model.opts.default then Nothing else Just (encInt model) + } Saved) + Saved GApi.Success -> ({ model | saved = True, state = Api.Normal }, Cmd.none) + Saved e -> ({ model | state = Api.Error e }, Cmd.none) encBase64Alpha : Int -> String @@ -71,7 +84,7 @@ encInt m = view : Model -> Html Msg view model = div [] - [ if encInt model == model.opts.default + [ if model.opts.save == Nothing && encInt model == model.opts.default then text "" else input [ type_ "hidden", name "s", value (encBase64 (encInt model)) ] [] , DD.view model.dd Api.Normal @@ -89,7 +102,17 @@ view model = div [] , linkRadio (model.results == 3) (Results 3) [ text "100" ], text " / " , linkRadio (model.results == 4) (Results 4) [ text "200" ] ] ] - , tr [] [ td [] [], td [] [ input [ type_ "submit", class "submit", value "Update" ] [] ] ] + , tr [] [ td [] [], td [] + [ input [ type_ "submit", class "submit", value "Update" ] [] + , case (model.opts.save, model.saved) of + (_, True) -> text "Saved!" + (Just _, _) -> inputButton "Save as default" Save [] + _ -> text "" + , case model.state of + Api.Normal -> text "" + Api.Loading -> span [ class "spinner" ] [] + Api.Error e -> b [ class "standout" ] [ text <| Api.showResponse e ] + ] ] ] ]) ] diff --git a/lib/VNWeb/Chars/List.pm b/lib/VNWeb/Chars/List.pm index cefaad88..7f48981c 100644 --- a/lib/VNWeb/Chars/List.pm +++ b/lib/VNWeb/Chars/List.pm @@ -5,7 +5,9 @@ use VNWeb::AdvSearch; use VNWeb::Filters; use VNWeb::Images::Lib; -our $TABLEOPTS = tableopts _views => [qw|rows cards grid|]; +our $TABLEOPTS = tableopts + _pref => 'tableopts_c', + _views => [qw|rows cards grid|]; # Also used by VNWeb::TT::TraitPage diff --git a/lib/VNWeb/TableOpts.pm b/lib/VNWeb/TableOpts.pm index 23f7fcee..6d6384fb 100644 --- a/lib/VNWeb/TableOpts.pm +++ b/lib/VNWeb/TableOpts.pm @@ -18,6 +18,9 @@ package VNWeb::TableOpts; # # Which views are supported (default: all) # _views => [ 'rows', 'cards', 'grid' ], # +# # SQL column in the users table to store the saved default +# _pref => 'tableopts_something', +# # # Column config. # # The key names are only used internally. # title => { @@ -64,6 +67,7 @@ use v5.26; use Carp 'croak'; use Exporter 'import'; use TUWF; +use VNWeb::Auth; use VNWeb::HTML (); use VNWeb::Validation; use VNWeb::Elm; @@ -98,6 +102,10 @@ sub tableopts { $o{views} = [ map $views{$_}//croak("unknown view: $_"), ref $v ? @$v : $v ]; next; } + if($k eq '_pref') { + $o{pref} = $v; + next; + } $o{columns}{$k} = $v; push $o{col_order}->@*, $k; $o{sort_ids}[$v->{sort_id}] = $k if defined $v->{sort_id}; @@ -113,9 +121,12 @@ sub tableopts { TUWF::set('custom_validations')->{tableopts} = sub { my($t) = @_; - +{ onerror => bless([$t->{default},$t], __PACKAGE__), func => sub { + +{ onerror => sub { + my $d = $t->{pref} && auth ? tuwf->dbVali('SELECT', $t->{pref}, 'FROM users WHERE id =', \auth->uid) : undef; + bless([$d // $t->{default},$t], __PACKAGE__) + }, func => sub { # TODO: compatibility with the old ?s=<colname> sort parameter - my $v = _dec $_[0] or return 0; + my $v = _dec($_[0]) // return 0; # We could do strict validation on the individual fields, but the methods below can handle incorrect data. $_[0] = bless [$v, $t], __PACKAGE__; 1; @@ -136,18 +147,28 @@ sub results { $results[($_[0][0] >> 2) & 7] || $results[0] } my $FORM_OUT = form_compile any => { + save => { required => 0 }, views => { type => 'array', values => { uint => 1 } }, default => { uint => 1 }, value => { uint => 1 }, # TODO: Sorting & column visibility }; -elm_api TableOptsSave => $FORM_OUT, {}, sub { ... }; +elm_api TableOptsSave => $FORM_OUT, { + save => { enum => ['tableopts_c'] }, + value => { required => 0, uint => 1 } +}, sub { + my($f) = @_; + return elm_Unauth if !auth; + tuwf->dbExeci('UPDATE users SET', { $f->{save} => $f->{value} }, 'WHERE id =', \auth->uid); + elm_Success +}; sub elm_ { my $self = shift; my($v,$o) = $self->@*; VNWeb::HTML::elm_ TableOpts => $FORM_OUT, { + save => auth ? $o->{pref} : undef, views => $o->{views}, default => $o->{default}, value => $v, diff --git a/sql/perms.sql b/sql/perms.sql index 272ce1f3..783f3699 100644 --- a/sql/perms.sql +++ b/sql/perms.sql @@ -80,7 +80,7 @@ GRANT SELECT ( id, username, registered, ip, ign_votes, email_confirmed, last_re , skin, customcss, notify_dbedit, notify_announce, notify_post, notify_comment , tags_all, tags_cont, tags_ero, tags_tech, spoilers, traits_sexual, max_sexual, max_violence , nodistract_can, nodistract_noads, nodistract_nofancy, support_can, support_enabled, uniname_can, uniname, pubskin_can, pubskin_enabled - , ulist_votes, ulist_vnlist, ulist_wish + , ulist_votes, ulist_vnlist, ulist_wish, tableopts_c , c_vns, c_wish, c_votes, c_changes, c_imgvotes, c_tags), INSERT ( username, mail, ip), UPDATE ( username, ign_votes, email_confirmed, last_reports @@ -88,7 +88,7 @@ GRANT SELECT ( id, username, registered, ip, ign_votes, email_confirmed, last_re , skin, customcss, notify_dbedit, notify_announce, notify_post, notify_comment , tags_all, tags_cont, tags_ero, tags_tech, spoilers, traits_sexual, max_sexual, max_violence , nodistract_can, nodistract_noads, nodistract_nofancy, support_can, support_enabled, uniname_can, uniname, pubskin_can, pubskin_enabled - , ulist_votes, ulist_vnlist, ulist_wish + , ulist_votes, ulist_vnlist, ulist_wish, tableopts_c , c_vns, c_wish, c_votes, c_changes, c_imgvotes, c_tags) ON users TO vndb_site; GRANT SELECT, INSERT, UPDATE ON vn TO vndb_site; diff --git a/sql/schema.sql b/sql/schema.sql index ebe85451..a49feb09 100644 --- a/sql/schema.sql +++ b/sql/schema.sql @@ -938,7 +938,8 @@ CREATE TABLE users ( last_reports timestamptz, -- For mods: Most recent activity seen on the reports listing perm_review boolean NOT NULL DEFAULT true, notify_post boolean NOT NULL DEFAULT true, - notify_comment boolean NOT NULL DEFAULT true + notify_comment boolean NOT NULL DEFAULT true, + tableopts_c int ); -- vn diff --git a/util/updates/2021-02-22-tableopts-char.sql b/util/updates/2021-02-22-tableopts-char.sql new file mode 100644 index 00000000..af5f5168 --- /dev/null +++ b/util/updates/2021-02-22-tableopts-char.sql @@ -0,0 +1,2 @@ +ALTER TABLE users ADD COLUMN tableopts_c int; +\i sql/perms.sql |