Skip to content

Commit 0054d7d

Browse files
committed
share conversations of a user
1 parent f4201ba commit 0054d7d

File tree

5 files changed

+111
-4
lines changed

5 files changed

+111
-4
lines changed

app/Http/Middleware/HandleInertiaRequests.php

+3
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22

33
namespace App\Http\Middleware;
44

5+
use App\Models\Conversation;
56
use Illuminate\Foundation\Inspiring;
67
use Illuminate\Http\Request;
8+
use Illuminate\Support\Facades\Auth;
79
use Inertia\Middleware;
810

911
class HandleInertiaRequests extends Middleware
@@ -45,6 +47,7 @@ public function share(Request $request): array
4547
'auth' => [
4648
'user' => $request->user(),
4749
],
50+
'conversations' => Auth::check() ? Conversation::getConversationsForSidebar(Auth::user()) : [],
4851
];
4952
}
5053
}

app/Models/Conversation.php

+12
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ class Conversation extends Model
4141
*/
4242
protected $guarded = ['id'];
4343

44+
public static function getConversationsForSidebar(User|null $user)
45+
{
46+
$users = User::getUsersExceptUSer($user);
47+
$groups = Group::getGroupsForUser($user);
48+
49+
return $users->map(function (User $user){
50+
return $user->toConversationArray();
51+
})->concat($groups->map(function (Group $group){
52+
return $group->toConversationArray();
53+
}));
54+
}
55+
4456

4557
public function lastMessage(): BelongsTo
4658
{

app/Models/Group.php

+29
Original file line numberDiff line numberDiff line change
@@ -66,4 +66,33 @@ public function lastMessage(): BelongsTo
6666
return $this->belongsTo(Message::class, 'last_message_id');
6767
}
6868

69+
public static function getGroupsForUser(User|null $user)
70+
{
71+
return self::select(['groups.*', 'messages.content as last_message', 'messages.created_at as last_message_date'])
72+
->join('group_user', 'group_user.group_id', '=', 'groups.id')
73+
->leftJoin('messages', 'messages.id', '=', 'groups.last_message_id')
74+
->where('group_user.user_id', '=', $user->id)
75+
->orderByDesc('messages.created_at')
76+
->orderBy('groups.name')
77+
->get();
78+
}
79+
80+
public function toConversationArray()
81+
{
82+
return [
83+
'id' => $this->id,
84+
'name' => $this->name,
85+
'description' => $this->description,
86+
'is_group' => true,
87+
'is_user' => false,
88+
'is_admin' => false,
89+
'users' => $this->users,
90+
'user_ids' => $this->users->pluck('id')->toArray(),
91+
'created_at' => $this->created_at,
92+
'updated_at' => $this->updated_at,
93+
'last_message' => $this->last_message,
94+
'last_message_date' => $this->last_message_date
95+
];
96+
}
97+
6998
}

app/Models/User.php

+35-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use Illuminate\Notifications\Notifiable;
1010

1111
/**
12-
*
12+
*
1313
*
1414
* @property int $id
1515
* @property string $name
@@ -89,4 +89,38 @@ public function groups(): BelongsToMany
8989
{
9090
return $this->belongsToMany(Group::class, 'group_user');
9191
}
92+
93+
public static function getUsersExceptUSer(User $user): \Illuminate\Database\Eloquent\Collection
94+
{
95+
return User::select(['users.*', 'messages.content as last_message', 'messages.created_at as last_message_date'])
96+
->where('users.id', '!=', $user->id)
97+
->when(!$user->is_admin, function ($query) {
98+
$query->whereNull('users.blocked_at');
99+
})->leftJoin('conversations', function($join) use ($user) {
100+
$join->on('conversations.user_id1', '=', 'users.id')
101+
->where('conversations.user_id2', '=', $user->id)
102+
->orWhere(function($query) use ($user) {
103+
$query->on('conversations.user_id2', '=', 'users.id')
104+
->where('conversations.user_id1', '=', $user->id);
105+
});
106+
})->leftJoin('messages', 'messages.id', '=', 'conversations.last_message_id')
107+
->orderByRaw('IFNULL(users.blocked_at, 1)')
108+
->orderByDesc('messages.created_at')
109+
->get();
110+
}
111+
112+
public function toConversationArray()
113+
{
114+
return [
115+
'id' => $this->id,
116+
'name' => $this->name,
117+
'is_group' => false,
118+
'is_user' => true,
119+
'is_admin' => (bool) $this->is_admin,
120+
'created_at' => $this->created_at,
121+
'updated_at' => $this->updated_at,
122+
'last_message' => $this->last_message,
123+
'last_message_date' => $this->last_message_date
124+
];
125+
}
92126
}

resources/js/layouts/chat/chat-sidebar-layout.tsx

+32-3
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,46 @@ import { ChatSidebar } from '@/components/chat-sidebar';
33
import { AppContent } from '@/components/app-content';
44
import { ChatShell } from '@/components/chat-shell';
55
import ChatHeaderLayout from '@/layouts/chat/chat-header-layout';
6-
import { useEffect, useState } from 'react';
6+
import { useEffect, useState, useMemo } from 'react';
77

88
const ChatSidebarLayout = ({children, breadcrumbs = []}) => {
99
const page = usePage();
10-
const conversations = page.props.conversations;
10+
const conversations = useMemo(() => page.props.conversations ?? [], [page.props.conversations])
1111
const selectedConversation = page.props.selectedConversation;
12-
const [onlineUsers, setOnlineUsers] = useState({});
12+
const [onlineUsers, setOnlineUsers] = useState([]);
13+
const [localConversations, setLocalConversations] = useState([]);
14+
const [sortedConversations, setSortedConversations] = useState([]);
15+
16+
const isUserOnline = (userId) => onlineUsers[userId];
1317

1418
console.log("conversations :", conversations);
1519
console.log("selectedConversation ", selectedConversation);
1620

21+
useEffect(() => {
22+
setSortedConversations(
23+
localConversations.sort((a,b) => {
24+
if(a.blocked_at && b.blocked_at) {
25+
return a.blocked_at > b.blocked_at ? 1 : -1;
26+
}else if(a.blocked_at){
27+
return 1;
28+
}else if (b.blocked_at){
29+
return -1;
30+
}
31+
if (a.last_message_date && b.last_message_date){
32+
return b.last_message_date.localeCompare(a.last_message_date)
33+
} else if (a.last_message_date){
34+
return -1
35+
} if ( b.last_message_date){
36+
return 1
37+
}else return 0;
38+
})
39+
)
40+
}, [localConversations]);
41+
42+
useEffect(() => {
43+
setLocalConversations(conversations)
44+
}, [conversations]);
45+
1746
useEffect(() => {
1847
Echo.join('online')
1948
.here((users)=>{

0 commit comments

Comments
 (0)