mirror of https://github.com/sualko/cloud_bbb
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 listpull/149/head
parent
c39ab49e76
commit
958af34244
|
@ -89,6 +89,15 @@ class API {
|
||||||
$joinMeetingParams->setRedirect(true);
|
$joinMeetingParams->setRedirect(true);
|
||||||
$joinMeetingParams->setGuest($uid === null);
|
$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') {
|
if ($this->config->getAppValue('bbb', 'join.theme') === 'true') {
|
||||||
$primaryColor = $this->defaults->getColorPrimary();
|
$primaryColor = $this->defaults->getColorPrimary();
|
||||||
$textColor = $this->defaults->getTextColorPrimary();
|
$textColor = $this->defaults->getTextColorPrimary();
|
||||||
|
|
|
@ -115,7 +115,10 @@ class RoomController extends Controller {
|
||||||
string $access,
|
string $access,
|
||||||
bool $everyoneIsModerator,
|
bool $everyoneIsModerator,
|
||||||
bool $requireModerator,
|
bool $requireModerator,
|
||||||
?string $moderatorToken
|
?string $moderatorToken,
|
||||||
|
bool $listenOnly,
|
||||||
|
bool $mediaCheck,
|
||||||
|
bool $cleanLayout
|
||||||
): DataResponse {
|
): DataResponse {
|
||||||
$room = $this->service->find($id);
|
$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 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->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);
|
return $this->service->update($id, $name, $welcome, $maxParticipants, $record, $access, $everyoneIsModerator, $requireModerator, $moderatorToken, $listenOnly, $mediaCheck, $cleanLayout);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,9 @@ use OCP\AppFramework\Db\Entity;
|
||||||
* @method bool getRequireModerator()
|
* @method bool getRequireModerator()
|
||||||
* @method bool getEveryoneIsModerator()
|
* @method bool getEveryoneIsModerator()
|
||||||
* @method string getModeratorToken()
|
* @method string getModeratorToken()
|
||||||
|
* @method bool getListenOnly()
|
||||||
|
* @method bool getMediaCheck()
|
||||||
|
* @method bool getCleanLayout()
|
||||||
* @method void setUid(string $uid)
|
* @method void setUid(string $uid)
|
||||||
* @method void setName(string $name)
|
* @method void setName(string $name)
|
||||||
* @method void setAttendeePassword(string $pw)
|
* @method void setAttendeePassword(string $pw)
|
||||||
|
@ -34,6 +37,9 @@ use OCP\AppFramework\Db\Entity;
|
||||||
* @method void setEveryoneIsModerator(bool $everyone)
|
* @method void setEveryoneIsModerator(bool $everyone)
|
||||||
* @method void setRequireModerator(bool $require)
|
* @method void setRequireModerator(bool $require)
|
||||||
* @method void setModeratorToken(string $moderatorToken)
|
* @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 {
|
class Room extends Entity implements JsonSerializable {
|
||||||
public const ACCESS_PUBLIC = 'public';
|
public const ACCESS_PUBLIC = 'public';
|
||||||
|
@ -58,6 +64,9 @@ class Room extends Entity implements JsonSerializable {
|
||||||
public $requireModerator = false;
|
public $requireModerator = false;
|
||||||
public $shared = false;
|
public $shared = false;
|
||||||
public $moderatorToken;
|
public $moderatorToken;
|
||||||
|
public $listenOnly;
|
||||||
|
public $mediaCheck;
|
||||||
|
public $cleanLayout;
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
$this->addType('maxParticipants', 'integer');
|
$this->addType('maxParticipants', 'integer');
|
||||||
|
@ -65,6 +74,9 @@ class Room extends Entity implements JsonSerializable {
|
||||||
$this->addType('everyoneIsModerator', 'boolean');
|
$this->addType('everyoneIsModerator', 'boolean');
|
||||||
$this->addType('requireModerator', 'boolean');
|
$this->addType('requireModerator', 'boolean');
|
||||||
$this->addType('shared', 'boolean');
|
$this->addType('shared', 'boolean');
|
||||||
|
$this->addType('listenOnly', 'boolean');
|
||||||
|
$this->addType('mediaCheck', 'boolean');
|
||||||
|
$this->addType('cleanLayout', 'boolean');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function jsonSerialize(): array {
|
public function jsonSerialize(): array {
|
||||||
|
@ -82,6 +94,9 @@ class Room extends Entity implements JsonSerializable {
|
||||||
'requireModerator' => boolval($this->requireModerator),
|
'requireModerator' => boolval($this->requireModerator),
|
||||||
'shared' => boolval($this->shared),
|
'shared' => boolval($this->shared),
|
||||||
'moderatorToken' => $this->moderatorToken,
|
'moderatorToken' => $this->moderatorToken,
|
||||||
|
'listenOnly' => boolval($this->listenOnly),
|
||||||
|
'mediaCheck' => boolval($this->mediaCheck),
|
||||||
|
'cleanLayout' => boolval($this->cleanLayout),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace OCA\BigBlueButton\Migration;
|
||||||
|
|
||||||
|
use Closure;
|
||||||
|
use OCP\DB\ISchemaWrapper;
|
||||||
|
use OCP\Migration\IOutput;
|
||||||
|
use OCP\Migration\SimpleMigrationStep;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto-generated migration step: Please modify to your needs!
|
||||||
|
*/
|
||||||
|
class Version000000Date20210419132000 extends SimpleMigrationStep {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IOutput $output
|
||||||
|
* @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper`
|
||||||
|
* @param array $options
|
||||||
|
* @return null|ISchemaWrapper
|
||||||
|
*/
|
||||||
|
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options) {
|
||||||
|
$schema = $schemaClosure();
|
||||||
|
|
||||||
|
if ($schema->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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -102,7 +102,19 @@ class RoomService {
|
||||||
*
|
*
|
||||||
* @return \OCP\AppFramework\Db\Entity|null
|
* @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 {
|
try {
|
||||||
$room = $this->mapper->find($id);
|
$room = $this->mapper->find($id);
|
||||||
|
|
||||||
|
@ -121,6 +133,9 @@ class RoomService {
|
||||||
$room->setAccess($access);
|
$room->setAccess($access);
|
||||||
$room->setEveryoneIsModerator($everyoneIsModerator);
|
$room->setEveryoneIsModerator($everyoneIsModerator);
|
||||||
$room->setRequireModerator($requireModerator);
|
$room->setRequireModerator($requireModerator);
|
||||||
|
$room->setListenOnly($listenOnly);
|
||||||
|
$room->setMediaCheck($mediaCheck);
|
||||||
|
$room->setCleanLayout($cleanLayout);
|
||||||
|
|
||||||
return $this->mapper->update($room);
|
return $this->mapper->update($room);
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
|
|
|
@ -39,6 +39,9 @@ export interface Room {
|
||||||
requireModerator: boolean;
|
requireModerator: boolean;
|
||||||
shared: boolean;
|
shared: boolean;
|
||||||
moderatorToken: string;
|
moderatorToken: string;
|
||||||
|
listenOnly: boolean,
|
||||||
|
mediaCheck: boolean,
|
||||||
|
cleanLayout: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface RoomShare {
|
export interface RoomShare {
|
||||||
|
|
|
@ -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.'),
|
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.'),
|
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.'),
|
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=';
|
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,6 +156,7 @@ const EditRoomDialog: React.FC<Props> = ({ room, restriction, updateProperty, op
|
||||||
<em>{descriptions.moderatorToken}</em>
|
<em>{descriptions.moderatorToken}</em>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div className="bbb-form-element">
|
||||||
<h3>{t('bbb', 'Miscellaneous')}</h3>
|
<h3>{t('bbb', 'Miscellaneous')}</h3>
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -177,6 +181,40 @@ const EditRoomDialog: React.FC<Props> = ({ room, restriction, updateProperty, op
|
||||||
</div>
|
</div>
|
||||||
<p><em>{descriptions.requireModerator}</em></p>
|
<p><em>{descriptions.requireModerator}</em></p>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<input id={`bbb-listenOnly-${room.id}`}
|
||||||
|
type="checkbox"
|
||||||
|
className="checkbox"
|
||||||
|
checked={room.listenOnly}
|
||||||
|
onChange={(event) => updateProperty('listenOnly', event.target.checked)} />
|
||||||
|
<label htmlFor={`bbb-listenOnly-${room.id}`}>{t('bbb', 'Listen only option')}</label>
|
||||||
|
</div>
|
||||||
|
<p><em>{descriptions.listenOnly}</em></p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<input id={`bbb-mediaCheck-${room.id}`}
|
||||||
|
type="checkbox"
|
||||||
|
className="checkbox"
|
||||||
|
checked={!room.mediaCheck}
|
||||||
|
onChange={(event) => updateProperty('mediaCheck', !event.target.checked)} />
|
||||||
|
<label htmlFor={`bbb-mediaCheck-${room.id}`}>{t('bbb', 'Skip media check before usage')}</label>
|
||||||
|
</div>
|
||||||
|
<p><em>{descriptions.mediaCheck}</em></p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<input id={`bbb-cleanLayout-${room.id}`}
|
||||||
|
type="checkbox"
|
||||||
|
className="checkbox"
|
||||||
|
checked={room.cleanLayout}
|
||||||
|
onChange={(event) => updateProperty('cleanLayout', event.target.checked)} />
|
||||||
|
<label htmlFor={`bbb-cleanLayout-${room.id}`}>{t('bbb', 'Clean layout')}</label>
|
||||||
|
</div>
|
||||||
|
<p><em>{descriptions.cleanLayout}</em></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue