From 958af34244217960693336f6c0cc776380900461 Mon Sep 17 00:00:00 2001 From: sualko Date: Mon, 19 Apr 2021 14:47:15 +0200 Subject: [PATCH] feat: add new join options - disable listen only mode - skip audio check and video preview on first join - clean layout without presentation, chat area and user list --- lib/BigBlueButton/API.php | 9 +++ lib/Controller/RoomController.php | 9 ++- lib/Db/Room.php | 15 ++++ .../Version000000Date20210419132000.php | 55 ++++++++++++++ lib/Service/RoomService.php | 17 ++++- ts/Common/Api.ts | 3 + ts/Manager/EditRoomDialog.tsx | 76 ++++++++++++++----- 7 files changed, 161 insertions(+), 23 deletions(-) create mode 100644 lib/Migration/Version000000Date20210419132000.php diff --git a/lib/BigBlueButton/API.php b/lib/BigBlueButton/API.php index 6fc04e3..573d514 100644 --- a/lib/BigBlueButton/API.php +++ b/lib/BigBlueButton/API.php @@ -89,6 +89,15 @@ class API { $joinMeetingParams->setRedirect(true); $joinMeetingParams->setGuest($uid === null); + $joinMeetingParams->addUserData('bbb_listen_only_mode', $room->getListenOnly()); + + $joinMeetingParams->addUserData('bbb_skip_check_audio_on_first_join', !$room->getMediaCheck()); // 2.3 + $joinMeetingParams->addUserData('bbb_skip_video_preview_on_first_join', !$room->getMediaCheck()); // 2.3 + + $joinMeetingParams->addUserData('bbb_auto_swap_layout', $room->getCleanLayout()); + $joinMeetingParams->addUserData('bbb_show_participants_on_login', !$room->getCleanLayout()); + $joinMeetingParams->addUserData('bbb_show_public_chat_on_login', !$room->getCleanLayout()); + if ($this->config->getAppValue('bbb', 'join.theme') === 'true') { $primaryColor = $this->defaults->getColorPrimary(); $textColor = $this->defaults->getTextColorPrimary(); diff --git a/lib/Controller/RoomController.php b/lib/Controller/RoomController.php index 62e8c17..3a72119 100644 --- a/lib/Controller/RoomController.php +++ b/lib/Controller/RoomController.php @@ -115,7 +115,10 @@ class RoomController extends Controller { string $access, bool $everyoneIsModerator, bool $requireModerator, - ?string $moderatorToken + ?string $moderatorToken, + bool $listenOnly, + bool $mediaCheck, + bool $cleanLayout ): DataResponse { $room = $this->service->find($id); @@ -138,8 +141,8 @@ class RoomController extends Controller { return new DataResponse(['message' => 'Access type not allowed.'], Http::STATUS_BAD_REQUEST); } - return $this->handleNotFound(function () use ($id, $name, $welcome, $maxParticipants, $record, $access, $everyoneIsModerator, $requireModerator, $moderatorToken) { - return $this->service->update($id, $name, $welcome, $maxParticipants, $record, $access, $everyoneIsModerator, $requireModerator, $moderatorToken); + return $this->handleNotFound(function () use ($id, $name, $welcome, $maxParticipants, $record, $access, $everyoneIsModerator, $requireModerator, $moderatorToken, $listenOnly, $mediaCheck, $cleanLayout) { + return $this->service->update($id, $name, $welcome, $maxParticipants, $record, $access, $everyoneIsModerator, $requireModerator, $moderatorToken, $listenOnly, $mediaCheck, $cleanLayout); }); } diff --git a/lib/Db/Room.php b/lib/Db/Room.php index 068f96f..47fc27d 100644 --- a/lib/Db/Room.php +++ b/lib/Db/Room.php @@ -21,6 +21,9 @@ use OCP\AppFramework\Db\Entity; * @method bool getRequireModerator() * @method bool getEveryoneIsModerator() * @method string getModeratorToken() + * @method bool getListenOnly() + * @method bool getMediaCheck() + * @method bool getCleanLayout() * @method void setUid(string $uid) * @method void setName(string $name) * @method void setAttendeePassword(string $pw) @@ -34,6 +37,9 @@ use OCP\AppFramework\Db\Entity; * @method void setEveryoneIsModerator(bool $everyone) * @method void setRequireModerator(bool $require) * @method void setModeratorToken(string $moderatorToken) + * @method void setListenOnly(bool $listenOnly) + * @method void setMediaCheck(bool $mediaCheck) + * @method void setCleanLayout(bool $cleanLayout) */ class Room extends Entity implements JsonSerializable { public const ACCESS_PUBLIC = 'public'; @@ -58,6 +64,9 @@ class Room extends Entity implements JsonSerializable { public $requireModerator = false; public $shared = false; public $moderatorToken; + public $listenOnly; + public $mediaCheck; + public $cleanLayout; public function __construct() { $this->addType('maxParticipants', 'integer'); @@ -65,6 +74,9 @@ class Room extends Entity implements JsonSerializable { $this->addType('everyoneIsModerator', 'boolean'); $this->addType('requireModerator', 'boolean'); $this->addType('shared', 'boolean'); + $this->addType('listenOnly', 'boolean'); + $this->addType('mediaCheck', 'boolean'); + $this->addType('cleanLayout', 'boolean'); } public function jsonSerialize(): array { @@ -82,6 +94,9 @@ class Room extends Entity implements JsonSerializable { 'requireModerator' => boolval($this->requireModerator), 'shared' => boolval($this->shared), 'moderatorToken' => $this->moderatorToken, + 'listenOnly' => boolval($this->listenOnly), + 'mediaCheck' => boolval($this->mediaCheck), + 'cleanLayout' => boolval($this->cleanLayout), ]; } } diff --git a/lib/Migration/Version000000Date20210419132000.php b/lib/Migration/Version000000Date20210419132000.php new file mode 100644 index 0000000..ba5f82e --- /dev/null +++ b/lib/Migration/Version000000Date20210419132000.php @@ -0,0 +1,55 @@ +hasTable('bbb_rooms')) { + $table = $schema->getTable('bbb_rooms'); + + if (!$table->hasColumn('listen_only')) { + $table->addColumn('listen_only', 'boolean', [ + 'notnull' => true, + 'default' => true + ]); + } + + if (!$table->hasColumn('media_check')) { + $table->addColumn('media_check', 'boolean', [ + 'notnull' => true, + 'default' => true + ]); + } + + if (!$table->hasColumn('clean_layout')) { + $table->addColumn('clean_layout', 'boolean', [ + 'notnull' => true, + 'default' => false + ]); + } + + return $schema; + } + + return null; + } +} diff --git a/lib/Service/RoomService.php b/lib/Service/RoomService.php index f99e14e..9c7eba3 100644 --- a/lib/Service/RoomService.php +++ b/lib/Service/RoomService.php @@ -102,7 +102,19 @@ class RoomService { * * @return \OCP\AppFramework\Db\Entity|null */ - public function update(int $id, string $name, string $welcome, int $maxParticipants, bool $record, string $access, bool $everyoneIsModerator, bool $requireModerator, ?string $moderatorToken) { + public function update( + int $id, + string $name, + string $welcome, + int $maxParticipants, + bool $record, + string $access, + bool $everyoneIsModerator, + bool $requireModerator, + ?string $moderatorToken, + bool $listenOnly, + bool $mediaCheck, + bool $cleanLayout) { try { $room = $this->mapper->find($id); @@ -121,6 +133,9 @@ class RoomService { $room->setAccess($access); $room->setEveryoneIsModerator($everyoneIsModerator); $room->setRequireModerator($requireModerator); + $room->setListenOnly($listenOnly); + $room->setMediaCheck($mediaCheck); + $room->setCleanLayout($cleanLayout); return $this->mapper->update($room); } catch (Exception $e) { diff --git a/ts/Common/Api.ts b/ts/Common/Api.ts index 56111a1..2360164 100644 --- a/ts/Common/Api.ts +++ b/ts/Common/Api.ts @@ -39,6 +39,9 @@ export interface Room { requireModerator: boolean; shared: boolean; moderatorToken: string; + listenOnly: boolean, + mediaCheck: boolean, + cleanLayout: boolean, } export interface RoomShare { diff --git a/ts/Manager/EditRoomDialog.tsx b/ts/Manager/EditRoomDialog.tsx index 7edda7a..74dc07d 100644 --- a/ts/Manager/EditRoomDialog.tsx +++ b/ts/Manager/EditRoomDialog.tsx @@ -17,6 +17,9 @@ const descriptions: { [key: string]: string } = { requireModerator: t('bbb', 'If enabled, normal users have to wait until a moderator is in the room.'), moderatorToken: t('bbb', 'If enabled, a moderator URL is generated which allows access with moderator permission.'), internalRestrictedShareWith: t('bbb', 'Only selected users and groups are allowed to access the room.'), + listenOnly: t('bbb', 'If disabled, a microphone is needed to join the conference.'), + mediaCheck: t('bbb', 'If enabled, the user has not to perform an echo call and webcam preview on the first join (available since BBB server 2.3).'), + cleanLayout: t('bbb', 'If enabled, the user list, chat area and presentation are hidden by default.'), }; const LOGO_QR = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAOxAAADsQBlSsOGwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAAGnSURBVFiF7de9TxRBHMbxzxG5BonRBOGsVRJfIvGFPwFKX0tjJGqsrfwvCC0YtbJSQyT4J0hB1BhtjZFCI4FoqTRCsbO43g24e+5Q3ZNsZm9+z8zzvZns7Rw9/a0jeIx1bNZ8rYe5WzuFt7CSILj9WsFwHtooADzA7XD/DG/CgDrUwHlcDZ/ncLfdtBoCn9cUGtN8yPiWd/QVikOhfZcQ4G1oD8cA8u2oa9ljyufe3vq+HYx7ph7Avv8YO4Rx2b4uy35oKqubFWhiBl+wiJf4imn0V52smxWYxc22vn7cwwHcqjJZ1RUYi4QXNYUzKQEm/1FvYCIlwEAJz/6UAB9KeN6nBFjAp13qH2VPRjKADdkr9Uek9h3XgicZwGk8wcFI7VConUoFMIZXOLGL5ySWVHgUywI08RSDJbyDwdusE+AGjpb0wjFcrxPgSoXwXJerAnScVgo63gXAaKSv49RVBFgL7dnIwN9dAMR0LrSreUfxbfgCd3BJdix/7Q/pBn5WDPuF++G+gQu4WMjq0Ii9+WPyWeFU3K4WHsm2o+7gNTwMX7SnbW0BScCZl0uGVe8AAAAASUVORK5CYII='; @@ -153,29 +156,64 @@ const EditRoomDialog: React.FC = ({ room, restriction, updateProperty, op {descriptions.moderatorToken} -

{t('bbb', 'Miscellaneous')}

-
+
+

{t('bbb', 'Miscellaneous')}

- updateProperty('record', event.target.checked)} /> - +
+ updateProperty('record', event.target.checked)} /> + +
+

{descriptions.recording}

-

{descriptions.recording}

-
-
- updateProperty('requireModerator', event.target.checked)} /> - +
+ updateProperty('requireModerator', event.target.checked)} /> + +
+

{descriptions.requireModerator}

+
+
+
+ updateProperty('listenOnly', event.target.checked)} /> + +
+

{descriptions.listenOnly}

+
+
+
+ updateProperty('mediaCheck', !event.target.checked)} /> + +
+

{descriptions.mediaCheck}

+
+
+
+ updateProperty('cleanLayout', event.target.checked)} /> + +
+

{descriptions.cleanLayout}

-

{descriptions.requireModerator}

);