Skip to content

Commit 6b6d889

Browse files
authored
Reactions Widgets and Documentation (#24)
- Added a Reactions view component - Added documentation for using Reactions - Added Open-source documentation section - Improved the documentation intro
2 parents 93c09b2 + a843c23 commit 6b6d889

File tree

5 files changed

+168
-12
lines changed

5 files changed

+168
-12
lines changed

README.md

Lines changed: 132 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Add Nested comments/replies to filament forms, infolists and resources
1+
# Filament Nested Comments & Emoji Reactions
22

33
[![Latest Version on Packagist](https://img.shields.io/packagist/v/coolsam/nested-comments.svg?style=flat-square)](https://packagist.org/packages/coolsam/nested-comments)
44
[![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/coolsam726/nested-comments/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/coolsam726/nested-comments/actions?query=workflow%3Arun-tests+branch%3Amain)
@@ -7,7 +7,6 @@
77
[![Total Downloads](https://img.shields.io/packagist/dt/coolsam/nested-comments.svg?style=flat-square)](https://packagist.org/packages/coolsam/nested-comments)
88

99

10-
1110
This package allows you to incorporate comments and replies in your Filament forms, infolists, pages, widgets etc, or even simply in your livewire components. Comment replies can be nested as deep as you want, using the Nested Set data structure. Additionally, the package comes with a Reactions feature to enable your users to react to any of your models (e.g comments or posts) with selected emoji reactions.
1211

1312
![image](https://github.com/user-attachments/assets/2900e2a4-9ad2-40e2-8819-2650b6d70803)
@@ -210,13 +209,144 @@ $record = Conference::find(1); // Get your record from the database then,
210209
<livewire:nested-comments::comments :record="$record"/>
211210
```
212211

212+
### Mentions
213+
The package uses Filament TipTap Editor which supports mentions. You can mention users in your comments by typing `@` followed by the user's name. The package will automatically resolve the user and send them a notification.
214+
You can customize how to fetch mentions by changing the `.closures.getMentionsUsing` closure in the config file. Two sample methods have been included in the main class for getting all users in the DB or only users that have been mentioned in the current thread (default). Customize this however you wish.
215+
216+
**Get only users mentioned in the current thread:**
217+
218+
```php
219+
[
220+
'getMentionsUsing' => fn (
221+
string $query,
222+
Model $commentable
223+
) => app(\Coolsam\NestedComments\NestedComments::class)->getCurrentThreadUsers($query, $commentable),
224+
]
225+
```
226+
227+
**Get all users from your database**
228+
229+
```php
230+
[
231+
'getMentionsUsing' => 'getMentionsUsing' => fn (string $query, Model $commentable) => app(\Coolsam\NestedComments\NestedComments::class)->getUserMentions($query),
232+
]
233+
```
234+
![image](https://github.com/user-attachments/assets/bd7a395a-fc32-4057-b6bc-24763132f555)
235+
236+
237+
## Usage: Emoji Reactions
238+
This package also allows you to add emoji reactions to your models. You can use the `HasReactions` trait to add reactions to any model. The reactions are stored in a separate table, and you can customize the reactions that are available via the configuration file.
239+
The Comments model that powers the comments feature described above already uses emoji reactions.
240+
241+
In order to start using reactions for your model, add the `HasReactions` trait to your model. You can then use the `reactions` method to get the reactions for the model.
242+
243+
```php
244+
use Coolsam\NestedComments\Traits\HasReactions;
245+
246+
class Conference extends Model
247+
{
248+
use HasReactions;
249+
250+
// ...
251+
}
252+
```
253+
The above trait adds the `react()` method to your model, allowing you to toggle a reaction for the model. You can also use the `reactions` method to get the reactions for the model.
254+
255+
```php
256+
$conference = Conference::find(1);
257+
$comference->react('👍'); // React to the conference with a thumbs up emoji
258+
```
259+
You can also use the `reactions` method to get the reactions for the model.
260+
261+
```php
262+
$conference = Conference::find(1);
263+
$reactions = $conference->reactions; // Get the reactions for the conference
264+
```
265+
Other useful methods include
266+
```php
267+
/**
268+
* @var \Illuminate\Database\Eloquent\Model&\Coolsam\NestedComments\Concerns\HasReactions $conference
269+
*/
270+
$conference = Conference::find(1);
271+
$conference->total_reactions; // Get the total number of reactions for the conference
272+
$conference->reactions_counts; // Get the no of reactions for each emoji for the model
273+
$conference->my_reactions; // Get the reactions for the current user
274+
$conference->emoji_reactors // Get the list of users who reacted to the model, grouped by emoji
275+
$conference->isAllowed('👍') // check if the app allows the user to react with the specified emoji
276+
$conference->reactions_map // return the map of all the reactions for the model, grouped by emoji. This tells you the number of reactions for each emoji, and whether the current user has reacted with that emoji
277+
```
278+
To interact with the methods above with ease within and even outside Filament, this package comes with the following handy components:
279+
280+
### Reactions Infolist Entry
281+
```php
282+
use Coolsam\NestedComments\Filament\Infolists\ReactionsEntry;
283+
284+
public static function infolist(Infolist $infolist): Infolist
285+
{
286+
return $infolist
287+
->schema([
288+
Section::make('Basic Details')
289+
->schema([
290+
TextEntry::make('name'),
291+
TextEntry::make('start_date')
292+
->dateTime(),
293+
TextEntry::make('end_date')
294+
->dateTime(),
295+
TextEntry::make('created_at')
296+
->dateTime(),
297+
// Add the reactions entry
298+
ReactionsEntry::make('reactions')->columnSpanFull(),
299+
])->columns(4),
300+
]);
301+
}
302+
```
303+
![image](https://github.com/user-attachments/assets/06ae7e76-1668-4e92-9a4f-a125f7d94b03)
304+
305+
### Reactions Blade Component
306+
Just include the blade component anywhere in your blade file and pass the model record to it.
307+
```php
308+
$record = Conference::find(1); // Get your record from the database then,
309+
```
310+
In your view:
311+
```bladehtml
312+
<x-nested-comments::reactions :record="$record"/>
313+
```
314+
315+
### Reactions Livewire Component
316+
Similar to the blade component, you can use the Livewire component anywhere in your Livewire component and pass the model record to it.
317+
```php
318+
$record = Conference::find(1); // Get your record from the database then,
319+
```
320+
In your view:
321+
```bladehtml
322+
<livewire:nested-comments::reaction-panel :record="$record"/>
323+
```
324+
The two components can be used anywhere, in resource pages, custom pages, actions, form fields, widgets, livewire components or just plain blade views. Here is a sample screenshot of how the components will be rendered:
325+
![image](https://github.com/user-attachments/assets/0162f294-0477-454c-ae5c-67424edc207f)
326+
327+
328+
## Package Customization
329+
You can customize the package by changing most of the default values in the config file after publishing it.
213330

214331
## Testing
215332

216333
```bash
217334
composer test
218335
```
219336

337+
## Open Source Dependencies
338+
339+
This package uses the following awesome open source packages, among many others under the hood:
340+
341+
* [Filament](https://filamentphp.com/)
342+
* [Livewire](https://livewire.laravel.com/)
343+
* [Laravel](https://laravel.com/)
344+
* [AlpineJS](https://alpinejs.dev/)
345+
* [Laravel NestedSet](https://github.com/lazychaser/laravel-nestedset)
346+
* [Filament Tiptap Editor](https://github.com/awcodes/filament-tiptap-editor)
347+
348+
I am grateful for the work that has been put into these packages. They have made it possible to build this package in a short time.
349+
220350
## Changelog
221351

222352
Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
@props([
2+
'record'
3+
])
4+
@if(isset($record))
5+
@if(app(\Coolsam\NestedComments\NestedComments::class)->classHasTrait($record, \Coolsam\NestedComments\Concerns\HasReactions::class))
6+
<livewire:nested-comments::reaction-panel :record="$record"/>
7+
@else
8+
<p>__('The current record is not configured for reactions. Please include the `HasReactions` trait to the model.')</p>
9+
@endif
10+
@endif
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
2+
<x-nested-comments::reactions :record="$getRecord()" />
3+
</x-dynamic-component>

src/Concerns/HasReactions.php

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,20 @@ public function getReactionsCountsAttribute()
3232
});
3333
}
3434

35-
public function getEmojiReactors()
35+
public function getEmojiReactorsAttribute()
3636
{
37-
return $this->reactions()->get(['id', 'emoji', 'user_id', 'guest_id'])->groupBy('emoji')->map(function ($item) {
38-
return $item->map(function ($reaction) {
39-
return [
40-
'id' => $reaction->getKey(),
41-
'user_id' => $reaction->getAttribute('user_id'),
42-
'guest_id' => $reaction->getAttribute('guest_id'),
43-
'name' => $reaction->getAttribute('user_id') ? call_user_func(config('nested-comments.closures.getUserNameUsing'), $reaction->getAttribute('user')) : $reaction->getAttribute('guest_name'),
44-
];
37+
return $this->reactions()->get(['id', 'emoji', 'user_id', 'guest_id', 'guest_name'])
38+
->groupBy('emoji')
39+
->map(function (Collection $item) {
40+
return $item->map(function ($reaction) {
41+
return [
42+
'id' => $reaction->getKey(),
43+
'user_id' => $reaction->getAttribute('user_id'),
44+
'guest_id' => $reaction->getAttribute('guest_id'),
45+
'name' => $reaction->getAttribute('user_id') ? call_user_func(config('nested-comments.closures.getUserNameUsing'), $reaction->getAttribute('user')) : $reaction->getAttribute('guest_name'),
46+
];
47+
});
4548
});
46-
});
4749
}
4850

4951
public function getMyReactionsAttribute(): array
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Coolsam\NestedComments\Filament\Infolists;
4+
5+
use Filament\Infolists\Components\Entry;
6+
7+
class ReactionsEntry extends Entry
8+
{
9+
/** @phpstan-ignore-next-line */
10+
protected string $view = 'nested-comments::filament.infolists.reactions-entry';
11+
}

0 commit comments

Comments
 (0)