diff options
Diffstat (limited to 'web')
-rw-r--r-- | web/_controller/_util/post.php | 129 | ||||
-rw-r--r-- | web/_controller/apps/home.php | 70 | ||||
-rw-r--r-- | web/_model/format.php | 2 | ||||
-rw-r--r-- | web/_views/apps/home/main.php | 5 | ||||
-rw-r--r-- | web/_views/template/comment.php | 7 | ||||
-rw-r--r-- | web/_views/template/post.php | 31 | ||||
-rw-r--r-- | web/_views/template/posts.php | 23 | ||||
-rw-r--r-- | web/core/database.php | 12 | ||||
-rw-r--r-- | web/public/css/post.css | 4 | ||||
-rw-r--r-- | web/public/js/shared/post.js | 58 |
10 files changed, 253 insertions, 88 deletions
diff --git a/web/_controller/_util/post.php b/web/_controller/_util/post.php new file mode 100644 index 0000000..b128d67 --- /dev/null +++ b/web/_controller/_util/post.php @@ -0,0 +1,129 @@ +<?php /* Copyright (c) 2024 Freya Murphy */ +class Post_controller extends Controller { + + // the request model + private $request_model; + + // the caceh model + private $cache_model; + + // page size + private $page_size; + + function __construct($load) { + parent::__construct($load); + $this->request_model = $this->load->model('request'); + $this->cache_model = $this->load->model('cache'); + $this->page_size = 10; + } + + public function index(): void { + $this->view('template/posts'); + } + + /** + * @return array<string,mixed> + */ + public function posts(): array { + $page = $this->request_model->get_int('page', 0); + $max = $this->request_model->get_int('max'); + $offset = $page * $this->page_size; + + $user = $this->main->user(); + + $query = $this->db; + + if ($user) { + $query = $query->select('p.*, l.post_id IS NOT NULL as liked'); + } else { + $query = $query->select('p.*, FALSE as liked'); + } + + $query = $query->from('api.post p'); + + if ($user) { + $query = $query->join('admin.like l', 'p.id = l.post_id AND l.user_id') + ->eq($user['id']); + } + + if ($max) { + $query = $query + ->where('id')->le($max); + } + + $posts = $query + ->limit($this->page_size) + ->offset($offset) + ->rows(); + + $users = $this->cache_model->get_users($posts); + $max = 0; + + foreach ($posts as $post) { + $max = max($max, $post['id']); + $data = array(); + $data['page_size'] = $this->page_size; + $data['user'] = $users[$post['user_id']]; + $data['post'] = $post; + $this->view('template/post', $data); + } + + $pc = $this->db + ->select('COUNT(p.id) as pc') + ->from('api.post p') + ->row()['pc']; + + + return array( + 'loaded' => count($posts), + 'total' => $pc, + 'page_size' => $this->page_size, + 'max' => $max, + ); + } + + /** + * @return array<string,mixed> + */ + public function comments(): array { + $page = $this->request_model->get_int('page', 0); + $max = $this->request_model->get_int('max'); + $id = $this->request_model->get_int('id', 0); + $offset = $page * $this->page_size; + + $query = $this->db + ->select('*') + ->from('api.comment') + ->where('post_id') + ->eq($id); + + if ($max) { + $query = $query + ->and() + ->where('id') + ->le($max); + } + + $comments = $query + ->limit($this->page_size) + ->offset($offset) + ->rows(); + + $users = $this->cache_model->get_users($comments); + $max = 0; + + foreach ($comments as $comment) { + $max = max($max, $comment['id']); + $data = array(); + $data['user'] = $users[$comment['user_id']]; + $data['comment'] = $comment; + $this->view('template/comment', $data); + } + + return array( + 'loaded' => count($comments), + 'page_size' => $this->page_size, + 'max' => $max, + ); + } +} diff --git a/web/_controller/apps/home.php b/web/_controller/apps/home.php index 25c8c4e..edf7e2b 100644 --- a/web/_controller/apps/home.php +++ b/web/_controller/apps/home.php @@ -4,17 +4,13 @@ class Home_controller extends Controller { // the home model private $home_model; - // the request model - private $request_model; - - // the caceh model - private $cache_model; + // the post controller + protected $post_controller; function __construct($load) { parent::__construct($load); $this->home_model = $this->load->model('apps/home'); - $this->request_model = $this->load->model('request'); - $this->cache_model = $this->load->model('cache'); + $this->post_controller = $this->load->controller('_util/post'); } public function index(): void { @@ -24,66 +20,6 @@ class Home_controller extends Controller { $this->view('apps/home/main', $data); } - public function posts(): void { - $page = $this->request_model->get_int('page', 0); - $page_size = 20; - $offset = $page * $page_size; - - $user = $this->main->user(); - - $query = $this->db; - - if ($user) { - $query = $query->select('p.*, l.post_id IS NOT NULL as liked'); - } else { - $query = $query->select('p.*, FALSE as liked'); - } - - $query = $query->from('api.post p'); - - if ($user) { - $query = $query->join('admin.like l', 'p.id = l.post_id') - ->where('l.user_id')->eq($user['id']) - ->or()->where('l.user_id IS NULL'); - } - - $posts = $query->limit($page_size) - ->offset($offset) - ->rows(); - - $users = $this->cache_model->get_users($posts); - - foreach ($posts as $post) { - $data = array(); - $data['user'] = $users[$post['user_id']]; - $data['post'] = $post; - $this->view('template/post', $data); - } - } - - public function comments(): void { - $page = $this->request_model->get_int('page', 0); - $id = $this->request_model->get_int('id'); - $page_size = 20; - $offset = $page * $page_size; - - $comments = $this->db - ->select('*') - ->from('admin.comment') - ->limit($page_size) - ->offset($offset) - ->rows(); - - $users = $this->cache_model->get_users($comments); - - foreach ($comments as $comment) { - $data = array(); - $data['user'] = $users[$comment['user_id']]; - $data['comment'] = $comment; - $this->view('template/comment', $data); - } - } - } ?> diff --git a/web/_model/format.php b/web/_model/format.php index d8c7480..52b51be 100644 --- a/web/_model/format.php +++ b/web/_model/format.php @@ -1,5 +1,5 @@ <?php /* Copyright (c) 2024 Freya Murphy */ -class Format_model extends Modal { +class Format_model extends Model { function __construct($load) { parent::__construct($load); diff --git a/web/_views/apps/home/main.php b/web/_views/apps/home/main.php index b1c1efc..5cfdf8c 100644 --- a/web/_views/apps/home/main.php +++ b/web/_views/apps/home/main.php @@ -23,8 +23,5 @@ </script> </div> <?php endif; ?> - <div id="post-container"> - <?=$this->posts()?> - </div> - <?=ilang('action_load_posts', id: 'action-load-posts', class: 'btn btn-line')?> + <?php $this->post_controller->index(); ?> </div> diff --git a/web/_views/template/comment.php b/web/_views/template/comment.php index 943f232..20032b2 100644 --- a/web/_views/template/comment.php +++ b/web/_views/template/comment.php @@ -1,11 +1,14 @@ <?php /* Copyright (c) 2024 Freya Murphy */ ?> <?php /* vi: syntax=php */ ?> +<?php + $format_model = $this->load->model('format'); +?> <div class="comment row mt"> <?php $this->view('template/pfp', array('user' => $user))?> <div class="ml col sub-card"> <div class="row"> - <strong><?=$this->main->display_name($user)?></strong> - <span class="dim ml"><?=$this->main->display_date($comment['date'])?></span> + <strong><?=$format_model->name($user)?></strong> + <span class="dim ml"><?=$format_model->date($comment['date'])?></span> </div> <?=$comment['content']?> </div> diff --git a/web/_views/template/post.php b/web/_views/template/post.php index 40a3c1d..4fbf485 100644 --- a/web/_views/template/post.php +++ b/web/_views/template/post.php @@ -29,25 +29,40 @@ <div class="col comments"> <?php $_GET['id'] = $post['id']; - $this->comments(); - ilang('action_load_comments', - class: 'action-load-comments btn btn-line mt', - attrs: array('postId' => $post['id']) - ); + $cdata = $this->comments(); + + $loaded = $cdata['loaded']; + $max = $cdata['max']; + $page_size = $cdata['page_size']; + $total = $post['comment_count']; + + if ($loaded >= $page_size && $page_size < $total) { + ilang('action_load_comments', + class: 'action-load-comments btn btn-line mt', + attrs: array( + 'postId' => $post['id'], + 'loaded' => $loaded, + 'pageSize' => $page_size, + 'commentCount' => $total, + 'commentMax' => $max, + ) + ); + } + ?> </div> <?php if ($self): ?> <div class="row grow mt"> <?php $this->view('template/pfp', array('user' => $user))?> - <form class="ml"> + <form class="ml action-new-comment-form"> <input type="hidden" name="id" value="<?=$post['id']?>" > <input - id="new-comment-<?=$post['id']?>" - class="input" + class="action-new-comment input" + postId="<?=$post['id']?>" autocomplete="off" type="text" name="text" diff --git a/web/_views/template/posts.php b/web/_views/template/posts.php new file mode 100644 index 0000000..f57a25f --- /dev/null +++ b/web/_views/template/posts.php @@ -0,0 +1,23 @@ +<div id="post-container"> +<?php + $pdata = $this->posts(); + + $loaded = $pdata['loaded']; + $page_size = $pdata['page_size']; + $total = $pdata['total']; + $max = $pdata['max']; + + if ($loaded >= $page_size && $page_size < $total) { + ilang('action_load_posts', + id: 'action-load-posts', + class: 'btn btn-line mb', + attrs: array( + 'loaded' => $loaded, + 'pageSize' => $page_size, + 'postCount' => $total, + 'postMax' => $max, + ) + ); + } +?> +</div> diff --git a/web/core/database.php b/web/core/database.php index 4b44e86..079b0de 100644 --- a/web/core/database.php +++ b/web/core/database.php @@ -69,6 +69,18 @@ class DatabaseQuery { return $this; } + public function lt($item) { + $this->query .= "< ?\n"; + array_push($this->param, $item); + return $this; + } + + public function le($item) { + $this->query .= "<= ?\n"; + array_push($this->param, $item); + return $this; + } + public function where_in($column, $array) { if (!$this->where) { $this->where = TRUE; diff --git a/web/public/css/post.css b/web/public/css/post.css index 6ad14ba..4030da3 100644 --- a/web/public/css/post.css +++ b/web/public/css/post.css @@ -10,3 +10,7 @@ .action-load-comments { margin-left: 4rem; } + +#action-load-posts { + justify-content: center; +} diff --git a/web/public/js/shared/post.js b/web/public/js/shared/post.js index afbeaf0..f22dd99 100644 --- a/web/public/js/shared/post.js +++ b/web/public/js/shared/post.js @@ -5,14 +5,28 @@ observe('#main-content', '.action-load-comments', function(me) { page = '1'; } let newPage = Number(page) + 1; - let id = me.attr('postId'); me.attr('page', newPage + ''); - let url = '/home/comments?page=' + page + '&id=' + id; + + let postId = me.attr('postId'); + let loaded = Number(me.attr('loaded')); + let pageSize = Number(me.attr('pageSize')); + let commmentCount = Number(me.attr('commentCount')); + let commentMax = Number(me.attr('commentMax')); + + let url = '/_util/post/comments?page=' + page + '&id=' + postId + '&max' + commentMax; $.get(url, function (data) { if (data === '') { me.remove(); + return; + } + + $(data).insertBefore(me); + + loaded += pageSize; + if (loaded >= commmentCount) { + me.remove(); } else { - $(me).prepend(data); + me.attr('loaded', loaded + ''); } }); }); @@ -26,13 +40,45 @@ observe('#main-content', '#action-load-posts', function(me) { } let newPage = Number(page) + 1; me.attr('page', newPage + ''); - let url = '/home/posts?page=' + page; - $.get(url, function (data) { + + let loaded = Number(me.attr('loaded')); + let pageSize = Number(me.attr('pageSize')); + let postCount = Number(me.attr('postCount')); + let postMax = Number(me.attr('postMax')); + + let url = '/_util/post/posts?page=' + page + '&max=' + postMax; + $.get(url, function (data) { if (data === '') { me.remove(); + return; + } + + $(data).insertBefore(me); + + loaded += pageSize; + if (loaded >= postCount) { + me.remove(); } else { - $('#post-container').append(data); + me.attr('loaded', loaded + ''); } }); }); }); + +observe('#main-content', '.action-new-comment-form', function(me) { + me.on('submit', function(e) { + e.preventDefault(); + let input = me.find('.action-new-comment'); + let content = input.val(); + let post_id = input.attr('postId'); + $.ajax({ + url: '/api/comment', + method: 'POST', + data: JSON.stringify({ post_id, content }), + success: function(_data) { + window.location.reload(); + }, + error: errorToast + }); + }); +}); |