From ac2626bc2c8b278d614a0f388d341dcfab5f6066 Mon Sep 17 00:00:00 2001 From: Sebastien Marinier Date: Wed, 29 May 2024 17:25:29 +0200 Subject: [PATCH] feat: videos for all users and moderators Admin may change the "published" status of a video. users/moderators may only see the published ones. --- appinfo/routes.php | 1 + lib/BigBlueButton/API.php | 9 ++++++++ lib/Controller/ServerController.php | 25 ++++++++++++++++++++-- ts/Common/Api.ts | 8 +++++++ ts/Manager/RecordingRow.tsx | 33 +++++++++++++++++++++++++---- ts/Manager/RoomRow.tsx | 2 +- 6 files changed, 71 insertions(+), 7 deletions(-) diff --git a/appinfo/routes.php b/appinfo/routes.php index 2b70b37..269123b 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -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'], diff --git a/lib/BigBlueButton/API.php b/lib/BigBlueButton/API.php index 2176ca3..4912f4c 100644 --- a/lib/BigBlueButton/API.php +++ b/lib/BigBlueButton/API.php @@ -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)[] * diff --git a/lib/Controller/ServerController.php b/lib/Controller/ServerController.php index a3c22bf..476cd0f 100644 --- a/lib/Controller/ServerController.php +++ b/lib/Controller/ServerController.php @@ -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); diff --git a/ts/Common/Api.ts b/ts/Common/Api.ts index cc684ad..e31c5b5 100644 --- a/ts/Common/Api.ts +++ b/ts/Common/Api.ts @@ -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`; diff --git a/ts/Manager/RecordingRow.tsx b/ts/Manager/RecordingRow.tsx index 3b89d0e..6279b28 100644 --- a/ts/Manager/RecordingRow.tsx +++ b/ts/Manager/RecordingRow.tsx @@ -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 = ({recording, deleteRecording, storeRecording}) => { +const RecordingRow: React.FC = ({recording, isAdmin, deleteRecording, storeRecording, publishRecording}) => { + + + function checkPublished(recording: Recording, onChange: (value: boolean) => void) { + return ( +
+ onChange(event.target.checked)} /> + +
+ ); + } + + return ( @@ -40,10 +58,17 @@ const RecordingRow: React.FC = ({recording, deleteRecording, storeRecordi {recording.type} + + {isAdmin && checkPublished(recording, (checked) => { + publishRecording(recording, checked); + })} + - + {isAdmin && + + } ); diff --git a/ts/Manager/RoomRow.tsx b/ts/Manager/RoomRow.tsx index 1833143..7d015f5 100644 --- a/ts/Manager/RoomRow.tsx +++ b/ts/Manager/RoomRow.tsx @@ -261,7 +261,7 @@ const RoomRow: React.FC = (props) => { } - {(adminRoom || true ) && + { }