Skip to content

Commit

Permalink
add: livewire chat
Browse files Browse the repository at this point in the history
  • Loading branch information
Roardom committed Jul 6, 2023
1 parent f9c965a commit 2d312da
Show file tree
Hide file tree
Showing 20 changed files with 450 additions and 2,335 deletions.
51 changes: 51 additions & 0 deletions app/Events/CreateMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* NOTICE OF LICENSE.
*
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D Community Edition
*
* @author HDVinnie <hdinnovations@protonmail.com>
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
*/

namespace App\Events;

use App\Models\Message;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PresenceChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class CreateMessage implements ShouldBroadcastNow
{
use Dispatchable;
use InteractsWithSockets;
use SerializesModels;

public Message $message;

/**
* Create a new event instance.
*/
public function __construct(Message $message)
{
$this->message = $message->load([
'user:id,username,group_id' => [
'group:id,name,icon,color',
'chatStatus:id,name,color',
]
]);
}

/**
* Get the channels the event should broadcast on.
*/
public function broadcastOn(): PresenceChannel
{
return new PresenceChannel('messages.'.$this->message->chatroom_id.'.create');
}
}
43 changes: 43 additions & 0 deletions app/Events/DestroyMessage.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php
/**
* NOTICE OF LICENSE.
*
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D Community Edition
*
* @author HDVinnie <hdinnovations@protonmail.com>
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
*/

namespace App\Events;

use App\Models\Message;
use Illuminate\Broadcasting\InteractsWithSockets;
use Illuminate\Broadcasting\PrivateChannel;
use Illuminate\Contracts\Broadcasting\ShouldBroadcastNow;
use Illuminate\Foundation\Events\Dispatchable;
use Illuminate\Queue\SerializesModels;

class DestroyMessage implements ShouldBroadcastNow
{
use Dispatchable;
use InteractsWithSockets;
use SerializesModels;

/**
* Create a new event instance.
*/
public function __construct(public Message $message)
{
}

/**
* Get the channels the event should broadcast on.
*/
public function broadcastOn(): PrivateChannel
{
return new PrivateChannel('messages.'.$this->message->chatroom_id.'.destroy');
}
}
192 changes: 192 additions & 0 deletions app/Http/Livewire/Messages.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
<?php
/**
* NOTICE OF LICENSE.
*
* UNIT3D Community Edition is open-sourced software licensed under the GNU Affero General Public License v3.0
* The details is bundled with this project in the file LICENSE.txt.
*
* @project UNIT3D Community Edition
*
* @author HDVinnie <hdinnovations@protonmail.com>
* @license https://www.gnu.org/licenses/agpl-3.0.en.html/ GNU Affero General Public License v3.0
*/

namespace App\Http\Livewire;

use App\Events\CreateMessage;
use App\Events\DestroyMessage;
use App\Models\Chatroom;
use App\Models\ChatStatus;
use App\Models\Message;
use App\Models\User;
use Livewire\Component;

class Messages extends Component
{
public ?int $chatroomId = null;

public ?int $chatStatusId = null;

public ?User $user = null;

public string $message = "";

public array $messages = [];

public array $users = [];

protected $rules = [
'chatroomId' => [
'required',
'exists:chatrooms,id',
],
'message' => [
'required',
'max:65535',
]
];

/*
* Lifecycle hooks
*/

final public function mount(): void
{
$this->user = auth()->user();
$this->chatroomId = $this->user->chatroom_id;
$this->chatStatusId = $this->user->chat_status_id;
$this->messages = $this->initialMessages();
}

final public function updatedChatroomId(int $value): void
{
$this->dispatchBrowserEvent('updatedChatroomId', [
'previous' => $this->user->chatroom_id,
'new' => $value
]);

$this->user->chatroom_id = $value;
$this->user->save();

$this->messages = $this->initialMessages();
}

final public function updatedChatStatusId(int $value): void
{
$this->user->chat_status_id = $value;
$this->user->save();
}

/*
* Listeners
*/

public function getListeners(): array
{
return [
'listenCreateMessage',
'listenDestroyMessage',
'chatroomUsersIndex',
'chatroomUsersStore',
'chatroomUsersDestroy',
];
}

final public function listenCreateMessage(array $event): void
{
$this->messages[$event['message']['id']] = $event['message'];
}

final public function listenDestroyMessage(array $event): void
{
unset($this->messages[$event['message']['id']]);
}

final public function chatroomUsersIndex(array $event): void
{
$this->users = collect($event)->keyBy('id')->toArray();
}

final public function chatroomUsersStore(array $event): void
{
$this->users[$event['id']] = $event;
}

final public function chatroomUsersDestroy(array $event): void
{
unset($this->users[$event['id']]);
}

/*
* Actions
*/

final public function store(): void
{
$this->validate();

// switch (mb_substr($this->message, 0, 1)) {
// case '/msg ':
// case '/gift ':
// }

$message = Message::create([
'user_id' => $this->user->id,
'chatroom_id' => $this->chatroomId,
'message' => $this->message,
]);

$this->message = '';

CreateMessage::dispatch($message);
}

final public function destroy(Message $message): void
{
abort_unless($message->user_id === $this->user->id || $this->user->group->is_modo, 403);

$message->delete();

DestroyMessage::dispatch($message);
}

// Custom methods

final public function initialMessages(): array
{
return Message::where('chatroom_id', '=', $this->chatroomId)
->select(['id', 'user_id', 'message', 'created_at'])
->with(['user:id,username,group_id' => ['group:id,name,icon,color']])
->latest()
->limit(100)
->get()
->keyBy('id')
->toArray();
}

/*
* Properties
*/

final public function getChatroomsProperty(): \Illuminate\Database\Eloquent\Collection
{
return Chatroom::all();
}

final public function getChatStatusesProperty(): \Illuminate\Database\Eloquent\Collection
{
return ChatStatus::all();
}

/*
* Rendering
*/

final public function render(): \Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View|\Illuminate\Contracts\Foundation\Application
{
return view('livewire.messages', [
'chatrooms' => $this->chatrooms,
'chatStatuses' => $this->chatStatuses
]);
}
}
Loading

0 comments on commit 2d312da

Please sign in to comment.