feat: initial release of relaticle/comments
Filament comments package with: - Polymorphic commenting on any Eloquent model - Threaded replies with configurable depth - @mentions with autocomplete and user search - Emoji reactions with toggle and who-reacted tooltips - File attachments via Livewire uploads - Reply and mention notifications via Filament notification system - Thread subscriptions for notification control - Real-time broadcasting (opt-in Echo) with polling fallback - Dark mode support - CommentsAction, CommentsTableAction, CommentsEntry for Filament integration - 204 tests, 421 assertions
This commit is contained in:
48
src/Filament/Actions/CommentsAction.php
Normal file
48
src/Filament/Actions/CommentsAction.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Relaticle\Comments\Filament\Actions;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Relaticle\Comments\Concerns\HasComments;
|
||||
|
||||
class CommentsAction extends Action
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this
|
||||
->label(__('Comments'))
|
||||
->icon('heroicon-o-chat-bubble-left-right')
|
||||
->slideOver()
|
||||
->modalHeading(__('Comments'))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelAction(false)
|
||||
->modalContent(function (): View {
|
||||
return view('comments::filament.comments-action', [
|
||||
'record' => $this->getRecord(),
|
||||
]);
|
||||
})
|
||||
->badge(function (): ?int {
|
||||
$record = $this->getRecord();
|
||||
|
||||
if (! $record) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! in_array(HasComments::class, class_uses_recursive($record))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$count = $record->commentCount();
|
||||
|
||||
return $count > 0 ? $count : null;
|
||||
});
|
||||
}
|
||||
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'comments';
|
||||
}
|
||||
}
|
||||
48
src/Filament/Actions/CommentsTableAction.php
Normal file
48
src/Filament/Actions/CommentsTableAction.php
Normal file
@@ -0,0 +1,48 @@
|
||||
<?php
|
||||
|
||||
namespace Relaticle\Comments\Filament\Actions;
|
||||
|
||||
use Filament\Actions\Action;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Relaticle\Comments\Concerns\HasComments;
|
||||
|
||||
class CommentsTableAction extends Action
|
||||
{
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this
|
||||
->label(__('Comments'))
|
||||
->icon('heroicon-o-chat-bubble-left-right')
|
||||
->slideOver()
|
||||
->modalHeading(__('Comments'))
|
||||
->modalSubmitAction(false)
|
||||
->modalCancelAction(false)
|
||||
->modalContent(function (): View {
|
||||
return view('comments::filament.comments-action', [
|
||||
'record' => $this->getRecord(),
|
||||
]);
|
||||
})
|
||||
->badge(function (): ?int {
|
||||
$record = $this->getRecord();
|
||||
|
||||
if (! $record) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! in_array(HasComments::class, class_uses_recursive($record))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$count = $record->commentCount();
|
||||
|
||||
return $count > 0 ? $count : null;
|
||||
});
|
||||
}
|
||||
|
||||
public static function getDefaultName(): ?string
|
||||
{
|
||||
return 'comments';
|
||||
}
|
||||
}
|
||||
17
src/Filament/Infolists/Components/CommentsEntry.php
Normal file
17
src/Filament/Infolists/Components/CommentsEntry.php
Normal file
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Relaticle\Comments\Filament\Infolists\Components;
|
||||
|
||||
use Filament\Infolists\Components\Entry;
|
||||
|
||||
class CommentsEntry extends Entry
|
||||
{
|
||||
protected string $view = 'comments::filament.infolists.components.comments-entry';
|
||||
|
||||
protected function setUp(): void
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
$this->columnSpanFull();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user