feat: option to set everyone as moderator

pull/63/head
sualko 2020-06-17 08:19:54 +02:00
parent 2624175af6
commit d48c9da09c
8 changed files with 83 additions and 13 deletions

View File

@ -74,10 +74,11 @@ class RoomController extends Controller
string $welcome, string $welcome,
int $maxParticipants, int $maxParticipants,
bool $record, bool $record,
string $access string $access,
bool $everyoneIsModerator
): DataResponse { ): DataResponse {
return $this->handleNotFound(function () use ($id, $name, $welcome, $maxParticipants, $record, $access) { return $this->handleNotFound(function () use ($id, $name, $welcome, $maxParticipants, $record, $everyoneIsModerator, $access) {
return $this->service->update($id, $name, $welcome, $maxParticipants, $record, $access, $this->userId); return $this->service->update($id, $name, $welcome, $maxParticipants, $record, $access, $everyoneIsModerator, $this->userId);
}); });
} }

View File

@ -23,24 +23,27 @@ class Room extends Entity implements JsonSerializable
public $userId; public $userId;
public $access; public $access;
public $password; public $password;
public $everyoneIsModerator;
public function __construct() public function __construct()
{ {
$this->addType('maxParticipants', 'integer'); $this->addType('maxParticipants', 'integer');
$this->addType('record', 'boolean'); $this->addType('record', 'boolean');
$this->addType('everyoneIsModerator', 'boolean');
} }
public function jsonSerialize(): array public function jsonSerialize(): array
{ {
return [ return [
'id' => $this->id, 'id' => $this->id,
'uid' => $this->uid, 'uid' => $this->uid,
'name' => $this->name, 'name' => $this->name,
'welcome' => $this->welcome, 'welcome' => $this->welcome,
'maxParticipants' => (int) $this->maxParticipants, 'maxParticipants' => (int) $this->maxParticipants,
'record' => boolval($this->record), 'record' => boolval($this->record),
'access' => $this->access, 'access' => $this->access,
'password' => $this->password, 'password' => $this->password,
'everyoneIsModerator' => boolval($this->everyoneIsModerator),
]; ];
} }
} }

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace OCA\BigBlueButton\Migration;
use Closure;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version000000Date20200617055735 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)
{
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
if ($schema->hasTable('bbb_rooms')) {
$table = $schema->getTable('bbb_rooms');
if (!$table->hasColumn('everyone_is_moderator')) {
$table->addColumn('everyone_is_moderator', 'boolean', [
'notnull' => true,
'default' => false,
]);
}
return $schema;
}
return null;
}
}

View File

@ -34,6 +34,10 @@ class Permission
public function isModerator(Room $room, string $uid) public function isModerator(Room $room, string $uid)
{ {
if ($room->everyoneIsModerator) {
return true;
}
return $this->hasPermission($room, $uid, function (RoomShare $share) { return $this->hasPermission($room, $uid, function (RoomShare $share) {
return $share->hasModeratorPermission(); return $share->hasModeratorPermission();
}); });

View File

@ -75,7 +75,7 @@ class RoomService
return $this->mapper->insert($room); return $this->mapper->insert($room);
} }
public function update($id, $name, $welcome, $maxParticipants, $record, $access, $userId) public function update($id, $name, $welcome, $maxParticipants, $record, $access, $everyoneIsModerator, $userId)
{ {
try { try {
$room = $this->mapper->find($id, $userId); $room = $this->mapper->find($id, $userId);
@ -89,6 +89,7 @@ class RoomService
$room->setMaxParticipants($maxParticipants); $room->setMaxParticipants($maxParticipants);
$room->setRecord($record); $room->setRecord($record);
$room->setAccess($access); $room->setAccess($access);
$room->setEveryoneIsModerator($everyoneIsModerator);
$room->setUserId($userId); $room->setUserId($userId);
return $this->mapper->update($room); return $this->mapper->update($room);

View File

@ -21,6 +21,7 @@ export interface Room {
record: boolean; record: boolean;
access: Access; access: Access;
password?: string; password?: string;
everyoneIsModerator: boolean;
} }
export interface RoomShare { export interface RoomShare {

View File

@ -7,6 +7,14 @@
margin-top: 25px; margin-top: 25px;
} }
.bbb-mb-1 {
margin-bottom: 1em;
}
.bbb-mt-1 {
margin-top: 1em;
}
#bbb-warning { #bbb-warning {
padding: 1em; padding: 1em;
background-color: rgb(255, 255, 123); background-color: rgb(255, 255, 123);

View File

@ -10,6 +10,7 @@ const descriptions: { [key: string]: string } = {
maxParticipants: t('bbb', 'Sets a limit on the number of participants for this room. Zero means there is no limit.'), maxParticipants: t('bbb', 'Sets a limit on the number of participants for this room. Zero means there is no limit.'),
recording: t('bbb', 'If enabled, the moderator is able to start the recording.'), recording: t('bbb', 'If enabled, the moderator is able to start the recording.'),
access: t('bbb', 'Public: Everyone knowing the link is able to join. Password: Guests have to provide a password. Waiting room: A moderator has to accept every guest before they can join. Internal: Only Nextcloud users can join.'), access: t('bbb', 'Public: Everyone knowing the link is able to join. Password: Guests have to provide a password. Waiting room: A moderator has to accept every guest before they can join. Internal: Only Nextcloud users can join.'),
moderator: t('bbb', 'A moderator is able to manage all participants in a meeting including kicking, muting or selecting a presenter. Users with the role moderator are also able to close a meeting or change the default settings.'),
}; };
type Props = { type Props = {
@ -96,7 +97,17 @@ const EditRoomDialog: React.FC<Props> = ({ room, updateProperty, open, setOpen }
<h3>Moderator</h3> <h3>Moderator</h3>
</label> </label>
<ShareWith permission={Permission.Moderator} room={room} shares={shares} setShares={setShares} /> {!room.everyoneIsModerator && <ShareWith permission={Permission.Moderator} room={room} shares={shares} setShares={setShares} />}
<div className="bbb-mt-1">
<input id={`bbb-everyoneIsModerator-${room.id}`}
type="checkbox"
className="checkbox"
checked={room.everyoneIsModerator}
onChange={(event) => updateProperty('everyoneIsModerator', event.target.checked)} />
<label htmlFor={`bbb-everyoneIsModerator-${room.id}`}>{t('bbb', 'Every participant is moderator')}</label>
</div>
<em>{descriptions.moderator}</em>
</div> </div>
<h3>{t('bbb', 'Miscellaneous')}</h3> <h3>{t('bbb', 'Miscellaneous')}</h3>