135 lines
4.5 KiB
PHP
135 lines
4.5 KiB
PHP
<?php
|
||
|
||
namespace App\Http\Controllers\Frontend;
|
||
|
||
use App\Http\Controllers\Controller;
|
||
use App\Models\VoiceCall;
|
||
use App\Models\User;
|
||
use App\Services\AgoraTokenService;
|
||
use Illuminate\Http\Request;
|
||
use Illuminate\Support\Facades\Auth;
|
||
use Illuminate\Support\Str;
|
||
|
||
class VoiceCallController extends Controller
|
||
{
|
||
public function initiate(Request $request)
|
||
{
|
||
$request->validate(['callee_id' => 'required|integer|exists:users,id']);
|
||
$caller = Auth::user();
|
||
$callee = User::findOrFail($request->callee_id);
|
||
|
||
if ($caller->id === $callee->id) {
|
||
return response()->json(['error' => 'Kendinizi arayamazsınız.'], 422);
|
||
}
|
||
|
||
// End any previous active calls
|
||
VoiceCall::where('caller_id', $caller->id)
|
||
->whereIn('status', ['ringing', 'active'])
|
||
->update(['status' => 'ended', 'ended_at' => now()]);
|
||
|
||
$channelName = 'vc_' . Str::random(20);
|
||
$call = VoiceCall::create([
|
||
'caller_id' => $caller->id,
|
||
'callee_id' => $callee->id,
|
||
'channel_name' => $channelName,
|
||
'status' => 'ringing',
|
||
]);
|
||
|
||
$callerToken = AgoraTokenService::generateToken($channelName, $caller->id);
|
||
$calleeToken = AgoraTokenService::generateToken($channelName, $callee->id);
|
||
|
||
return response()->json([
|
||
'call_id' => $call->id,
|
||
'channel_name' => $channelName,
|
||
'token' => $callerToken,
|
||
'callee' => [
|
||
'id' => $callee->id,
|
||
'name' => $callee->name,
|
||
'avatar' => $callee->avatar ? \App\Support\MediaUrl::fromStoragePath($callee->avatar) : null,
|
||
],
|
||
'agora_app_id' => env('AGORA_APP_ID', ''),
|
||
]);
|
||
}
|
||
|
||
public function answer(VoiceCall $call)
|
||
{
|
||
$user = Auth::user();
|
||
abort_unless($call->callee_id === $user->id, 403);
|
||
abort_unless($call->status === 'ringing', 422, 'Call is no longer ringing.');
|
||
|
||
$call->update(['status' => 'active', 'answered_at' => now()]);
|
||
|
||
$token = AgoraTokenService::generateToken($call->channel_name, $user->id);
|
||
|
||
return response()->json([
|
||
'channel_name' => $call->channel_name,
|
||
'token' => $token,
|
||
'agora_app_id' => env('AGORA_APP_ID', ''),
|
||
'caller' => [
|
||
'id' => $call->caller->id,
|
||
'name' => $call->caller->name,
|
||
'avatar' => $call->caller->avatar ? \App\Support\MediaUrl::fromStoragePath($call->caller->avatar) : null,
|
||
],
|
||
]);
|
||
}
|
||
|
||
public function decline(VoiceCall $call)
|
||
{
|
||
$user = Auth::user();
|
||
abort_unless($call->callee_id === $user->id || $call->caller_id === $user->id, 403);
|
||
abort_unless($call->status === 'ringing', 422);
|
||
|
||
$call->update(['status' => 'declined', 'ended_at' => now()]);
|
||
|
||
return response()->json(['ok' => true]);
|
||
}
|
||
|
||
public function end(VoiceCall $call)
|
||
{
|
||
$user = Auth::user();
|
||
abort_unless($call->callee_id === $user->id || $call->caller_id === $user->id, 403);
|
||
|
||
$call->update(['status' => 'ended', 'ended_at' => now()]);
|
||
|
||
return response()->json(['ok' => true]);
|
||
}
|
||
|
||
public function poll(Request $request)
|
||
{
|
||
$user = Auth::user();
|
||
|
||
// Check for incoming ringing call
|
||
$incoming = VoiceCall::where('callee_id', $user->id)
|
||
->where('status', 'ringing')
|
||
->with('caller')
|
||
->latest()
|
||
->first();
|
||
|
||
if ($incoming) {
|
||
return response()->json([
|
||
'type' => 'incoming',
|
||
'call_id' => $incoming->id,
|
||
'caller' => [
|
||
'id' => $incoming->caller->id,
|
||
'name' => $incoming->caller->name,
|
||
'avatar' => $incoming->caller->avatar ? \App\Support\MediaUrl::fromStoragePath($incoming->caller->avatar) : null,
|
||
],
|
||
]);
|
||
}
|
||
|
||
// Check if an active call we're in has been ended by the other side
|
||
$call_id = $request->query('call_id');
|
||
if ($call_id) {
|
||
$call = VoiceCall::find($call_id);
|
||
if ($call && in_array($user->id, [$call->caller_id, $call->callee_id])) {
|
||
return response()->json([
|
||
'type' => 'status',
|
||
'status' => $call->status,
|
||
]);
|
||
}
|
||
}
|
||
|
||
return response()->json(['type' => 'none']);
|
||
}
|
||
}
|