mirror of
https://github.com/HDInnovations/UNIT3D-Community-Edition.git
synced 2026-02-05 03:00:52 -06:00
Merge pull request #2260 from HDInnovations/Livewire-Comments
(Feature) Livewire Comments
This commit is contained in:
@@ -1,733 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* NOTICE OF LICENSE.
|
||||
*
|
||||
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
|
||||
* The details is bundled with this project in the file LICENSE.txt.
|
||||
*
|
||||
* @project UNIT3D Community Edition
|
||||
*
|
||||
* @author HDVinnie <hdinnovations@protonmail.com>
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
||||
*/
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Achievements\UserMade100Comments;
|
||||
use App\Achievements\UserMade200Comments;
|
||||
use App\Achievements\UserMade300Comments;
|
||||
use App\Achievements\UserMade400Comments;
|
||||
use App\Achievements\UserMade500Comments;
|
||||
use App\Achievements\UserMade50Comments;
|
||||
use App\Achievements\UserMade600Comments;
|
||||
use App\Achievements\UserMade700Comments;
|
||||
use App\Achievements\UserMade800Comments;
|
||||
use App\Achievements\UserMade900Comments;
|
||||
use App\Achievements\UserMadeComment;
|
||||
use App\Achievements\UserMadeTenComments;
|
||||
use App\Models\Article;
|
||||
use App\Models\Collection;
|
||||
use App\Models\Comment;
|
||||
use App\Models\Playlist;
|
||||
use App\Models\Ticket;
|
||||
use App\Models\Torrent;
|
||||
use App\Models\TorrentRequest;
|
||||
use App\Models\User;
|
||||
use App\Notifications\NewComment;
|
||||
use App\Repositories\ChatRepository;
|
||||
use App\Repositories\TaggedUserRepository;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
|
||||
/**
|
||||
* @see \Tests\Feature\Http\Controllers\CommentControllerTest
|
||||
*/
|
||||
class CommentController extends Controller
|
||||
{
|
||||
public $tag;
|
||||
|
||||
/**
|
||||
* CommentController Constructor.
|
||||
*/
|
||||
public function __construct(private readonly TaggedUserRepository $taggedUserRepository, private readonly ChatRepository $chatRepository)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Add A Comment To A Collection.
|
||||
*/
|
||||
public function collection(Request $request, int $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$collection = Collection::findOrFail($id);
|
||||
$user = $request->user();
|
||||
|
||||
if (RateLimiter::tooManyAttempts('collection-comment:'.$user->id, \config('unit3d.comment-rate-limit'))) {
|
||||
return \to_route('collection.show', ['id' => $id])
|
||||
->withErrors(\trans('comment.slow-down'));
|
||||
}
|
||||
|
||||
RateLimiter::hit('collection-comment:'.$user->id);
|
||||
|
||||
if ($user->can_comment == 0) {
|
||||
return \to_route('collection.show', ['id' => $collection->id])
|
||||
->withErrors(\trans('comment.rights-revoked'));
|
||||
}
|
||||
|
||||
$comment = new Comment();
|
||||
$comment->content = $request->input('content');
|
||||
$comment->anon = $request->input('anonymous');
|
||||
$comment->user_id = $user->id;
|
||||
$comment->collection_id = $collection->id;
|
||||
|
||||
$v = \validator($comment->toArray(), [
|
||||
'content' => 'required',
|
||||
'user_id' => 'required',
|
||||
'collection_id' => 'required',
|
||||
'anon' => 'required',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
return \to_route('collection.show', ['id' => $collection->id])
|
||||
->withErrors($v->errors());
|
||||
}
|
||||
|
||||
$comment->save();
|
||||
|
||||
$collectionUrl = \href_collection($collection);
|
||||
$profileUrl = \href_profile($user);
|
||||
|
||||
// Auto Shout
|
||||
if ($comment->anon == 0) {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('[url=%s]%s[/url] has left a comment on collection [url=%s]%s[/url]', $profileUrl, $user->username, $collectionUrl, $collection->name)
|
||||
);
|
||||
} else {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('An anonymous user has left a comment on collection [url=%s]%s[/url]', $collectionUrl, $collection->name)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->taggedUserRepository->hasTags($request->input('content'))) {
|
||||
if ($this->taggedUserRepository->contains($request->input('content'), '@here') && $user->group->is_modo) {
|
||||
$users = \collect([]);
|
||||
|
||||
$collection->comments()->get()->each(function ($c, $v) use ($users) {
|
||||
$users->push($c->user);
|
||||
});
|
||||
$this->tag->messageCommentUsers(
|
||||
'collection',
|
||||
$users,
|
||||
$user,
|
||||
'Staff',
|
||||
$comment
|
||||
);
|
||||
} else {
|
||||
$sender = $comment->anon ? 'Anonymous' : $user->username;
|
||||
$this->taggedUserRepository->messageTaggedCommentUsers(
|
||||
'collection',
|
||||
$request->input('content'),
|
||||
$user,
|
||||
$sender,
|
||||
$comment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Achievements
|
||||
if ($comment->anon == 0) {
|
||||
$user->unlock(new UserMadeComment(), 1);
|
||||
$user->addProgress(new UserMadeTenComments(), 1);
|
||||
$user->addProgress(new UserMade50Comments(), 1);
|
||||
$user->addProgress(new UserMade100Comments(), 1);
|
||||
$user->addProgress(new UserMade200Comments(), 1);
|
||||
$user->addProgress(new UserMade300Comments(), 1);
|
||||
$user->addProgress(new UserMade400Comments(), 1);
|
||||
$user->addProgress(new UserMade500Comments(), 1);
|
||||
$user->addProgress(new UserMade600Comments(), 1);
|
||||
$user->addProgress(new UserMade700Comments(), 1);
|
||||
$user->addProgress(new UserMade800Comments(), 1);
|
||||
$user->addProgress(new UserMade900Comments(), 1);
|
||||
}
|
||||
|
||||
return \to_route('mediahub.collections.show', ['id' => $collection->id, 'hash' => '#comments'])
|
||||
->withSuccess(\trans('comment.added'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store A New Comment To A Article.
|
||||
*/
|
||||
public function article(Request $request, int $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$article = Article::findOrFail($id);
|
||||
$user = $request->user();
|
||||
|
||||
if (RateLimiter::tooManyAttempts('article-comment:'.$user->id, \config('unit3d.comment-rate-limit'))) {
|
||||
return \to_route('articles.show', ['id' => $id])
|
||||
->withErrors(\trans('comment.slow-down'));
|
||||
}
|
||||
|
||||
RateLimiter::hit('article-comment:'.$user->id);
|
||||
|
||||
if ($user->can_comment == 0) {
|
||||
return \to_route('articles.show', ['id' => $article->id])
|
||||
->withErrors(\trans('comment.rights-revoked'));
|
||||
}
|
||||
|
||||
$comment = new Comment();
|
||||
$comment->content = $request->input('content');
|
||||
$comment->anon = $request->input('anonymous');
|
||||
$comment->user_id = $user->id;
|
||||
$comment->article_id = $article->id;
|
||||
|
||||
$v = \validator($comment->toArray(), [
|
||||
'content' => 'required',
|
||||
'user_id' => 'required',
|
||||
'article_id' => 'required',
|
||||
'anon' => 'required',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
return \to_route('articles.show', ['id' => $article->id])
|
||||
->withErrors($v->errors());
|
||||
}
|
||||
|
||||
$comment->save();
|
||||
$articleUrl = \href_article($article);
|
||||
$profileUrl = \href_profile($user);
|
||||
// Auto Shout
|
||||
if ($comment->anon == 0) {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('[url=%s]%s[/url] has left a comment on article [url=%s]%s[/url]', $profileUrl, $user->username, $articleUrl, $article->title)
|
||||
);
|
||||
} else {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('An anonymous user has left a comment on article [url=%s]%s[/url]', $articleUrl, $article->title)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->taggedUserRepository->hasTags($request->input('content'))) {
|
||||
if ($this->taggedUserRepository->contains($request->input('content'), '@here') && $user->group->is_modo) {
|
||||
$users = \collect([]);
|
||||
|
||||
$article->comments()->get()->each(function ($c) use ($users) {
|
||||
$users->push($c->user);
|
||||
});
|
||||
$this->taggedUserRepository->messageCommentUsers(
|
||||
'article',
|
||||
$users,
|
||||
$user,
|
||||
'Staff',
|
||||
$comment
|
||||
);
|
||||
} else {
|
||||
$sender = $comment->anon ? 'Anonymous' : $user->username;
|
||||
$this->taggedUserRepository->messageTaggedCommentUsers(
|
||||
'article',
|
||||
$request->input('content'),
|
||||
$user,
|
||||
$sender,
|
||||
$comment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Achievements
|
||||
if ($comment->anon == 0) {
|
||||
$user->unlock(new UserMadeComment(), 1);
|
||||
$user->addProgress(new UserMadeTenComments(), 1);
|
||||
$user->addProgress(new UserMade50Comments(), 1);
|
||||
$user->addProgress(new UserMade100Comments(), 1);
|
||||
$user->addProgress(new UserMade200Comments(), 1);
|
||||
$user->addProgress(new UserMade300Comments(), 1);
|
||||
$user->addProgress(new UserMade400Comments(), 1);
|
||||
$user->addProgress(new UserMade500Comments(), 1);
|
||||
$user->addProgress(new UserMade600Comments(), 1);
|
||||
$user->addProgress(new UserMade700Comments(), 1);
|
||||
$user->addProgress(new UserMade800Comments(), 1);
|
||||
$user->addProgress(new UserMade900Comments(), 1);
|
||||
}
|
||||
|
||||
return \to_route('articles.show', ['id' => $article->id])
|
||||
->withSuccess(\trans('comment.added'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store A New Comment To A Playlist.
|
||||
*/
|
||||
public function playlist(Request $request, int $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$playlist = Playlist::findOrFail($id);
|
||||
$user = $request->user();
|
||||
|
||||
if (RateLimiter::tooManyAttempts('playlist-comment:'.$user->id, \config('unit3d.comment-rate-limit'))) {
|
||||
return \to_route('playlists.show', ['id' => $id])
|
||||
->withErrors(\trans('comment.slow-down'));
|
||||
}
|
||||
|
||||
RateLimiter::hit('playlist-comment:'.$user->id);
|
||||
|
||||
if ($user->can_comment == 0) {
|
||||
return \to_route('playlists.show', ['id' => $playlist->id])
|
||||
->withErrors(\trans('comment.rights-revoked'));
|
||||
}
|
||||
|
||||
$comment = new Comment();
|
||||
$comment->content = $request->input('content');
|
||||
$comment->anon = $request->input('anonymous');
|
||||
$comment->user_id = $user->id;
|
||||
$comment->playlist_id = $playlist->id;
|
||||
|
||||
$v = \validator($comment->toArray(), [
|
||||
'content' => 'required',
|
||||
'user_id' => 'required',
|
||||
'playlist_id' => 'required',
|
||||
'anon' => 'required',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
return \to_route('playlists.show', ['id' => $playlist->id])
|
||||
->withErrors($v->errors());
|
||||
}
|
||||
|
||||
$comment->save();
|
||||
$playlistUrl = \href_playlist($playlist);
|
||||
$profileUrl = \href_profile($user);
|
||||
// Auto Shout
|
||||
if ($comment->anon == 0) {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('[url=%s]%s[/url] has left a comment on playlist [url=%s]%s[/url]', $profileUrl, $user->username, $playlistUrl, $playlist->name)
|
||||
);
|
||||
} else {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('An anonymous user has left a comment on playlist [url=%s]%s[/url]', $playlistUrl, $playlist->name)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->taggedUserRepository->hasTags($request->input('content'))) {
|
||||
if ($this->taggedUserRepository->contains($request->input('content'), '@here') && $user->group->is_modo) {
|
||||
$users = \collect([]);
|
||||
|
||||
$playlist->comments()->get()->each(function ($c) use ($users) {
|
||||
$users->push($c->user);
|
||||
});
|
||||
$this->taggedUserRepository->messageCommentUsers(
|
||||
'playlist',
|
||||
$users,
|
||||
$user,
|
||||
'Staff',
|
||||
$comment
|
||||
);
|
||||
} else {
|
||||
$sender = $comment->anon ? 'Anonymous' : $user->username;
|
||||
$this->taggedUserRepository->messageTaggedCommentUsers(
|
||||
'playlist',
|
||||
$request->input('content'),
|
||||
$user,
|
||||
$sender,
|
||||
$comment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Achievements
|
||||
if ($comment->anon == 0) {
|
||||
$user->unlock(new UserMadeComment(), 1);
|
||||
$user->addProgress(new UserMadeTenComments(), 1);
|
||||
$user->addProgress(new UserMade50Comments(), 1);
|
||||
$user->addProgress(new UserMade100Comments(), 1);
|
||||
$user->addProgress(new UserMade200Comments(), 1);
|
||||
$user->addProgress(new UserMade300Comments(), 1);
|
||||
$user->addProgress(new UserMade400Comments(), 1);
|
||||
$user->addProgress(new UserMade500Comments(), 1);
|
||||
$user->addProgress(new UserMade600Comments(), 1);
|
||||
$user->addProgress(new UserMade700Comments(), 1);
|
||||
$user->addProgress(new UserMade800Comments(), 1);
|
||||
$user->addProgress(new UserMade900Comments(), 1);
|
||||
}
|
||||
|
||||
return \to_route('playlists.show', ['id' => $playlist->id, 'hash' => '#comments'])
|
||||
->withSuccess(\trans('comment.added'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store A New Comment To A Torrent.
|
||||
*/
|
||||
public function torrent(Request $request, int $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$torrent = Torrent::findOrFail($id);
|
||||
$user = $request->user();
|
||||
|
||||
if (RateLimiter::tooManyAttempts('torrent-comment:'.$user->id, \config('unit3d.comment-rate-limit'))) {
|
||||
return \to_route('torrent', ['id' => $torrent->id])
|
||||
->withErrors(\trans('comment.slow-down'));
|
||||
}
|
||||
|
||||
RateLimiter::hit('torrent-comment:'.$user->id);
|
||||
|
||||
if ($user->can_comment == 0) {
|
||||
return \to_route('torrent', ['id' => $torrent->id])
|
||||
->withErrors(\trans('comment.rights-revoked'));
|
||||
}
|
||||
|
||||
$comment = new Comment();
|
||||
$comment->content = $request->input('content');
|
||||
$comment->anon = $request->input('anonymous');
|
||||
$comment->user_id = $user->id;
|
||||
$comment->torrent_id = $torrent->id;
|
||||
|
||||
$v = \validator($comment->toArray(), [
|
||||
'content' => 'required',
|
||||
'user_id' => 'required',
|
||||
'torrent_id' => 'required',
|
||||
'anon' => 'required',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
return \to_route('torrent', ['id' => $torrent->id])
|
||||
->withErrors($v->errors());
|
||||
}
|
||||
|
||||
$comment->save();
|
||||
//Notification
|
||||
if ($user->id != $torrent->user_id) {
|
||||
$torrent->notifyUploader('comment', $comment);
|
||||
}
|
||||
|
||||
$torrentUrl = \href_torrent($torrent);
|
||||
$profileUrl = \href_profile($user);
|
||||
// Auto Shout
|
||||
if ($comment->anon == 0) {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('[url=%s]%s[/url] has left a comment on Torrent [url=%s]%s[/url]', $profileUrl, $user->username, $torrentUrl, $torrent->name)
|
||||
);
|
||||
} else {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('An anonymous user has left a comment on torrent [url=%s]%s[/url]', $torrentUrl, $torrent->name)
|
||||
);
|
||||
}
|
||||
|
||||
if ($this->taggedUserRepository->hasTags($request->input('content'))) {
|
||||
if ($this->taggedUserRepository->contains($request->input('content'), '@here') && $user->group->is_modo) {
|
||||
$users = \collect([]);
|
||||
|
||||
$torrent->comments()->get()->each(function ($c) use ($users) {
|
||||
$users->push($c->user);
|
||||
});
|
||||
$this->taggedUserRepository->messageCommentUsers(
|
||||
'torrent',
|
||||
$users,
|
||||
$user,
|
||||
'Staff',
|
||||
$comment
|
||||
);
|
||||
} else {
|
||||
$sender = $comment->anon ? 'Anonymous' : $user->username;
|
||||
$this->taggedUserRepository->messageTaggedCommentUsers(
|
||||
'torrent',
|
||||
$request->input('content'),
|
||||
$user,
|
||||
$sender,
|
||||
$comment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Achievements
|
||||
if ($comment->anon == 0) {
|
||||
$user->unlock(new UserMadeComment(), 1);
|
||||
$user->addProgress(new UserMadeTenComments(), 1);
|
||||
$user->addProgress(new UserMade50Comments(), 1);
|
||||
$user->addProgress(new UserMade100Comments(), 1);
|
||||
$user->addProgress(new UserMade200Comments(), 1);
|
||||
$user->addProgress(new UserMade300Comments(), 1);
|
||||
$user->addProgress(new UserMade400Comments(), 1);
|
||||
$user->addProgress(new UserMade500Comments(), 1);
|
||||
$user->addProgress(new UserMade600Comments(), 1);
|
||||
$user->addProgress(new UserMade700Comments(), 1);
|
||||
$user->addProgress(new UserMade800Comments(), 1);
|
||||
$user->addProgress(new UserMade900Comments(), 1);
|
||||
}
|
||||
|
||||
return \to_route('torrent', ['id' => $torrent->id, 'hash' => '#comments'])
|
||||
->withSuccess(\trans('comment.added'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store A New Comment To A Request.
|
||||
*/
|
||||
public function request(Request $request, int $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$tr = TorrentRequest::findOrFail($id);
|
||||
$user = $request->user();
|
||||
|
||||
if (RateLimiter::tooManyAttempts('request-comment:'.$user->id, \config('unit3d.comment-rate-limit'))) {
|
||||
return \to_route('request', ['id' => $id])
|
||||
->withErrors(\trans('comment.slow-down'));
|
||||
}
|
||||
|
||||
RateLimiter::hit('request-comment:'.$user->id);
|
||||
|
||||
if ($user->can_comment == 0) {
|
||||
return \to_route('request', ['id' => $tr->id])
|
||||
->withErrors(\trans('comment.rights-revoked'));
|
||||
}
|
||||
|
||||
$comment = new Comment();
|
||||
$comment->content = $request->input('content');
|
||||
$comment->anon = $request->input('anonymous');
|
||||
$comment->user_id = $user->id;
|
||||
$comment->requests_id = $tr->id;
|
||||
|
||||
$v = \validator($comment->toArray(), [
|
||||
'content' => 'required',
|
||||
'user_id' => 'required',
|
||||
'requests_id' => 'required',
|
||||
'anon' => 'required',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
return \to_route('request', ['id' => $tr->id])
|
||||
->withErrors($v->errors());
|
||||
}
|
||||
|
||||
$comment->save();
|
||||
$trUrl = \href_request($tr);
|
||||
$profileUrl = \href_profile($user);
|
||||
// Auto Shout
|
||||
if ($comment->anon == 0) {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('[url=%s]%s[/url] has left a comment on Request [url=%s]%s[/url]', $profileUrl, $user->username, $trUrl, $tr->name)
|
||||
);
|
||||
} else {
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('An anonymous user has left a comment on Request [url=%s]%s[/url]', $trUrl, $tr->name)
|
||||
);
|
||||
}
|
||||
|
||||
//Notification
|
||||
if ($user->id != $tr->user_id) {
|
||||
$tr->notifyRequester('comment', $comment);
|
||||
}
|
||||
|
||||
if ($this->taggedUserRepository->hasTags($request->input('content'))) {
|
||||
if ($this->taggedUserRepository->contains($request->input('content'), '@here') && $user->group->is_modo) {
|
||||
$users = \collect([]);
|
||||
|
||||
$tr->comments()->get()->each(function ($c) use ($users) {
|
||||
$users->push($c->user);
|
||||
});
|
||||
$this->taggedUserRepository->messageCommentUsers(
|
||||
'request',
|
||||
$users,
|
||||
$user,
|
||||
'Staff',
|
||||
$comment
|
||||
);
|
||||
} else {
|
||||
$sender = $comment->anon ? 'Anonymous' : $user->username;
|
||||
$this->taggedUserRepository->messageTaggedCommentUsers(
|
||||
'request',
|
||||
$request->input('content'),
|
||||
$user,
|
||||
$sender,
|
||||
$comment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Achievements
|
||||
if ($comment->anon == 0) {
|
||||
$user->unlock(new UserMadeComment(), 1);
|
||||
$user->addProgress(new UserMadeTenComments(), 1);
|
||||
$user->addProgress(new UserMade50Comments(), 1);
|
||||
$user->addProgress(new UserMade100Comments(), 1);
|
||||
$user->addProgress(new UserMade200Comments(), 1);
|
||||
$user->addProgress(new UserMade300Comments(), 1);
|
||||
$user->addProgress(new UserMade400Comments(), 1);
|
||||
$user->addProgress(new UserMade500Comments(), 1);
|
||||
$user->addProgress(new UserMade600Comments(), 1);
|
||||
$user->addProgress(new UserMade700Comments(), 1);
|
||||
$user->addProgress(new UserMade800Comments(), 1);
|
||||
$user->addProgress(new UserMade900Comments(), 1);
|
||||
}
|
||||
|
||||
return \to_route('request', ['id' => $tr->id, 'hash' => '#comments'])
|
||||
->withSuccess(\trans('comment.added'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store A New Comment To A Request.
|
||||
*/
|
||||
public function ticket(Request $request, int $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$ticket = Ticket::findOrFail($id);
|
||||
$user = $request->user();
|
||||
|
||||
if (RateLimiter::tooManyAttempts('ticket-comment:'.$user->id, \config('unit3d.comment-rate-limit'))) {
|
||||
return \to_route('tickets.show', ['id' => $id])
|
||||
->withErrors(\trans('comment.slow-down'));
|
||||
}
|
||||
|
||||
RateLimiter::hit('ticket-comment:'.$user->id);
|
||||
|
||||
$comment = new Comment();
|
||||
$comment->content = $request->input('content');
|
||||
$comment->anon = 0;
|
||||
$comment->user_id = $user->id;
|
||||
$comment->ticket_id = $ticket->id;
|
||||
|
||||
$v = \validator($comment->toArray(), [
|
||||
'content' => 'required',
|
||||
'user_id' => 'required',
|
||||
'ticket_id' => 'required',
|
||||
'anon' => 'required',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
return \to_route('tickets.show', ['id' => $id])
|
||||
->withErrors($v->errors());
|
||||
}
|
||||
|
||||
if ($user->id != $ticket->user_id) {
|
||||
$ticket->user_read = 0;
|
||||
}
|
||||
|
||||
if ($user->id == $ticket->user_id) {
|
||||
$ticket->staff_read = 0;
|
||||
}
|
||||
|
||||
$comment->save();
|
||||
$ticket->save();
|
||||
|
||||
return \to_route('tickets.show', ['id' => $ticket->id])
|
||||
->withSuccess(\trans('comment.added'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Store A New Comment To A Torrent Via Quick Thanks.
|
||||
*/
|
||||
public function quickthanks(Request $request, int $id): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$torrent = Torrent::findOrFail($id);
|
||||
$user = $request->user();
|
||||
|
||||
if (RateLimiter::tooManyAttempts('torrent-comment:'.$user->id, \config('unit3d.comment-rate-limit'))) {
|
||||
return \to_route('torrent', ['id' => $torrent->id])
|
||||
->withErrors(\trans('comment.slow-down'));
|
||||
}
|
||||
|
||||
RateLimiter::hit('torrent-comment:'.$user->id);
|
||||
|
||||
if ($user->can_comment == 0) {
|
||||
return \to_route('torrent', ['id' => $torrent->id])
|
||||
->withErrors(\trans('comment.rights-revoked'));
|
||||
}
|
||||
|
||||
$comment = new Comment();
|
||||
|
||||
if ($torrent->anon === 1) {
|
||||
$thankArray = [
|
||||
'Thanks for the upload! :thumbsup_tone2:',
|
||||
'Time and effort is much appreciated :thumbsup_tone2:',
|
||||
'Great upload! :fire:', 'Thank you :smiley:',
|
||||
];
|
||||
} else {
|
||||
$uploader = User::where('id', '=', $torrent->user_id)->first();
|
||||
$uploaderUrl = \href_profile($uploader);
|
||||
|
||||
$thankArray = [
|
||||
\sprintf('Thanks for the upload [url=%s][color=%s][b]%s[/b][/color][/url] :vulcan_tone2:', $uploaderUrl, $uploader->group->color, $uploader->username),
|
||||
\sprintf('Beautiful upload [url=%s][color=%s][b]%s[/b][/color][/url] :fire:', $uploaderUrl, $uploader->group->color, $uploader->username),
|
||||
\sprintf('Cheers [url=%s][color=%s][b]%s[/b][/color][/url] for the upload :beers:', $uploaderUrl, $uploader->group->color, $uploader->username),
|
||||
];
|
||||
}
|
||||
|
||||
$selected = random_int(0, (\is_countable($thankArray) ? \count($thankArray) : 0) - 1);
|
||||
$comment->content = $thankArray[$selected];
|
||||
$comment->user_id = $user->id;
|
||||
$comment->torrent_id = $torrent->id;
|
||||
|
||||
$v = \validator($comment->toArray(), [
|
||||
'content' => 'required',
|
||||
'user_id' => 'required',
|
||||
'torrent_id' => 'required',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
return \to_route('torrent', ['id' => $torrent->id])
|
||||
->withErrors($v->errors());
|
||||
}
|
||||
|
||||
$comment->save();
|
||||
|
||||
// Achievements
|
||||
if ($comment->anon == 0) {
|
||||
$user->unlock(new UserMadeComment(), 1);
|
||||
$user->addProgress(new UserMadeTenComments(), 1);
|
||||
$user->addProgress(new UserMade50Comments(), 1);
|
||||
$user->addProgress(new UserMade100Comments(), 1);
|
||||
$user->addProgress(new UserMade200Comments(), 1);
|
||||
$user->addProgress(new UserMade300Comments(), 1);
|
||||
$user->addProgress(new UserMade400Comments(), 1);
|
||||
$user->addProgress(new UserMade500Comments(), 1);
|
||||
$user->addProgress(new UserMade600Comments(), 1);
|
||||
$user->addProgress(new UserMade700Comments(), 1);
|
||||
$user->addProgress(new UserMade800Comments(), 1);
|
||||
$user->addProgress(new UserMade900Comments(), 1);
|
||||
}
|
||||
|
||||
//Notification
|
||||
if ($user->id != $torrent->user_id) {
|
||||
User::find($torrent->user_id)->notify(new NewComment('torrent', $comment));
|
||||
}
|
||||
|
||||
// Auto Shout
|
||||
$torrentUrl = \href_torrent($torrent);
|
||||
$profileUrl = \href_profile($user);
|
||||
$this->chatRepository->systemMessage(
|
||||
\sprintf('[url=%s]%s[/url] has left a comment on Torrent [url=%s]%s[/url]', $profileUrl, $user->username, $torrentUrl, $torrent->name)
|
||||
);
|
||||
|
||||
return \to_route('torrent', ['id' => $torrent->id])
|
||||
->withSuccess(\trans('comment.added'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Edit A Comment.
|
||||
*/
|
||||
public function editComment(Request $request, int $commentId): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
$comment = Comment::findOrFail($commentId);
|
||||
|
||||
\abort_unless($user->group->is_modo || $user->id == $comment->user_id, 403);
|
||||
$comment->content = $request->input('comment-edit');
|
||||
|
||||
$v = \validator($comment->toArray(), [
|
||||
'content' => 'required',
|
||||
]);
|
||||
|
||||
if ($v->fails()) {
|
||||
return \redirect()->back()
|
||||
->withErrors($v->errors());
|
||||
}
|
||||
|
||||
$comment->save();
|
||||
|
||||
return \redirect()->back()->withSuccess(\trans('comment.edited'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete A Comment.
|
||||
*/
|
||||
public function deleteComment(Request $request, int $commentId): \Illuminate\Http\RedirectResponse
|
||||
{
|
||||
$user = $request->user();
|
||||
$comment = Comment::findOrFail($commentId);
|
||||
|
||||
\abort_unless($user->group->is_modo || $user->id == $comment->user_id, 403);
|
||||
$comment->delete();
|
||||
|
||||
return \redirect()->back()->withSuccess(\trans('comment.deleted'));
|
||||
}
|
||||
}
|
||||
190
app/Http/Livewire/Comment.php
Normal file
190
app/Http/Livewire/Comment.php
Normal file
@@ -0,0 +1,190 @@
|
||||
<?php
|
||||
/**
|
||||
* NOTICE OF LICENSE.
|
||||
*
|
||||
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
|
||||
* The details is bundled with this project in the file LICENSE.txt.
|
||||
*
|
||||
* @project UNIT3D Community Edition
|
||||
*
|
||||
* @author HDVinnie <hdinnovations@protonmail.com>
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
||||
*/
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Achievements\UserMade100Comments;
|
||||
use App\Achievements\UserMade200Comments;
|
||||
use App\Achievements\UserMade300Comments;
|
||||
use App\Achievements\UserMade400Comments;
|
||||
use App\Achievements\UserMade500Comments;
|
||||
use App\Achievements\UserMade50Comments;
|
||||
use App\Achievements\UserMade600Comments;
|
||||
use App\Achievements\UserMade700Comments;
|
||||
use App\Achievements\UserMade800Comments;
|
||||
use App\Achievements\UserMade900Comments;
|
||||
use App\Achievements\UserMadeComment;
|
||||
use App\Achievements\UserMadeTenComments;
|
||||
use App\Models\User;
|
||||
use App\Notifications\NewComment;
|
||||
use App\Repositories\TaggedUserRepository;
|
||||
use Livewire\Component;
|
||||
use voku\helper\AntiXSS;
|
||||
|
||||
class Comment extends Component
|
||||
{
|
||||
public $comment;
|
||||
|
||||
public $anon = false;
|
||||
|
||||
private TaggedUserRepository $taggedUserRepository;
|
||||
|
||||
public \Illuminate\Contracts\Auth\Authenticatable|\App\Models\User $user;
|
||||
|
||||
protected $listeners = [
|
||||
'refresh' => '$refresh',
|
||||
];
|
||||
|
||||
protected $validationAttributes = [
|
||||
'replyState.content' => 'reply',
|
||||
];
|
||||
|
||||
public $isReplying = false;
|
||||
|
||||
public $replyState = [
|
||||
'content' => '',
|
||||
];
|
||||
|
||||
public $isEditing = false;
|
||||
|
||||
public $editState = [
|
||||
'content' => '',
|
||||
];
|
||||
|
||||
final public function mount(TaggedUserRepository $taggedUserRepository): void
|
||||
{
|
||||
$this->taggedUserRepository = $taggedUserRepository;
|
||||
$this->user = \auth()->user();
|
||||
}
|
||||
|
||||
final public function updatedIsEditing($isEditing): void
|
||||
{
|
||||
if (! $isEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->editState = [
|
||||
'content' => $this->comment->content,
|
||||
];
|
||||
}
|
||||
|
||||
final public function editComment(): void
|
||||
{
|
||||
if (\auth()->user()->id !== $this->comment->user_id || ! \auth()->user()->group->is_modo) {
|
||||
$this->dispatchBrowserEvent('error', ['type' => 'error', 'message' => 'Permission Denied!']);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->comment->update((new AntiXSS())->xss_clean($this->editState));
|
||||
|
||||
$this->isEditing = false;
|
||||
}
|
||||
|
||||
final public function deleteComment(): void
|
||||
{
|
||||
if (\auth()->user()->id !== $this->comment->user_id || ! \auth()->user()->group->is_modo) {
|
||||
$this->dispatchBrowserEvent('error', ['type' => 'error', 'message' => 'Permission Denied!']);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->comment->delete();
|
||||
|
||||
$this->emitUp('refresh');
|
||||
}
|
||||
|
||||
final public function postReply(): void
|
||||
{
|
||||
if (\auth()->user()->can_comment === 0) {
|
||||
$this->dispatchBrowserEvent('error', ['type' => 'error', 'message' => \trans('comment.rights-revoked')]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (! $this->comment->isParent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->validate([
|
||||
'replyState.content' => 'required',
|
||||
]);
|
||||
|
||||
$reply = $this->comment->children()->make((new AntiXSS())->xss_clean($this->replyState));
|
||||
$reply->user()->associate(\auth()->user());
|
||||
$reply->commentable()->associate($this->comment->commentable);
|
||||
$reply->anon = $this->anon;
|
||||
$reply->save();
|
||||
|
||||
$this->replyState = [
|
||||
'content' => '',
|
||||
];
|
||||
|
||||
// Achievements
|
||||
if ($reply->anon === 0) {
|
||||
$this->user->unlock(new UserMadeComment(), 1);
|
||||
$this->user->addProgress(new UserMadeTenComments(), 1);
|
||||
$this->user->addProgress(new UserMade50Comments(), 1);
|
||||
$this->user->addProgress(new UserMade100Comments(), 1);
|
||||
$this->user->addProgress(new UserMade200Comments(), 1);
|
||||
$this->user->addProgress(new UserMade300Comments(), 1);
|
||||
$this->user->addProgress(new UserMade400Comments(), 1);
|
||||
$this->user->addProgress(new UserMade500Comments(), 1);
|
||||
$this->user->addProgress(new UserMade600Comments(), 1);
|
||||
$this->user->addProgress(new UserMade700Comments(), 1);
|
||||
$this->user->addProgress(new UserMade800Comments(), 1);
|
||||
$this->user->addProgress(new UserMade900Comments(), 1);
|
||||
}
|
||||
|
||||
//Notification
|
||||
if ($this->user->id !== $this->comment->user_id) {
|
||||
User::find($this->comment->user_id)->notify(new NewComment($this->comment, $reply));
|
||||
}
|
||||
|
||||
// Tagging
|
||||
if ($this->taggedUserRepository->hasTags($this->replyState)) {
|
||||
if ($this->user->group->is_modo && $this->taggedUserRepository->contains($this->replyState, '@here')) {
|
||||
$users = \collect([]);
|
||||
|
||||
$this->comment->children()->get()->each(function ($c) use ($users) {
|
||||
$users->push($c->user);
|
||||
});
|
||||
$this->taggedUserRepository->messageCommentUsers(
|
||||
$this->comment,
|
||||
$users,
|
||||
$this->user,
|
||||
'Staff',
|
||||
$reply
|
||||
);
|
||||
} else {
|
||||
$sender = $reply->anon !== 0 ? $this->user->username : 'Anonymous';
|
||||
$this->taggedUserRepository->messageTaggedCommentUsers(
|
||||
$this->comment,
|
||||
$this->replyState[],
|
||||
$this->user,
|
||||
$sender,
|
||||
$reply
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->isReplying = false;
|
||||
|
||||
$this->emitSelf('refresh');
|
||||
}
|
||||
|
||||
final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
|
||||
{
|
||||
return \view('livewire.comment');
|
||||
}
|
||||
}
|
||||
160
app/Http/Livewire/Comments.php
Normal file
160
app/Http/Livewire/Comments.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php
|
||||
/**
|
||||
* NOTICE OF LICENSE.
|
||||
*
|
||||
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
|
||||
* The details is bundled with this project in the file LICENSE.txt.
|
||||
*
|
||||
* @project UNIT3D Community Edition
|
||||
*
|
||||
* @author HDVinnie <hdinnovations@protonmail.com>
|
||||
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
|
||||
*/
|
||||
|
||||
namespace App\Http\Livewire;
|
||||
|
||||
use App\Achievements\UserMade100Comments;
|
||||
use App\Achievements\UserMade200Comments;
|
||||
use App\Achievements\UserMade300Comments;
|
||||
use App\Achievements\UserMade400Comments;
|
||||
use App\Achievements\UserMade500Comments;
|
||||
use App\Achievements\UserMade50Comments;
|
||||
use App\Achievements\UserMade600Comments;
|
||||
use App\Achievements\UserMade700Comments;
|
||||
use App\Achievements\UserMade800Comments;
|
||||
use App\Achievements\UserMade900Comments;
|
||||
use App\Achievements\UserMadeComment;
|
||||
use App\Achievements\UserMadeTenComments;
|
||||
use App\Models\User;
|
||||
use App\Notifications\NewComment;
|
||||
use App\Repositories\TaggedUserRepository;
|
||||
use Livewire\Component;
|
||||
use Livewire\WithPagination;
|
||||
use voku\helper\AntiXSS;
|
||||
|
||||
class Comments extends Component
|
||||
{
|
||||
use WithPagination;
|
||||
|
||||
private TaggedUserRepository $taggedUserRepository;
|
||||
|
||||
public \Illuminate\Contracts\Auth\Authenticatable|\App\Models\User $user;
|
||||
|
||||
public $model;
|
||||
|
||||
public $anon = false;
|
||||
|
||||
public int $perPage = 10;
|
||||
|
||||
protected $listeners = [
|
||||
'refresh' => '$refresh',
|
||||
];
|
||||
|
||||
public $newCommentState = [
|
||||
'content' => '',
|
||||
];
|
||||
|
||||
protected $validationAttributes = [
|
||||
'newCommentState.content' => 'comment',
|
||||
];
|
||||
|
||||
final public function mount(TaggedUserRepository $taggedUserRepository): void
|
||||
{
|
||||
$this->taggedUserRepository = $taggedUserRepository;
|
||||
$this->user = \auth()->user();
|
||||
}
|
||||
|
||||
final public function loadMore()
|
||||
{
|
||||
$this->perPage += 10;
|
||||
}
|
||||
|
||||
final public function postComment(): void
|
||||
{
|
||||
if ($this->user->can_comment === 0) {
|
||||
$this->dispatchBrowserEvent('error', ['type' => 'error', 'message' => \trans('comment.rights-revoked')]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->validate([
|
||||
'newCommentState.content' => 'required',
|
||||
]);
|
||||
|
||||
$comment = $this->model->comments()->make((new AntiXSS())->xss_clean($this->newCommentState));
|
||||
$comment->user()->associate($this->user);
|
||||
$comment->anon = $this->anon;
|
||||
$comment->save();
|
||||
|
||||
$this->newCommentState = [
|
||||
'content' => '',
|
||||
];
|
||||
|
||||
// Achievements
|
||||
if ($comment->anon === 0) {
|
||||
$this->user->unlock(new UserMadeComment(), 1);
|
||||
$this->user->addProgress(new UserMadeTenComments(), 1);
|
||||
$this->user->addProgress(new UserMade50Comments(), 1);
|
||||
$this->user->addProgress(new UserMade100Comments(), 1);
|
||||
$this->user->addProgress(new UserMade200Comments(), 1);
|
||||
$this->user->addProgress(new UserMade300Comments(), 1);
|
||||
$this->user->addProgress(new UserMade400Comments(), 1);
|
||||
$this->user->addProgress(new UserMade500Comments(), 1);
|
||||
$this->user->addProgress(new UserMade600Comments(), 1);
|
||||
$this->user->addProgress(new UserMade700Comments(), 1);
|
||||
$this->user->addProgress(new UserMade800Comments(), 1);
|
||||
$this->user->addProgress(new UserMade900Comments(), 1);
|
||||
}
|
||||
|
||||
//Notification
|
||||
if ($this->user->id !== $this->model->user_id) {
|
||||
User::find($this->model->user_id)->notify(new NewComment($this->model, $comment));
|
||||
}
|
||||
|
||||
// Tagging
|
||||
if ($this->taggedUserRepository->hasTags($this->newCommentState)) {
|
||||
if ($this->user->group->is_modo && $this->taggedUserRepository->contains($this->newCommentState, '@here')) {
|
||||
$users = \collect([]);
|
||||
|
||||
$this->model->comments()->get()->each(function ($c) use ($users) {
|
||||
$users->push($c->user);
|
||||
});
|
||||
$this->taggedUserRepository->messageCommentUsers(
|
||||
$this->model,
|
||||
$users,
|
||||
$this->user,
|
||||
'Staff',
|
||||
$comment
|
||||
);
|
||||
} else {
|
||||
$sender = $comment->anon !== 0 ? $this->user->username : 'Anonymous';
|
||||
$this->taggedUserRepository->messageTaggedCommentUsers(
|
||||
$this->model,
|
||||
$this->newCommentState[],
|
||||
$this->user,
|
||||
$sender,
|
||||
$comment
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$this->gotoPage(1);
|
||||
}
|
||||
|
||||
final public function getCommentsProperty(): \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||
{
|
||||
return $this->model
|
||||
->comments()
|
||||
->with('user', 'children.user', 'children.children')
|
||||
->parent()
|
||||
->latest()
|
||||
->paginate($this->perPage);
|
||||
}
|
||||
|
||||
final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
|
||||
{
|
||||
return \view('livewire.comments', [
|
||||
'comments' => $this->comments,
|
||||
]);
|
||||
}
|
||||
}
|
||||
@@ -36,12 +36,9 @@ class Article extends Model
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Comments.
|
||||
*/
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
{
|
||||
return $this->hasMany(Comment::class);
|
||||
return $this->morphMany(Comment::class, 'commentable');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -23,12 +23,9 @@ class Collection extends Model
|
||||
|
||||
protected $table = 'collection';
|
||||
|
||||
/**
|
||||
* Has Many Comments.
|
||||
*/
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
{
|
||||
return $this->hasMany(Comment::class, 'collection_id');
|
||||
return $this->morphMany(Comment::class, 'commentable');
|
||||
}
|
||||
|
||||
public function movie(): \Illuminate\Database\Eloquent\Relations\BelongsToMany
|
||||
|
||||
@@ -17,15 +17,24 @@ use App\Events\TicketWentStale;
|
||||
use App\Helpers\Bbcode;
|
||||
use App\Helpers\Linkify;
|
||||
use App\Traits\Auditable;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use voku\helper\AntiXSS;
|
||||
|
||||
class Comment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use Auditable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*/
|
||||
protected $fillable = [
|
||||
'content',
|
||||
'user_id',
|
||||
'anon',
|
||||
];
|
||||
|
||||
/**
|
||||
* Belongs To A User.
|
||||
*/
|
||||
@@ -37,52 +46,24 @@ class Comment extends Model
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Belongs To A Torrent.
|
||||
*/
|
||||
public function torrent(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
public function commentable(): \Illuminate\Database\Eloquent\Relations\MorphTo
|
||||
{
|
||||
return $this->belongsTo(Torrent::class);
|
||||
return $this->morphTo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Belongs To A Article.
|
||||
*/
|
||||
public function article(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
public function children(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
{
|
||||
return $this->belongsTo(Article::class);
|
||||
return $this->hasMany(__CLASS__, 'parent_id')->oldest();
|
||||
}
|
||||
|
||||
/**
|
||||
* Belongs To A Request.
|
||||
*/
|
||||
public function request(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
public function isParent(): bool
|
||||
{
|
||||
return $this->belongsTo(TorrentRequest::class, 'requests_id', 'id');
|
||||
return is_null($this->parent_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Belongs To A Playlist.
|
||||
*/
|
||||
public function playlist(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
public function scopeParent(Builder $builder): void
|
||||
{
|
||||
return $this->belongsTo(Playlist::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Belongs To A Ticket.
|
||||
*/
|
||||
public function ticket(): \Illuminate\Database\Eloquent\Relations\BelongsTo
|
||||
{
|
||||
return $this->belongsTo(Ticket::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set The Comments Content After Its Been Purified.
|
||||
*/
|
||||
public function setContentAttribute(?string $value): void
|
||||
{
|
||||
$this->attributes['content'] = \htmlspecialchars((new AntiXSS())->xss_clean($value), ENT_NOQUOTES);
|
||||
$builder->whereNull('parent_id');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,11 +41,8 @@ class Playlist extends Model
|
||||
return $this->hasMany(PlaylistTorrent::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Comments.
|
||||
*/
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
{
|
||||
return $this->hasMany(Comment::class, 'playlist_id');
|
||||
return $this->morphMany(Comment::class, 'commentable');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,11 +95,8 @@ class Ticket extends Model
|
||||
return $this->hasMany(TicketAttachment::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Comments.
|
||||
*/
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
{
|
||||
return $this->hasMany(Comment::class);
|
||||
return $this->morphMany(Comment::class, 'commentable');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,12 +182,9 @@ class Torrent extends Model
|
||||
return $this->hasMany(TorrentFile::class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Comments.
|
||||
*/
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
{
|
||||
return $this->hasMany(Comment::class);
|
||||
return $this->morphMany(Comment::class, 'commentable');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -108,12 +108,9 @@ class TorrentRequest extends Model
|
||||
return $this->belongsTo(Torrent::class, 'filled_hash', 'info_hash');
|
||||
}
|
||||
|
||||
/**
|
||||
* Has Many Comments.
|
||||
*/
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\HasMany
|
||||
public function comments(): \Illuminate\Database\Eloquent\Relations\MorphMany
|
||||
{
|
||||
return $this->hasMany(Comment::class, 'requests_id', 'id');
|
||||
return $this->morphMany(Comment::class, 'commentable');
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
use App\Models\Comment;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class () extends Migration {
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::table('comments', function (Blueprint $table) {
|
||||
$table->bigIncrements('id')->change();
|
||||
$table->morphs('commentable');
|
||||
$table->foreignId('parent_id')->after('user_id')->nullable()->constrained('comments')->onDelete('cascade');
|
||||
});
|
||||
|
||||
$comments = Comment::all();
|
||||
foreach ($comments as $comment) {
|
||||
if ($comment->torrent_id !== null) {
|
||||
$comment->commentable_id = $comment->torrent_id;
|
||||
$comment->commentable_type = 'App\Models\Torrent';
|
||||
$comment->save();
|
||||
}
|
||||
|
||||
if ($comment->article_id !== null) {
|
||||
$comment->commentable_id = $comment->article_id;
|
||||
$comment->commentable_type = 'App\Models\Article';
|
||||
$comment->save();
|
||||
}
|
||||
|
||||
if ($comment->requests_id !== null) {
|
||||
$comment->commentable_id = $comment->requests_id;
|
||||
$comment->commentable_type = 'App\Models\TorrentRequest';
|
||||
$comment->save();
|
||||
}
|
||||
|
||||
if ($comment->collection_id !== null) {
|
||||
$comment->commentable_id = $comment->collection_id;
|
||||
$comment->commentable_type = 'App\Models\Collection';
|
||||
$comment->save();
|
||||
}
|
||||
|
||||
if ($comment->playlist_id !== null) {
|
||||
$comment->commentable_id = $comment->playlist_id;
|
||||
$comment->commentable_type = 'App\Models\Playlist';
|
||||
$comment->save();
|
||||
}
|
||||
|
||||
if ($comment->ticket_id !== null) {
|
||||
$comment->commentable_id = $comment->ticket_id;
|
||||
$comment->commentable_type = 'App\Models\Ticket';
|
||||
$comment->save();
|
||||
}
|
||||
}
|
||||
|
||||
Schema::table('comments', function (Blueprint $table) {
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=0;');
|
||||
$table->dropForeign('fk_comments_articles_1');
|
||||
$table->dropIndex('fk_comments_torrents_1');
|
||||
$table->dropIndex('comments_playlist_id_index');
|
||||
$table->dropIndex('comments_collection_id_index');
|
||||
$table->dropIndex('comments_ticket_id_index');
|
||||
$table->dropColumn('torrent_id', 'article_id', 'requests_id', 'collection_id', 'playlist_id', 'ticket_id');
|
||||
DB::statement('SET FOREIGN_KEY_CHECKS=1;');
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -19,7 +19,7 @@
|
||||
@import 'components/achievement';
|
||||
@import 'components/article-preview';
|
||||
@import 'components/bbcode-input';
|
||||
@import 'components/chip';
|
||||
@import 'components/comment';
|
||||
@import 'components/comparison';
|
||||
@import 'components/data-table';
|
||||
@import 'components/dialog';
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
.chip--anonymous__link {
|
||||
opacity: 0.8;
|
||||
font-weight: 200 !important;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.chip--user__link {
|
||||
font-family: var(--font);
|
||||
white-space: nowrap;
|
||||
}
|
||||
122
resources/sass/components/_comment.scss
Normal file
122
resources/sass/components/_comment.scss
Normal file
@@ -0,0 +1,122 @@
|
||||
.comments,
|
||||
.comment__reply-list {
|
||||
padding: 0;
|
||||
margin-top: 10px;
|
||||
list-style-type: none;
|
||||
background-color: inherit !important; /* Overrides theming */
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
row-gap: 10px;
|
||||
|
||||
> li {
|
||||
background-color: inherit;
|
||||
max-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.comment {
|
||||
display: grid;
|
||||
grid-template-columns: 0 auto auto 1fr auto;
|
||||
grid-template-rows: min-content auto;
|
||||
grid-template-areas:
|
||||
'avatar author timestamp . actions'
|
||||
'avatar content content content content';
|
||||
gap: 0;
|
||||
align-items: center;
|
||||
padding: 12px 16px;
|
||||
margin-left: 58px;
|
||||
border-radius: 20px;
|
||||
font-size: 13px;
|
||||
color: var(--message-bubble-fg, currentColor);
|
||||
background-color: var(--message-bubble-bg, inherit);
|
||||
box-shadow: 0 1px 1px 0 rgba(0, 0, 0, 0.14), 0 2px 1px -1px rgba(0, 0, 0, 0.12), 0 1px 3px 0 rgba(0, 0, 0, 0.2);
|
||||
width: fit-content;
|
||||
}
|
||||
|
||||
.comment__header {
|
||||
display: contents;
|
||||
}
|
||||
|
||||
.comment__avatar {
|
||||
grid-area: avatar;
|
||||
position: relative;
|
||||
left: -58px;
|
||||
bottom: -12px;
|
||||
border-radius: 50%;
|
||||
width: 36px;
|
||||
align-self: self-end;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.comment__author {
|
||||
grid-area: author;
|
||||
margin: 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.comment__author-link {
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.comment__timestamp {
|
||||
grid-area: timestamp;
|
||||
font-size: 11px;
|
||||
margin: 0 8px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.comment__actions {
|
||||
grid-area: actions;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 12px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.comment__edit,
|
||||
.comment__reply,
|
||||
.comment__delete {
|
||||
background-color: transparent;
|
||||
border-radius: 50%;
|
||||
line-height: 1;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
flex: 1;
|
||||
border: none;
|
||||
font-size: 13px;
|
||||
|
||||
&:hover {
|
||||
filter: brightness(0.8);
|
||||
}
|
||||
}
|
||||
|
||||
/* Can be removed once `abbr[title]` underlined styling is removed site-wide */
|
||||
.comment__edit-abbr,
|
||||
.comment__reply-abbr,
|
||||
.comment__delete-abbr {
|
||||
border-bottom: none !important;
|
||||
text-decoration: none !important;
|
||||
cursor: unset !important;
|
||||
}
|
||||
|
||||
.comment__content {
|
||||
grid-area: content;
|
||||
position: relative;
|
||||
margin-top: 0 !important; /* can be removed once site-wide `p` styling is removed */
|
||||
}
|
||||
|
||||
.edit-comment {
|
||||
grid-area: content;
|
||||
width: 9999px;
|
||||
}
|
||||
|
||||
.comment__replies {
|
||||
background-color: inherit;
|
||||
margin-left: 54px;
|
||||
}
|
||||
|
||||
.reply-comment {
|
||||
width: 9999px;
|
||||
}
|
||||
149
resources/sass/components/_form.scss
Normal file
149
resources/sass/components/_form.scss
Normal file
@@ -0,0 +1,149 @@
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
padding-top: 12px;
|
||||
background-color: inherit;
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
/* Form groups (inputs + labels) */
|
||||
|
||||
.form__group {
|
||||
background-color: inherit;
|
||||
position: relative;
|
||||
margin-top: 0 !important; /* Can be removed once site-wide <p> styles are removed */
|
||||
}
|
||||
|
||||
/* Form labels */
|
||||
|
||||
.form__label {
|
||||
user-select: none;
|
||||
font-size: 14px;
|
||||
font-weight: normal !important; /* Needed until site-wide <label> styles are removed */
|
||||
}
|
||||
|
||||
.form__label--floating {
|
||||
background-color: inherit;
|
||||
border-radius: 50% 50% 0 0 / 8px;
|
||||
cursor: text;
|
||||
height: auto;
|
||||
line-height: 1;
|
||||
position: absolute;
|
||||
padding: 8px 4px 0 4px;
|
||||
display: inline-block;
|
||||
top: 6px;
|
||||
left: 8px;
|
||||
color: var(--textarea-border);
|
||||
|
||||
@media screen and (prefers-reduced-motion: no-preference) {
|
||||
transition: top 400ms cubic-bezier(0.25, 0.8, 0.25, 1), font-size 400ms cubic-bezier(0.25, 0.8, 0.25, 1),
|
||||
color 400ms cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Buttons */
|
||||
|
||||
.form__button {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
line-height: 1;
|
||||
margin: 6px;
|
||||
padding: 8px 12px;
|
||||
border-radius: 9999px;
|
||||
align-self: flex-start;
|
||||
transition: filter 300ms;
|
||||
|
||||
&:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
&:active {
|
||||
filter: brightness(0.9);
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
|
||||
.form__button--filled {
|
||||
background: var(--button-filled-bg);
|
||||
color: var(--button-filled-fg);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.form__button--text {
|
||||
background: var(--button-text-bg);
|
||||
color: var(--button-text-fg);
|
||||
border: 0;
|
||||
}
|
||||
|
||||
/* Textareas */
|
||||
|
||||
.form__textarea {
|
||||
background-color: inherit;
|
||||
border: 1px solid var(--textarea-border);
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
height: 40px;
|
||||
padding: 12px;
|
||||
border-radius: 5px;
|
||||
outline: none;
|
||||
font-size: 14px;
|
||||
font-weight: normal;
|
||||
|
||||
@media screen and (prefers-reduced-motion: no-preference) {
|
||||
transition: border-color 600ms cubic-bezier(0.25, 0.8, 0.25, 1), height 600ms cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
border: 2px solid var(--textarea-border-hover);
|
||||
}
|
||||
|
||||
&:focus,
|
||||
&:focus:hover {
|
||||
border: 2px solid var(--textarea-border-active);
|
||||
height: 140px;
|
||||
|
||||
& + .form__label--floating {
|
||||
top: -11px;
|
||||
font-size: 11px;
|
||||
color: #2196f3;
|
||||
}
|
||||
}
|
||||
|
||||
&:valid {
|
||||
height: 140px;
|
||||
|
||||
& + .form__label--floating {
|
||||
top: -11px;
|
||||
font-size: 11px;
|
||||
}
|
||||
}
|
||||
|
||||
&:invalid:focus {
|
||||
border: 1px solid #ba1b1b;
|
||||
|
||||
& + .form__label--floating {
|
||||
color: #ba1b1b;
|
||||
|
||||
> strong {
|
||||
color: inherit; /* Can be removed once site-wide <strong> styling is removed */
|
||||
}
|
||||
}
|
||||
|
||||
& ~ .form__hint {
|
||||
color: #ba1b1b;
|
||||
font-size: 12px;
|
||||
margin-left: 16px;
|
||||
|
||||
> strong {
|
||||
color: inherit; /* Can be removed once site-wide <strong> styling is removed */
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Checkboxes */
|
||||
|
||||
.form__checkbox {
|
||||
all: revert !important; /* Can be removed once site-wide checkbox styling is removed */
|
||||
}
|
||||
@@ -1,4 +1,14 @@
|
||||
:root {
|
||||
--message-bubble-bg: white;
|
||||
--message-bubble-fg: currentColor;
|
||||
--button-filled-bg: #5cb579 linear-gradient(to bottom right, #0ba360, #2bb673);
|
||||
--button-filled-fg: white;
|
||||
--button-text-bg: inherit;
|
||||
--button-text-fg: currentColor;
|
||||
--textarea-border: #555;
|
||||
--textarea-border-hover: #999;
|
||||
--textarea-border-active: #2196f3;
|
||||
|
||||
--achievement-fg: inherit;
|
||||
--achievement-bg: #e7e7e7;
|
||||
|
||||
@@ -3174,6 +3184,7 @@ button.list-group-item-danger.active:hover {
|
||||
|
||||
.panel-body {
|
||||
padding: 15px;
|
||||
background-color: #e2e2e2;
|
||||
}
|
||||
|
||||
.panel-body:after,
|
||||
@@ -10796,7 +10807,7 @@ div.single_column {
|
||||
display: block !important;
|
||||
border-top-left-radius: 15px;
|
||||
border-top-right-radius: 15px;
|
||||
background-color: #ffffff;
|
||||
background-color: var(--message-bubble-bg);
|
||||
padding: 4px 12px 0 8px;
|
||||
margin: 4px 12px 0 48px;
|
||||
}
|
||||
@@ -10804,7 +10815,7 @@ div.single_column {
|
||||
.sent > div {
|
||||
display: block !important;
|
||||
border-bottom-right-radius: 15px;
|
||||
background-color: #ffffff;
|
||||
background-color: var(--message-bubble-bg);
|
||||
padding: 0 12px 4px 8px !important;
|
||||
margin: 0 12px 4px 48px !important;
|
||||
}
|
||||
@@ -10819,7 +10830,7 @@ div.single_column {
|
||||
bottom: 4px;
|
||||
left: 38px;
|
||||
width: 0;
|
||||
border-right: 10px solid #ffffff;
|
||||
border-right: 10px solid var(--message-bubble-bg);
|
||||
border-top: 10px solid transparent;
|
||||
/* border-bottom: 10px solid transparent; */
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
:root {
|
||||
--message-bubble-bg: #363636;
|
||||
|
||||
--achievement-fg: inherit;
|
||||
--achievement-bg: #272727;
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@
|
||||
--color-bright-white: hsl(0, 0%, 100%);
|
||||
--color-light-orange: hsl(20, 20%, 50%);
|
||||
|
||||
--message-bubble-bg: #222;
|
||||
--message-bubble-fg: currentColor;
|
||||
--button-filled-bg: var(--color-green);
|
||||
|
||||
--achievement-fg: inherit;
|
||||
--achievement-bg: #2c2c2c;
|
||||
|
||||
@@ -1109,7 +1113,7 @@ fieldset[disabled] {
|
||||
display: block !important;
|
||||
border-top-left-radius: 15px;
|
||||
border-top-right-radius: 15px;
|
||||
background-color: #363636 !important;
|
||||
background-color: var(--message-bubble-bg) !important;
|
||||
padding: 4px 12px 0 8px;
|
||||
margin: 4px 12px 0 48px;
|
||||
}
|
||||
@@ -1117,7 +1121,7 @@ fieldset[disabled] {
|
||||
.sent > div {
|
||||
display: block !important;
|
||||
border-bottom-right-radius: 15px;
|
||||
background-color: #363636 !important;
|
||||
background-color: var(--message-bubble-bg) !important;
|
||||
padding: 0 12px 4px 8px !important;
|
||||
margin: 0 12px 4px 48px !important;
|
||||
}
|
||||
@@ -1132,7 +1136,7 @@ fieldset[disabled] {
|
||||
bottom: 4px;
|
||||
left: 38px;
|
||||
width: 0;
|
||||
border-right: 10px solid #363636 !important;
|
||||
border-right: 10px solid var(--message-bubble-bg) !important;
|
||||
border-top: 10px solid transparent;
|
||||
/* border-bottom: 10px solid transparent; */
|
||||
}
|
||||
|
||||
@@ -22,148 +22,26 @@
|
||||
@section('page', 'page__articles--show')
|
||||
|
||||
@section('main')
|
||||
<section class="panelV2">
|
||||
<header class="panel__header">
|
||||
<h1 class="panel__heading">{{ $article->title }}</h1>
|
||||
<div class="panel__actions">
|
||||
<time class="panel__action page__published" datetime="{{ $article->created_at }}">
|
||||
{{ $article->created_at->toDayDateTimeString() }}
|
||||
</time>
|
||||
</div>
|
||||
</header>
|
||||
<div class="panel__body">
|
||||
@joypixels($article->getContentHtml())
|
||||
<section class="panelV2">
|
||||
<header class="panel__header">
|
||||
<h1 class="panel__heading">{{ $article->title }}</h1>
|
||||
<div class="panel__actions">
|
||||
<time class="panel__action page__published" datetime="{{ $article->created_at }}">
|
||||
{{ $article->created_at->toDayDateTimeString() }}
|
||||
</time>
|
||||
</div>
|
||||
</section>
|
||||
<section class="panelV2">
|
||||
<h4 class="panel__heading">
|
||||
<i class="{{ config('other.font-awesome') }} fa-comment"></i>
|
||||
{{ __('common.comments') }}
|
||||
</h4>
|
||||
<div class="panel-body no-padding">
|
||||
<ul class="media-list comments-list">
|
||||
@if (count($article->comments) == 0)
|
||||
<div class="text-center">
|
||||
<h4 class="text-bold text-danger">
|
||||
<i class="{{ config('other.font-awesome') }} fa-frown"></i>
|
||||
{{ __('common.no-comments') }}!
|
||||
</h4>
|
||||
</div>
|
||||
@else
|
||||
@foreach ($article->comments as $comment)
|
||||
<li class="media" style="border-left: 5px solid #01bc8c;">
|
||||
<div class="media-body">
|
||||
@if ($comment->anon == 1)
|
||||
<a href="#" class="pull-left" style="padding-right: 10px;">
|
||||
<img src="{{ url('img/profile.png') }}" class="img-avatar-48">
|
||||
<strong>{{ strtoupper(__('common.anonymous')) }}</strong>
|
||||
</a>
|
||||
@if (auth()->user()->id == $comment->user->id || auth()->user()->group->is_modo)
|
||||
<a
|
||||
href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};"
|
||||
>
|
||||
(
|
||||
<span>
|
||||
<i class="{{ $comment->user->group->icon }}"></i>
|
||||
{{ $comment->user->username }}
|
||||
</span>
|
||||
)
|
||||
</a>
|
||||
@endif
|
||||
@else
|
||||
<a
|
||||
href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
class="pull-left" style="padding-right: 10px;"
|
||||
>
|
||||
@if ($comment->user->image != null)
|
||||
<img
|
||||
src="{{ url('files/img/' . $comment->user->image) }}"
|
||||
alt="{{ $comment->user->username }}" class="img-avatar-48"
|
||||
>
|
||||
</a>
|
||||
@else
|
||||
<img
|
||||
src="{{ url('img/profile.png') }}"
|
||||
alt="{{ $comment->user->username }}" class="img-avatar-48"
|
||||
>
|
||||
</a>
|
||||
@endif
|
||||
<strong>
|
||||
<a
|
||||
href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};"
|
||||
>
|
||||
<span>
|
||||
<i class="{{ $comment->user->group->icon }}"></i>
|
||||
{{ $comment->user->username }}
|
||||
</span>
|
||||
</a>
|
||||
</strong>
|
||||
@endif
|
||||
<span class="text-muted">
|
||||
<small>
|
||||
<em>{{$comment->created_at->diffForHumans() }}</em>
|
||||
</small>
|
||||
</span>
|
||||
@if ($comment->user_id == auth()->id() || auth()->user()->group->is_modo)
|
||||
<div class="pull-right" style="display: inline-block;">
|
||||
<a data-toggle="modal" data-target="#modal-comment-edit-{{ $comment->id }}">
|
||||
<button class="btn btn-circle btn-info">
|
||||
<i class="{{ config('other.font-awesome') }} fa-pencil"></i>
|
||||
</button>
|
||||
</a>
|
||||
<form
|
||||
action="{{ route('comment_delete', ['comment_id' => $comment->id]) }}"
|
||||
method="POST"
|
||||
style="display: inline-block;"
|
||||
>
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-circle btn-danger">
|
||||
<i class="{{ config('other.font-awesome') }} fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
<div class="pt-5">
|
||||
@joypixels($comment->getContentHtml())
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@include('partials.modals', ['comment' => $comment])
|
||||
@endforeach
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</section>
|
||||
<section class="panelV2">
|
||||
<header class="panel__header">
|
||||
<h2 class="panel__heading">{{ __('common.your-comment') }}</h2>
|
||||
<div class="panel__actions">
|
||||
<span class="panel__action" x-data="{ emoji: false }">
|
||||
<img src="{{ url('img/emoji-add.png') }}" width="32px" x-on:click="emoji = ! emoji">
|
||||
<div style="position: absolute; z-index: 1; width: 240px; right: 0;" x-show="emoji" x-on:click.away="emoji = false">
|
||||
<emoji-picker></emoji-picker>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</header>
|
||||
<div class="panel__body">
|
||||
<form class="form" method="POST" action="{{ route('comment_article', ['id' => $article->id]) }}">
|
||||
@csrf
|
||||
<p class="form__group">
|
||||
<textarea id="editor" name="content" cols="30" rows="5" class="form-control"></textarea>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<input type="hidden" value="0" name="anonymous">
|
||||
<input type="checkbox" id="anon-comment" class="form__checkbox" value="1" name="anonymous">
|
||||
<label for="anon-comment">{{ __('common.anonymous') }} {{ __('common.comment') }}</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<button type="submit" class="form__button form__button--filled">{{ __('common.submit') }}</button>
|
||||
</p>
|
||||
</form>
|
||||
</div>
|
||||
</section>
|
||||
</header>
|
||||
<div class="panel__body">
|
||||
@joypixels($article->getContentHtml())
|
||||
</div>
|
||||
</section>
|
||||
<section class="panelV2">
|
||||
<h4 class="panel__heading">
|
||||
<i class="{{ config('other.font-awesome') }} fa-comment"></i>
|
||||
{{ __('common.comments') }}
|
||||
</h4>
|
||||
<div class="panel-body no-padding">
|
||||
<livewire:comments :model="$article"/>
|
||||
</div>
|
||||
</section>
|
||||
@endsection
|
||||
|
||||
139
resources/views/livewire/comment.blade.php
Normal file
139
resources/views/livewire/comment.blade.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<li>
|
||||
<article class="comment">
|
||||
<header class="comment__header">
|
||||
<img
|
||||
class="comment__avatar"
|
||||
src="{{ url((!$comment->anon && $comment->user->image !== null) ? 'files/img/'.$comment->user->image : '/img/profile.png') }}"
|
||||
alt=""
|
||||
>
|
||||
<address class="comment__author">
|
||||
<x-user_tag :anon="$comment->anon" :user="$comment->user"/>
|
||||
</address>
|
||||
<time
|
||||
class="comment__timestamp"
|
||||
datetime="{{ $comment->created_at }}"
|
||||
title="{{ $comment->created_at }}"
|
||||
>
|
||||
{{ $comment->created_at->diffForHumans() }}
|
||||
</time>
|
||||
<menu class="comment__actions">
|
||||
@if ($comment->isParent())
|
||||
<button wire:click="$toggle('isReplying')" class="comment__reply">
|
||||
<abbr class="comment__reply-abbr" title="Reply to this comment">
|
||||
<i class="{{ config('other.font-awesome') }} fa-reply"></i>
|
||||
<span class="sr-only">__('pm.reply')</span>
|
||||
</abbr>
|
||||
</button>
|
||||
@endif
|
||||
@if ($comment->user_id === auth()->id() || auth()->user()->group->is_modo)
|
||||
<button wire:click="$toggle('isEditing')" class="comment__edit">
|
||||
<abbr class="comment__edit-abbr" title="{{ __('common.edit-your-comment') }}">
|
||||
<i class="{{ config('other.font-awesome') }} fa-pencil"></i>
|
||||
<span class="sr-only">__('common.edit')</span>
|
||||
</abbr>
|
||||
</button>
|
||||
<button
|
||||
class="comment__delete"
|
||||
x-on:click="confirmCommentDeletion"
|
||||
x-data="{
|
||||
confirmCommentDeletion () {
|
||||
if (window.confirm('You sure?')) {
|
||||
@this.call('deleteComment')
|
||||
}
|
||||
}
|
||||
}"
|
||||
>
|
||||
<abbr class="comment__delete-abbr" title="{{ __('common.delete-your-comment') }}">
|
||||
<i class="{{ config('other.font-awesome') }} fa-trash"></i>
|
||||
<span class="sr-only">__('common.delete')</span>
|
||||
</abbr>
|
||||
</button>
|
||||
@endif
|
||||
</menu>
|
||||
</header>
|
||||
@if ($isEditing)
|
||||
<form wire:submit.prevent="editComment" class="form edit-comment">
|
||||
<p class="form__group">
|
||||
<textarea
|
||||
name="comment"
|
||||
id="edit-comment"
|
||||
class="form__textarea"
|
||||
aria-describedby="edit-comment__textarea-hint"
|
||||
wire:model.defer="editState.content"
|
||||
required
|
||||
></textarea>
|
||||
<label for="edit-comment" class="form__label form__label--floating">
|
||||
@error('editState.content')
|
||||
<strong>{{ __('common.error') }}: </strong>
|
||||
@enderror
|
||||
Edit your comment...
|
||||
</label>
|
||||
@error('editState.content')
|
||||
<span class="form__hint" id="edit-comment__textarea-hint">{{ $message }}</p>
|
||||
@enderror
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<button type="submit" class="form__button form__button--filled">
|
||||
{{ __('common.edit') }}
|
||||
</button>
|
||||
<button type="button" wire:click="$toggle('isEditing')" class="form__button form__button--text">
|
||||
{{ __('common.cancel') }}
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
@else
|
||||
<p class="comment__content">
|
||||
@joypixels($comment->getContentHtml())
|
||||
</p>
|
||||
@endif
|
||||
</article>
|
||||
|
||||
@if ($comment->isParent())
|
||||
<section class="comment__replies">
|
||||
<h5 class="sr-only">Replies</h5>
|
||||
@if ($isReplying)
|
||||
<form wire:submit.prevent="postReply" class="form reply-comment">
|
||||
<p class="form__group">
|
||||
<textarea
|
||||
name="comment"
|
||||
id="reply-comment"
|
||||
class="form__textarea"
|
||||
aria-describedby="reply-comment__textarea-hint"
|
||||
wire:model.defer="replyState.content"
|
||||
required
|
||||
></textarea>
|
||||
<label for="reply-comment" class="form__label form__label--floating">
|
||||
@error('editState.content')
|
||||
<strong>{{ __('common.error') }}: </strong>
|
||||
@enderror
|
||||
Reply to parent comment...
|
||||
</label>
|
||||
@error('replyState.content')
|
||||
<span class="form__hint" id="reply-comment__textarea-hint">{{ $message }}</p>
|
||||
@enderror
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<input type="checkbox" id="reply-anon" class="form__checkbox" wire:modal="anon">
|
||||
<label for="reply-anon" class="form__label">{{ __('common.anonymous') }}?</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<button type="submit" class="form__button form__button--filled">
|
||||
{{ __('common.comment') }}
|
||||
</button>
|
||||
<button type="button" wire:click="$toggle('isReplying')"
|
||||
class="form__button form__button--text">
|
||||
{{ __('common.cancel') }}
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
@endif
|
||||
@if ($comment->children->count() > 0)
|
||||
<ul class="comment__reply-list">
|
||||
@foreach ($comment->children as $child)
|
||||
<livewire:comment :comment="$child" :key="$child->id"/>
|
||||
@endforeach
|
||||
</ul>
|
||||
@endif
|
||||
</section>
|
||||
@endif
|
||||
</li>
|
||||
56
resources/views/livewire/comments.blade.php
Normal file
56
resources/views/livewire/comments.blade.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<section class="panelV2">
|
||||
<h4 class="panel__heading">
|
||||
<i class="{{ config('other.font-awesome') }} fa-comment"></i>
|
||||
{{ __('common.comments') }}
|
||||
</h4>
|
||||
<div class="panel-body no-padding">
|
||||
<form wire:submit.prevent="postComment" class="form new-comment">
|
||||
<p class="form__group">
|
||||
<textarea
|
||||
name="comment"
|
||||
id="new-comment__textarea"
|
||||
class="form__textarea"
|
||||
aria-describedby="new-comment__textarea-hint"
|
||||
wire:model.defer="newCommentState.content"
|
||||
required
|
||||
></textarea>
|
||||
<label for="new-comment__textarea" class="form__label form__label--floating">
|
||||
@error('newCommentState.content')
|
||||
<strong>{{ __('common.error') }}: </strong>
|
||||
@enderror
|
||||
Add a comment...
|
||||
</label>
|
||||
@error('newCommentState.content')
|
||||
<span class="form__hint" id="new-comment__textarea-hint">{{ $message }}</p>
|
||||
@enderror
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<input type="checkbox" id="anon" class="form__checkbox" wire:modal="anon">
|
||||
<label for="anon" class="form__label">{{ __('common.anonymous') }}?</label>
|
||||
</p>
|
||||
<p class="form__group">
|
||||
<button type="submit" class="form__button form__button--filled">
|
||||
Comment
|
||||
</button>
|
||||
<button type="reset" class="form__button form__button--text">
|
||||
{{ __('common.cancel') }}
|
||||
</button>
|
||||
</p>
|
||||
</form>
|
||||
<ul class="comments">
|
||||
@forelse($comments as $comment)
|
||||
<livewire:comment :comment="$comment" :key="$comment->id"/>
|
||||
@empty
|
||||
<li>
|
||||
<i class="{{ config('other.font-awesome') }} fa-frown"></i>
|
||||
{{ __('common.no-comments') }}!
|
||||
</li>
|
||||
@endforelse
|
||||
</ul>
|
||||
@if ($comments->hasMorePages())
|
||||
<div class="text-center">
|
||||
<button class="btn btn-md btn-primary" wire:click.prevent="loadMore">Load More Comments</button>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</section>
|
||||
@@ -107,105 +107,8 @@
|
||||
</div>
|
||||
|
||||
<div class="torrent box container" id="comments">
|
||||
<!-- Comments -->
|
||||
<div class="clearfix"></div>
|
||||
<div class="row ">
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<div class="panel panel-chat shoutbox">
|
||||
<div class="panel-heading">
|
||||
<h4>
|
||||
<i class="{{ config('other.font-awesome') }} fa-comment"></i> {{ __('common.comments') }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="panel-body no-padding">
|
||||
<ul class="media-list comments-list">
|
||||
@if (count($collection->comments) == 0)
|
||||
<div class="text-center"><h4 class="text-bold text-danger"><i
|
||||
class="{{ config('other.font-awesome') }} fa-frown"></i> {{ __('common.no-comments') }}
|
||||
!</h4>
|
||||
</div>
|
||||
@else
|
||||
@foreach ($collection->comments as $comment)
|
||||
<li class="media" style="border-left: 5px solid #01BC8C;">
|
||||
<div class="media-body">
|
||||
@if ($comment->anon == 1)
|
||||
<a href="#" class="pull-left" style="padding-right: 10px;">
|
||||
<img src="{{ url('img/profile.png') }}" class="img-avatar-48">
|
||||
<strong>{{ strtoupper(__('common.anonymous')) }}</strong></a> @if (auth()->user()->id == $comment->user->id || auth()->user()->group->is_modo)
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};">(<span><i
|
||||
class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span>)</a> @endif
|
||||
@else
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
class="pull-left" style="padding-right: 10px;">
|
||||
@if ($comment->user->image != null)
|
||||
<img src="{{ url('files/img/' . $comment->user->image) }}"
|
||||
alt="{{ $comment->user->username }}" class="img-avatar-48"></a>
|
||||
@else
|
||||
<img src="{{ url('img/profile.png') }}"
|
||||
alt="{{ $comment->user->username }}" class="img-avatar-48"></a>
|
||||
@endif
|
||||
<strong><a
|
||||
href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};"><span><i
|
||||
class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span></a></strong> @endif
|
||||
<span class="text-muted"><small><em>{{ $comment->created_at->toDayDateTimeString() }} ({{ $comment->created_at->diffForHumans() }})</em></small></span>
|
||||
@if ($comment->user_id == auth()->id() || auth()->user()->group->is_modo)
|
||||
<div class="pull-right" style="display: inline-block;">
|
||||
<a data-toggle="modal"
|
||||
data-target="#modal-comment-edit-{{ $comment->id }}">
|
||||
<button class="btn btn-circle btn-info">
|
||||
<i class="{{ config('other.font-awesome') }} fa-pencil"></i>
|
||||
</button>
|
||||
</a>
|
||||
<form action="{{ route('comment_delete', ['comment_id' => $comment->id]) }}"
|
||||
method="POST" style="display: inline-block;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-circle btn-danger">
|
||||
<i class="{{ config('other.font-awesome') }} fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
<div class="pt-5">
|
||||
@joypixels($comment->getContentHtml())
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@include('partials.modals', ['comment' => $comment])
|
||||
@endforeach
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Comments -->
|
||||
<br>
|
||||
<!-- Add comment -->
|
||||
<div class="col-md-12">
|
||||
<form role="form" method="POST" action="{{ route('comment_collection', ['id' => $collection->id]) }}">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label for="content">{{ __('common.your-comment') }}:</label>
|
||||
<span class="badge-extra">BBCode {{ __('common.is-allowed') }}</span>
|
||||
<span class="pull-right" x-data="{ emoji: false }">
|
||||
<img src="{{ url('img/emoji-add.png') }}" width="32px" x-on:click="emoji = ! emoji">
|
||||
|
||||
<div style="position: absolute; z-index: 1;" x-show="emoji" @click.away="emoji = false">
|
||||
<emoji-picker></emoji-picker>
|
||||
</div>
|
||||
</span>
|
||||
<textarea id="editor" name="content" cols="30" rows="5" class="form-control"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-danger">{{ __('common.submit') }}</button>
|
||||
<label class="radio-inline"><strong>{{ __('common.anonymous') }} {{ __('common.comment') }}
|
||||
:</strong></label>
|
||||
<input type="radio" value="1" name="anonymous"> {{ __('common.yes') }}
|
||||
<input type="radio" value="0" checked="checked" name="anonymous"> {{ __('common.no') }}
|
||||
</form>
|
||||
</div>
|
||||
<!-- /Add comment -->
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<livewire:comments :model="$collection"/>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
<div class="modal fade" id="modal-comment-edit-{{ $comment->id }}" tabindex="-1" role="dialog" aria-hidden="true">
|
||||
<div class="modal-dialog{{ modal_style() }}">
|
||||
<div class="modal-content">
|
||||
<meta charset="utf-8">
|
||||
<title>{{ __('common.edit-your-comment') }}</title>
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
|
||||
aria-hidden="true">×</span></button>
|
||||
<h4 class="modal-title" id="myModalLabel">{{ __('common.edit-your-comment') }}</h4>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<form class="form-horizontal" role="form" method="POST"
|
||||
action="{{ route('comment_edit', ['comment_id' => $comment->id]) }}">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<label for="comment-edit"></label>
|
||||
<textarea class="form-control" rows="5" name="comment-edit" cols="50"
|
||||
id="comment-edit">{{ $comment->content }}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-12">
|
||||
<input style="float:right;" class="btn btn-primary" type="submit"
|
||||
value="{{ __('common.submit') }}">
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -233,102 +233,8 @@
|
||||
</div>
|
||||
|
||||
<div class="block" id="comments">
|
||||
<div class="row ">
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<div class="panel panel-chat shoutbox">
|
||||
<div class="panel-heading">
|
||||
<h4>
|
||||
<i class="{{ config('other.font-awesome') }} fa-comment"></i> {{ __('common.comments') }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="panel-body no-padding">
|
||||
<ul class="media-list comments-list">
|
||||
@if (count($playlist->comments) == 0)
|
||||
<div class="text-center"><h4 class="text-bold text-danger">
|
||||
<i class="{{ config('other.font-awesome') }} fa-frown"></i> {{ __('common.no-comments') }}
|
||||
!</h4>
|
||||
</div>
|
||||
@else
|
||||
@foreach ($playlist->comments as $comment)
|
||||
<li class="media" style="border-left: 5px solid #01BC8C;">
|
||||
<div class="media-body">
|
||||
@if ($comment->anon == 1)
|
||||
<a href="#" class="pull-left" style="padding-right: 10px;">
|
||||
<img src="{{ url('img/profile.png') }}" class="img-avatar-48">
|
||||
<strong>{{ strtoupper(__('common.anonymous')) }}</strong></a> @if (auth()->user()->id == $comment->user->id || auth()->user()->group->is_modo)
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};">(<span><i
|
||||
class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span>)</a> @endif
|
||||
@else
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
class="pull-left" style="padding-right: 10px;">
|
||||
@if ($comment->user->image != null)
|
||||
<img src="{{ url('files/img/' . $comment->user->image) }}"
|
||||
alt="{{ $comment->user->username }}"
|
||||
class="img-avatar-48"></a>
|
||||
@else
|
||||
<img src="{{ url('img/profile.png') }}"
|
||||
alt="{{ $comment->user->username }}"
|
||||
class="img-avatar-48"></a>
|
||||
@endif
|
||||
<strong><a
|
||||
href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};"><span><i
|
||||
class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span></a></strong> @endif
|
||||
<span class="text-muted"><small><em>{{ $comment->created_at->toDayDateTimeString() }} ({{ $comment->created_at->diffForHumans() }})</em></small></span>
|
||||
@if ($comment->user_id == auth()->id() || auth()->user()->group->is_modo)
|
||||
<div class="pull-right" style="display: inline-block;">
|
||||
<a data-toggle="modal"
|
||||
data-target="#modal-comment-edit-{{ $comment->id }}">
|
||||
<button class="btn btn-circle btn-info">
|
||||
<i class="{{ config('other.font-awesome') }} fa-pencil"></i>
|
||||
</button>
|
||||
</a>
|
||||
<form action="{{ route('comment_delete', ['comment_id' => $comment->id]) }}"
|
||||
method="POST" style="display: inline-block;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-circle btn-danger">
|
||||
<i class="{{ config('other.font-awesome') }} fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
<div class="pt-5">
|
||||
@joypixels($comment->getContentHtml())
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@include('partials.modals', ['comment' => $comment])
|
||||
@endforeach
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="col-md-12">
|
||||
<form role="form" method="POST" action="{{ route('comment_playlist', ['id' => $playlist->id]) }}">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label for="content">{{ __('common.your-comment') }}:</label>
|
||||
<span class="badge-extra">BBCode {{ __('common.is-allowed') }}</span>
|
||||
<span class="pull-right" x-data="{ emoji: false }">
|
||||
<img src="{{ url('img/emoji-add.png') }}" width="32px" x-on:click="emoji = ! emoji">
|
||||
|
||||
<div style="position: absolute; z-index: 1;" x-show="emoji" @click.away="emoji = false">
|
||||
<emoji-picker></emoji-picker>
|
||||
</div>
|
||||
</span>
|
||||
<textarea id="editor" name="content" cols="30" rows="5" class="form-control"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-danger">{{ __('common.submit') }}</button>
|
||||
<label class="radio-inline"><strong>{{ __('common.anonymous') }} {{ __('common.comment') }}
|
||||
:</strong></label>
|
||||
<input type="radio" value="1" name="anonymous"> {{ __('common.yes') }}
|
||||
<input type="radio" value="0" checked="checked" name="anonymous"> {{ __('common.no') }}
|
||||
</form>
|
||||
</div>
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<livewire:comments :model="$playlist"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -377,119 +377,10 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="block" id="comments">
|
||||
<div class="clearfix"></div>
|
||||
<div class="row ">
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<div class="panel panel-danger">
|
||||
<div class="panel-heading border-light">
|
||||
<h4 class="panel-title">
|
||||
<i class="{{ config('other.font-awesome') }} fa-comment"></i> {{ __('common.comments') }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="panel-body no-padding">
|
||||
<ul class="media-list comments-list">
|
||||
@if (count($comments) == 0)
|
||||
<div class="text-center">
|
||||
<h4 class="text-bold text-danger"><i
|
||||
class="{{ config('other.font-awesome') }} fa-frown"></i> {{ __('common.no-comments') }}
|
||||
!
|
||||
</h4></div>
|
||||
@else @foreach ($comments as $comment)
|
||||
<li class="media" style="border-left: 5px solid #01bc8c;">
|
||||
<div class="media-body">
|
||||
@if ($comment->anon == 1)
|
||||
<a href="#" class="pull-left" style="padding-right: 10px;">
|
||||
<img src="{{ url('img/profile.png') }}" class="img-avatar-48">
|
||||
<strong>{{ strtoupper(__('common.anonymous')) }}</strong></a> @if (auth()->user()->id == $comment->user->id || auth()->user()->group->is_modo)
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};">(<span><i
|
||||
class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span>)</a>
|
||||
@endif
|
||||
@else
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
class="pull-left" style="padding-right: 10px;">
|
||||
@if ($comment->user->image != null)
|
||||
<img src="{{ url('files/img/' . $comment->user->image) }}"
|
||||
alt="{{ $comment->user->username }}"
|
||||
class="img-avatar-48"></a>
|
||||
@else
|
||||
<img src="{{ url('img/profile.png') }}"
|
||||
alt="{{ $comment->user->username }}"
|
||||
class="img-avatar-48"></a>
|
||||
@endif
|
||||
<strong><a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};"><span><i
|
||||
class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span></a></strong>
|
||||
@endif
|
||||
<span class="text-muted"><small><em>{{ $comment->created_at->toDayDateTimeString() }} ({{ $comment->created_at->diffForHumans() }})</em></small></span>
|
||||
@if ($comment->user_id == auth()->id() || auth()->user()->group->is_modo)
|
||||
<div class="pull-right" style="display: inline-block;">
|
||||
<a data-toggle="modal"
|
||||
data-target="#modal-comment-edit-{{ $comment->id }}">
|
||||
<button class="btn btn-circle btn-info">
|
||||
<i class="{{ config('other.font-awesome') }} fa-pencil"></i>
|
||||
</button>
|
||||
</a>
|
||||
<form action="{{ route('comment_delete', ['comment_id' => $comment->id]) }}"
|
||||
method="POST" style="display: inline-block;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-circle btn-danger">
|
||||
<i class="{{ config('other.font-awesome') }} fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
<div class="pt-5">
|
||||
@joypixels($comment->getContentHtml())
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@include('partials.modals', ['comment' => $comment])
|
||||
@endforeach
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="col-md-12 home-pagination">
|
||||
<div class="text-center">{{ $comments->links() }}</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div class="col-md-12">
|
||||
<form role="form" method="POST"
|
||||
action="{{ route('comment_request',['id' => $torrentRequest->id]) }}">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label for="content">{{ __('common.your-comment') }}:</label>
|
||||
<span class="badge-extra">BBCode {{ strtolower(__('common.is-allowed')) }}</span>
|
||||
<span class="pull-right" x-data="{ emoji: false }">
|
||||
<img src="{{ url('img/emoji-add.png') }}" width="32px" x-on:click="emoji = ! emoji">
|
||||
|
||||
<div style="position: absolute; z-index: 1;" x-show="emoji" @click.away="emoji = false">
|
||||
<emoji-picker></emoji-picker>
|
||||
</div>
|
||||
</span>
|
||||
<textarea id="editor" name="content" cols="30" rows="5"
|
||||
class="form-control"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-danger">{{ __('common.submit') }}</button>
|
||||
<label class="radio-inline"><strong>{{ __('common.anonymous') }} {{ strtolower(__('common.comment')) }}
|
||||
:</strong></label>
|
||||
<label>
|
||||
<input type="radio" value="1" name="anonymous">
|
||||
</label> {{ __('common.yes') }}
|
||||
<label>
|
||||
<input type="radio" value="0" checked="checked" name="anonymous">
|
||||
</label> {{ __('common.no') }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<livewire:comments :model="$torrentRequest"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@include('requests.request_modals')
|
||||
@endif
|
||||
@endsection
|
||||
|
||||
@@ -167,67 +167,10 @@
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<div class="panel panel-chat shoutbox">
|
||||
<div class="panel-heading">
|
||||
<h4>
|
||||
<i class="{{ config('other.font-awesome') }} fa-comment"></i> {{ __('common.comments') }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="panel-body no-padding">
|
||||
<ul class="media-list comments-list">
|
||||
@if (count($ticket->comments) == 0)
|
||||
<div class="text-center">
|
||||
<h4 class="text-bold text-danger">
|
||||
<i class="{{ config('other.font-awesome') }} fa-frown"></i> {{ __('common.no-comments') }}
|
||||
!
|
||||
</h4>
|
||||
</div>
|
||||
@else
|
||||
@foreach ($ticket->comments as $comment)
|
||||
<li class="media" style="border-left: 5px solid rgb(1,188,140);">
|
||||
<div class="media-body">
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
class="pull-left" style="padding-right: 10px;">
|
||||
@if ($comment->user->image != null)
|
||||
<img src="{{ url('files/img/' . $comment->user->image) }}"
|
||||
alt="{{ $comment->user->username }}" class="img-avatar-48"></a>
|
||||
@else
|
||||
<img src="{{ url('img/profile.png') }}"
|
||||
alt="{{ $comment->user->username }}"
|
||||
class="img-avatar-48"></a>
|
||||
@endif
|
||||
<strong>
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};">
|
||||
<span><i class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span>
|
||||
</a>
|
||||
</strong>
|
||||
<span class="text-muted"><small><em>{{ $comment->created_at->toDayDateTimeString() }} ({{ $comment->created_at->diffForHumans() }})</em></small></span>
|
||||
<div class="pt-5">
|
||||
@joypixels($comment->getContentHtml())
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@endforeach
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-12">
|
||||
<form role="form" method="POST" action="{{ route('comment_ticket', ['id' => $ticket->id]) }}">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label for="content">{{ __('common.your-comment') }}:</label>
|
||||
<textarea id="editor" name="content" cols="30" rows="5" class="form-control"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-success">{{ __('common.submit') }}</button>
|
||||
</form>
|
||||
<livewire:comments :model="$ticket"/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -38,13 +38,6 @@
|
||||
</button>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('comment_thanks', ['id' => $torrent->id]) }}" method="POST" style="display: inline;">
|
||||
@csrf
|
||||
<button type="submit" class="btn btn-sm btn-primary">
|
||||
<i class='{{ config("other.font-awesome") }} fa-heart'></i> {{ __('torrent.quick-comment') }}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<a data-toggle="modal" href="#myModal" role="button" class="btn btn-sm btn-primary">
|
||||
<i class='{{ config("other.font-awesome") }} fa-file'></i> {{ __('torrent.show-files') }}
|
||||
</a>
|
||||
|
||||
@@ -1,107 +1 @@
|
||||
<div class="clearfix"></div>
|
||||
<div class="row ">
|
||||
<div class="col-md-12 col-sm-12">
|
||||
<div class="panel panel-chat shoutbox">
|
||||
<div class="panel-heading">
|
||||
<h4>
|
||||
<i class="{{ config('other.font-awesome') }} fa-comment"></i> {{ __('common.comments') }}
|
||||
</h4>
|
||||
</div>
|
||||
<div class="panel-body no-padding">
|
||||
<ul class="media-list comments-list">
|
||||
@if (count($comments) == 0)
|
||||
<div class="text-center"><h4 class="text-bold text-danger"><i
|
||||
class="{{ config('other.font-awesome') }} fa-frown"></i> {{ __('common.no-comments') }}
|
||||
!</h4>
|
||||
</div>
|
||||
@else
|
||||
@foreach ($comments as $comment)
|
||||
<li class="media" style="border-left: 5px solid rgb(1,188,140);">
|
||||
<div class="media-body">
|
||||
@if ($comment->anon == 1)
|
||||
<a href="#" class="pull-left" style="padding-right: 10px;">
|
||||
<img src="{{ url('img/profile.png') }}" class="img-avatar-48">
|
||||
<strong>{{ strtoupper(__('common.anonymous')) }}</strong></a> @if (auth()->user()->id == $comment->user->id || auth()->user()->group->is_modo)
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};">(<span><i
|
||||
class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span>)</a> @endif
|
||||
@else
|
||||
<a href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
class="pull-left" style="padding-right: 10px;">
|
||||
@if ($comment->user->image != null)
|
||||
<img src="{{ url('files/img/' . $comment->user->image) }}"
|
||||
alt="{{ $comment->user->username }}" class="img-avatar-48"></a>
|
||||
@else
|
||||
<img src="{{ url('img/profile.png') }}"
|
||||
alt="{{ $comment->user->username }}" class="img-avatar-48"></a>
|
||||
@endif
|
||||
<strong><a
|
||||
href="{{ route('users.show', ['username' => $comment->user->username]) }}"
|
||||
style="color:{{ $comment->user->group->color }};"><span><i
|
||||
class="{{ $comment->user->group->icon }}"></i> {{ $comment->user->username }}</span></a></strong> @endif
|
||||
<span class="text-muted"><small><em>{{ $comment->created_at->toDayDateTimeString() }} ({{ $comment->created_at->diffForHumans() }})</em></small></span>
|
||||
@if ($comment->user_id == auth()->id() || auth()->user()->group->is_modo)
|
||||
<div class="pull-right" style="display: inline-block;">
|
||||
<a data-toggle="modal" data-target="#modal-comment-edit-{{ $comment->id }}">
|
||||
<button class="btn btn-circle btn-info">
|
||||
<i class="{{ config('other.font-awesome') }} fa-pencil"></i>
|
||||
</button>
|
||||
</a>
|
||||
<form action="{{ route('comment_delete', ['comment_id' => $comment->id]) }}"
|
||||
method="POST" style="display: inline-block;">
|
||||
@csrf
|
||||
@method('DELETE')
|
||||
<button type="submit" class="btn btn-circle btn-danger">
|
||||
<i class="{{ config('other.font-awesome') }} fa-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
<div class="pt-5">
|
||||
@joypixels($comment->getContentHtml())
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
@include('partials.modals', ['comment' => $comment])
|
||||
@endforeach
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="clearfix"></div>
|
||||
<div class="col-md-12 home-pagination">
|
||||
<div class="text-center">{{ $comments->links() }}</div>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<div class="col-md-12">
|
||||
<form role="form" method="POST"
|
||||
action="{{ route('comment_torrent', ['id' => $torrent->id]) }}">
|
||||
@csrf
|
||||
<div class="form-group">
|
||||
<label for="content">{{ __('common.your-comment') }}:</label>
|
||||
<span class="badge-extra">BBCode {{ __('common.is-allowed') }}</span>
|
||||
<span class="pull-right" x-data="{ emoji: false }">
|
||||
<img src="{{ url('img/emoji-add.png') }}" width="32px" x-on:click="emoji = ! emoji">
|
||||
|
||||
<div style="position: absolute; z-index: 1;" x-show="emoji" @click.away="emoji = false">
|
||||
<emoji-picker></emoji-picker>
|
||||
</div>
|
||||
</span>
|
||||
<textarea id="editor" name="content" cols="30" rows="5" class="form-control"></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-danger">{{ __('common.submit') }}</button>
|
||||
<label class="radio-inline"><strong>{{ __('common.anonymous') }} {{ __('common.comment') }}
|
||||
:</strong></label>
|
||||
<label>
|
||||
<input type="radio" value="1" name="anonymous">
|
||||
</label> {{ __('common.yes') }}
|
||||
<label>
|
||||
<input type="radio" value="0" checked="checked" name="anonymous">
|
||||
</label> {{ __('common.no') }}
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<livewire:comments :model="$torrent"/>
|
||||
|
||||
@@ -371,17 +371,17 @@
|
||||
<ul class="list-inline mb-0">
|
||||
<li>
|
||||
<span class="badge-extra"><strong>{{ __('user.article-comments') }}:</strong>
|
||||
<span class="text-green text-bold">{{ $user->comments()->where('article_id', '>', 0)->count() }}</span>
|
||||
<span class="text-green text-bold">{{ $user->comments()->whereHasMorph('commentable', [App\Models\Article::class])->count() }}</span>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="badge-extra"><strong>{{ __('user.torrent-comments') }}:</strong>
|
||||
<span class="text-green text-bold">{{ $user->comments()->where('torrent_id', '>', 0)->count() }}</span>
|
||||
<span class="text-green text-bold">{{ $user->comments()->whereHasMorph('commentable', [App\Models\Torrent::class])->count() }}</span>
|
||||
</span>
|
||||
</li>
|
||||
<li>
|
||||
<span class="badge-extra"><strong>{{ __('user.request-comments') }}:</strong>
|
||||
<span class="text-green text-bold">{{ $user->comments()->where('requests_id', '>', 0)->count() }}</span>
|
||||
<span class="text-green text-bold">{{ $user->comments()->whereHasMorph('commentable', [App\Models\TorrentRequest::class])->count() }}</span>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -133,19 +133,6 @@ Route::group(['middleware' => 'language'], function () {
|
||||
Route::get('/{id}', [App\Http\Controllers\PageController::class, 'show'])->where('id', '[0-9]+')->name('pages.show');
|
||||
});
|
||||
|
||||
// Comments System
|
||||
Route::group(['prefix' => 'comments'], function () {
|
||||
Route::post('/article/{id}', [App\Http\Controllers\CommentController::class, 'article'])->name('comment_article');
|
||||
Route::post('/torrent/{id}', [App\Http\Controllers\CommentController::class, 'torrent'])->name('comment_torrent');
|
||||
Route::post('/thanks/{id}', [App\Http\Controllers\CommentController::class, 'quickthanks'])->name('comment_thanks');
|
||||
Route::post('/request/{id}', [App\Http\Controllers\CommentController::class, 'request'])->name('comment_request');
|
||||
Route::post('/playlist/{id}', [App\Http\Controllers\CommentController::class, 'playlist'])->name('comment_playlist');
|
||||
Route::post('/collection/{id}', [App\Http\Controllers\CommentController::class, 'collection'])->name('comment_collection');
|
||||
Route::post('/ticket/{id}', [App\Http\Controllers\CommentController::class, 'ticket'])->name('comment_ticket');
|
||||
Route::post('/edit/{comment_id}', [App\Http\Controllers\CommentController::class, 'editComment'])->name('comment_edit');
|
||||
Route::delete('/delete/{comment_id}', [App\Http\Controllers\CommentController::class, 'deleteComment'])->name('comment_delete');
|
||||
});
|
||||
|
||||
// Extra-Stats System
|
||||
Route::group(['prefix' => 'stats'], function () {
|
||||
Route::get('/', [App\Http\Controllers\StatsController::class, 'index'])->name('stats');
|
||||
|
||||
@@ -1,205 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Feature\Http\Controllers;
|
||||
|
||||
use App\Models\Article;
|
||||
use App\Models\Comment;
|
||||
use App\Models\Playlist;
|
||||
use App\Models\Torrent;
|
||||
use App\Models\TorrentRequest;
|
||||
use App\Models\User;
|
||||
use Database\Seeders\BotsTableSeeder;
|
||||
use Database\Seeders\ChatroomTableSeeder;
|
||||
use Database\Seeders\GroupsTableSeeder;
|
||||
use Database\Seeders\UsersTableSeeder;
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @see \App\Http\Controllers\CommentController
|
||||
*/
|
||||
class CommentControllerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function article_returns_an_ok_response(): void
|
||||
{
|
||||
$this->seed(UsersTableSeeder::class);
|
||||
$this->seed(GroupsTableSeeder::class);
|
||||
$this->seed(BotsTableSeeder::class);
|
||||
$this->seed(ChatroomTableSeeder::class);
|
||||
|
||||
$user = User::factory()->create([
|
||||
'can_comment' => true,
|
||||
]);
|
||||
|
||||
$article = Article::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(route('comment_article', ['id' => $article->id]), [
|
||||
'content' => 'foo',
|
||||
'anonymous' => '0',
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('articles.show', $article->id))
|
||||
->assertSessionHas('success', 'Your Comment Has Been Added!');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function delete_comment_returns_an_ok_response(): void
|
||||
{
|
||||
$this->seed(UsersTableSeeder::class);
|
||||
$this->seed(GroupsTableSeeder::class);
|
||||
$this->seed(BotsTableSeeder::class);
|
||||
$this->seed(ChatroomTableSeeder::class);
|
||||
|
||||
$user = User::factory()->create([
|
||||
'can_comment' => true,
|
||||
]);
|
||||
|
||||
$comment = Comment::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->delete(route('comment_delete', ['comment_id' => $comment->id]));
|
||||
|
||||
$response->assertRedirect(route('home.index'))
|
||||
->assertSessionHas('success', 'Comment Has Been Deleted.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function edit_comment_returns_an_ok_response(): void
|
||||
{
|
||||
$this->seed(UsersTableSeeder::class);
|
||||
$this->seed(GroupsTableSeeder::class);
|
||||
|
||||
$user = User::factory()->create([
|
||||
'can_comment' => true,
|
||||
]);
|
||||
|
||||
$comment = Comment::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(route('comment_edit', ['comment_id' => $comment->id]), [
|
||||
'comment-edit' => 'bar',
|
||||
]);
|
||||
|
||||
$response->assertRedirect()
|
||||
->assertSessionHas('success', 'Comment Has Been Edited.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function playlist_returns_an_ok_response(): void
|
||||
{
|
||||
$this->seed(UsersTableSeeder::class);
|
||||
$this->seed(GroupsTableSeeder::class);
|
||||
$this->seed(BotsTableSeeder::class);
|
||||
$this->seed(ChatroomTableSeeder::class);
|
||||
|
||||
$user = User::factory()->create([
|
||||
'can_comment' => true,
|
||||
]);
|
||||
|
||||
$playlist = Playlist::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(route('comment_playlist', ['id' => $playlist->id]), [
|
||||
'content' => 'foo',
|
||||
'anonymous' => 0,
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('playlists.show', [
|
||||
'id' => $playlist->id,
|
||||
'hash' => '#comments',
|
||||
]))->assertSessionHas('success', 'Your Comment Has Been Added!');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function quickthanks_returns_an_ok_response(): void
|
||||
{
|
||||
$this->seed(UsersTableSeeder::class);
|
||||
$this->seed(GroupsTableSeeder::class);
|
||||
$this->seed(BotsTableSeeder::class);
|
||||
$this->seed(ChatroomTableSeeder::class);
|
||||
|
||||
$user = User::factory()->create([
|
||||
'can_comment' => true,
|
||||
]);
|
||||
|
||||
$torrent = Torrent::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(route('comment_thanks', ['id' => $torrent->id]));
|
||||
|
||||
$response->assertRedirect(route('torrent', ['id' => $torrent->id]))
|
||||
->assertSessionHas('success', 'Your Comment Has Been Added!');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function request_returns_an_ok_response(): void
|
||||
{
|
||||
$this->seed(UsersTableSeeder::class);
|
||||
$this->seed(GroupsTableSeeder::class);
|
||||
$this->seed(BotsTableSeeder::class);
|
||||
$this->seed(ChatroomTableSeeder::class);
|
||||
|
||||
$user = User::factory()->create([
|
||||
'can_comment' => true,
|
||||
]);
|
||||
|
||||
$torrentRequest = TorrentRequest::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(route('comment_request', ['id' => $torrentRequest->id]), [
|
||||
'content' => 'foo',
|
||||
'anonymous' => 0,
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('request', ['id' => $torrentRequest->id, 'hash' => '#comments']))
|
||||
->assertSessionHas('success', 'Your Comment Has Been Added!');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function torrent_returns_an_ok_response(): void
|
||||
{
|
||||
$this->seed(UsersTableSeeder::class);
|
||||
$this->seed(GroupsTableSeeder::class);
|
||||
$this->seed(BotsTableSeeder::class);
|
||||
$this->seed(ChatroomTableSeeder::class);
|
||||
|
||||
$user = User::factory()->create([
|
||||
'can_comment' => true,
|
||||
]);
|
||||
|
||||
$torrent = Torrent::factory()->create([
|
||||
'user_id' => $user->id,
|
||||
'status' => 1,
|
||||
]);
|
||||
|
||||
$response = $this->actingAs($user)->post(route('comment_torrent', ['id' => $torrent->id]), [
|
||||
'content' => 'foo',
|
||||
'anonymous' => 0,
|
||||
]);
|
||||
|
||||
$response->assertRedirect(route('torrent', ['id' => $torrent->id, 'hash' => '#comments']))
|
||||
->assertSessionHas('success', 'Your Comment Has Been Added!');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Tests\Todo\Feature\Http\Controllers;
|
||||
|
||||
use Tests\TestCase;
|
||||
|
||||
/**
|
||||
* @see \App\Http\Controllers\CommentController
|
||||
*/
|
||||
class CommentControllerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function store_comment_returns_an_ok_response(): void
|
||||
{
|
||||
$this->markTestIncomplete('This test case was generated by Shift. When you are ready, remove this line and complete this test case.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function delete_comment_returns_an_ok_response(): void
|
||||
{
|
||||
$this->markTestIncomplete('This test case was generated by Shift. When you are ready, remove this line and complete this test case.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @test
|
||||
*/
|
||||
public function edit_comment_returns_an_ok_response(): void
|
||||
{
|
||||
$this->markTestIncomplete('This test case was generated by Shift. When you are ready, remove this line and complete this test case.');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user