Merge photo comments feature #114
@ -113,6 +113,7 @@ class ConfigHelper
|
|||||||
'items_per_page' => 12,
|
'items_per_page' => 12,
|
||||||
'items_per_page_admin' => 10,
|
'items_per_page_admin' => 10,
|
||||||
'photo_comments_require_login' => true,
|
'photo_comments_require_login' => true,
|
||||||
|
'photo_comments_thread_depth' => 3,
|
||||||
'public_statistics' => true,
|
'public_statistics' => true,
|
||||||
'recaptcha_enabled_registration' => false,
|
'recaptcha_enabled_registration' => false,
|
||||||
'recaptcha_secret_key' => '',
|
'recaptcha_secret_key' => '',
|
||||||
|
@ -254,6 +254,7 @@ class DefaultController extends Controller
|
|||||||
'facebook_app_secret',
|
'facebook_app_secret',
|
||||||
'google_app_id',
|
'google_app_id',
|
||||||
'google_app_secret',
|
'google_app_secret',
|
||||||
|
'photo_comments_thread_depth',
|
||||||
'sender_address',
|
'sender_address',
|
||||||
'sender_name',
|
'sender_name',
|
||||||
'smtp_server',
|
'smtp_server',
|
||||||
|
@ -26,4 +26,23 @@ class PhotoComment extends Model
|
|||||||
{
|
{
|
||||||
return $this->belongsTo(User::class, 'created_user_id');
|
return $this->belongsTo(User::class, 'created_user_id');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function depth()
|
||||||
|
{
|
||||||
|
$depth = 0;
|
||||||
|
$current = $this;
|
||||||
|
|
||||||
|
while (!is_null($current->parent))
|
||||||
|
{
|
||||||
|
$current = $current->parent;
|
||||||
|
$depth++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function parent()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(PhotoComment::class, 'parent_comment_id');
|
||||||
|
}
|
||||||
}
|
}
|
22
resources/assets/js/gallery.js
Normal file
22
resources/assets/js/gallery.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* This model is used by gallery/photo.blade.php, to handle comments and individual photo actions.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function PhotoViewModel() {
|
||||||
|
this.el = '#photo-app';
|
||||||
|
|
||||||
|
this.data = {
|
||||||
|
is_reply_form_loading: false,
|
||||||
|
reply_comment_id: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
this.methods = {
|
||||||
|
replyToComment: function(e) {
|
||||||
|
var replyButton = $(e.target).closest('.photo-comment');
|
||||||
|
this.reply_comment_id = replyButton.data('comment-id');
|
||||||
|
|
||||||
|
this.is_reply_form_loading = true;
|
||||||
|
$('#comment-reply-modal').modal('show');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -202,6 +202,15 @@ return [
|
|||||||
'security_heading' => 'Permissions',
|
'security_heading' => 'Permissions',
|
||||||
'security_text' => 'You can assign permissions on this album to either groups (recommended) or directly to users.',
|
'security_text' => 'You can assign permissions on this album to either groups (recommended) or directly to users.',
|
||||||
'security_users_heading' => 'User Permissions',
|
'security_users_heading' => 'User Permissions',
|
||||||
|
'select_all_action' => 'Select all',
|
||||||
|
'select_all_album_active' => 'Any action you select in the list below will apply to all photos in this album.',
|
||||||
|
'select_all_choice' => [
|
||||||
|
'all_action' => 'All in this album',
|
||||||
|
'message' => 'Do you want to select all the photos in the album, or just those that are visible on this page?',
|
||||||
|
'title' => 'Select all in album?',
|
||||||
|
'visible_action' => 'Only those visible'
|
||||||
|
],
|
||||||
|
'select_none_action' => 'Clear selection',
|
||||||
'settings' => [
|
'settings' => [
|
||||||
'albums_menu_heading' => 'Albums Navigation Menu',
|
'albums_menu_heading' => 'Albums Navigation Menu',
|
||||||
'albums_menu_number_items' => 'Number of albums to display:',
|
'albums_menu_number_items' => 'Number of albums to display:',
|
||||||
@ -213,6 +222,7 @@ return [
|
|||||||
'analytics_enable_visitor_hits' => 'Enable built-in visitor hit tracking',
|
'analytics_enable_visitor_hits' => 'Enable built-in visitor hit tracking',
|
||||||
'analytics_enable_visitor_hits_description' => 'Visitor hits to the public gallery will be recorded in the Blue Twilight database, allowing for analysis such as the most popular album/photo.',
|
'analytics_enable_visitor_hits_description' => 'Visitor hits to the public gallery will be recorded in the Blue Twilight database, allowing for analysis such as the most popular album/photo.',
|
||||||
'analytics_tab' => 'Analytics',
|
'analytics_tab' => 'Analytics',
|
||||||
|
'comments_tab' => 'Comments',
|
||||||
'permissions_cache' => 'Permissions Cache',
|
'permissions_cache' => 'Permissions Cache',
|
||||||
'permissions_cache_intro' => 'Blue Twilight maintains the permissions each user has to albums in the database. If you feel these aren\'t correct based on what\'s configured, you can rebuild the cache by clicking the button below.',
|
'permissions_cache_intro' => 'Blue Twilight maintains the permissions each user has to albums in the database. If you feel these aren\'t correct based on what\'s configured, you can rebuild the cache by clicking the button below.',
|
||||||
'rebuild_permissions_cache' => 'Rebuild Permissions Cache',
|
'rebuild_permissions_cache' => 'Rebuild Permissions Cache',
|
||||||
@ -225,15 +235,6 @@ return [
|
|||||||
'social_tab' => 'Social',
|
'social_tab' => 'Social',
|
||||||
'social_twitter' => 'Twitter'
|
'social_twitter' => 'Twitter'
|
||||||
],
|
],
|
||||||
'select_all_action' => 'Select all',
|
|
||||||
'select_all_album_active' => 'Any action you select in the list below will apply to all photos in this album.',
|
|
||||||
'select_all_choice' => [
|
|
||||||
'all_action' => 'All in this album',
|
|
||||||
'message' => 'Do you want to select all the photos in the album, or just those that are visible on this page?',
|
|
||||||
'title' => 'Select all in album?',
|
|
||||||
'visible_action' => 'Only those visible'
|
|
||||||
],
|
|
||||||
'select_none_action' => 'Clear selection',
|
|
||||||
'settings_email_tab' => 'E-mail',
|
'settings_email_tab' => 'E-mail',
|
||||||
'settings_general_tab' => 'General',
|
'settings_general_tab' => 'General',
|
||||||
'settings_security_tab' => 'Security',
|
'settings_security_tab' => 'Security',
|
||||||
|
@ -52,6 +52,8 @@ return [
|
|||||||
'select_current_text' => '(current)',
|
'select_current_text' => '(current)',
|
||||||
'settings_allow_photo_comments' => 'Allow comments on photos',
|
'settings_allow_photo_comments' => 'Allow comments on photos',
|
||||||
'settings_allow_photo_comments_help' => 'With this option enabled, users can comment on individual photos.',
|
'settings_allow_photo_comments_help' => 'With this option enabled, users can comment on individual photos.',
|
||||||
|
'settings_photo_comments_thread_depth' => 'Maximum depth for nested comments:',
|
||||||
|
'settings_photo_comments_thread_depth_help' => 'Set to zero to disable nested comments.',
|
||||||
'settings_photo_comments_require_login' => 'Require login before posting comments',
|
'settings_photo_comments_require_login' => 'Require login before posting comments',
|
||||||
'settings_photo_comments_require_login_help' => 'If this option is enabled, users must login before they can post comments.',
|
'settings_photo_comments_require_login_help' => 'If this option is enabled, users must login before they can post comments.',
|
||||||
'settings_hotlink_protection' => 'Prevent hot-linking to images',
|
'settings_hotlink_protection' => 'Prevent hot-linking to images',
|
||||||
|
@ -35,8 +35,10 @@ return [
|
|||||||
'other_albums_heading' => 'More Albums in :album_name',
|
'other_albums_heading' => 'More Albums in :album_name',
|
||||||
'photo_comment_posted_successfully' => 'Your comment was posted successfully and will appear after it has been moderated.',
|
'photo_comment_posted_successfully' => 'Your comment was posted successfully and will appear after it has been moderated.',
|
||||||
'photo_comments_heading' => 'Comments',
|
'photo_comments_heading' => 'Comments',
|
||||||
|
'photo_comments_reply_action' => 'Reply',
|
||||||
'photo_comments_reply_form_heading' => 'Leave a reply',
|
'photo_comments_reply_form_heading' => 'Leave a reply',
|
||||||
'photo_comments_reply_form_p1' => 'Complete the form below to start a new reply thread.',
|
'photo_comments_reply_form_p1' => 'Complete the form below to start a new reply thread.',
|
||||||
|
'photo_comments_reply_modal_title' => 'Reply to comment',
|
||||||
'photos' => 'photo|photos',
|
'photos' => 'photo|photos',
|
||||||
'previous_button' => '« Previous Photo',
|
'previous_button' => '« Previous Photo',
|
||||||
'show_more_albums' => '... and :count other|... and :count others',
|
'show_more_albums' => '... and :count other|... and :count others',
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
@include(Theme::viewName('partials.tab'), ['active_tab' => 'general', 'tab_name' => 'security', 'tab_icon' => 'lock', 'tab_text' => trans('admin.settings_security_tab')])
|
@include(Theme::viewName('partials.tab'), ['active_tab' => 'general', 'tab_name' => 'security', 'tab_icon' => 'lock', 'tab_text' => trans('admin.settings_security_tab')])
|
||||||
@include(Theme::viewName('partials.tab'), ['active_tab' => 'general', 'tab_name' => 'analytics', 'tab_icon' => 'line-chart', 'tab_text' => trans('admin.settings.analytics_tab')])
|
@include(Theme::viewName('partials.tab'), ['active_tab' => 'general', 'tab_name' => 'analytics', 'tab_icon' => 'line-chart', 'tab_text' => trans('admin.settings.analytics_tab')])
|
||||||
@include(Theme::viewName('partials.tab'), ['active_tab' => 'general', 'tab_name' => 'social', 'tab_icon' => 'users', 'tab_text' => trans('admin.settings.social_tab')])
|
@include(Theme::viewName('partials.tab'), ['active_tab' => 'general', 'tab_name' => 'social', 'tab_icon' => 'users', 'tab_text' => trans('admin.settings.social_tab')])
|
||||||
|
@include(Theme::viewName('partials.tab'), ['active_tab' => 'general', 'tab_name' => 'comments', 'tab_icon' => 'edit', 'tab_text' => trans('admin.settings.comments_tab')])
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
{{-- Tab panes --}}
|
{{-- Tab panes --}}
|
||||||
@ -329,22 +330,6 @@
|
|||||||
|
|
||||||
{{-- Social --}}
|
{{-- Social --}}
|
||||||
<div role="tabpanel" class="tab-pane" id="social-tab">
|
<div role="tabpanel" class="tab-pane" id="social-tab">
|
||||||
<div class="form-check">
|
|
||||||
<input type="checkbox" class="form-check-input" id="allow-photo-comments" name="allow_photo_comments" @if (old('allow_photo_comments', UserConfig::get('allow_photo_comments')))checked="checked"@endif>
|
|
||||||
<label class="form-check-label" for="allow-photo-comments">
|
|
||||||
<strong>@lang('forms.settings_allow_photo_comments')</strong><br/>
|
|
||||||
@lang('forms.settings_allow_photo_comments_help')
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check mt-3">
|
|
||||||
<input type="checkbox" class="form-check-input" id="photo-comments-require-login" name="photo_comments_require_login" @if (old('photo_comments_require_login', UserConfig::get('photo_comments_require_login')))checked="checked"@endif>
|
|
||||||
<label class="form-check-label" for="photo-comments-require-login">
|
|
||||||
<strong>@lang('forms.settings_photo_comments_require_login')</strong><br/>
|
|
||||||
@lang('forms.settings_photo_comments_require_login_help')
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="form-check mt-3">
|
<div class="form-check mt-3">
|
||||||
<input type="checkbox" class="form-check-input" id="social-user-profiles" name="social_user_profiles" @if (old('social_user_profiles', UserConfig::get('social_user_profiles')))checked="checked"@endif>
|
<input type="checkbox" class="form-check-input" id="social-user-profiles" name="social_user_profiles" @if (old('social_user_profiles', UserConfig::get('social_user_profiles')))checked="checked"@endif>
|
||||||
<label class="form-check-label" for="social-user-profiles">
|
<label class="form-check-label" for="social-user-profiles">
|
||||||
@ -492,6 +477,37 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{-- Comments tab --}}
|
||||||
|
<div role="tabpanel" class="tab-pane" id="comments-tab">
|
||||||
|
<div class="form-check">
|
||||||
|
<input type="checkbox" class="form-check-input" id="allow-photo-comments" name="allow_photo_comments" @if (old('allow_photo_comments', UserConfig::get('allow_photo_comments')))checked="checked"@endif>
|
||||||
|
<label class="form-check-label" for="allow-photo-comments">
|
||||||
|
<strong>@lang('forms.settings_allow_photo_comments')</strong><br/>
|
||||||
|
@lang('forms.settings_allow_photo_comments_help')
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-check mt-3">
|
||||||
|
<input type="checkbox" class="form-check-input" id="photo-comments-require-login" name="photo_comments_require_login" @if (old('photo_comments_require_login', UserConfig::get('photo_comments_require_login')))checked="checked"@endif>
|
||||||
|
<label class="form-check-label" for="photo-comments-require-login">
|
||||||
|
<strong>@lang('forms.settings_photo_comments_require_login')</strong><br/>
|
||||||
|
@lang('forms.settings_photo_comments_require_login_help')
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group mt-3">
|
||||||
|
<label class="form-control-label" for="photo-comments-thread-depth">@lang('forms.settings_photo_comments_thread_depth')</label>
|
||||||
|
<input type="text" class="form-control{{ $errors->has('photo_comments_thread_depth') ? ' is-invalid' : '' }}" id="photo-comments-thread-depth" name="photo_comments_thread_depth" value="{{ old('photo_comments_thread_depth', $config['photo_comments_thread_depth']) }}" style="max-width: 100px;">
|
||||||
|
<small class="form-text text-muted">@lang('forms.settings_photo_comments_thread_depth_help')</small>
|
||||||
|
|
||||||
|
@if ($errors->has('photo_comments_thread_depth'))
|
||||||
|
<div class="invalid-feedback">
|
||||||
|
<strong>{{ $errors->first('photo_comments_thread_depth') }}</strong>
|
||||||
|
</div>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="pull-right" style="margin-top: 15px;">
|
<div class="pull-right" style="margin-top: 15px;">
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="container">
|
<div class="container" id="photo-app">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<h1>{{ $photo->name }}</h1>
|
<h1>{{ $photo->name }}</h1>
|
||||||
@ -157,4 +157,14 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
var photoViewModel = new PhotoViewModel();
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
var app = new Vue(photoViewModel);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
@ -10,12 +10,32 @@
|
|||||||
@if ($photo->approvedComments()->count() > 0)
|
@if ($photo->approvedComments()->count() > 0)
|
||||||
<ul>
|
<ul>
|
||||||
@foreach ($photo->approvedComments as $comment)
|
@foreach ($photo->approvedComments as $comment)
|
||||||
<li>
|
@include(Theme::viewName('partials.photo_single_comment'))
|
||||||
Comment by <b>{{ $comment->createdBy->name }}</b>:<br/>
|
|
||||||
{{ $comment->comment_text }}
|
|
||||||
</li>
|
|
||||||
@endforeach
|
@endforeach
|
||||||
</ul>
|
</ul>
|
||||||
@endif
|
@endif
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal" tabindex="-1" role="dialog" id="comment-reply-modal">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h5 class="modal-title">@lang('gallery.photo_comments_reply_modal_title')</h5>
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<div v-if="is_reply_form_loading" class="text-center">
|
||||||
|
<p class="m-2"><img src="{{ asset('ripple.svg') }}" alt="@lang('global.please_wait')" title="@lang('global.please_wait')"></p>
|
||||||
|
<p>@lang('global.please_wait')</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer" v-if="!is_reply_form_loading">
|
||||||
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||||
|
<button type="button" class="btn btn-primary">Save changes</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
@ -0,0 +1,8 @@
|
|||||||
|
<li class="photo-comment" data-comment-id="{{ $comment->id }}">
|
||||||
|
Comment by <b>{{ $comment->createdBy->name }}</b>:<br/>
|
||||||
|
{{ $comment->comment_text }}
|
||||||
|
|
||||||
|
@if ($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>
|
||||||
|
@endif
|
||||||
|
</li>
|
Loading…
Reference in New Issue
Block a user