feat: add Reverb realtime messaging

This commit is contained in:
2026-03-21 12:51:59 +01:00
parent 60f78e8235
commit e8b5edf5d2
45 changed files with 3609 additions and 339 deletions

View File

@@ -5,6 +5,7 @@ namespace App\Http\Controllers\Api\Messaging;
use App\Events\TypingStarted;
use App\Events\TypingStopped;
use App\Http\Controllers\Controller;
use App\Models\Conversation;
use App\Models\ConversationParticipant;
use Illuminate\Cache\Repository;
use Illuminate\Http\JsonResponse;
@@ -15,13 +16,13 @@ class TypingController extends Controller
{
public function start(Request $request, int $conversationId): JsonResponse
{
$this->assertParticipant($request, $conversationId);
$this->findConversationOrFail($conversationId);
$ttl = max(5, (int) config('messaging.typing.ttl_seconds', 8));
$this->store()->put($this->key($conversationId, (int) $request->user()->id), 1, now()->addSeconds($ttl));
if ((bool) config('messaging.realtime', false)) {
event(new TypingStarted($conversationId, (int) $request->user()->id));
event(new TypingStarted($conversationId, $request->user()));
}
return response()->json(['ok' => true]);
@@ -29,11 +30,11 @@ class TypingController extends Controller
public function stop(Request $request, int $conversationId): JsonResponse
{
$this->assertParticipant($request, $conversationId);
$this->findConversationOrFail($conversationId);
$this->store()->forget($this->key($conversationId, (int) $request->user()->id));
if ((bool) config('messaging.realtime', false)) {
event(new TypingStopped($conversationId, (int) $request->user()->id));
event(new TypingStopped($conversationId, $request->user()));
}
return response()->json(['ok' => true]);
@@ -41,7 +42,7 @@ class TypingController extends Controller
public function index(Request $request, int $conversationId): JsonResponse
{
$this->assertParticipant($request, $conversationId);
$this->findConversationOrFail($conversationId);
$userId = (int) $request->user()->id;
$participants = ConversationParticipant::query()
@@ -93,4 +94,12 @@ class TypingController extends Controller
return Cache::store();
}
}
private function findConversationOrFail(int $conversationId): Conversation
{
$conversation = Conversation::query()->findOrFail($conversationId);
$this->authorize('view', $conversation);
return $conversation;
}
}