summaryrefslogtreecommitdiff
path: root/web
diff options
context:
space:
mode:
authorFreya Murphy <freya@freyacat.org>2024-03-30 16:36:54 -0400
committerFreya Murphy <freya@freyacat.org>2024-03-30 16:36:54 -0400
commit1f647374a8cdf3bc5c2d29ff8be277b027925c8c (patch)
tree9fdf42d250edb941de13ecd1aab9185ba2b30b00 /web
parentrename views to _views (diff)
downloadxssbook2-1f647374a8cdf3bc5c2d29ff8be277b027925c8c.tar.gz
xssbook2-1f647374a8cdf3bc5c2d29ff8be277b027925c8c.tar.bz2
xssbook2-1f647374a8cdf3bc5c2d29ff8be277b027925c8c.zip
post comments, refactor post loading, hide load more btn
Diffstat (limited to 'web')
-rw-r--r--web/_controller/_util/post.php129
-rw-r--r--web/_controller/apps/home.php70
-rw-r--r--web/_model/format.php2
-rw-r--r--web/_views/apps/home/main.php5
-rw-r--r--web/_views/template/comment.php7
-rw-r--r--web/_views/template/post.php31
-rw-r--r--web/_views/template/posts.php23
-rw-r--r--web/core/database.php12
-rw-r--r--web/public/css/post.css4
-rw-r--r--web/public/js/shared/post.js58
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
+ });
+ });
+});