Init
This commit is contained in:
91
resources/views/vendor/comments/_comment.blade.php
vendored
Normal file
91
resources/views/vendor/comments/_comment.blade.php
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
@inject('markdown', 'Parsedown')
|
||||
@php
|
||||
// TODO: There should be a better place for this.
|
||||
$markdown->setSafeMode(true);
|
||||
@endphp
|
||||
|
||||
|
||||
<div id="comment-{{ $comment->getKey() }}" class="flex rounded-lg p-1 mb-2 ">
|
||||
|
||||
<a class="contents" href="{{ route('user.index', ['username' => $comment->commenter->username]) }}">
|
||||
@if($comment->commenter->avatar)
|
||||
<img class="w-12 h-12 rounded-lg m-2" src="https://external-content.duckduckgo.com/iu/?u=https://cdn.discordapp.com/avatars/{{ $comment->commenter->id }}/{{ $comment->commenter->avatar }}.webp" alt="{{ $comment->commenter->global_name ?? $comment->commenter->username }} Avatar">
|
||||
@else
|
||||
<img class="w-12 h-12 rounded-lg m-2" src="/images/default-avatar.webp" alt="{{ $comment->commenter->global_name ?? $comment->commenter->username }} Avatar">
|
||||
@endif
|
||||
</a>
|
||||
|
||||
<div class="text-gray-800 dark:text-gray-200">
|
||||
<a href="{{ route('user.index', ['username' => $comment->commenter->username]) }}">
|
||||
@if($comment->commenter->is_patreon)
|
||||
<h5 class="text-gray-800 dark:text-gray-400">{{ $comment->commenter->global_name ?? $comment->commenter->username }} <a data-te-toggle="tooltip" title="Badge of appreciation for the horny people supporting us! :3"><i class="fa-solid fa-hand-holding-heart text-rose-600 animate-pulse"></i></a> <small class="text-muted">- {{ $comment->created_at->diffForHumans() }}</small></h5>
|
||||
@else
|
||||
<h5 class="text-gray-800 dark:text-gray-400">{{ $comment->commenter->global_name ?? $comment->commenter->username }} <small class="text-muted">- {{ $comment->created_at->diffForHumans() }}</small></h5>
|
||||
@endif
|
||||
</a>
|
||||
<div style="white-space: pre-wrap;">{!! $markdown->line($comment->comment) !!}</div>
|
||||
|
||||
@if (! Illuminate\Support\Facades\Route::is('profile.comments'))
|
||||
<div>
|
||||
@can('reply-to-comment', $comment)
|
||||
<button data-te-toggle="modal" data-te-target="#reply-modal-{{ $comment->getKey() }}" class="inline-flex items-center px-4 py-2 mt-2 dark:focus:ring-offset-gray-800 bg-rose-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-rose-700 focus:bg-rose-700 active:bg-rose-900 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2 transition ease-in-out duration-150">@lang('comments::comments.reply')</button>
|
||||
@endcan
|
||||
@can('edit-comment', $comment)
|
||||
<button data-te-toggle="modal" data-te-target="#comment-modal-{{ $comment->getKey() }}" class="inline-flex items-center px-4 py-2 mt-2 dark:focus:ring-offset-gray-800 bg-rose-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-rose-700 focus:bg-rose-700 active:bg-rose-900 focus:outline-none focus:ring-2 focus:ring-rose-500 focus:ring-offset-2 transition ease-in-out duration-150">@lang('comments::comments.edit')</button>
|
||||
@endcan
|
||||
@can('delete-comment', $comment)
|
||||
<a href="{{ route('comments.destroy', $comment->getKey()) }}" onclick="event.preventDefault();document.getElementById('comment-delete-form-{{ $comment->getKey() }}').submit();" class="inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 dark:focus:ring-offset-gray-800 transition ease-in-out duration-150 mt-2">@lang('comments::comments.delete')</a>
|
||||
<form id="comment-delete-form-{{ $comment->getKey() }}" action="{{ route('comments.destroy', $comment->getKey()) }}" method="POST" style="display: none;">
|
||||
@method('DELETE')
|
||||
@csrf
|
||||
</form>
|
||||
@endcan
|
||||
</div>
|
||||
@endif
|
||||
|
||||
|
||||
@can('edit-comment', $comment)
|
||||
@include('modals.comment-edit')
|
||||
@endcan
|
||||
|
||||
@can('reply-to-comment', $comment)
|
||||
@include('modals.comment-reply')
|
||||
@endcan
|
||||
|
||||
<br />{{-- Margin bottom --}}
|
||||
|
||||
<?php
|
||||
if (!isset($indentationLevel)) {
|
||||
$indentationLevel = 1;
|
||||
} else {
|
||||
$indentationLevel++;
|
||||
}
|
||||
?>
|
||||
|
||||
{{-- Recursion for children --}}
|
||||
@if($grouped_comments->has($comment->getKey()) && $indentationLevel <= $maxIndentationLevel)
|
||||
{{-- TODO: Don't repeat code. Extract to a new file and include it. --}}
|
||||
@foreach($grouped_comments[$comment->getKey()] as $child)
|
||||
<div class="flex">
|
||||
<div class="h-[100px] bg-rose-600 w-[4px] rounded-lg"></div>
|
||||
@include('comments::_comment', [
|
||||
'comment' => $child,
|
||||
'grouped_comments' => $grouped_comments
|
||||
])
|
||||
</div>
|
||||
@endforeach
|
||||
@endif
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{-- Recursion for children --}}
|
||||
@if($grouped_comments->has($comment->getKey()) && $indentationLevel > $maxIndentationLevel)
|
||||
{{-- TODO: Don't repeat code. Extract to a new file and include it. --}}
|
||||
@foreach($grouped_comments[$comment->getKey()] as $child)
|
||||
@include('comments::_comment', [
|
||||
'comment' => $child,
|
||||
'grouped_comments' => $grouped_comments
|
||||
])
|
||||
@endforeach
|
||||
@endif
|
30
resources/views/vendor/comments/_form.blade.php
vendored
Normal file
30
resources/views/vendor/comments/_form.blade.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
|
||||
<div class="pt-5">
|
||||
@if($errors->has('commentable_type'))
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{ $errors->first('commentable_type') }}
|
||||
</div>
|
||||
@endif
|
||||
@if($errors->has('commentable_id'))
|
||||
<div class="alert alert-danger" role="alert">
|
||||
{{ $errors->first('commentable_id') }}
|
||||
</div>
|
||||
@endif
|
||||
<form class="block rounded-lg p-6 dark:bg-neutral-700/40" method="POST" action="{{ route('comments.store') }}">
|
||||
@csrf
|
||||
@honeypot
|
||||
<input type="hidden" name="commentable_type" value="\{{ get_class($model) }}" />
|
||||
<input type="hidden" name="commentable_id" value="{{ $model->getKey() }}" />
|
||||
|
||||
<div class="pb-5">
|
||||
<label class="mb-2 text-xl font-medium leading-tight text-gray-800 dark:text-gray-200 w-full" for="message">@lang('comments::comments.enter_your_message_here')</label>
|
||||
<textarea class="peer block min-h-[auto] w-full border-1 bg-transparent px-3 py-[0.32rem] leading-[1.6] outline-none transition-all duration-200 ease-linear dark:placeholder:text-neutral-200 border-gray-300 dark:border-neutral-950 dark:bg-neutral-900 dark:text-gray-300 focus:border-rose-500 dark:focus:border-rose-600 focus:ring-rose-500 dark:focus:ring-rose-600 rounded-md shadow-sm @if($errors->has('message')) is-invalid @endif" name="message" rows="3"></textarea>
|
||||
</div>
|
||||
|
||||
<x-primary-button>
|
||||
@lang('comments::comments.submit')
|
||||
</x-primary-button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<br />
|
80
resources/views/vendor/comments/components/comments.blade.php
vendored
Normal file
80
resources/views/vendor/comments/components/comments.blade.php
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
@php
|
||||
if (isset($approved) and $approved == true) {
|
||||
$comments = $model->approvedComments;
|
||||
} else {
|
||||
$comments = $model->comments;
|
||||
}
|
||||
@endphp
|
||||
|
||||
@if($comments->count() < 1)
|
||||
<div class="mb-4 rounded-lg text-black px-6 py-5 text-base dark:text-neutral-50 bg-white dark:bg-neutral-700/40">@lang('comments::comments.there_are_no_comments')</div>
|
||||
@endif
|
||||
|
||||
<div>
|
||||
@php
|
||||
$comments = $comments->sortByDesc('created_at');
|
||||
|
||||
if (isset($perPage)) {
|
||||
$page = request()->query('page', 1) - 1;
|
||||
|
||||
$parentComments = $comments->where('child_id', '');
|
||||
|
||||
$slicedParentComments = $parentComments->slice($page * $perPage, $perPage);
|
||||
|
||||
$m = Config::get('comments.model'); // This has to be done like this, otherwise it will complain.
|
||||
$modelKeyName = (new $m)->getKeyName(); // This defaults to 'id' if not changed.
|
||||
|
||||
$slicedParentCommentsIds = $slicedParentComments->pluck($modelKeyName)->toArray();
|
||||
|
||||
// Remove parent Comments from comments.
|
||||
$comments = $comments->where('child_id', '!=', '');
|
||||
|
||||
$grouped_comments = new \Illuminate\Pagination\LengthAwarePaginator(
|
||||
$slicedParentComments->merge($comments)->groupBy('child_id'),
|
||||
$parentComments->count(),
|
||||
$perPage
|
||||
);
|
||||
|
||||
$grouped_comments->withPath(request()->url());
|
||||
} else {
|
||||
$grouped_comments = $comments->groupBy('child_id');
|
||||
}
|
||||
@endphp
|
||||
@foreach($grouped_comments as $comment_id => $comments)
|
||||
{{-- Process parent nodes --}}
|
||||
@if($comment_id == '')
|
||||
@foreach($comments as $comment)
|
||||
@include('comments::_comment', [
|
||||
'comment' => $comment,
|
||||
'grouped_comments' => $grouped_comments,
|
||||
'maxIndentationLevel' => $maxIndentationLevel ?? 3
|
||||
])
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
@isset ($perPage)
|
||||
{{ $grouped_comments->links() }}
|
||||
@endisset
|
||||
|
||||
@if ((! Illuminate\Support\Facades\Route::is('profile.comments')) && (! Illuminate\Support\Facades\Route::is('home.index')))
|
||||
@auth
|
||||
@include('comments::_form')
|
||||
@elseif(Config::get('comments.guest_commenting') == true)
|
||||
@include('comments::_form', [
|
||||
'guest_commenting' => true
|
||||
])
|
||||
@else
|
||||
<div class="block rounded-lg p-6 shadow-[0_2px_15px_-3px_rgba(0,0,0,0.07),0_10px_20px_-2px_rgba(0,0,0,0.04)] bg-white dark:bg-neutral-700/40">
|
||||
<div class="card-body">
|
||||
<h5 class="mb-2 text-xl font-medium leading-tight text-gray-800 dark:text-gray-200 w-full">@lang('comments::comments.authentication_required')</h5>
|
||||
<p class="mb-2 leading-tight text-gray-800 dark:text-gray-200 w-full">@lang('comments::comments.you_must_login_to_post_a_comment')</p>
|
||||
<br>
|
||||
<a href="{{ route('login') }}" class="relative bg-blue-700 hover:bg-blue-600 text-white font-bold px-6 h-10 rounded pt-2 pb-2" style="width: 12px">
|
||||
<i class="fa-brands fa-discord"></i> Login
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@endauth
|
||||
@endif
|
110
resources/views/vendor/pagination/tailwind.blade.php
vendored
Normal file
110
resources/views/vendor/pagination/tailwind.blade.php
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex items-center justify-between">
|
||||
<div class="flex justify-between flex-1 sm:hidden">
|
||||
@if ($paginator->onFirstPage())
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 dark:text-neutral-800 bg-white dark:bg-neutral-900 border border-gray-300 dark:border-neutral-800 cursor-default leading-5 rounded-md">
|
||||
{!! __('pagination.previous') !!}
|
||||
</span>
|
||||
@else
|
||||
<a wire:click="previousPage" class="relative cursor-pointer inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 dark:text-gray-500 bg-white dark:bg-neutral-950 border border-gray-300 dark:border-neutral-800 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
{!! __('pagination.previous') !!}
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if ($paginator->hasMorePages())
|
||||
<a wire:click="nextPage" class="relative cursor-pointer inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-white dark:bg-neutral-950 border border-gray-300 dark:border-neutral-800 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
|
||||
{!! __('pagination.next') !!}
|
||||
</a>
|
||||
@else
|
||||
<span class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-white dark:bg-neutral-900 border border-gray-300 dark:border-neutral-800 cursor-default leading-5 rounded-md">
|
||||
{!! __('pagination.next') !!}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="hidden sm:flex-1 sm:grid sm:justify-between grid-cols-1 text-center">
|
||||
<div></div>
|
||||
<div>
|
||||
<div>
|
||||
<span class="relative z-0 inline-flex shadow-sm rounded-md">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
|
||||
<span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 dark:text-neutral-800 bg-white dark:bg-neutral-900 border border-gray-300 dark:border-neutral-800 cursor-default rounded-l-md leading-5" aria-hidden="true">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
@else
|
||||
<a wire:click="previousPage" @click="scrollTo({top: 0, behavior: 'smooth'})" rel="prev" class="relative cursor-pointer inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 dark:bg-neutral-950 bg-white border border-gray-300 dark:border-neutral-800 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<span aria-disabled="true">
|
||||
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white dark:bg-neutral-950 border border-gray-300 dark:border-neutral-800 cursor-default leading-5">{{ $element }}</span>
|
||||
</span>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<span aria-current="page">
|
||||
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 dark:text-rose-600 bg-white dark:bg-neutral-950 border border-gray-300 dark:border-neutral-800 cursor-default leading-5">{{ $page }}</span>
|
||||
</span>
|
||||
@else
|
||||
<a wire:click="gotoPage({{ $page }})" @click="scrollTo({top: 0, behavior: 'smooth'})" class="relative cursor-pointer inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 dark:text-neutral-400 bg-white dark:bg-neutral-950 border border-gray-300 dark:border-neutral-800 leading-5 hover:text-neutral-500 focus:z-10 focus:outline-none focus:ring ring-rose-600 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
|
||||
{{ $page }}
|
||||
</a>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<a wire:click="nextPage" @click="scrollTo({top: 0, behavior: 'smooth'})" rel="next" class="relative cursor-pointer inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white dark:bg-neutral-950 border border-gray-300 dark:border-neutral-800 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
@else
|
||||
<span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
|
||||
<span class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white dark:bg-neutral-900 border border-gray-300 dark:border-neutral-800 cursor-default rounded-r-md leading-5" aria-hidden="true">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="w-[100%]">
|
||||
<p class="text-sm text-gray-700 dark:text-white leading-5">
|
||||
{!! __('search.showing') !!}
|
||||
@if ($paginator->firstItem())
|
||||
<span class="font-medium">{{ $paginator->firstItem() }}</span>
|
||||
{!! __('search.to') !!}
|
||||
<span class="font-medium">{{ $paginator->lastItem() }}</span>
|
||||
@else
|
||||
{{ $paginator->count() }}
|
||||
@endif
|
||||
{!! __('search.of') !!}
|
||||
<span class="font-medium">{{ $paginator->total() }}</span>
|
||||
{!! __('search.results') !!}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div></div>
|
||||
</div>
|
||||
</nav>
|
||||
@endif
|
44
resources/views/vendor/sweetalert/alert.blade.php
vendored
Normal file
44
resources/views/vendor/sweetalert/alert.blade.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
@if (config('sweetalert.alwaysLoadJS') === true || Session::has('alert.config') || Session::has('alert.delete'))
|
||||
@if (config('sweetalert.animation.enable'))
|
||||
<link rel="stylesheet" href="{{ config('sweetalert.animatecss') }}">
|
||||
@endif
|
||||
|
||||
@if (config('sweetalert.theme') != 'default')
|
||||
<link href="https://cdn.jsdelivr.net/npm/@sweetalert2/theme-{{ config('sweetalert.theme') }}" rel="stylesheet">
|
||||
@endif
|
||||
|
||||
@if (config('sweetalert.neverLoadJS') === false)
|
||||
<script src="{{ $cdn ?? asset('vendor/sweetalert/sweetalert.all.js') }}"></script>
|
||||
@endif
|
||||
|
||||
@if (Session::has('alert.delete') || Session::has('alert.config'))
|
||||
<script>
|
||||
document.addEventListener('click', function(event) {
|
||||
// Check if the clicked element or its parent has the attribute
|
||||
var target = event.target;
|
||||
var confirmDeleteElement = target.closest('[data-confirm-delete]');
|
||||
|
||||
if (confirmDeleteElement) {
|
||||
event.preventDefault();
|
||||
Swal.fire({!! Session::pull('alert.delete') !!}).then(function(result) {
|
||||
if (result.isConfirmed) {
|
||||
var form = document.createElement('form');
|
||||
form.action = confirmDeleteElement.href;
|
||||
form.method = 'POST';
|
||||
form.innerHTML = `
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
`;
|
||||
document.body.appendChild(form);
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@if (Session::has('alert.config'))
|
||||
Swal.fire({!! Session::pull('alert.config') !!});
|
||||
@endif
|
||||
</script>
|
||||
@endif
|
||||
@endif
|
Reference in New Issue
Block a user