Added comment editing support
In other news, editing a post doesn't reload page anymore (yay for editing tags for Youtube posts)
This commit is contained in:
parent
fd9433a2e3
commit
100303173e
16 changed files with 310 additions and 184 deletions
|
@ -117,6 +117,8 @@ listComments=anonymous
|
|||
addComment=registered
|
||||
deleteComment.own=registered
|
||||
deleteComment.all=moderator
|
||||
editComment.own=registered
|
||||
editComment.all=admin
|
||||
|
||||
listTags=anonymous
|
||||
mergeTags=moderator
|
||||
|
|
12
public_html/media/css/comment-edit.css
Normal file
12
public_html/media/css/comment-edit.css
Normal file
|
@ -0,0 +1,12 @@
|
|||
.preview {
|
||||
border: 1px solid yellow;
|
||||
background: url('../img/preview.png') lemonchiffon;
|
||||
padding: 0.5em;
|
||||
display: none;
|
||||
}
|
||||
|
||||
form.edit-comment textarea,
|
||||
form.add-comment textarea {
|
||||
width: 50em;
|
||||
height: 8em;
|
||||
}
|
|
@ -31,18 +31,22 @@
|
|||
}
|
||||
|
||||
.comment .date,
|
||||
.comment .edit,
|
||||
.comment .delete {
|
||||
font-size: small;
|
||||
}
|
||||
.comment .edit:before,
|
||||
.comment .delete:before {
|
||||
margin-left: 0.2em;
|
||||
content: ' [';
|
||||
color: silver;
|
||||
}
|
||||
.comment .edit:after,
|
||||
.comment .delete:after {
|
||||
content: ']';
|
||||
color: silver;
|
||||
}
|
||||
.comment .edit a,
|
||||
.comment .delete a {
|
||||
color: silver;
|
||||
}
|
||||
|
|
|
@ -133,7 +133,7 @@ i.icon-dl {
|
|||
margin: 2px;
|
||||
}
|
||||
|
||||
form.edit-post {
|
||||
.unit.edit-post {
|
||||
display: none;
|
||||
}
|
||||
form.edit-post .safety label:not(.left) {
|
||||
|
@ -145,15 +145,3 @@ ul.tagit {
|
|||
margin: 0;
|
||||
font-size: 1em;
|
||||
}
|
||||
|
||||
.preview {
|
||||
border: 1px solid yellow;
|
||||
background: url('../img/preview.png') lemonchiffon;
|
||||
padding: 0.5em;
|
||||
display: none;
|
||||
}
|
||||
|
||||
form.add-comment textarea {
|
||||
width: 50em;
|
||||
height: 8em;
|
||||
}
|
||||
|
|
105
public_html/media/js/comment-edit.js
Normal file
105
public_html/media/js/comment-edit.js
Normal file
|
@ -0,0 +1,105 @@
|
|||
$(function()
|
||||
{
|
||||
function onDomUpdate()
|
||||
{
|
||||
$('form.edit-comment, form.add-comment').submit(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
rememberLastSearchQuery();
|
||||
|
||||
var formDom = $(this);
|
||||
if (formDom.hasClass('inactive'))
|
||||
return;
|
||||
formDom.addClass('inactive');
|
||||
formDom.find(':input').attr('readonly', true);
|
||||
|
||||
var url = formDom.attr('action') + '?json';
|
||||
var fd = new FormData(formDom[0]);
|
||||
|
||||
var preview = false;
|
||||
$.each(formDom.serializeArray(), function(i, x)
|
||||
{
|
||||
if (x.name == 'sender' && x.value == 'preview')
|
||||
preview = true;
|
||||
});
|
||||
|
||||
var ajaxData =
|
||||
{
|
||||
url: url,
|
||||
data: fd,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
type: 'POST',
|
||||
|
||||
success: function(data)
|
||||
{
|
||||
if (data['success'])
|
||||
{
|
||||
if (preview)
|
||||
{
|
||||
formDom.find('.preview').html(data['textPreview']).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
formDom.find('.preview').hide();
|
||||
var cb = function()
|
||||
{
|
||||
$.get(window.location.href, function(data)
|
||||
{
|
||||
$('.comments-wrapper').replaceWith($(data).find('.comments-wrapper'));
|
||||
$('body').trigger('dom-update');
|
||||
});
|
||||
}
|
||||
if (formDom.hasClass('add-comment'))
|
||||
{
|
||||
cb();
|
||||
formDom.find('textarea').val('');
|
||||
}
|
||||
else
|
||||
{
|
||||
formDom.slideUp(function()
|
||||
{
|
||||
cb();
|
||||
$(this).remove();
|
||||
});
|
||||
}
|
||||
}
|
||||
formDom.find(':input').attr('readonly', false);
|
||||
formDom.removeClass('inactive');
|
||||
}
|
||||
else
|
||||
{
|
||||
alert(data['message']);
|
||||
formDom.find(':input').attr('readonly', false);
|
||||
formDom.removeClass('inactive');
|
||||
}
|
||||
},
|
||||
error: function()
|
||||
{
|
||||
alert('Fatal error');
|
||||
formDom.find(':input').attr('readonly', false);
|
||||
formDom.removeClass('inactive');
|
||||
}
|
||||
};
|
||||
|
||||
$.ajax(ajaxData);
|
||||
});
|
||||
|
||||
$('.comment .edit a').click(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
var commentDom = $(this).parents('.comment');
|
||||
$.get($(this).attr('href'), function(data)
|
||||
{
|
||||
commentDom.find('form.edit-comment').remove();
|
||||
var otherForm = $(data).find('form.edit-comment');
|
||||
otherForm.hide();
|
||||
commentDom.find('.body').append(otherForm);
|
||||
otherForm.slideDown();
|
||||
$('body').trigger('dom-update');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
$('body').bind('dom-update', onDomUpdate);
|
||||
});
|
|
@ -1,6 +1,8 @@
|
|||
function onDomUpdate()
|
||||
$(function()
|
||||
{
|
||||
$('li.edit a').click(function(e)
|
||||
function onDomUpdate()
|
||||
{
|
||||
$('#sidebar .edit a').click(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
|
||||
|
@ -9,25 +11,27 @@ function onDomUpdate()
|
|||
return;
|
||||
aDom.addClass('inactive');
|
||||
|
||||
var tags = [];
|
||||
var formDom = $('form.edit-post');
|
||||
if (formDom.find('.tagit').length == 0)
|
||||
{
|
||||
$.getJSON('/tags?json', {filter: 'order:popularity,desc'}, function(data)
|
||||
{
|
||||
aDom.removeClass('inactive');
|
||||
var formDom = $('form.edit-post');
|
||||
tags = data['tags'];
|
||||
var tags = data['tags'];
|
||||
|
||||
if (!$(formDom).is(':visible'))
|
||||
{
|
||||
var tagItOptions = getTagItOptions();
|
||||
tagItOptions.availableTags = tags;
|
||||
tagItOptions.placeholderText = $('.tags input').attr('placeholder');
|
||||
$('.tags input').tagit(tagItOptions);
|
||||
formDom.show().css('height', formDom.height()).hide().slideDown();
|
||||
}
|
||||
|
||||
formDom.find('input[type=text]:visible:eq(0)').focus();
|
||||
$('html, body').animate({ scrollTop: $(formDom).offset().top + 'px' }, 'fast');
|
||||
});
|
||||
}
|
||||
else
|
||||
aDom.removeClass('inactive');
|
||||
|
||||
if (!$(formDom).is(':visible'))
|
||||
formDom.parents('.unit').show().css('height', formDom.height()).hide().slideDown();
|
||||
$('html, body').animate({ scrollTop: $(formDom).offset().top + 'px' }, 'fast');
|
||||
formDom.find('input[type=text]:visible:eq(0)').focus();
|
||||
});
|
||||
|
||||
$('.comments.unit a.simple-action').data('callback', function()
|
||||
|
@ -47,10 +51,8 @@ function onDomUpdate()
|
|||
$('body').trigger('dom-update');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(function()
|
||||
{
|
||||
$('body').bind('dom-update', onDomUpdate);
|
||||
|
||||
$('form.edit-post').submit(function(e)
|
||||
|
@ -79,82 +81,20 @@ $(function()
|
|||
{
|
||||
if (data['success'])
|
||||
{
|
||||
window.location.reload();
|
||||
}
|
||||
else
|
||||
{
|
||||
alert(data['message']);
|
||||
formDom.find(':input').attr('readonly', false);
|
||||
formDom.removeClass('inactive');
|
||||
}
|
||||
},
|
||||
error: function()
|
||||
{
|
||||
alert('Fatal error');
|
||||
formDom.find(':input').attr('readonly', false);
|
||||
formDom.removeClass('inactive');
|
||||
}
|
||||
};
|
||||
|
||||
$.ajax(ajaxData);
|
||||
});
|
||||
|
||||
$('form.add-comment').submit(function(e)
|
||||
{
|
||||
e.preventDefault();
|
||||
rememberLastSearchQuery();
|
||||
|
||||
var formDom = $(this);
|
||||
if (formDom.hasClass('inactive'))
|
||||
return;
|
||||
formDom.addClass('inactive');
|
||||
formDom.find(':input').attr('readonly', true);
|
||||
|
||||
var url = formDom.attr('action') + '?json';
|
||||
var fd = new FormData(formDom[0]);
|
||||
|
||||
var preview = false;
|
||||
$.each(formDom.serializeArray(), function(i, x)
|
||||
{
|
||||
if (x.name == 'sender' && x.value == 'preview')
|
||||
preview = true;
|
||||
});
|
||||
|
||||
var ajaxData =
|
||||
{
|
||||
url: url,
|
||||
data: fd,
|
||||
processData: false,
|
||||
contentType: false,
|
||||
type: 'POST',
|
||||
|
||||
success: function(data)
|
||||
{
|
||||
if (data['success'])
|
||||
{
|
||||
if (preview)
|
||||
{
|
||||
formDom.find('.preview').html(data['textPreview']).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
formDom.find('.preview').hide();
|
||||
$.get(window.location.href, function(data)
|
||||
{
|
||||
$('.comments-wrapper').replaceWith($(data).find('.comments-wrapper'));
|
||||
$('#sidebar').replaceWith($(data).find('#sidebar'));
|
||||
$('#edit-token').replaceWith($(data).find('#edit-token'));
|
||||
$('body').trigger('dom-update');
|
||||
});
|
||||
formDom.find('textarea').val('');
|
||||
}
|
||||
formDom.find(':input').attr('readonly', false);
|
||||
formDom.removeClass('inactive');
|
||||
formDom.parents('.unit').hide();
|
||||
}
|
||||
else
|
||||
{
|
||||
alert(data['message']);
|
||||
}
|
||||
formDom.find(':input').attr('readonly', false);
|
||||
formDom.removeClass('inactive');
|
||||
}
|
||||
},
|
||||
error: function()
|
||||
{
|
||||
|
|
|
@ -11,9 +11,11 @@ class CommentController
|
|||
$this->context->stylesheets []= 'post-small.css';
|
||||
$this->context->stylesheets []= 'comment-list.css';
|
||||
$this->context->stylesheets []= 'comment-small.css';
|
||||
$this->context->stylesheets []= 'comment-edit.css';
|
||||
$this->context->stylesheets []= 'paginator.css';
|
||||
if ($this->context->user->hasEnabledEndlessScrolling())
|
||||
$this->context->scripts []= 'paginator-endless.js';
|
||||
$this->context->scripts []= 'comment-edit.js';
|
||||
|
||||
$page = intval($page);
|
||||
$commentsPerPage = intval($this->config->comments->commentsPerPage);
|
||||
|
@ -52,6 +54,7 @@ class CommentController
|
|||
PrivilegesHelper::confirmEmail($this->context->user);
|
||||
|
||||
$post = PostModel::findById($postId);
|
||||
$this->context->transport->post = $post;
|
||||
|
||||
if (InputHelper::get('submit'))
|
||||
{
|
||||
|
@ -66,6 +69,7 @@ class CommentController
|
|||
$comment->setCommenter(null);
|
||||
$comment->commentDate = time();
|
||||
$comment->text = $text;
|
||||
|
||||
if (InputHelper::get('sender') != 'preview')
|
||||
{
|
||||
CommentModel::save($comment);
|
||||
|
@ -78,6 +82,36 @@ class CommentController
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* @route /comment/{id}/edit
|
||||
* @validate id [0-9]+
|
||||
*/
|
||||
public function editAction($id)
|
||||
{
|
||||
$comment = CommentModel::findById($id);
|
||||
$this->context->transport->comment = $comment;
|
||||
|
||||
PrivilegesHelper::confirmWithException(Privilege::EditComment, PrivilegesHelper::getIdentitySubPrivilege($comment->getCommenter()));
|
||||
|
||||
if (InputHelper::get('submit'))
|
||||
{
|
||||
$text = InputHelper::get('text');
|
||||
$text = CommentModel::validateText($text);
|
||||
|
||||
$comment->text = $text;
|
||||
|
||||
if (InputHelper::get('sender') != 'preview')
|
||||
{
|
||||
CommentModel::save($comment);
|
||||
LogHelper::log('{user} has edited comment in {post}', ['post' => TextHelper::reprPost($comment->getPost())]);
|
||||
}
|
||||
$this->context->transport->textPreview = $comment->getText();
|
||||
StatusHelper::success();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @route /comment/{id}/delete
|
||||
* @validate id [0-9]+
|
||||
|
|
|
@ -462,7 +462,9 @@ class PostController
|
|||
$this->context->pageThumb = \Chibi\UrlHelper::route('post', 'thumb', ['name' => $post->name]);
|
||||
$this->context->stylesheets []= 'post-view.css';
|
||||
$this->context->stylesheets []= 'comment-small.css';
|
||||
$this->context->stylesheets []= 'comment-edit.css';
|
||||
$this->context->scripts []= 'post-view.js';
|
||||
$this->context->scripts []= 'comment-edit.js';
|
||||
$this->context->subTitle = 'showing ' . TextHelper::reprPost($post) . ' – ' . TextHelper::reprTags($post->getTags());
|
||||
$this->context->favorite = $favorite;
|
||||
$this->context->score = $score;
|
||||
|
|
|
@ -251,6 +251,13 @@ class TextHelper
|
|||
return $path;
|
||||
}
|
||||
|
||||
public static function secureWhitespace($text)
|
||||
{
|
||||
$text = str_replace(["\r\n", "\r", "\n"], ' ', $text);
|
||||
$text = str_replace(' ', ' ', $text);
|
||||
return $text;
|
||||
}
|
||||
|
||||
const HTML_OPEN = 1;
|
||||
const HTML_CLOSE = 2;
|
||||
const HTML_LEAF = 3;
|
||||
|
|
|
@ -34,6 +34,7 @@ class Privilege extends Enum
|
|||
const ListComments = 20;
|
||||
const AddComment = 23;
|
||||
const DeleteComment = 24;
|
||||
const EditComment = 37;
|
||||
|
||||
const ListTags = 21;
|
||||
const MergeTags = 27;
|
||||
|
|
16
src/Views/comment-add.phtml
Normal file
16
src/Views/comment-add.phtml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<form action="<?php echo \Chibi\UrlHelper::route('comment', 'add', ['postId' => $this->context->transport->post->id]) ?>" method="post" class="add-comment aligned">
|
||||
<h1>add comment</h1>
|
||||
|
||||
<div class="preview"></div>
|
||||
|
||||
<div class="text">
|
||||
<div class="input-wrapper"><textarea name="text" cols="50" rows="3"></textarea></div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="submit" value="1"/>
|
||||
|
||||
<div>
|
||||
<button name="sender" class="submit" type="submit" value="preview">Preview</button>
|
||||
<button name="sender" class="submit" type="submit" value="submit">Submit</button>
|
||||
</div>
|
||||
</form>
|
16
src/Views/comment-edit.phtml
Normal file
16
src/Views/comment-edit.phtml
Normal file
|
@ -0,0 +1,16 @@
|
|||
<form action="<?php echo \Chibi\UrlHelper::route('comment', 'edit', ['id' => $this->context->transport->comment->id]) ?>" method="post" class="edit-comment aligned">
|
||||
<h1>edit comment</h1>
|
||||
|
||||
<div class="preview"></div>
|
||||
|
||||
<div class="text">
|
||||
<div class="input-wrapper"><textarea name="text" cols="50" rows="3"><?php echo TextHelper::secureWhitespace($this->context->transport->comment->text) ?></textarea></div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="submit" value="1"/>
|
||||
|
||||
<div>
|
||||
<button name="sender" class="submit" type="submit" value="preview">Preview</button>
|
||||
<button name="sender" class="submit" type="submit" value="submit">Submit</button>
|
||||
</div>
|
||||
</form>
|
|
@ -1,6 +1,7 @@
|
|||
<?php if (empty($this->context->transport->comments)): ?>
|
||||
<p class="alert alert-warning">No comments to show.</p>
|
||||
<?php else: ?>
|
||||
<div class="comments-wrapper">
|
||||
<div class="comments paginator-content">
|
||||
<?php
|
||||
$groups = [];
|
||||
|
@ -38,4 +39,5 @@
|
|||
</div>
|
||||
|
||||
<?php $this->renderFile('paginator') ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
|
|
@ -26,6 +26,14 @@
|
|||
<?php echo date('Y-m-d H:i', $this->context->comment->commentDate) ?>
|
||||
</span>
|
||||
|
||||
<?php if (PrivilegesHelper::confirm(Privilege::EditComment, PrivilegesHelper::getIdentitySubPrivilege($commenter))): ?>
|
||||
<span class="edit">
|
||||
<a href="<?php echo \Chibi\UrlHelper::route('comment', 'edit', ['id' => $this->context->comment->id]) ?>">
|
||||
edit
|
||||
</a>
|
||||
</span>
|
||||
<?php endif ?>
|
||||
|
||||
<?php if (PrivilegesHelper::confirm(Privilege::DeleteComment, PrivilegesHelper::getIdentitySubPrivilege($commenter))): ?>
|
||||
<span class="delete">
|
||||
<a class="simple-action confirmable" href="<?php echo \Chibi\UrlHelper::route('comment', 'delete', ['id' => $this->context->comment->id]) ?>" data-confirm-text="Are you sure you want to delete this comment?">
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<form action="<?php echo \Chibi\UrlHelper::route('post', 'edit', ['id' => $this->context->transport->post->id]) ?>" method="post" enctype="multipart/form-data" class="edit-post aligned unit">
|
||||
<form action="<?php echo \Chibi\UrlHelper::route('post', 'edit', ['id' => $this->context->transport->post->id]) ?>" method="post" enctype="multipart/form-data" class="edit-post aligned">
|
||||
<h1>edit post</h1>
|
||||
<?php if (PrivilegesHelper::confirm(Privilege::EditPostSafety, PrivilegesHelper::getIdentitySubPrivilege($this->context->transport->post->getUploader()))): ?>
|
||||
<div class="safety">
|
||||
|
|
|
@ -312,7 +312,9 @@
|
|||
</div>
|
||||
|
||||
<?php if ($canEditAnything): ?>
|
||||
<div class="edit-post unit">
|
||||
<?php $this->renderFile('post-edit') ?>
|
||||
</div>
|
||||
<?php endif ?>
|
||||
|
||||
<div class="comments-wrapper">
|
||||
|
@ -330,21 +332,8 @@
|
|||
</div>
|
||||
|
||||
<?php if (PrivilegesHelper::confirm(Privilege::AddComment)): ?>
|
||||
<form action="<?php echo \Chibi\UrlHelper::route('comment', 'add', ['postId' => $this->context->transport->post->id]) ?>" method="post" class="add-comment aligned unit">
|
||||
<h1>add comment</h1>
|
||||
|
||||
<div class="preview"></div>
|
||||
|
||||
<div class="text">
|
||||
<div class="input-wrapper"><textarea name="text" cols="50" rows="3"></textarea></div>
|
||||
<div class="unit">
|
||||
<?php $this->renderFile('comment-add') ?>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="submit" value="1"/>
|
||||
|
||||
<div>
|
||||
<button name="sender" class="submit" type="submit" value="preview">Preview</button>
|
||||
<button name="sender" class="submit" type="submit" value="submit">Submit</button>
|
||||
</div>
|
||||
</form>
|
||||
<?php endif ?>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue