From e702fd91395e7664a313dc91d331f09bf70aa361 Mon Sep 17 00:00:00 2001 From: swaggboi Date: Sun, 14 Aug 2022 18:30:22 -0400 Subject: [PATCH] Implement paging for viewing threads (and fixed a broken test) --- PostText.pl | 31 +++++++++++++--- cpanfile | 1 + lib/PostText/Model/Thread.pm | 46 ++++++++++++++++++++++-- t/post.t | 2 +- templates/{view.html.ep => page.html.ep} | 5 +++ 5 files changed, 77 insertions(+), 8 deletions(-) rename templates/{view.html.ep => page.html.ep} (74%) diff --git a/PostText.pl b/PostText.pl index 03a3131..d9887bc 100755 --- a/PostText.pl +++ b/PostText.pl @@ -5,7 +5,7 @@ use Mojolicious::Lite -signatures; use Mojo::Pg; -#use Data::Dumper; # For your debugging pleasure +use Data::Dumper; # For your debugging pleasure # Load the local modules too use lib 'lib'; @@ -13,6 +13,7 @@ use PostText::Model::Thread; # Load Mojo plugins plugin 'Config'; +plugin 'TagHelpers::Pagination'; # Helpers helper pg => sub { @@ -34,12 +35,28 @@ under sub ($c) { get '/', sub ($c) { $c->redirect_to('view') }; # View -get '/view', sub ($c) { - my $threads = $c->thread->get_threads(); +group { + under 'view'; - $c->stash(threads => $threads); + get '/:page', [page => qr/[0-9]+/], {page => 1}, sub ($c) { + my $base_path = '/view'; + my $this_page = $c->param('page'); + my $last_page = $c->thread->get_last_page(); + my $threads = $c->thread->get_threads_by_page($this_page); - $c->render(); + $c->stash( + threads => $threads, + this_page => $this_page, + last_page => $last_page, + base_path => $base_path + ); + + unless (my $thread = @$threads[0]) { + $c->stash(status => 404) + } + + $c->render(); + }; }; # Post @@ -71,5 +88,9 @@ app->secrets(app->config->{'secrets'}) || die $@; app->pg->migrations->from_dir('migrations')->migrate(3); +if (my $threads_per_page = app->config->{'threads_per_page'}) { + app->thread->threads_per_page($threads_per_page) +} + # Send it app->start(); diff --git a/cpanfile b/cpanfile index 24a65db..3aa5e26 100644 --- a/cpanfile +++ b/cpanfile @@ -1,2 +1,3 @@ requires 'Mojolicious'; requires 'Mojo::Pg'; +requires 'Mojolicious::Plugin::TagHelpers::Pagination'; diff --git a/lib/PostText/Model/Thread.pm b/lib/PostText/Model/Thread.pm index 749cb0b..de475c2 100644 --- a/lib/PostText/Model/Thread.pm +++ b/lib/PostText/Model/Thread.pm @@ -7,7 +7,10 @@ use Mojo::Base -base, -signatures; has 'pg'; sub new($class, $pg, $pg_reference) { - bless {$pg => $pg_reference}, $class + bless { + $pg => $pg_reference, + threads_per_page => 5 + }, $class } sub create_thread($self, $author, $title, $body, $hidden = 0, $flagged = 0) { @@ -25,7 +28,7 @@ sub create_thread($self, $author, $title, $body, $hidden = 0, $flagged = 0) { END_SQL } -sub get_threads($self) { +sub get_all_threads($self) { $self->pg->db->query(<<~'END_SQL')->hashes() SELECT thread_id AS id, TO_CHAR(thread_date, 'Dy Mon DD HH:MI:SS AM TZ YYYY') AS date, @@ -38,4 +41,43 @@ sub get_threads($self) { END_SQL } +sub get_threads_by_page($self, $this_page = 1) { + my $row_count = $self->{'threads_per_page'}; + my $offset = ($this_page - 1) * $row_count; + + $self->pg->db->query(<<~'END_SQL', $row_count, $offset)->hashes(); + SELECT thread_id AS id, + TO_CHAR(thread_date, 'Dy Mon DD HH:MI:SS AM TZ YYYY') AS date, + thread_author AS author, + thread_title AS title, + thread_body AS body + FROM threads + WHERE NOT hidden_status + ORDER BY thread_date DESC + LIMIT ? OFFSET ?; + END_SQL +} + +sub threads_per_page($self, $value = undef) { + $self->{'threads_per_page'} = $value // $self->{'threads_per_page'} +} + +sub get_last_page($self) { + my $thread_count = $self->get_thread_count(); + my $last_page = int($thread_count / $self->{'threads_per_page'}); + + # Add a page for 'remainder' posts + return ++$last_page if $thread_count % $self->{'threads_per_page'}; + + return $last_page; +} + +sub get_thread_count($self) { + $self->pg->db->query(<<~'END_SQL')->text() + SELECT COUNT(*) + FROM threads + WHERE NOT hidden_status; + END_SQL +} + 1; diff --git a/t/post.t b/t/post.t index aee4a27..33dd6cb 100644 --- a/t/post.t +++ b/t/post.t @@ -11,7 +11,7 @@ my $t = Test::Mojo->new($script); my %valid_params = ( name => 'Anonymous', title => 'hi', - body => 'ayy... lmao' + post => 'ayy... lmao' ); $t->ua->max_redirects(1); diff --git a/templates/view.html.ep b/templates/page.html.ep similarity index 74% rename from templates/view.html.ep rename to templates/page.html.ep index 2a7c3db..49d68b3 100644 --- a/templates/view.html.ep +++ b/templates/page.html.ep @@ -11,3 +11,8 @@ <% } =%> +<% if ($last_page && $last_page != 1) { =%> + +<% } =%>