367 lines
12 KiB
PHP
367 lines
12 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\User;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
class ConversationApiController extends Controller
|
|
{
|
|
private function ensureUserConversation($user)
|
|
{
|
|
// Return existing conversation ID for user, or null if none created
|
|
return DB::table('mobile_conversation_participants')
|
|
->where('user_id', $user->id)
|
|
->value('conversation_id');
|
|
}
|
|
|
|
public function conversations(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
|
|
$convIds = DB::table('mobile_conversation_participants')
|
|
->where('user_id', $user->id)
|
|
->pluck('conversation_id');
|
|
|
|
$typeFilter = $request->query('type');
|
|
|
|
$conversations = DB::table('mobile_conversations')
|
|
->whereIn('id', $convIds)
|
|
->when($typeFilter, function ($query, $type) {
|
|
return $query->where('type', $type);
|
|
})
|
|
->get()
|
|
->map(function ($c) use ($user) {
|
|
$lastMsg = DB::table('mobile_messages')
|
|
->where('conversation_id', $c->id)
|
|
->latest()
|
|
->first();
|
|
|
|
$unreadCount = DB::table('mobile_messages')
|
|
->where('conversation_id', $c->id)
|
|
->where('sender_id', '!=', $user->id)
|
|
->where('is_read', false)
|
|
->count();
|
|
|
|
$participantIds = DB::table('mobile_conversation_participants')
|
|
->where('conversation_id', $c->id)
|
|
->pluck('user_id');
|
|
|
|
$participants = User::whereIn('id', $participantIds)
|
|
->select('id', 'name', 'email', 'avatar', 'type')
|
|
->get()
|
|
->map(function ($u) {
|
|
$u->avatar = check_file($u->avatar) ? get_file($u->avatar) : $u->avatar;
|
|
return $u;
|
|
});
|
|
|
|
$otherUser = $participants->firstWhere('id', '!=', $user->id);
|
|
|
|
return [
|
|
'id' => $c->id,
|
|
'type' => $c->type,
|
|
'name' => $c->type === 'direct' && $otherUser ? $otherUser->name : ($c->name ?? 'Chat'),
|
|
'avatar' => $c->type === 'direct' && $otherUser ? $otherUser->avatar : null,
|
|
'last_message' => $lastMsg ? $lastMsg->content : 'No messages yet',
|
|
'last_message_at' => $lastMsg && $lastMsg->created_at ? date('h:i A', strtotime($lastMsg->created_at)) : date('h:i A'),
|
|
'unread_count' => $unreadCount,
|
|
'participants' => $participants,
|
|
];
|
|
});
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $conversations,
|
|
'message' => null,
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request)
|
|
{
|
|
$isGroup = $request->boolean('is_group') || $request->filled('name') || (is_array($request->participant_ids) && count($request->participant_ids) > 1);
|
|
|
|
if ($isGroup) {
|
|
return $this->createGroup($request);
|
|
}
|
|
|
|
return $this->createDirect($request);
|
|
}
|
|
|
|
public function createDirect(Request $request)
|
|
{
|
|
$recipientId = $request->recipient_id ?? ($request->participant_ids[0] ?? null);
|
|
|
|
if (!$recipientId) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'The recipient_id or participant_ids field is required.',
|
|
'errors' => ['recipient_id' => ['Recipient required']],
|
|
], 422);
|
|
}
|
|
|
|
$user = $request->user();
|
|
$recipient = User::find($recipientId);
|
|
|
|
if (!$recipient) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Recipient user not found',
|
|
'errors' => null,
|
|
], 404);
|
|
}
|
|
|
|
$myConvs = DB::table('mobile_conversation_participants')
|
|
->where('user_id', $user->id)
|
|
->pluck('conversation_id');
|
|
|
|
$existing = DB::table('mobile_conversation_participants')
|
|
->whereIn('conversation_id', $myConvs)
|
|
->where('user_id', $recipientId)
|
|
->first();
|
|
|
|
if ($existing) {
|
|
$conv = DB::table('mobile_conversations')->where('id', $existing->conversation_id)->first();
|
|
$participants = User::whereIn('id', [$user->id, $recipientId])->select('id', 'name', 'email', 'avatar', 'type')->get();
|
|
|
|
return response()->json([
|
|
'id' => $conv->id,
|
|
'name' => $recipient->name,
|
|
'type' => 'direct',
|
|
'participants' => $participants,
|
|
'success' => true,
|
|
'data' => [
|
|
'id' => $conv->id,
|
|
'name' => $recipient->name,
|
|
'type' => 'direct',
|
|
'participants' => $participants,
|
|
],
|
|
'message' => 'Conversation existing',
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
$convId = DB::table('mobile_conversations')->insertGetId([
|
|
'name' => $recipient->name,
|
|
'type' => 'direct',
|
|
'created_by' => $user->id,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
DB::table('mobile_conversation_participants')->insert([
|
|
['conversation_id' => $convId, 'user_id' => $user->id, 'created_at' => now(), 'updated_at' => now()],
|
|
['conversation_id' => $convId, 'user_id' => $recipientId, 'created_at' => now(), 'updated_at' => now()],
|
|
]);
|
|
|
|
$participants = User::whereIn('id', [$user->id, $recipientId])->select('id', 'name', 'email', 'avatar', 'type')->get();
|
|
|
|
return response()->json([
|
|
'id' => $convId,
|
|
'name' => $recipient->name,
|
|
'type' => 'direct',
|
|
'participants' => $participants,
|
|
'success' => true,
|
|
'data' => [
|
|
'id' => $convId,
|
|
'name' => $recipient->name,
|
|
'type' => 'direct',
|
|
'participants' => $participants,
|
|
],
|
|
'message' => 'Direct conversation created',
|
|
'errors' => null,
|
|
], 201);
|
|
}
|
|
|
|
public function createGroup(Request $request)
|
|
{
|
|
$request->validate([
|
|
'name' => 'nullable|string|max:255',
|
|
'participant_ids' => 'required|array',
|
|
'participant_ids.*' => 'integer|exists:users,id',
|
|
]);
|
|
|
|
$user = $request->user();
|
|
$groupName = $request->name ?? 'New Team Group';
|
|
|
|
$convId = DB::table('mobile_conversations')->insertGetId([
|
|
'name' => $groupName,
|
|
'type' => 'group',
|
|
'created_by' => $user->id,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
$participants = array_unique(array_merge([$user->id], $request->participant_ids));
|
|
foreach ($participants as $pId) {
|
|
DB::table('mobile_conversation_participants')->insert([
|
|
'conversation_id' => $convId,
|
|
'user_id' => $pId,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
}
|
|
|
|
$participantUsers = User::whereIn('id', $participants)->select('id', 'name', 'email', 'avatar', 'type')->get();
|
|
|
|
return response()->json([
|
|
'id' => $convId,
|
|
'name' => $groupName,
|
|
'type' => 'group',
|
|
'participants' => $participantUsers,
|
|
'success' => true,
|
|
'data' => [
|
|
'id' => $convId,
|
|
'name' => $groupName,
|
|
'type' => 'group',
|
|
'participant_count' => count($participants),
|
|
'participants' => $participantUsers,
|
|
],
|
|
'message' => 'Group conversation created',
|
|
'errors' => null,
|
|
], 201);
|
|
}
|
|
|
|
public function messages(Request $request, $id)
|
|
{
|
|
$user = $request->user();
|
|
|
|
$isParticipant = DB::table('mobile_conversation_participants')
|
|
->where('conversation_id', $id)
|
|
->where('user_id', $user->id)
|
|
->exists();
|
|
|
|
if (!$isParticipant) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => [],
|
|
'message' => 'Unauthorized access to this conversation',
|
|
'errors' => null,
|
|
], 403);
|
|
}
|
|
|
|
DB::table('mobile_messages')
|
|
->where('conversation_id', $id)
|
|
->where('sender_id', '!=', $user->id)
|
|
->update(['is_read' => true]);
|
|
|
|
$messages = DB::table('mobile_messages')
|
|
->where('conversation_id', $id)
|
|
->orderBy('created_at', 'asc')
|
|
->get()
|
|
->map(function ($m) {
|
|
$sender = User::find($m->sender_id);
|
|
if ($sender && !empty($sender->avatar)) {
|
|
$sender->avatar = get_file($sender->avatar);
|
|
}
|
|
return [
|
|
'id' => $m->id,
|
|
'conversation_id' => (int)$m->conversation_id,
|
|
'sender_id' => $m->sender_id,
|
|
'sender_name' => $sender ? $sender->name : 'User',
|
|
'sender' => $sender ? [
|
|
'id' => $sender->id,
|
|
'name' => $sender->name,
|
|
'avatar' => $sender->avatar,
|
|
] : null,
|
|
'content' => $m->content,
|
|
'created_at' => date('M d, h:i A', strtotime($m->created_at)),
|
|
];
|
|
});
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $messages,
|
|
'message' => null,
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function sendMessage(Request $request, $id)
|
|
{
|
|
$request->validate([
|
|
'content' => 'required|string',
|
|
]);
|
|
|
|
$user = $request->user();
|
|
|
|
$isParticipant = DB::table('mobile_conversation_participants')
|
|
->where('conversation_id', $id)
|
|
->where('user_id', $user->id)
|
|
->exists();
|
|
|
|
if (!$isParticipant) {
|
|
return response()->json([
|
|
'success' => false,
|
|
'data' => null,
|
|
'message' => 'Unauthorized access to this conversation',
|
|
'errors' => null,
|
|
], 403);
|
|
}
|
|
|
|
$messageId = DB::table('mobile_messages')->insertGetId([
|
|
'conversation_id' => $id,
|
|
'sender_id' => $user->id,
|
|
'content' => $request->content,
|
|
'is_read' => false,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'message' => 'Message sent',
|
|
'data' => [
|
|
'id' => $messageId,
|
|
'conversation_id' => (int)$id,
|
|
'sender_id' => $user->id,
|
|
'sender_name' => $user->name,
|
|
'content' => $request->content,
|
|
'created_at' => date('M d, h:i A'),
|
|
],
|
|
'errors' => null,
|
|
], 201);
|
|
}
|
|
|
|
public function unreadCount(Request $request)
|
|
{
|
|
$user = $request->user();
|
|
$convIds = DB::table('mobile_conversation_participants')
|
|
->where('user_id', $user->id)
|
|
->pluck('conversation_id');
|
|
|
|
$unreadCount = DB::table('mobile_messages')
|
|
->whereIn('conversation_id', $convIds)
|
|
->where('sender_id', '!=', $user->id)
|
|
->where('is_read', false)
|
|
->count();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'unread_count' => $unreadCount,
|
|
'data' => ['unread_count' => $unreadCount],
|
|
'message' => null,
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
|
|
public function users(Request $request)
|
|
{
|
|
$users = User::where('id', '!=', $request->user()->id)
|
|
->select('id', 'name', 'email', 'type', 'avatar')
|
|
->limit(20)
|
|
->get();
|
|
|
|
return response()->json([
|
|
'success' => true,
|
|
'data' => $users,
|
|
'message' => null,
|
|
'errors' => null,
|
|
]);
|
|
}
|
|
}
|