Merge photo comments feature #114
@ -74,7 +74,7 @@ class PhotoCommentController extends Controller
|
|||||||
|
|
||||||
if (is_null($parentComment))
|
if (is_null($parentComment))
|
||||||
{
|
{
|
||||||
$request->getSession()->flash('success', trans('gallery.photo_comment_posted_successfully'));
|
//TODO $request->getSession()->flash('success', trans('gallery.photo_comment_posted_successfully'));
|
||||||
return redirect($photo->url());
|
return redirect($photo->url());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -82,14 +82,14 @@ class PhotoCommentController extends Controller
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'commentor_name' => 'required|max:255',
|
'name' => 'required|max:255',
|
||||||
'commentor_email' => 'sometimes|max:255|email',
|
'email' => 'sometimes|max:255|email',
|
||||||
'comment_text' => 'required'
|
'comment' => 'required'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$comment = new PhotoComment();
|
$comment = new PhotoComment();
|
||||||
$comment->photo_id = $photo->id;
|
$comment->photo_id = $photo->id;
|
||||||
$comment->fill($request->only(['commentor_email', 'commentor_name', 'comment_text']));
|
$comment->fill($request->only(['name', 'email', 'comment']));
|
||||||
|
|
||||||
if (!is_null($parentComment))
|
if (!is_null($parentComment))
|
||||||
{
|
{
|
||||||
|
@ -12,9 +12,9 @@ class PhotoComment extends Model
|
|||||||
* @var array
|
* @var array
|
||||||
*/
|
*/
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'commentor_name',
|
'name',
|
||||||
'commentor_email',
|
'email',
|
||||||
'comment_text'
|
'comment'
|
||||||
];
|
];
|
||||||
|
|
||||||
public function approvedBy()
|
public function approvedBy()
|
||||||
@ -22,6 +22,21 @@ class PhotoComment extends Model
|
|||||||
return $this->belongsTo(User::class, 'approved_user_id');
|
return $this->belongsTo(User::class, 'approved_user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function approvedChildren()
|
||||||
|
{
|
||||||
|
return $this->children()->whereNotNull('approved_at');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function authorDisplayName()
|
||||||
|
{
|
||||||
|
return is_null($this->createdBy) ? $this->name : $this->createdBy->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function children()
|
||||||
|
{
|
||||||
|
return $this->hasMany(PhotoComment::class, 'parent_comment_id');
|
||||||
|
}
|
||||||
|
|
||||||
public function createdBy()
|
public function createdBy()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(User::class, 'created_user_id');
|
return $this->belongsTo(User::class, 'created_user_id');
|
||||||
@ -45,4 +60,17 @@ class PhotoComment extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(PhotoComment::class, 'parent_comment_id');
|
return $this->belongsTo(PhotoComment::class, 'parent_comment_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function textAsHtml()
|
||||||
|
{
|
||||||
|
$start = '<p>';
|
||||||
|
$end = '</p>';
|
||||||
|
$isHtml = (
|
||||||
|
strlen($this->comment) > (strlen($start) + strlen($end)) && // text contains both our start + end string
|
||||||
|
strtolower(substr($this->comment, 0, strlen($start))) == strtolower($start) && // text starts with our start string
|
||||||
|
strtolower(substr($this->comment, strlen($this->comment) - strlen($end))) == strtolower($end) // text ends with our end string
|
||||||
|
);
|
||||||
|
|
||||||
|
return $isHtml ? $this->comment : sprintf('<p>%s</p>', $this->comment);
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,9 +16,9 @@ class CreatePhotoCommentsTable extends Migration
|
|||||||
Schema::create('photo_comments', function (Blueprint $table) {
|
Schema::create('photo_comments', function (Blueprint $table) {
|
||||||
$table->bigIncrements('id');
|
$table->bigIncrements('id');
|
||||||
$table->unsignedBigInteger('photo_id');
|
$table->unsignedBigInteger('photo_id');
|
||||||
$table->string('commentor_name');
|
$table->string('name');
|
||||||
$table->string('commentor_email');
|
$table->string('email');
|
||||||
$table->text('comment_text');
|
$table->text('comment');
|
||||||
$table->unsignedInteger('created_user_id')->nullable(true);
|
$table->unsignedInteger('created_user_id')->nullable(true);
|
||||||
$table->unsignedInteger('approved_user_id')->nullable(true);
|
$table->unsignedInteger('approved_user_id')->nullable(true);
|
||||||
$table->dateTime('approved_at')->nullable(true);
|
$table->dateTime('approved_at')->nullable(true);
|
||||||
|
@ -41569,12 +41569,21 @@ function PhotoViewModel(urls) {
|
|||||||
self.is_reply_form_loading = false;
|
self.is_reply_form_loading = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#comment-reply-modal').on('hide.bs.modal', function (event) {
|
||||||
|
tinymce.remove('#comment-text-reply');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
postCommentReply: function() {
|
postCommentReply: function() {
|
||||||
var form = $('form', '#comment-reply-form-content');
|
var form = $('form', '#comment-reply-form-content');
|
||||||
var formUrl = $(form).attr('action');
|
var formUrl = $(form).attr('action');
|
||||||
|
|
||||||
|
// Seems like the TinyMCE editor in the BS modal does not persist back to the textarea correctly - so do
|
||||||
|
// this manually (bit of a hack!)
|
||||||
|
$('#comment-text-reply', form).html(tinymce.get('comment-text-reply').getContent());
|
||||||
|
|
||||||
var formData = form.serialize();
|
var formData = form.serialize();
|
||||||
|
|
||||||
$.post(formUrl, formData, function(result)
|
$.post(formUrl, formData, function(result)
|
||||||
{
|
{
|
||||||
if (result.redirect_url)
|
if (result.redirect_url)
|
||||||
@ -41583,7 +41592,9 @@ function PhotoViewModel(urls) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
tinymce.remove('#comment-text-reply');
|
||||||
$('#comment-reply-form-content').html(result);
|
$('#comment-reply-form-content').html(result);
|
||||||
|
initTinyMce('#comment-text-reply');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -41593,6 +41604,9 @@ function PhotoViewModel(urls) {
|
|||||||
|
|
||||||
this.is_reply_form_loading = true;
|
this.is_reply_form_loading = true;
|
||||||
$('#comment-reply-modal').modal('show');
|
$('#comment-reply-modal').modal('show');
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
2
public/js/blue-twilight.min.js
vendored
2
public/js/blue-twilight.min.js
vendored
File diff suppressed because one or more lines are too long
@ -33,12 +33,21 @@ function PhotoViewModel(urls) {
|
|||||||
self.is_reply_form_loading = false;
|
self.is_reply_form_loading = false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#comment-reply-modal').on('hide.bs.modal', function (event) {
|
||||||
|
tinymce.remove('#comment-text-reply');
|
||||||
|
});
|
||||||
},
|
},
|
||||||
postCommentReply: function() {
|
postCommentReply: function() {
|
||||||
var form = $('form', '#comment-reply-form-content');
|
var form = $('form', '#comment-reply-form-content');
|
||||||
var formUrl = $(form).attr('action');
|
var formUrl = $(form).attr('action');
|
||||||
|
|
||||||
|
// Seems like the TinyMCE editor in the BS modal does not persist back to the textarea correctly - so do
|
||||||
|
// this manually (bit of a hack!)
|
||||||
|
$('#comment-text-reply', form).html(tinymce.get('comment-text-reply').getContent());
|
||||||
|
|
||||||
var formData = form.serialize();
|
var formData = form.serialize();
|
||||||
|
|
||||||
$.post(formUrl, formData, function(result)
|
$.post(formUrl, formData, function(result)
|
||||||
{
|
{
|
||||||
if (result.redirect_url)
|
if (result.redirect_url)
|
||||||
@ -47,7 +56,9 @@ function PhotoViewModel(urls) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
tinymce.remove('#comment-text-reply');
|
||||||
$('#comment-reply-form-content').html(result);
|
$('#comment-reply-form-content').html(result);
|
||||||
|
initTinyMce('#comment-text-reply');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -57,6 +68,9 @@ function PhotoViewModel(urls) {
|
|||||||
|
|
||||||
this.is_reply_form_loading = true;
|
this.is_reply_form_loading = true;
|
||||||
$('#comment-reply-modal').modal('show');
|
$('#comment-reply-modal').modal('show');
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -8,11 +8,9 @@
|
|||||||
@include(Theme::viewName('partials.photo_comments_reply_form'))
|
@include(Theme::viewName('partials.photo_comments_reply_form'))
|
||||||
|
|
||||||
@if ($photo->approvedComments()->count() > 0)
|
@if ($photo->approvedComments()->count() > 0)
|
||||||
<ul>
|
|
||||||
@foreach ($photo->approvedComments as $comment)
|
@foreach ($photo->approvedComments as $comment)
|
||||||
@include(Theme::viewName('partials.photo_single_comment'))
|
@include(Theme::viewName('partials.photo_single_comment'))
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,9 +4,9 @@ $is_reply = isset($reply_comment);
|
|||||||
|
|
||||||
{{-- Show a previous of the comment we're replying to --}}
|
{{-- Show a previous of the comment we're replying to --}}
|
||||||
@if ($is_reply)
|
@if ($is_reply)
|
||||||
<ul class="mb-3">
|
<div class="mb-3">
|
||||||
@include (Theme::viewName('partials.photo_single_comment'), ['comment' => $reply_comment, 'is_reply' => true])
|
@include (Theme::viewName('partials.photo_single_comment'), ['comment' => $reply_comment, 'is_reply' => true])
|
||||||
</ul>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
<form action="{{ $photo->postCommentUrl() }}" method="post">
|
<form action="{{ $photo->postCommentUrl() }}" method="post">
|
||||||
@ -18,33 +18,33 @@ $is_reply = isset($reply_comment);
|
|||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="commentor-name">@lang('forms.name_label')</label>
|
<label for="commentor-name">@lang('forms.name_label')</label>
|
||||||
<input type="text" class="form-control{{ $errors->has('commentor_name') ? ' is-invalid' : '' }}" id="commentor-name" name="commentor_name" value="{{ old('commentor_name') }}"/>
|
<input type="text" class="form-control{{ $errors->has('name') ? ' is-invalid' : '' }}" id="commentor-name" name="name" value="{{ old('name') }}"/>
|
||||||
|
|
||||||
@if ($errors->has('commentor_name'))
|
@if ($errors->has('name'))
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
<strong>{{ $errors->first('commentor_name') }}</strong>
|
<strong>{{ $errors->first('name') }}</strong>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="commentor-email">@lang('forms.email_label')</label>
|
<label for="commentor-email">@lang('forms.email_label')</label>
|
||||||
<input type="text" class="form-control{{ $errors->has('commentor_email') ? ' is-invalid' : '' }}" id="commentor-email" name="commentor_email" value="{{ old('commentor_email') }}" placeholder="@lang('forms.email_placeholder')"/>
|
<input type="text" class="form-control{{ $errors->has('email') ? ' is-invalid' : '' }}" id="commentor-email" name="email" value="{{ old('email') }}" placeholder="@lang('forms.email_placeholder')"/>
|
||||||
|
|
||||||
@if ($errors->has('commentor_email'))
|
@if ($errors->has('email'))
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
<strong>{{ $errors->first('commentor_email') }}</strong>
|
<strong>{{ $errors->first('email') }}</strong>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="comment-text{{ $is_reply ? '-reply' : '' }}">@lang('forms.photo_comment_text_label')</label>
|
<label for="comment-text{{ $is_reply ? '-reply' : '' }}">@lang('forms.photo_comment_text_label')</label>
|
||||||
<textarea class="form-control{{ $errors->has('comment_text') ? ' is-invalid' : '' }}" id="comment-text{{ $is_reply ? '-reply' : '' }}" name="comment_text" rows="10">{{ old('comment_text') }}</textarea>
|
<textarea class="form-control{{ $errors->has('comment') ? ' is-invalid' : '' }}" id="comment-text{{ $is_reply ? '-reply' : '' }}" name="comment" rows="10">{{ old('comment') }}</textarea>
|
||||||
|
|
||||||
@if ($errors->has('comment_text'))
|
@if ($errors->has('comment'))
|
||||||
<div class="invalid-feedback">
|
<div class="invalid-feedback">
|
||||||
<strong>{{ $errors->first('comment_text') }}</strong>
|
<strong>{{ $errors->first('comment') }}</strong>
|
||||||
</div>
|
</div>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,11 +2,20 @@
|
|||||||
$is_reply = (isset($is_reply) && $is_reply);
|
$is_reply = (isset($is_reply) && $is_reply);
|
||||||
@endphp
|
@endphp
|
||||||
|
|
||||||
<li class="photo-comment" data-comment-id="{{ $comment->id }}">
|
<div class="card photo-comment mt-2" data-comment-id="{{ $comment->id }}"@if (!$is_reply) style="margin-left: {{ $comment->depth() * 20 }}px;"@endif>
|
||||||
Comment by <b>{{ $comment->createdBy->name }}</b>:<br/>
|
<div class="card-body">
|
||||||
{{ $comment->comment_text }}
|
<h5 class="card-title"><b>{{ $comment->authorDisplayName() }}</b>:</h5>
|
||||||
|
<h6 class="card-subtitle mb-2 text-muted">{{ date(UserConfig::get('date_format'), strtotime($comment->created_at)) }}</h6>
|
||||||
|
<p>{!! $comment->textAsHtml() !!}</p>
|
||||||
|
|
||||||
@if (!$is_reply && $comment->depth() < UserConfig::get('photo_comments_thread_depth'))
|
@if (!$is_reply && $comment->depth() < UserConfig::get('photo_comments_thread_depth'))
|
||||||
<p><button v-on:click="replyToComment" class="btn btn-sm btn-outline-primary">@lang('gallery.photo_comments_reply_action')</button></p>
|
<a href="{{ $photo->replyToCommentFormUrl($comment->id) }}" v-on:click="replyToComment" class="card-link">@lang('gallery.photo_comments_reply_action')</a>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
@if (!$is_reply)
|
||||||
|
@foreach ($comment->approvedChildren as $childComment)
|
||||||
|
@include(Theme::viewName('partials.photo_single_comment'), ['comment' => $childComment])
|
||||||
|
@endforeach
|
||||||
@endif
|
@endif
|
||||||
</li>
|
|
Loading…
Reference in New Issue
Block a user