Files
animexe/app/Http/Controllers/Frontend/MessageController.php
T
2026-07-14 00:01:48 +03:00

264 lines
8.8 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace App\Http\Controllers\Frontend;
use App\Http\Controllers\Controller;
use App\Models\Conversation;
use App\Models\ConversationParticipant;
use App\Models\Message;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
class MessageController extends Controller
{
public function index()
{
$user = Auth::user();
try {
$conversations = $user->conversations()
->with(['participants', 'lastMessage.user'])
->orderByDesc('conversations.updated_at')
->get()
->map(function ($conv) use ($user) {
$other = $conv->participants->firstWhere('id', '!=', $user->id);
return [
'id' => $conv->id,
'other' => $other,
'last_message' => $conv->lastMessage,
'unread' => $conv->unreadCountFor($user->id),
'updated_at' => $conv->updated_at,
];
});
} catch (\Throwable $e) {
$conversations = collect();
}
return view('frontend.messages.index', compact('conversations'));
}
public function show(Conversation $conversation)
{
$user = Auth::user();
abort_unless(
$conversation->participants()->where('user_id', $user->id)->exists(),
403
);
$other = $conversation->participants()->where('user_id', '!=', $user->id)->first();
$messages = $conversation->messages()
->with('user')
->orderBy('created_at')
->get();
// Mark as read
$conversation->participants()
->updateExistingPivot($user->id, ['last_read_at' => now()]);
return view('frontend.messages.show', compact('conversation', 'messages', 'other'));
}
public function startOrOpen(User $user)
{
$me = Auth::user();
if ($me->id === $user->id) abort(422);
// Find existing conversation between these two users
$conv = Conversation::whereHas('participants', fn($q) => $q->where('user_id', $me->id))
->whereHas('participants', fn($q) => $q->where('user_id', $user->id))
->first();
if (!$conv) {
$conv = DB::transaction(function () use ($me, $user) {
$c = Conversation::create();
$c->participants()->attach([$me->id, $user->id]);
return $c;
});
}
return redirect()->route('messages.show', $conv);
}
public function send(Request $request, Conversation $conversation)
{
$user = Auth::user();
abort_unless(
$conversation->participants()->where('user_id', $user->id)->exists(),
403
);
$request->validate(['body' => 'required|string|max:5000']);
$message = Message::create([
'conversation_id' => $conversation->id,
'user_id' => $user->id,
'body' => $request->body,
]);
$conversation->touch();
// Mark sender as read
$conversation->participants()
->updateExistingPivot($user->id, ['last_read_at' => now()]);
if ($request->expectsJson()) {
return response()->json([
'id' => $message->id,
'body' => $message->body,
'user_id' => $user->id,
'created_at' => $message->created_at->format('H:i'),
'avatar' => $user->avatar ? \App\Support\MediaUrl::fromStoragePath($user->avatar) : null,
'name' => $user->name,
]);
}
return back();
}
public function poll(Request $request, Conversation $conversation)
{
$user = Auth::user();
abort_unless(
$conversation->participants()->where('user_id', $user->id)->exists(),
403
);
$after = $request->query('after', 0);
$messages = $conversation->messages()
->with('user')
->where('id', '>', $after)
->orderBy('created_at')
->get()
->map(fn($m) => [
'id' => $m->id,
'body' => $m->body,
'user_id' => $m->user_id,
'created_at' => $m->created_at->format('H:i'),
'avatar' => $m->user->avatar ? \App\Support\MediaUrl::fromStoragePath($m->user->avatar) : null,
'name' => $m->user->name,
]);
// Update last_read
$conversation->participants()
->updateExistingPivot($user->id, ['last_read_at' => now()]);
return response()->json(['messages' => $messages]);
}
public function unreadCount()
{
$user = Auth::user();
if (!$user) return response()->json(['count' => 0]);
$count = 0;
foreach ($user->conversations()->with(['messages'])->get() as $conv) {
$count += $conv->unreadCountFor($user->id);
}
return response()->json(['count' => $count]);
}
public function conversationsJson()
{
$user = Auth::user();
$convs = $user->conversations()
->with(['participants', 'lastMessage.user'])
->orderByDesc('conversations.updated_at')
->limit(30)
->get()
->map(function ($conv) use ($user) {
$other = $conv->participants->firstWhere('id', '!=', $user->id);
$last = $conv->lastMessage;
$unread = $conv->unreadCountFor($user->id);
$preview = null;
if ($last) {
if (str_starts_with($last->body, 'ANIMESHARE::')) {
try { $sd = json_decode(substr($last->body, 12), true); $preview = '🎬 ' . ($sd['title'] ?? 'Anime paylaştı'); } catch(\Throwable) {}
} elseif (str_starts_with($last->body, 'IMAGE::')) {
$preview = ($last->user_id === $user->id ? 'Sen: ' : '') . '📷 Fotoğraf';
} elseif (str_starts_with($last->body, 'GIF::')) {
$preview = ($last->user_id === $user->id ? 'Sen: ' : '') . '🎞 GIF';
} else {
$isMine = $last->user_id === $user->id;
$preview = ($isMine ? 'Sen: ' : '') . \Illuminate\Support\Str::limit($last->body, 50);
}
}
return [
'conv_id' => $conv->id,
'id' => $other?->id,
'name' => $other?->name ?? 'Silinmiş',
'avatar' => $other?->avatar ? \App\Support\MediaUrl::fromStoragePath($other->avatar) : null,
'last_preview' => $preview,
'unread' => $unread,
'time' => $conv->updated_at ? $conv->updated_at->diffForHumans(null, true) : null,
];
});
return response()->json($convs);
}
public function uploadImage(Request $request)
{
$request->validate([
'image' => 'required|file|image|max:8192|mimes:jpeg,jpg,png,gif,webp',
]);
$path = $request->file('image')->store('chat-images', 'public');
$url = Storage::disk('public')->url($path);
return response()->json(['url' => $url]);
}
public function quickShare(Request $request)
{
$request->validate([
'to_user_id' => 'required|integer|exists:users,id',
'body' => 'required|string|max:3000',
]);
$me = Auth::user();
$target = User::findOrFail($request->to_user_id);
if ($me->id === $target->id) abort(422, 'Kendinize gönderemezsiniz.');
$conv = Conversation::whereHas('participants', fn($q) => $q->where('user_id', $me->id))
->whereHas('participants', fn($q) => $q->where('user_id', $target->id))
->first();
if (!$conv) {
$conv = DB::transaction(function () use ($me, $target) {
$c = Conversation::create();
$c->participants()->attach([$me->id, $target->id]);
return $c;
});
}
$message = Message::create([
'conversation_id' => $conv->id,
'user_id' => $me->id,
'body' => $request->body,
]);
$conv->touch();
$conv->participants()->updateExistingPivot($me->id, ['last_read_at' => now()]);
return response()->json([
'ok' => true,
'conversation_id' => $conv->id,
'message_id' => $message->id,
]);
}
}