From eac60181c5962c9c787e7a2c4bf452c0d596a434 Mon Sep 17 00:00:00 2001 From: Samuel Weirich <4281791+SamuelWei@users.noreply.github.com> Date: Tue, 20 Jan 2026 15:24:59 +0100 Subject: [PATCH 1/7] Add option in room to always use sytem-wide default presentation # Conflicts: # app/Http/Controllers/api/v1/RoomFileController.php # app/Models/Room.php --- .../Controllers/api/v1/RoomFileController.php | 43 ++- .../UpdateRoomSystemDefaultPresentation.php | 16 ++ app/Models/Room.php | 10 +- app/Services/MeetingService.php | 15 +- ...ntation_in_next_meeting_to_rooms_table.php | 30 +++ lang/en/rooms.php | 17 +- resources/css/override/_animations.css | 5 + resources/js/components/InlineNote.vue | 6 +- resources/js/components/RoomTabFiles.vue | 85 ++++-- ...on.vue => RoomTabFilesConfigureButton.vue} | 61 +++-- .../components/RoomTabFilesSystemDefault.vue | 250 ++++++++++++++++++ routes/api.php | 1 + 12 files changed, 469 insertions(+), 70 deletions(-) create mode 100644 app/Http/Requests/UpdateRoomSystemDefaultPresentation.php create mode 100644 database/migrations/2026_01_19_105554_add_use_system_default_presentation_in_next_meeting_to_rooms_table.php rename resources/js/components/{RoomTabFilesEditButton.vue => RoomTabFilesConfigureButton.vue} (83%) create mode 100644 resources/js/components/RoomTabFilesSystemDefault.vue diff --git a/app/Http/Controllers/api/v1/RoomFileController.php b/app/Http/Controllers/api/v1/RoomFileController.php index 2d45bcbf8..cd52cc7a2 100644 --- a/app/Http/Controllers/api/v1/RoomFileController.php +++ b/app/Http/Controllers/api/v1/RoomFileController.php @@ -5,6 +5,7 @@ use App\Http\Controllers\Controller; use App\Http\Requests\StoreRoomFile; use App\Http\Requests\UpdateRoomFile; +use App\Http\Requests\UpdateRoomSystemDefaultPresentation; use App\Http\Resources\PrivateRoomFile; use App\Models\Room; use App\Models\RoomFile; @@ -67,6 +68,11 @@ public function index(Room $room, Request $request) // If user is allowed to view all files, return PrivateRoomFile resource to show additional information if (Gate::allows('viewAllFiles', $room)) { $additional['default'] = $room->files()->where('default', true)->first(); + $additional['system_default'] = [ + 'file' => app(BigBlueButtonSettings::class)->default_presentation, + 'use_in_meeting' => $room->use_system_default_presentation_in_meeting, + 'use_as_default' => $room->use_system_default_presentation_as_default, + ]; return PrivateRoomFile::collection($resource->paginate(app(GeneralSettings::class)->pagination_page_size))->additional($additional); } @@ -104,10 +110,6 @@ public function update(UpdateRoomFile $request, Room $room, RoomFile $file) { if ($request->has('use_in_meeting')) { $file->use_in_meeting = $request->use_in_meeting; - // If no default file for this room is set, set this file as default - if (! $room->files()->where('default', true)->exists()) { - $file->default = true; - } } if ($request->has('download')) { @@ -116,9 +118,13 @@ public function update(UpdateRoomFile $request, Room $room, RoomFile $file) if ($request->has('default') && $request->default === true) { // Make other files not the default - $room->files()->update(['default' => false]); + $room->files()->whereNot('id', $file->id)->update(['default' => false]); // Set this file as default $file->default = true; + + // If a file is set as default, the system default presentation must not be used as default + $room->use_system_default_presentation_as_default = false; + $room->save(); } $file->save(); @@ -130,6 +136,33 @@ public function update(UpdateRoomFile $request, Room $room, RoomFile $file) return response()->noContent(); } + public function updateSystemDefault(UpdateRoomSystemDefaultPresentation $request, Room $room) + { + if ($request->has('use_in_meeting')) { + $room->use_system_default_presentation_in_meeting = $request->use_in_meeting; + } + + if ($request->has('default')) { + // Make other files not the default + if ($request->default === true) { + $room->files()->update(['default' => false]); + + // If system default is set as default, it must also be used in the next meeting + $room->use_system_default_presentation_in_meeting = true; + } + + $room->use_system_default_presentation_as_default = $request->default; + } + + $room->save(); + + Log::info('Changed system default presentation settings in room {room}', ['room' => $room->getLogLabel()]); + + $room->updateDefaultFile(); + + return response()->noContent(); + } + /** * Remove the specified file from storage and database. * diff --git a/app/Http/Requests/UpdateRoomSystemDefaultPresentation.php b/app/Http/Requests/UpdateRoomSystemDefaultPresentation.php new file mode 100644 index 000000000..7fa8c5917 --- /dev/null +++ b/app/Http/Requests/UpdateRoomSystemDefaultPresentation.php @@ -0,0 +1,16 @@ + ['required', 'boolean'], + 'default' => ['required', 'boolean'], + ]; + } +} diff --git a/app/Models/Room.php b/app/Models/Room.php index 70591c156..d8ae46e3f 100644 --- a/app/Models/Room.php +++ b/app/Models/Room.php @@ -28,6 +28,8 @@ protected function casts() { $casts = [ 'expert_mode' => 'boolean', + 'use_system_default_presentation_in_meeting' => 'boolean', + 'use_system_default_presentation_as_default' => 'boolean', 'delete_inactive' => 'datetime', ]; @@ -201,7 +203,13 @@ public function updateDefaultFile() $currentDefault->default = false; $currentDefault->save(); } - // If any other files are found that are used in the next meeting, select the first one to become new default + + // If system has a default presentation and the system presentation is set as default, no further action needed + if (app(BigBlueButtonSettings::class)->default_presentation && $this->use_system_default_presentation_as_default) { + return; + } + + // If no default file is explicitly set or the system default should be used, $newDefaultFile = $this->files()->firstWhere('use_in_meeting', true); if ($newDefaultFile != null) { $newDefaultFile->default = true; diff --git a/app/Services/MeetingService.php b/app/Services/MeetingService.php index 5bccd3edb..3b65fe8f0 100644 --- a/app/Services/MeetingService.php +++ b/app/Services/MeetingService.php @@ -104,7 +104,13 @@ public function start(): ?\BigBlueButton\Responses\CreateMeetingResponse $meetingParams->addMeta('bbb-origin', 'PILOS'); $meetingParams->addMeta('pilos-sub-spool-dir', config('recording.spool-sub-directory')); - // get files that should be used in this meeting and add links to the files + // Use system default presentation as default, if explicitly set + $useSystemDefaultFileAsDefault = app(BigBlueButtonSettings::class)->default_presentation && $this->meeting->room->use_system_default_presentation_as_default; + if ($useSystemDefaultFileAsDefault) { + $meetingParams->addPresentation(app(BigBlueButtonSettings::class)->default_presentation); + } + + // Get files that should be used in this meeting and add links to the files $files = $this->meeting->room->files()->where('use_in_meeting', true)->orderBy('default', 'desc')->get(); foreach ($files as $file) { // Create file download url @@ -117,7 +123,12 @@ public function start(): ?\BigBlueButton\Responses\CreateMeetingResponse $meetingParams->addPresentation($fileUrl, null, preg_replace("/[^A-Za-z0-9.-_\(\)]/", '', $file->filename)); } - if (empty($meetingParams->getPresentations()) && app(BigBlueButtonSettings::class)->default_presentation) { + // Add system default presentation + // Only add it, if not already added as default file + // and if no other files are present or the room is set to use the system default in meetings + if (! $useSystemDefaultFileAsDefault && app(BigBlueButtonSettings::class)->default_presentation && ( + empty($files->toArray()) || $this->meeting->room->use_system_default_presentation_in_meeting + )) { $meetingParams->addPresentation(app(BigBlueButtonSettings::class)->default_presentation); } diff --git a/database/migrations/2026_01_19_105554_add_use_system_default_presentation_in_next_meeting_to_rooms_table.php b/database/migrations/2026_01_19_105554_add_use_system_default_presentation_in_next_meeting_to_rooms_table.php new file mode 100644 index 000000000..87ffb1e43 --- /dev/null +++ b/database/migrations/2026_01_19_105554_add_use_system_default_presentation_in_next_meeting_to_rooms_table.php @@ -0,0 +1,30 @@ +boolean('use_system_default_presentation_in_meeting')->default(false); + $table->boolean('use_system_default_presentation_as_default')->default(false); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('rooms', function (Blueprint $table) { + $table->dropColumn('use_system_default_presentation_in_meeting'); + $table->dropColumn('use_system_default_presentation_as_default'); + }); + } +}; diff --git a/lang/en/rooms.php b/lang/en/rooms.php index d09571019..762240725 100644 --- a/lang/en/rooms.php +++ b/lang/en/rooms.php @@ -107,12 +107,14 @@ 'feature_disabled_system' => ':name is disabled. Please contact the administrator.', 'files' => [ 'confirm_delete' => 'Do you want to delete this file :filename?', - 'default' => 'Default', + 'default' => 'Default presentation', 'delete' => 'Delete file', - 'download_hidden' => 'Download hidden', - 'download_visible' => 'Download visible', + 'download_allowed' => 'Download allowed', + 'download_not_allowed' => 'Download not allowed', 'downloadable' => 'Downloadable', - 'edit' => 'Edit file', + 'configure' => 'Configure file', + 'configure_dialog_title' => 'Configure ":name"', + 'configure_system_default' => 'Configure system-wide default presentation', 'filter' => [ 'all' => 'All files', 'downloadable' => 'Downloadable files', @@ -126,6 +128,8 @@ 'filename' => 'Filename', 'uploaded_at' => 'Added', ], + 'system_default' => 'System-wide default presentation', + 'system_default_description' => 'Automatically used when no other presentation is enabled for the next video conference', 'terms_of_use' => [ 'accept' => 'I accept the terms of use', 'required' => 'You must accept the terms of use before downloading this file.', @@ -134,8 +138,9 @@ 'title' => 'Files', 'upload' => 'Upload files', 'uploaded' => 'File \':name\' uploaded', - 'use_in_next_meeting' => 'Use in the next meeting', - 'use_in_next_meeting_disabled' => 'Not available in video conference', + 'always_available_in_meeting' => 'Always available in next video conference', + 'available_in_next_meeting' => 'Available in next video conference', + 'not_available_in_next_meeting' => 'Not available in next video conference', 'view' => 'View file', ], 'first_and_lastname' => 'First- and last name', diff --git a/resources/css/override/_animations.css b/resources/css/override/_animations.css index 2930e5735..083145e71 100644 --- a/resources/css/override/_animations.css +++ b/resources/css/override/_animations.css @@ -8,3 +8,8 @@ animation-duration: 0s !important; } } + +.inline-note.p-message-enter-active, +.p-message-leave-active { + animation-duration: 0s !important; +} diff --git a/resources/js/components/InlineNote.vue b/resources/js/components/InlineNote.vue index 24f03ceec..43198b660 100644 --- a/resources/js/components/InlineNote.vue +++ b/resources/js/components/InlineNote.vue @@ -8,7 +8,11 @@ defineProps({ diff --git a/resources/js/components/RoomTabFiles.vue b/resources/js/components/RoomTabFiles.vue index d8c0bf02a..8a1ca1edc 100644 --- a/resources/js/components/RoomTabFiles.vue +++ b/resources/js/components/RoomTabFiles.vue @@ -146,6 +146,20 @@ + +