mirror of https://github.com/sualko/cloud_bbb
feat: videos for all users and moderators
Admin may change the "published" status of a video. users/moderators may only see the published ones.pull/281/head
parent
9fed698723
commit
ac2626bc2c
|
@ -14,6 +14,7 @@ return [
|
|||
['name' => 'server#check', 'url' => '/server/check', 'verb' => 'POST'],
|
||||
['name' => 'server#version', 'url' => '/server/version', 'verb' => 'GET'],
|
||||
['name' => 'server#delete_record', 'url' => '/server/record/{recordId}', 'verb' => 'DELETE'],
|
||||
['name' => 'server#publish_record', 'url' => '/server/record/{recordId}/publish', 'verb' => 'POST'],
|
||||
['name' => 'join#index', 'url' => '/b/{token}/{moderatorToken}', 'verb' => 'GET', 'defaults' => ['moderatorToken' => '']],
|
||||
['name' => 'restriction#user', 'url' => '/restrictions/user', 'verb' => 'GET'],
|
||||
['name' => 'hook#meetingEnded', 'url' => '/hook/ended/{token}/{mac}', 'verb' => 'GET'],
|
||||
|
|
|
@ -10,6 +10,7 @@ use BigBlueButton\Parameters\GetRecordingsParameters;
|
|||
use BigBlueButton\Parameters\InsertDocumentParameters;
|
||||
use BigBlueButton\Parameters\IsMeetingRunningParameters;
|
||||
use BigBlueButton\Parameters\JoinMeetingParameters;
|
||||
use BigBlueButton\Parameters\PublishRecordingsParameters;
|
||||
use OCA\BigBlueButton\AppInfo\Application;
|
||||
use OCA\BigBlueButton\AvatarRepository;
|
||||
use OCA\BigBlueButton\Crypto;
|
||||
|
@ -262,6 +263,14 @@ class API {
|
|||
return $response->isDeleted();
|
||||
}
|
||||
|
||||
public function publishRecording(string $recordingId, bool $published): bool {
|
||||
$publishParams = new PublishRecordingsParameters($recordingId, $published);
|
||||
|
||||
$response = $this->getServer()->publishRecordings($publishParams);
|
||||
|
||||
return $response->isPublished();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return (array|bool|int|string)[]
|
||||
*
|
||||
|
|
|
@ -95,9 +95,9 @@ class ServerController extends Controller {
|
|||
$recordings = $this->server->getRecordings($room);
|
||||
|
||||
if (!$this->permission->isAdmin($room, $this->userId)) {
|
||||
$recordings = array_filter($recordings, function ($recording) {
|
||||
$recordings = array_values(array_filter($recordings, function ($recording) {
|
||||
return $recording['published'];
|
||||
});
|
||||
}));
|
||||
}
|
||||
|
||||
return new DataResponse($recordings);
|
||||
|
@ -124,6 +124,27 @@ class ServerController extends Controller {
|
|||
return new DataResponse($success);
|
||||
}
|
||||
|
||||
/**
|
||||
* @NoAdminRequired
|
||||
*/
|
||||
public function publishRecord(string $recordId, bool $published): DataResponse {
|
||||
$record = $this->server->getRecording($recordId);
|
||||
|
||||
$room = $this->service->findByUid($record['meetingId']);
|
||||
|
||||
if ($room === null) {
|
||||
return new DataResponse(false, Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
if (!$this->permission->isAdmin($room, $this->userId)) {
|
||||
return new DataResponse(false, Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
$success = $this->server->publishRecording($recordId, $published);
|
||||
|
||||
return new DataResponse($success);
|
||||
}
|
||||
|
||||
public function check(?string $url, ?string $secret): DataResponse {
|
||||
if ($url === null || empty($url) || $secret === null || empty($secret)) {
|
||||
return new DataResponse(false);
|
||||
|
|
|
@ -201,6 +201,14 @@ class Api {
|
|||
return response.data;
|
||||
}
|
||||
|
||||
public async publishRecording(id: string, publish: boolean,) {
|
||||
const response = await axios.post(this.getUrl(`server/record/${id}/publish`), {
|
||||
published: publish,
|
||||
});
|
||||
|
||||
return response.data;
|
||||
}
|
||||
|
||||
public async storeRecording(recording: Recording, path: string) {
|
||||
const startDate = new Date(recording.startTime);
|
||||
const filename = `${encodeURIComponent(recording.name + ' ' + startDate.toISOString())}.url`;
|
||||
|
|
|
@ -4,11 +4,29 @@ import { Recording } from '../Common/Api';
|
|||
|
||||
type Props = {
|
||||
recording: Recording;
|
||||
isAdmin : boolean;
|
||||
deleteRecording: (recording: Recording) => void;
|
||||
storeRecording: (recording: Recording) => void;
|
||||
publishRecording: (recording: Recording, publish: boolean) => void;
|
||||
}
|
||||
|
||||
const RecordingRow: React.FC<Props> = ({recording, deleteRecording, storeRecording}) => {
|
||||
const RecordingRow: React.FC<Props> = ({recording, isAdmin, deleteRecording, storeRecording, publishRecording}) => {
|
||||
|
||||
|
||||
function checkPublished(recording: Recording, onChange: (value: boolean) => void) {
|
||||
return (
|
||||
<div>
|
||||
<input id={`bbb-record-state-${recording.id}`}
|
||||
type="checkbox"
|
||||
className="checkbox"
|
||||
checked={recording.state === 'published'}
|
||||
onChange={(event) => onChange(event.target.checked)} />
|
||||
<label htmlFor={`bbb-record-state-${recording.id}`}>{t('bbb', 'Published')}</label>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return (
|
||||
<tr key={recording.id}>
|
||||
<td className="start icon-col">
|
||||
|
@ -40,10 +58,17 @@ const RecordingRow: React.FC<Props> = ({recording, deleteRecording, storeRecordi
|
|||
<td>
|
||||
{recording.type}
|
||||
</td>
|
||||
<td>
|
||||
{isAdmin && checkPublished(recording, (checked) => {
|
||||
publishRecording(recording, checked);
|
||||
})}
|
||||
</td>
|
||||
<td className="remove icon-col">
|
||||
{isAdmin &&
|
||||
<button className="action-item" onClick={() => deleteRecording(recording)} title={t('bbb', 'Delete')}>
|
||||
<span className="icon icon-delete icon-visible"></span>
|
||||
</button>
|
||||
}
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
|
|
@ -261,7 +261,7 @@ const RoomRow: React.FC<Props> = (props) => {
|
|||
</td>
|
||||
}
|
||||
<td className="bbb-shrink">
|
||||
{(adminRoom || true ) &&
|
||||
{
|
||||
<RecordingsNumber recordings={recordings} showRecordings={showRecordings} setShowRecordings={setShowRecordings} />
|
||||
}
|
||||
</td>
|
||||
|
|
Loading…
Reference in New Issue