Files
ladill-meet/app/Http/Controllers/Meet/ChannelController.php
T
isaaccladandCursor 965fb992e9
Deploy Ladill Meet / deploy (push) Failing after 7s
Initial Ladill Meet release.
Phases 0–18: core meetings, webinar, breakouts, team chat, live streaming, town hall, billing, and Ladill Mail calendar wiring.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-30 23:35:29 +00:00

131 lines
4.1 KiB
PHP

<?php
namespace App\Http\Controllers\Meet;
use App\Http\Controllers\Controller;
use App\Http\Controllers\Meet\Concerns\ScopesToAccount;
use App\Models\Channel;
use App\Models\ChannelMessage;
use App\Services\Meet\ChannelService;
use App\Services\Meet\WorkspaceSearchService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class ChannelController extends Controller
{
use ScopesToAccount;
public function __construct(
protected ChannelService $channels,
protected WorkspaceSearchService $search,
) {}
public function index(Request $request): View
{
$this->authorizeAbility($request, 'meetings.view');
$organization = $this->organization($request);
$owner = $this->ownerRef($request);
$query = Channel::owned($owner)->where('organization_id', $organization->id);
$this->scopeToBranch($request, $query);
$channels = $query->orderBy('name')->get();
return view('meet.channels.index', compact('channels', 'organization'));
}
public function create(Request $request): View
{
$this->authorizeAbility($request, 'meetings.manage');
return view('meet.channels.create', [
'organization' => $this->organization($request),
]);
}
public function store(Request $request): RedirectResponse
{
$this->authorizeAbility($request, 'meetings.manage');
$validated = $request->validate([
'name' => ['required', 'string', 'max:120'],
'visibility' => ['required', 'in:public,private'],
'description' => ['nullable', 'string', 'max:2000'],
]);
$channel = $this->channels->create(
$request->user(),
$this->organization($request),
$validated,
);
return redirect()->route('meet.channels.show', $channel)->with('success', 'Channel created.');
}
public function show(Request $request, Channel $channel): View
{
$this->authorizeAbility($request, 'meetings.view');
$this->authorizeOwner($request, $channel);
abort_unless($this->channels->canAccess($channel, $this->ownerRef($request)), 403);
$messages = $channel->messages()
->whereNull('parent_id')
->with('replies')
->orderBy('created_at')
->paginate(50);
return view('meet.channels.show', compact('channel', 'messages'));
}
public function postMessage(Request $request, Channel $channel): RedirectResponse|JsonResponse
{
$this->authorizeAbility($request, 'meetings.view');
$this->authorizeOwner($request, $channel);
$validated = $request->validate([
'body' => ['required', 'string', 'max:5000'],
'parent_id' => ['nullable', 'integer', 'exists:meet_channel_messages,id'],
]);
$message = $this->channels->postMessage(
$channel,
$request->user(),
$validated['body'],
$validated['parent_id'] ?? null,
);
if ($request->expectsJson()) {
return response()->json(['message' => $message]);
}
return back()->with('success', 'Message posted.');
}
public function react(Request $request, Channel $channel, ChannelMessage $message): JsonResponse
{
$this->authorizeOwner($request, $channel);
abort_unless($message->channel_id === $channel->id, 404);
$validated = $request->validate(['emoji' => ['required', 'string', 'max:16']]);
return response()->json([
'message' => $this->channels->react($message, $validated['emoji'], $this->ownerRef($request)),
]);
}
public function search(Request $request): JsonResponse
{
$this->authorizeAbility($request, 'meetings.view');
$validated = $request->validate(['q' => ['required', 'string', 'min:2', 'max:100']]);
return response()->json(
$this->search->search(
$this->organization($request),
$this->ownerRef($request),
$validated['q'],
),
);
}
}