Initialer Laravel Commit für BetiX
This commit is contained in:
198
app/Http/Controllers/DirectMessageController.php
Normal file
198
app/Http/Controllers/DirectMessageController.php
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\DirectMessage;
|
||||
use App\Models\DirectMessageReport;
|
||||
use App\Models\Friend;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class DirectMessageController extends Controller
|
||||
{
|
||||
private function formatUser(User $u): array
|
||||
{
|
||||
return [
|
||||
'id' => $u->id,
|
||||
'username' => $u->username,
|
||||
'name' => $u->name,
|
||||
'avatar' => $u->avatar,
|
||||
'avatar_url' => $u->avatar_url,
|
||||
];
|
||||
}
|
||||
|
||||
private function formatMessage(DirectMessage $m): array
|
||||
{
|
||||
return [
|
||||
'id' => $m->id,
|
||||
'message' => $m->is_deleted ? null : $m->message,
|
||||
'sender_id' => $m->sender_id,
|
||||
'is_deleted' => $m->is_deleted,
|
||||
'is_read' => $m->is_read,
|
||||
'created_at' => $m->created_at,
|
||||
'user' => $m->sender ? $this->formatUser($m->sender) : null,
|
||||
'reply_to' => $m->replyTo ? [
|
||||
'id' => $m->replyTo->id,
|
||||
'message' => $m->replyTo->is_deleted ? null : $m->replyTo->message,
|
||||
'sender_id' => $m->replyTo->sender_id,
|
||||
] : null,
|
||||
];
|
||||
}
|
||||
|
||||
// GET /api/dm/conversations
|
||||
public function conversations()
|
||||
{
|
||||
$me = Auth::id();
|
||||
|
||||
$sent = DirectMessage::where('sender_id', $me)->select('receiver_id as partner_id');
|
||||
$received = DirectMessage::where('receiver_id', $me)->select('sender_id as partner_id');
|
||||
|
||||
$partnerIds = $sent->union($received)->pluck('partner_id')->unique()->values();
|
||||
|
||||
$conversations = $partnerIds->map(function ($pid) use ($me) {
|
||||
$partner = User::select('id', 'username', 'name', 'avatar', 'avatar_url')->find($pid);
|
||||
if (!$partner) return null;
|
||||
|
||||
$lastMsg = DirectMessage::where(function ($q) use ($me, $pid) {
|
||||
$q->where('sender_id', $me)->where('receiver_id', $pid);
|
||||
})->orWhere(function ($q) use ($me, $pid) {
|
||||
$q->where('sender_id', $pid)->where('receiver_id', $me);
|
||||
})->orderByDesc('created_at')->first();
|
||||
|
||||
$unread = DirectMessage::where('sender_id', $pid)
|
||||
->where('receiver_id', $me)
|
||||
->where('is_read', false)
|
||||
->count();
|
||||
|
||||
return [
|
||||
'partner' => $this->formatUser($partner),
|
||||
'last_message' => $lastMsg ? [
|
||||
'id' => $lastMsg->id,
|
||||
'message' => $lastMsg->is_deleted ? null : $lastMsg->message,
|
||||
'sender_id' => $lastMsg->sender_id,
|
||||
'created_at' => $lastMsg->created_at,
|
||||
] : null,
|
||||
'unread_count' => $unread,
|
||||
];
|
||||
})->filter()->sortByDesc(fn ($c) => optional($c['last_message'])['created_at'])->values();
|
||||
|
||||
return response()->json(['data' => $conversations]);
|
||||
}
|
||||
|
||||
// GET /api/dm/{userId}
|
||||
public function messages($userId)
|
||||
{
|
||||
$me = Auth::id();
|
||||
|
||||
$msgs = DirectMessage::where(function ($q) use ($me, $userId) {
|
||||
$q->where('sender_id', $me)->where('receiver_id', $userId);
|
||||
})->orWhere(function ($q) use ($me, $userId) {
|
||||
$q->where('sender_id', $userId)->where('receiver_id', $me);
|
||||
})
|
||||
->with(['sender:id,username,name,avatar,avatar_url', 'replyTo'])
|
||||
->orderBy('created_at')
|
||||
->limit(100)
|
||||
->get()
|
||||
->map(fn ($m) => $this->formatMessage($m));
|
||||
|
||||
// Mark as read
|
||||
DirectMessage::where('sender_id', $userId)
|
||||
->where('receiver_id', $me)
|
||||
->where('is_read', false)
|
||||
->update(['is_read' => true]);
|
||||
|
||||
return response()->json(['data' => $msgs]);
|
||||
}
|
||||
|
||||
// POST /api/dm/{userId}
|
||||
public function send(Request $request, $userId)
|
||||
{
|
||||
$me = Auth::id();
|
||||
$request->validate([
|
||||
'message' => 'required|string|max:1000',
|
||||
'reply_to_id' => 'nullable|integer|exists:direct_messages,id',
|
||||
]);
|
||||
|
||||
User::findOrFail($userId);
|
||||
|
||||
$areFriends = Friend::where(function ($q) use ($me, $userId) {
|
||||
$q->where('user_id', $me)->where('friend_id', $userId);
|
||||
})->orWhere(function ($q) use ($me, $userId) {
|
||||
$q->where('user_id', $userId)->where('friend_id', $me);
|
||||
})->where('status', 'accepted')->exists();
|
||||
|
||||
if (!$areFriends) {
|
||||
return response()->json(['error' => 'You must be friends to send messages.'], 403);
|
||||
}
|
||||
|
||||
$msg = DirectMessage::create([
|
||||
'sender_id' => $me,
|
||||
'receiver_id' => $userId,
|
||||
'message' => $request->message,
|
||||
'reply_to_id' => $request->reply_to_id,
|
||||
]);
|
||||
|
||||
$msg->load(['sender:id,username,name,avatar,avatar_url', 'replyTo']);
|
||||
|
||||
return response()->json(['data' => $this->formatMessage($msg)], 201);
|
||||
}
|
||||
|
||||
// POST /api/dm/messages/{id}/report
|
||||
public function report(Request $request, $messageId)
|
||||
{
|
||||
$me = Auth::id();
|
||||
$request->validate([
|
||||
'reason' => 'required|string|max:64',
|
||||
'details' => 'nullable|string|max:500',
|
||||
]);
|
||||
|
||||
$msg = DirectMessage::where(function ($q) use ($me) {
|
||||
$q->where('sender_id', $me)->orWhere('receiver_id', $me);
|
||||
})->findOrFail($messageId);
|
||||
|
||||
DirectMessageReport::firstOrCreate(
|
||||
['reporter_id' => $me, 'message_id' => $msg->id],
|
||||
['reason' => $request->reason, 'details' => $request->details]
|
||||
);
|
||||
|
||||
return response()->json(['ok' => true]);
|
||||
}
|
||||
|
||||
// GET /api/friends
|
||||
public function friends()
|
||||
{
|
||||
$me = Auth::id();
|
||||
|
||||
$friends = Friend::where(function ($q) use ($me) {
|
||||
$q->where('user_id', $me)->orWhere('friend_id', $me);
|
||||
})->where('status', 'accepted')
|
||||
->with(['user:id,username,name,avatar,avatar_url', 'friend:id,username,name,avatar,avatar_url'])
|
||||
->get()
|
||||
->map(function ($f) use ($me) {
|
||||
$partner = $f->user_id === $me ? $f->friend : $f->user;
|
||||
return $partner ? $this->formatUser($partner) : null;
|
||||
})->filter()->values();
|
||||
|
||||
return response()->json(['data' => $friends]);
|
||||
}
|
||||
|
||||
// GET /api/friends/requests
|
||||
public function friendRequests()
|
||||
{
|
||||
$me = Auth::id();
|
||||
|
||||
$requests = Friend::where('friend_id', $me)
|
||||
->where('status', 'pending')
|
||||
->with('user:id,username,name,avatar,avatar_url')
|
||||
->orderByDesc('created_at')
|
||||
->get()
|
||||
->map(fn ($f) => [
|
||||
'id' => $f->id,
|
||||
'from' => $f->user ? $this->formatUser($f->user) : null,
|
||||
'created_at' => $f->created_at,
|
||||
])->filter(fn ($r) => $r['from'] !== null)->values();
|
||||
|
||||
return response()->json(['data' => $requests]);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user