Deploy Ladill Meet / deploy (push) Successful in 1m3s
Attendees reconnect to breakout rooms with publish access while hosts stay on stage; poll and media-token endpoints drive LiveKit reconnection, and the live room shows Events-linked programme when available. Co-authored-by: Cursor <cursoragent@cursor.com>
216 lines
18 KiB
PHP
216 lines
18 KiB
PHP
<?php
|
|
|
|
use App\Http\Controllers\Auth\SsoLoginController;
|
|
use App\Http\Controllers\Meet\AdminController;
|
|
use App\Http\Controllers\Meet\AiController;
|
|
use App\Http\Controllers\Meet\CalendarController;
|
|
use App\Http\Controllers\Meet\ConferenceController;
|
|
use App\Http\Controllers\Meet\ChannelController;
|
|
use App\Http\Controllers\Meet\ContactGroupController;
|
|
use App\Http\Controllers\Meet\DashboardController;
|
|
use App\Http\Controllers\Meet\DirectMessageController;
|
|
use App\Http\Controllers\Meet\InvitationController;
|
|
use App\Http\Controllers\Meet\JoinController;
|
|
use App\Http\Controllers\Meet\LeaveController;
|
|
use App\Http\Controllers\Meet\MeetingFeaturesController;
|
|
use App\Http\Controllers\Meet\MeetingRoomController;
|
|
use App\Http\Controllers\Meet\MemberController;
|
|
use App\Http\Controllers\Meet\OnboardingController;
|
|
use App\Http\Controllers\Meet\RecordingController;
|
|
use App\Http\Controllers\Meet\ReportController;
|
|
use App\Http\Controllers\Meet\RoomController;
|
|
use App\Http\Controllers\Meet\SpaceController;
|
|
use App\Http\Controllers\Meet\SettingsController;
|
|
use App\Http\Controllers\Meet\SummaryController;
|
|
use App\Http\Controllers\Meet\WebinarRegistrationController;
|
|
use App\Http\Controllers\Meet\WebinarController;
|
|
use App\Http\Controllers\Meet\WebhookSettingsController;
|
|
use App\Http\Controllers\NotificationController;
|
|
use App\Http\Controllers\WalletBalanceController;
|
|
use Illuminate\Support\Facades\Route;
|
|
|
|
Route::get('/', fn () => auth()->check()
|
|
? redirect()->route('meet.dashboard')
|
|
: redirect()->route('sso.connect'))->name('meet.root');
|
|
|
|
Route::get('/login', [SsoLoginController::class, 'connect'])->name('login');
|
|
Route::get('/sso/connect', [SsoLoginController::class, 'connect'])->name('sso.connect');
|
|
Route::get('/sso/callback', [SsoLoginController::class, 'callback'])->name('sso.callback');
|
|
Route::get('/sso/error', [SsoLoginController::class, 'failed'])->name('sso.failed');
|
|
Route::post('/logout', [SsoLoginController::class, 'logout'])->name('logout');
|
|
Route::get('/sso/logout-bridge', [SsoLoginController::class, 'logoutBridge'])->name('sso.logout-bridge');
|
|
Route::get('/sso/logout-frontchannel', [SsoLoginController::class, 'frontchannelLogout'])->name('sso.logout-frontchannel');
|
|
Route::get('/sso/platform-signed-out', [SsoLoginController::class, 'platformSignedOut'])->name('sso.platform-signed-out');
|
|
Route::get('/signed-out', fn () => auth()->check() ? redirect()->route('meet.dashboard') : view('auth.signed-out'))->name('meet.signed-out');
|
|
|
|
Route::get('/r/{room}', [JoinController::class, 'show'])->name('meet.join');
|
|
Route::get('/r/{room}/waiting', [JoinController::class, 'waiting'])->name('meet.join.waiting');
|
|
Route::get('/r/{room}/waiting/status', [JoinController::class, 'waitingStatus'])->name('meet.join.waiting.status');
|
|
Route::post('/r/{room}/passcode', [JoinController::class, 'verifyPasscode'])->name('meet.join.passcode');
|
|
Route::post('/r/{room}/enter', [JoinController::class, 'enter'])->name('meet.join.enter');
|
|
|
|
Route::get('/room/{session}/left', [LeaveController::class, 'show'])->name('meet.left');
|
|
Route::post('/room/{session}/left', [LeaveController::class, 'store'])->name('meet.left.feedback');
|
|
Route::get('/room/{session}/thanks', [LeaveController::class, 'thanks'])->name('meet.left.thanks');
|
|
Route::get('/room/{session}/ended', [LeaveController::class, 'ended'])->name('meet.ended');
|
|
|
|
Route::match(['get', 'post'], '/invite/{invitation}/rsvp', [InvitationController::class, 'rsvp'])->name('meet.invitations.rsvp');
|
|
|
|
Route::get('/w/{room}/register', [WebinarRegistrationController::class, 'show'])->name('meet.webinar.register');
|
|
Route::post('/w/{room}/register', [WebinarRegistrationController::class, 'store'])->name('meet.webinar.register.store');
|
|
|
|
Route::get('/room/{session}', [MeetingRoomController::class, 'show'])->name('meet.room');
|
|
Route::post('/room/{session}/end', [MeetingRoomController::class, 'end'])->name('meet.room.end');
|
|
Route::post('/room/{session}/leave', [MeetingRoomController::class, 'leave'])->name('meet.room.leave');
|
|
Route::post('/room/{session}/participants/{participant}/admit', [MeetingRoomController::class, 'admit'])->name('meet.room.admit');
|
|
Route::post('/room/{session}/participants/{participant}/deny', [MeetingRoomController::class, 'deny'])->name('meet.room.deny');
|
|
Route::post('/room/{session}/raise-hand', [MeetingRoomController::class, 'raiseHand'])->name('meet.room.raise-hand');
|
|
Route::post('/room/{session}/chat', [MeetingRoomController::class, 'sendMessage'])->name('meet.room.chat');
|
|
Route::post('/room/{session}/reaction', [MeetingRoomController::class, 'sendReaction'])->name('meet.room.reaction');
|
|
Route::get('/room/{session}/poll', [MeetingRoomController::class, 'poll'])->name('meet.room.poll');
|
|
Route::get('/room/{session}/media-token', [MeetingRoomController::class, 'mediaToken'])->name('meet.room.media-token');
|
|
Route::post('/room/{session}/recording/start', [MeetingRoomController::class, 'startRecording'])->name('meet.room.recording.start');
|
|
Route::post('/room/{session}/recording/stop', [MeetingRoomController::class, 'stopRecording'])->name('meet.room.recording.stop');
|
|
Route::post('/room/{session}/recordings/{recording}/upload', [MeetingRoomController::class, 'uploadRecording'])->name('meet.room.recording.upload');
|
|
Route::post('/room/{session}/lock', [MeetingRoomController::class, 'lock'])->name('meet.room.lock');
|
|
Route::post('/room/{session}/unlock', [MeetingRoomController::class, 'unlock'])->name('meet.room.unlock');
|
|
Route::post('/room/{session}/caption', [MeetingRoomController::class, 'caption'])->name('meet.room.caption');
|
|
|
|
Route::post('/room/{session}/qa', [MeetingFeaturesController::class, 'submitQuestion'])->name('meet.room.qa.submit');
|
|
Route::post('/room/{session}/qa/{question}/approve', [MeetingFeaturesController::class, 'approveQuestion'])->name('meet.room.qa.approve');
|
|
Route::post('/room/{session}/qa/{question}/answer', [MeetingFeaturesController::class, 'answerQuestion'])->name('meet.room.qa.answer');
|
|
Route::post('/room/{session}/qa/{question}/upvote', [MeetingFeaturesController::class, 'upvoteQuestion'])->name('meet.room.qa.upvote');
|
|
Route::post('/room/{session}/polls', [MeetingFeaturesController::class, 'createPoll'])->name('meet.room.polls.create');
|
|
Route::post('/room/{session}/polls/{poll}/vote', [MeetingFeaturesController::class, 'votePoll'])->name('meet.room.polls.vote');
|
|
Route::post('/room/{session}/polls/{poll}/close', [MeetingFeaturesController::class, 'closePoll'])->name('meet.room.polls.close');
|
|
Route::post('/room/{session}/breakouts', [MeetingFeaturesController::class, 'createBreakouts'])->name('meet.room.breakouts.create');
|
|
Route::post('/room/{session}/breakouts/{breakout}/join', [MeetingFeaturesController::class, 'moveToBreakout'])->name('meet.room.breakouts.join');
|
|
Route::post('/room/{session}/breakouts/return', [MeetingFeaturesController::class, 'returnFromBreakout'])->name('meet.room.breakouts.return');
|
|
Route::post('/room/{session}/breakouts/broadcast', [MeetingFeaturesController::class, 'broadcastBreakout'])->name('meet.room.breakouts.broadcast');
|
|
Route::post('/room/{session}/breakouts/close', [MeetingFeaturesController::class, 'closeBreakouts'])->name('meet.room.breakouts.close');
|
|
Route::post('/room/{session}/files', [MeetingFeaturesController::class, 'uploadFile'])->name('meet.room.files.upload');
|
|
Route::get('/room/{session}/files/{file}', [MeetingFeaturesController::class, 'downloadFile'])->name('meet.room.files.download');
|
|
Route::get('/room/{session}/whiteboard', [MeetingFeaturesController::class, 'showWhiteboard'])->name('meet.room.whiteboard.show');
|
|
Route::post('/room/{session}/whiteboard', [MeetingFeaturesController::class, 'saveWhiteboard'])->name('meet.room.whiteboard.save');
|
|
Route::post('/room/{session}/whiteboard/export', [MeetingFeaturesController::class, 'exportWhiteboard'])->name('meet.room.whiteboard.export');
|
|
|
|
Route::post('/room/{session}/live-stream', [MeetingFeaturesController::class, 'configureLiveStream'])->name('meet.room.livestream.configure');
|
|
Route::post('/room/{session}/live-stream/start', [MeetingFeaturesController::class, 'startLiveStream'])->name('meet.room.livestream.start');
|
|
Route::post('/room/{session}/live-stream/stop', [MeetingFeaturesController::class, 'stopLiveStream'])->name('meet.room.livestream.stop');
|
|
Route::post('/room/{session}/town-hall/green-room', [MeetingFeaturesController::class, 'startGreenRoom'])->name('meet.room.townhall.green');
|
|
Route::post('/room/{session}/town-hall/go-live', [MeetingFeaturesController::class, 'goLiveTownHall'])->name('meet.room.townhall.live');
|
|
Route::post('/room/{session}/town-hall/presenters', [MeetingFeaturesController::class, 'addPresenter'])->name('meet.room.townhall.presenters');
|
|
Route::post('/room/{session}/town-hall/handoff', [MeetingFeaturesController::class, 'handoffCoHost'])->name('meet.room.townhall.handoff');
|
|
Route::post('/room/{session}/stage', [MeetingFeaturesController::class, 'updateStage'])->name('meet.room.stage.update');
|
|
|
|
Route::middleware(['auth', 'platform.session'])->group(function () {
|
|
Route::get('/notifications', [NotificationController::class, 'index'])->name('notifications.index');
|
|
Route::get('/notifications/unread', [NotificationController::class, 'unread'])->name('notifications.unread');
|
|
Route::post('/notifications/{id}/read', [NotificationController::class, 'markAsRead'])->name('notifications.mark-read');
|
|
Route::post('/notifications/mark-all-read', [NotificationController::class, 'markAllAsRead'])->name('notifications.mark-all-read');
|
|
|
|
Route::get('/onboarding', [OnboardingController::class, 'show'])->name('meet.onboarding.show');
|
|
Route::post('/onboarding', [OnboardingController::class, 'store'])->name('meet.onboarding.store');
|
|
|
|
Route::middleware(['meet.setup'])->group(function () {
|
|
Route::post('/ai/chat', [AiController::class, 'chat'])->middleware('throttle:30,1')->name('meet.ai.chat');
|
|
|
|
Route::get('/dashboard', [DashboardController::class, 'index'])->name('meet.dashboard');
|
|
|
|
Route::get('/meetings/instant', [RoomController::class, 'instant'])->name('meet.instant');
|
|
Route::get('/meetings/personal', [RoomController::class, 'personal'])->name('meet.personal');
|
|
Route::get('/meetings', [RoomController::class, 'index'])->name('meet.rooms.index');
|
|
Route::get('/meetings/create', [RoomController::class, 'create'])->name('meet.rooms.create');
|
|
Route::post('/meetings', [RoomController::class, 'store'])->name('meet.rooms.store');
|
|
Route::get('/meetings/{room}', [RoomController::class, 'show'])->name('meet.rooms.show');
|
|
Route::post('/meetings/{room}/start', [RoomController::class, 'start'])->name('meet.rooms.start');
|
|
Route::post('/meetings/{room}/cancel', [RoomController::class, 'cancel'])->name('meet.rooms.cancel');
|
|
Route::get('/meetings/{room}/ical', [RoomController::class, 'ical'])->name('meet.rooms.ical');
|
|
Route::get('/meetings/{room}/qr', [RoomController::class, 'qr'])->name('meet.rooms.qr');
|
|
Route::get('/meetings/{room}/attendance', [RoomController::class, 'attendance'])->name('meet.rooms.attendance');
|
|
|
|
Route::get('/webinars', [WebinarController::class, 'index'])->name('meet.webinars.index');
|
|
Route::get('/webinars/create', [WebinarController::class, 'create'])->name('meet.webinars.create');
|
|
Route::post('/webinars', [WebinarController::class, 'store'])->name('meet.webinars.store');
|
|
Route::get('/webinars/{room}', [WebinarController::class, 'show'])->name('meet.webinars.show');
|
|
Route::post('/webinars/{room}/start', [WebinarController::class, 'start'])->name('meet.webinars.start');
|
|
Route::post('/webinars/{room}/settings', [WebinarController::class, 'updateSettings'])->name('meet.webinars.settings.update');
|
|
|
|
Route::get('/conferences', [ConferenceController::class, 'index'])->name('meet.conferences.index');
|
|
Route::get('/conferences/create', [ConferenceController::class, 'create'])->name('meet.conferences.create');
|
|
Route::post('/conferences', [ConferenceController::class, 'store'])->name('meet.conferences.store');
|
|
Route::get('/conferences/{room}', [ConferenceController::class, 'show'])->name('meet.conferences.show');
|
|
Route::post('/conferences/{room}/speakers', [ConferenceController::class, 'updateSpeakers'])->name('meet.conferences.speakers.update');
|
|
Route::post('/conferences/{room}/start', [ConferenceController::class, 'start'])->name('meet.conferences.start');
|
|
|
|
Route::get('/rooms', [SpaceController::class, 'index'])->name('meet.spaces.index');
|
|
Route::get('/rooms/create', [SpaceController::class, 'create'])->name('meet.spaces.create');
|
|
Route::post('/rooms', [SpaceController::class, 'store'])->name('meet.spaces.store');
|
|
Route::get('/rooms/{room}', [SpaceController::class, 'show'])->name('meet.spaces.show');
|
|
Route::post('/rooms/{room}/start', [SpaceController::class, 'start'])->name('meet.spaces.start');
|
|
|
|
Route::get('/meetings/{room}/webinar/registrations', [WebinarRegistrationController::class, 'manage'])->name('meet.webinar.registrations');
|
|
Route::post('/meetings/{room}/webinar/registrations/{registration}/approve', [WebinarRegistrationController::class, 'approve'])->name('meet.webinar.registrations.approve');
|
|
Route::post('/meetings/{room}/webinar/registrations/{registration}/reject', [WebinarRegistrationController::class, 'reject'])->name('meet.webinar.registrations.reject');
|
|
Route::get('/meetings/{room}/invitations', [InvitationController::class, 'index'])->name('meet.invitations.index');
|
|
Route::post('/meetings/{room}/invitations', [InvitationController::class, 'store'])->name('meet.invitations.store');
|
|
Route::post('/meetings/{room}/invitations/csv', [InvitationController::class, 'bulkCsv'])->name('meet.invitations.bulk');
|
|
Route::post('/invitations/{invitation}/resend', [InvitationController::class, 'resend'])->name('meet.invitations.resend');
|
|
Route::delete('/invitations/{invitation}', [InvitationController::class, 'destroy'])->name('meet.invitations.destroy');
|
|
Route::get('/contacts/search', [InvitationController::class, 'searchContacts'])->name('meet.contacts.search');
|
|
|
|
Route::get('/reports', [ReportController::class, 'index'])->name('meet.reports.index');
|
|
Route::get('/reports/{type}', [ReportController::class, 'show'])->name('meet.reports.show');
|
|
Route::get('/reports/{type}/export', [ReportController::class, 'export'])->name('meet.reports.export');
|
|
|
|
Route::get('/contacts/groups', [ContactGroupController::class, 'index'])->name('meet.contacts.groups');
|
|
Route::post('/contacts/groups', [ContactGroupController::class, 'store'])->name('meet.contacts.groups.store');
|
|
|
|
Route::get('/channels', [ChannelController::class, 'index'])->name('meet.channels.index');
|
|
Route::get('/channels/create', [ChannelController::class, 'create'])->name('meet.channels.create');
|
|
Route::post('/channels', [ChannelController::class, 'store'])->name('meet.channels.store');
|
|
Route::get('/channels/{channel}', [ChannelController::class, 'show'])->name('meet.channels.show');
|
|
Route::post('/channels/{channel}/messages', [ChannelController::class, 'postMessage'])->name('meet.channels.messages.store');
|
|
Route::post('/channels/{channel}/messages/{message}/react', [ChannelController::class, 'react'])->name('meet.channels.messages.react');
|
|
Route::get('/workspace/search', [ChannelController::class, 'search'])->name('meet.workspace.search');
|
|
|
|
Route::get('/messages', [DirectMessageController::class, 'index'])->name('meet.messages.index');
|
|
Route::post('/messages/start', [DirectMessageController::class, 'start'])->name('meet.messages.start');
|
|
Route::get('/messages/{conversation}', [DirectMessageController::class, 'show'])->name('meet.messages.show');
|
|
Route::post('/messages/{conversation}', [DirectMessageController::class, 'postMessage'])->name('meet.messages.store');
|
|
|
|
Route::get('/admin/usage', [AdminController::class, 'usage'])->name('meet.admin.usage');
|
|
|
|
Route::get('/settings/calendar', [CalendarController::class, 'settings'])->name('meet.settings.calendar');
|
|
Route::post('/settings/calendar/mail', [CalendarController::class, 'connectMail'])->name('meet.settings.calendar.mail');
|
|
Route::get('/settings/calendar/connect/{provider}', [CalendarController::class, 'connect'])->name('meet.settings.calendar.connect');
|
|
Route::get('/settings/calendar/callback', [CalendarController::class, 'callback'])->name('meet.settings.calendar.callback');
|
|
Route::get('/calendar/availability', [CalendarController::class, 'availability'])->name('meet.calendar.availability');
|
|
|
|
Route::get('/settings/webhooks', [WebhookSettingsController::class, 'index'])->name('meet.settings.webhooks');
|
|
Route::post('/settings/webhooks', [WebhookSettingsController::class, 'store'])->name('meet.settings.webhooks.store');
|
|
Route::delete('/settings/webhooks/{webhook}', [WebhookSettingsController::class, 'destroy'])->name('meet.settings.webhooks.destroy');
|
|
|
|
Route::get('/recordings', [RecordingController::class, 'index'])->name('meet.recordings.index');
|
|
Route::get('/recordings/{recording}', [RecordingController::class, 'show'])->name('meet.recordings.show');
|
|
Route::get('/recordings/{recording}/download', [RecordingController::class, 'download'])->name('meet.recordings.download');
|
|
Route::delete('/recordings/{recording}', [RecordingController::class, 'destroy'])->name('meet.recordings.destroy');
|
|
|
|
Route::get('/summaries/{summary}', [SummaryController::class, 'show'])->name('meet.summaries.show');
|
|
|
|
Route::get('/settings/security', [SettingsController::class, 'security'])->name('meet.settings.security');
|
|
Route::put('/settings/security', [SettingsController::class, 'updateSecurity'])->name('meet.settings.security.update');
|
|
Route::get('/settings', [SettingsController::class, 'edit'])->name('meet.settings');
|
|
Route::put('/settings', [SettingsController::class, 'update'])->name('meet.settings.update');
|
|
|
|
Route::get('/members', [MemberController::class, 'index'])->name('meet.members.index');
|
|
Route::get('/members/create', [MemberController::class, 'create'])->name('meet.members.create');
|
|
Route::post('/members', [MemberController::class, 'store'])->name('meet.members.store');
|
|
Route::delete('/members/{member}', [MemberController::class, 'destroy'])->name('meet.members.destroy');
|
|
|
|
Route::get('/wallet/balance', [WalletBalanceController::class, 'balance'])->name('wallet.balance');
|
|
Route::get('/wallet', fn () => redirect()->away(ladill_account_url('/wallet')))->name('meet.wallet');
|
|
Route::get('/team', fn () => redirect()->away(ladill_account_url('/account/team')))->name('meet.team');
|
|
});
|
|
});
|