Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
],
"require": {
"php": "^8.2",
"awcodes/filament-tiptap-editor": "^3.5",
"filament/filament": "^3",
"kalnoy/nestedset": "^6.0",
"spatie/laravel-package-tools": "^1.15.0"
Expand Down
2 changes: 2 additions & 0 deletions config/nested-comments.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,7 @@
'closures' => [
'getUserNameUsing' => fn (Authenticatable | Model $user) => $user->getAttribute('name'),
'getUserAvatarUsing' => fn (Authenticatable | Model | string $user) => app(\Coolsam\NestedComments\NestedComments::class)->geDefaultUserAvatar($user),
// 'getMentionsUsing' => fn (string $query) => app(\Coolsam\NestedComments\NestedComments::class)->getUserMentions($query), // Get mentions of all users in the DB
'getMentionsUsing' => fn (string $query, Model $commentable) => app(\Coolsam\NestedComments\NestedComments::class)->getCurrentThreadUsers($query, $commentable),
],
];
5 changes: 5 additions & 0 deletions resources/css/index.css
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
@import '../../vendor/filament/filament/resources/css/theme.css';
@import '../../vendor/awcodes/filament-tiptap-editor/resources/css/plugin.css';

.comment-mention, [data-mention-id] {
@apply bg-primary-50 !text-primary-500 dark:bg-gray-700 dark:text-primary-50 dark:border-primary-500 p-1 rounded-full px-2 before:content-["@"];
}
2 changes: 1 addition & 1 deletion resources/dist/nested-comments.css

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion resources/views/livewire/add-comment.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
@if($this->addingComment)
<form wire:submit.prevent="create" wire:loading.attr="disabled" class="space-y-4">
{{ $this->form }}

<x-filament::button type="submit">
Submit
</x-filament::button>
Expand Down
17 changes: 13 additions & 4 deletions resources/views/livewire/comment-card.blade.php
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<div x-data wire:poll.15s>
<div class="my-4 p-4 bg-primary-50 rounded-lg ring-gray-100 dark:bg-gray-950">
<div class="my-4 p-8 bg-gray-50 rounded-lg ring-gray-100 dark:bg-gray-950">
<div class="flex flex-wrap items-center justify-between">
<div x-data="{showFullDate: false}" class="flex items-center space-x-2">
<x-filament::avatar
Expand All @@ -9,7 +9,7 @@
size="md"
:circular="false"
/>
<div x-on:click="showFullDate = !showFullDate" title="{{__('Show full date')}}" class="cursor-pointer">
<div x-on:mouseover="showFullDate = true" x-on:mouseout="showFullDate = false" class="cursor-pointer">
<p class="text-sm font-semibold text-gray-900 dark:text-white">
{{ $this->comment->user?->name }}
</p>
Expand All @@ -30,7 +30,7 @@ class="text-xs text-gray-500 dark:text-gray-400"
<x-filament::link
size="xs"
class="cursor-pointer"
icon="heroicon-o-arrow-uturn-left"
icon="heroicon-s-chat-bubble-left-right"
wire:click.prevent="toggleReplies">
@if($this->comment->replies_count > 0)
<span title="{{ \Illuminate\Support\Number::format($this->comment->replies_count) }}">
Expand Down Expand Up @@ -69,4 +69,13 @@ class="cursor-pointer"
label="Hide replies" icon="heroicon-o-minus-circle" class="absolute -left-8 -bottom-4" wire:click.prevent="toggleReplies"/>
</div>
@endif
</div>
</div>

@script
<script>
document.querySelectorAll('[data-mention-id]').forEach(element => {
// add an @ before using a pseudo-element
element.classList.add(['comment-mention']);
});
</script>
@endscript
2 changes: 1 addition & 1 deletion resources/views/livewire/comments.blade.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<x-filament::section icon="heroicon-o-chat-bubble-bottom-center-text" class="!ring-0">
<x-filament::section class="!ring-0">
<x-slot name="heading">
<div class="flex items-center space-x-2">
<div>
Expand Down
15 changes: 13 additions & 2 deletions src/Livewire/AddComment.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@
namespace Coolsam\NestedComments\Livewire;

use Coolsam\NestedComments\Models\Comment;
use Coolsam\NestedComments\NestedComments;
use Coolsam\NestedComments\NestedCommentsServiceProvider;
use Filament\Forms;
use Filament\Forms\Concerns\InteractsWithForms;
use Filament\Forms\Contracts\HasForms;
use Filament\Forms\Form;
use FilamentTiptapEditor\Concerns\HasFormMentions;
use FilamentTiptapEditor\TiptapEditor;
use Illuminate\Contracts\View\View;
use Illuminate\Database\Eloquent\Model;
use Livewire\Component;
Expand All @@ -17,6 +19,7 @@
*/
class AddComment extends Component implements HasForms
{
use HasFormMentions;
use InteractsWithForms;

public ?array $data = [];
Expand Down Expand Up @@ -48,9 +51,17 @@ public function getCommentable(): Model

public function form(Form $form): Form
{
$mentionsClosure = config('nested-comments.closures.getMentionsUsing', fn (string $query, Model $commentable) => app(NestedComments::class)->getUserMentions($query));

return $form
->schema([
Forms\Components\RichEditor::make('body')->required()->autofocus(true),
TiptapEditor::make('body')
->label(__('Your comment'))
->profile('minimal')
->extraInputAttributes(['style' => 'min-height: 12rem;'])
->getMentionItemsUsing(fn (string $query) => $mentionsClosure($query, $this->getCommentable()))
->required()
->autofocus(),
])
->statePath('data')
->model(config('nested-comments.models.comment', Comment::class));
Expand Down
49 changes: 48 additions & 1 deletion src/NestedComments.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Filament\AvatarProviders\UiAvatarsProvider;
use Filament\Support\Facades\FilamentColor;
use FilamentTiptapEditor\Data\MentionItem;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
Expand All @@ -24,7 +25,10 @@ public function getGuestId(): ?string
public function getGuestName(): string
{
if (Auth::check()) {
return call_user_func(config('nested-comments.closures.getUserNameUsing', fn (Authenticatable | Model $user) => $user->getAttribute('name')), Auth::user());
return call_user_func(config(
'nested-comments.closures.getUserNameUsing',
fn (Authenticatable | Model $user) => $user->getAttribute('name')
), Auth::user());
}

return session(self::GUEST_NAME_FIELD, 'Guest');
Expand Down Expand Up @@ -75,4 +79,47 @@ public function geDefaultUserAvatar(Authenticatable | Model | string $user)
return app(UiAvatarsProvider::class)->get($user);
}
}

public function getUserMentions(string $query)
{
$userModel = config('nested-comments.models.user', config('auth.providers.users.model', 'App\\Models\\User'));

return $userModel::query()
->where('name', 'like', "%{$query}%")
->orWhere('email', 'like', "%{$query}%")
->take(20)
->get()
->map(function ($user) {
return new MentionItem(
id: $user->getKey(),
label: call_user_func(config('nested-comments.closures.getUserNameUsing'), $user),
image: call_user_func(config('nested-comments.closures.getUserAvatarUsing'), $user),
roundedImage: true,
);
})->toArray();
}

public function getCurrentThreadUsers(string $searchQuery, Model $commentable)
{
$userModel = config('nested-comments.models.user', config('auth.providers.users.model', 'App\\Models\\User'));
$ids = $commentable->comments()->pluck('user_id')->filter()->unique()->toArray();

return $userModel::query()
->whereIn('id', $ids)
->where(
fn ($q) => $q
->where('name', 'like', "%{$searchQuery}%")
->orWhere('email', 'like', "%{$searchQuery}%")
)
->take(20)
->get()
->map(function ($user) {
return new MentionItem(
id: $user->getKey(),
label: call_user_func(config('nested-comments.closures.getUserNameUsing'), $user),
image: call_user_func(config('nested-comments.closures.getUserAvatarUsing'), $user),
roundedImage: true,
);
})->toArray();
}
}
22 changes: 21 additions & 1 deletion src/NestedCommentsServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@
use Filament\Support\Assets\Js;
use Filament\Support\Facades\FilamentAsset;
use Filament\Support\Facades\FilamentIcon;
use Illuminate\Console\Command;
use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Facades\Artisan;
use Livewire\Features\SupportTesting\Testable;
use Livewire\Livewire;
use Spatie\LaravelPackageTools\Commands\InstallCommand;
Expand All @@ -38,7 +40,25 @@ public function configurePackage(Package $package): void
->hasCommands($this->getCommands())
->hasInstallCommand(function (InstallCommand $command) {
$command
->publishConfigFile()
->startWith(function (Command $command) {
$command->comment('Publishing config file...');
$forceConfig = $command->confirm(__('Do you want to override existing config file?'), false);
Artisan::call('vendor:publish', [
'--tag' => 'nested-comments-config',
'--force' => $forceConfig,
]);
$command->info('Config file published successfully.');

$forceAssets = $command->confirm(__('Do you want to override existing assets with new assets?'), true);
if ($forceAssets) {
// Delete the existing assets in public/css/coolsam and public/js/coolsam
$filesystem = app(Filesystem::class);
$filesystem->deleteDirectory(public_path('css/coolsam/nested-comments'));
$filesystem->deleteDirectory(public_path('js/coolsam/nested-comments'));
Artisan::call('filament:assets');
}
})
->publishAssets()
->publishMigrations()
->askToRunMigrations()
->askToStarRepoOnGitHub('coolsam/nested-comments');
Expand Down
1 change: 1 addition & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ module.exports = {
'./src/**/*.php',
'./resources/views/**/*.blade.php',
'./vendor/filament/**/*.blade.php',
'./vendor/awcodes/filament-tiptap-editor/resources/**/*.blade.php',
],
}