Public: render newly submitted comments without page reload
This commit is contained in:
parent
803ab55c37
commit
2760e46a17
67
index.php
67
index.php
|
|
@ -27,13 +27,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && (string)($_POST['action'] ?? '') ==
|
||||||
|| str_contains((string)($_SERVER['HTTP_ACCEPT'] ?? ''), 'application/json');
|
|| str_contains((string)($_SERVER['HTTP_ACCEPT'] ?? ''), 'application/json');
|
||||||
|
|
||||||
$commentSaved = false;
|
$commentSaved = false;
|
||||||
|
$savedComment = null;
|
||||||
$errorMessage = '';
|
$errorMessage = '';
|
||||||
|
$errorCode = 422;
|
||||||
|
|
||||||
if ($token !== '' && $photoId > 0 && $text !== '') {
|
if ($token !== '' && $photoId > 0 && $text !== '') {
|
||||||
$u = commenterByToken($token);
|
$u = commenterByToken($token);
|
||||||
if ($u) {
|
if ($u) {
|
||||||
commentAdd($photoId, (int)$u['id'], limitText($text, 1000));
|
try {
|
||||||
$commentSaved = true;
|
$savedComment = commentAdd($photoId, (int)$u['id'], limitText($text, 1000));
|
||||||
|
$commentSaved = true;
|
||||||
|
} catch (Throwable) {
|
||||||
|
$errorMessage = 'Не удалось отправить комментарий.';
|
||||||
|
$errorCode = 500;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$errorMessage = 'Ссылка для комментариев недействительна.';
|
$errorMessage = 'Ссылка для комментариев недействительна.';
|
||||||
}
|
}
|
||||||
|
|
@ -44,11 +51,20 @@ if ($_SERVER['REQUEST_METHOD'] === 'POST' && (string)($_POST['action'] ?? '') ==
|
||||||
if ($isAjax) {
|
if ($isAjax) {
|
||||||
header('Content-Type: application/json; charset=utf-8');
|
header('Content-Type: application/json; charset=utf-8');
|
||||||
if ($commentSaved) {
|
if ($commentSaved) {
|
||||||
echo json_encode(['ok' => true, 'message' => 'Ваш комментарий отправлен.'], JSON_UNESCAPED_UNICODE);
|
echo json_encode([
|
||||||
|
'ok' => true,
|
||||||
|
'message' => 'Ваш комментарий отправлен.',
|
||||||
|
'comment' => $savedComment ? [
|
||||||
|
'id' => (int)($savedComment['id'] ?? 0),
|
||||||
|
'comment_text' => (string)($savedComment['comment_text'] ?? ''),
|
||||||
|
'created_at' => (string)($savedComment['created_at'] ?? ''),
|
||||||
|
'display_name' => (string)($savedComment['display_name'] ?? 'Пользователь'),
|
||||||
|
] : null,
|
||||||
|
], JSON_UNESCAPED_UNICODE);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
http_response_code(422);
|
http_response_code($errorCode);
|
||||||
echo json_encode(['ok' => false, 'message' => $errorMessage !== '' ? $errorMessage : 'Не удалось отправить комментарий.'], JSON_UNESCAPED_UNICODE);
|
echo json_encode(['ok' => false, 'message' => $errorMessage !== '' ? $errorMessage : 'Не удалось отправить комментарий.'], JSON_UNESCAPED_UNICODE);
|
||||||
exit;
|
exit;
|
||||||
}
|
}
|
||||||
|
|
@ -688,9 +704,11 @@ function outputWatermarked(string $path, string $mime): never
|
||||||
<p class="muted">Комментарии может оставлять только пользователь с персональной ссылкой.</p>
|
<p class="muted">Комментарии может оставлять только пользователь с персональной ссылкой.</p>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
|
|
||||||
<?php foreach($comments as $c): ?>
|
<div class="js-comments-list">
|
||||||
<div class="cmt"><strong><?= h((string)($c['display_name'] ?? 'Пользователь')) ?></strong> <span class="muted">· <?= h((string)$c['created_at']) ?></span><br><?= nl2br(h((string)$c['comment_text'])) ?></div>
|
<?php foreach($comments as $c): ?>
|
||||||
<?php endforeach; ?>
|
<div class="cmt"><strong><?= h((string)($c['display_name'] ?? 'Пользователь')) ?></strong> <span class="muted">· <?= h((string)$c['created_at']) ?></span><br><?= nl2br(h((string)$c['comment_text'])) ?></div>
|
||||||
|
<?php endforeach; ?>
|
||||||
|
</div>
|
||||||
|
|
||||||
<?php if ($detailTotal > 0): ?>
|
<?php if ($detailTotal > 0): ?>
|
||||||
<div class="pager">
|
<div class="pager">
|
||||||
|
|
@ -889,6 +907,38 @@ function outputWatermarked(string $path, string $mime): never
|
||||||
const commentForm = commentTextarea ? commentTextarea.closest('.js-comment-form') : null;
|
const commentForm = commentTextarea ? commentTextarea.closest('.js-comment-form') : null;
|
||||||
const commentFeedback = commentForm ? commentForm.querySelector('.js-comment-feedback') : null;
|
const commentFeedback = commentForm ? commentForm.querySelector('.js-comment-feedback') : null;
|
||||||
const commentSubmitButton = commentForm ? commentForm.querySelector('button[type="submit"]') : null;
|
const commentSubmitButton = commentForm ? commentForm.querySelector('button[type="submit"]') : null;
|
||||||
|
const commentsList = document.querySelector('.js-comments-list');
|
||||||
|
|
||||||
|
const prependComment = (comment) => {
|
||||||
|
if (!commentsList || !comment || typeof comment !== 'object') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const item = document.createElement('div');
|
||||||
|
item.className = 'cmt';
|
||||||
|
|
||||||
|
const author = document.createElement('strong');
|
||||||
|
author.textContent = String(comment.display_name || 'Пользователь');
|
||||||
|
|
||||||
|
const meta = document.createElement('span');
|
||||||
|
meta.className = 'muted';
|
||||||
|
meta.textContent = `· ${String(comment.created_at || '')}`;
|
||||||
|
|
||||||
|
item.appendChild(author);
|
||||||
|
item.append(' ');
|
||||||
|
item.appendChild(meta);
|
||||||
|
item.appendChild(document.createElement('br'));
|
||||||
|
|
||||||
|
const lines = String(comment.comment_text || '').split(/\r\n|\r|\n/);
|
||||||
|
lines.forEach((line, index) => {
|
||||||
|
item.append(document.createTextNode(line));
|
||||||
|
if (index < lines.length - 1) {
|
||||||
|
item.appendChild(document.createElement('br'));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
commentsList.prepend(item);
|
||||||
|
};
|
||||||
|
|
||||||
const setCommentFeedback = (message, isError) => {
|
const setCommentFeedback = (message, isError) => {
|
||||||
if (!commentFeedback) {
|
if (!commentFeedback) {
|
||||||
|
|
@ -960,6 +1010,9 @@ function outputWatermarked(string $path, string $mime): never
|
||||||
}
|
}
|
||||||
|
|
||||||
setCommentFeedback(payload.message || 'Ваш комментарий отправлен.', false);
|
setCommentFeedback(payload.message || 'Ваш комментарий отправлен.', false);
|
||||||
|
if (payload.comment) {
|
||||||
|
prependComment(payload.comment);
|
||||||
|
}
|
||||||
commentTextarea.value = '';
|
commentTextarea.value = '';
|
||||||
commentTextarea.focus();
|
commentTextarea.focus();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -360,10 +360,31 @@ function commentsByPhoto(int $photoId): array
|
||||||
return $st->fetchAll();
|
return $st->fetchAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
function commentAdd(int $photoId, int $userId, string $text): void
|
function commentAdd(int $photoId, int $userId, string $text): array
|
||||||
{
|
{
|
||||||
$st = db()->prepare('INSERT INTO photo_comments(photo_id, user_id, comment_text) VALUES (:p,:u,:t)');
|
$st = db()->prepare('INSERT INTO photo_comments(photo_id, user_id, comment_text) VALUES (:p,:u,:t)');
|
||||||
$st->execute(['p' => $photoId, 'u' => $userId, 't' => $text]);
|
$st->execute(['p' => $photoId, 'u' => $userId, 't' => $text]);
|
||||||
|
|
||||||
|
$commentId = (int)db()->lastInsertId();
|
||||||
|
$detail = db()->prepare('SELECT c.*, u.display_name
|
||||||
|
FROM photo_comments c
|
||||||
|
LEFT JOIN comment_users u ON u.id=c.user_id
|
||||||
|
WHERE c.id=:id');
|
||||||
|
$detail->execute(['id' => $commentId]);
|
||||||
|
$row = $detail->fetch();
|
||||||
|
|
||||||
|
if (!$row) {
|
||||||
|
return [
|
||||||
|
'id' => $commentId,
|
||||||
|
'photo_id' => $photoId,
|
||||||
|
'user_id' => $userId,
|
||||||
|
'comment_text' => $text,
|
||||||
|
'created_at' => date('Y-m-d H:i:s'),
|
||||||
|
'display_name' => 'Пользователь',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $row;
|
||||||
}
|
}
|
||||||
|
|
||||||
function commentDelete(int $id): void
|
function commentDelete(int $id): void
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user