|
3 | 3 | namespace Musonza\Chat\Models; |
4 | 4 |
|
5 | 5 | use Chat; |
| 6 | +use Illuminate\Contracts\Pagination\CursorPaginator; |
6 | 7 | use Illuminate\Contracts\Pagination\LengthAwarePaginator; |
7 | 8 | use Illuminate\Database\Eloquent\Model; |
8 | 9 | use Illuminate\Database\Eloquent\Relations\HasMany; |
@@ -89,6 +90,21 @@ public function getMessages(Model $participant, $paginationParams, $deleted = fa |
89 | 90 | return $this->getConversationMessages($participant, $paginationParams, $deleted); |
90 | 91 | } |
91 | 92 |
|
| 93 | + /** |
| 94 | + * Get messages for a conversation using cursor-based pagination. |
| 95 | + * |
| 96 | + * Cursor pagination is more suitable for real-time chat applications |
| 97 | + * as it avoids duplicate messages when new messages arrive between page loads. |
| 98 | + * |
| 99 | + * @param array $paginationParams |
| 100 | + * @param bool $deleted |
| 101 | + * @return CursorPaginator |
| 102 | + */ |
| 103 | + public function getMessagesWithCursor(Model $participant, $paginationParams, $deleted = false) |
| 104 | + { |
| 105 | + return $this->getConversationMessagesWithCursor($participant, $paginationParams, $deleted); |
| 106 | + } |
| 107 | + |
92 | 108 | public function getParticipantConversations($participant, array $options) |
93 | 109 | { |
94 | 110 | return $this->getConversationsList($participant, $options); |
@@ -324,6 +340,37 @@ private function getConversationMessages(Model $participant, $paginationParams, |
324 | 340 | return $messages; |
325 | 341 | } |
326 | 342 |
|
| 343 | + /** |
| 344 | + * Get messages in conversation using cursor-based pagination. |
| 345 | + * |
| 346 | + * @return CursorPaginator |
| 347 | + */ |
| 348 | + private function getConversationMessagesWithCursor(Model $participant, $paginationParams, $deleted) |
| 349 | + { |
| 350 | + $messages = $this->messages() |
| 351 | + ->join($this->tablePrefix . 'message_notifications', $this->tablePrefix . 'message_notifications.message_id', '=', $this->tablePrefix . 'messages.id') |
| 352 | + ->where($this->tablePrefix . 'message_notifications.messageable_type', $participant->getMorphClass()) |
| 353 | + ->where($this->tablePrefix . 'message_notifications.messageable_id', $participant->getKey()); |
| 354 | + $messages = $deleted ? $messages->whereNotNull($this->tablePrefix . 'message_notifications.deleted_at') : $messages->whereNull($this->tablePrefix . 'message_notifications.deleted_at'); |
| 355 | + $messages = $messages->orderBy($this->tablePrefix . 'messages.id', $paginationParams['sorting']) |
| 356 | + ->cursorPaginate( |
| 357 | + $paginationParams['perPage'], |
| 358 | + [ |
| 359 | + $this->tablePrefix . 'message_notifications.updated_at as read_at', |
| 360 | + $this->tablePrefix . 'message_notifications.deleted_at as deleted_at', |
| 361 | + $this->tablePrefix . 'message_notifications.messageable_id', |
| 362 | + $this->tablePrefix . 'message_notifications.id as notification_id', |
| 363 | + $this->tablePrefix . 'message_notifications.is_seen', |
| 364 | + $this->tablePrefix . 'message_notifications.is_sender', |
| 365 | + $this->tablePrefix . 'messages.*', |
| 366 | + ], |
| 367 | + $paginationParams['cursorName'] ?? 'cursor', |
| 368 | + $paginationParams['cursor'] ?? null |
| 369 | + ); |
| 370 | + |
| 371 | + return $messages; |
| 372 | + } |
| 373 | + |
327 | 374 | /** |
328 | 375 | * @return mixed |
329 | 376 | */ |
|
0 commit comments