Add API to opt out of call notifications

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2021-10-07 19:34:55 +02:00
Родитель f772525127
Коммит 0c379ce846
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 7076EA9751AACDDA
12 изменённых файлов: 136 добавлений и 1 удалений

Просмотреть файл

@ -16,7 +16,7 @@ And in the works for the [coming versions](https://github.com/nextcloud/spreed/m
]]></description>
<version>13.0.0-dev.3</version>
<version>13.0.0-dev.4</version>
<licence>agpl</licence>
<author>Daniel Calviño Sánchez</author>

Просмотреть файл

@ -463,6 +463,15 @@ return [
'token' => '^[a-z0-9]{4,30}$',
],
],
[
'name' => 'Room#setNotificationCalls',
'url' => '/api/{apiVersion}/room/{token}/notify-calls',
'verb' => 'POST',
'requirements' => [
'apiVersion' => 'v(4)',
'token' => '^[a-z0-9]{4,30}$',
],
],
[
'name' => 'Room#setLobby',
'url' => '/api/{apiVersion}/room/{token}/webinar/lobby',

Просмотреть файл

@ -84,3 +84,4 @@ title: Capabilities
## 13
* `direct-mention-flag` - The conversation list populates the boolean `unreadMentionDirect` when the user was mentioned directly (ignoring @all mentions) since their last visit
* `notification-calls` - Whether the API to opt out of call notifications is available

Просмотреть файл

@ -46,6 +46,10 @@ title: Constants
* `2` Notify on mention
* `3` Never notify
### Participant call notification levels
* `0` Off
* `1` On (default)
### Participant read status privacy
* `0` Read status is public
* `1` Read status is private

Просмотреть файл

@ -309,6 +309,24 @@
+ `401 Unauthorized` When the participant is a guest
+ `404 Not Found` When the conversation could not be found for the participant
## Set notification level for calls
* Required capability: `notification-calls`
* Method: `POST`
* Endpoint: `/room/{token}/notify-calls`
* Data:
field | type | Description
---|---|---
`level` | int | The call notification level (See [Participant call notification levels](constants.md#Participant-call-notification-levels))
* Response:
- Status code:
+ `200 OK`
+ `400 Bad Request` When the given level is invalid
+ `401 Unauthorized` When the participant is a guest
+ `404 Not Found` When the conversation could not be found for the participant
## Open a conversation
* Required capability: `listable-rooms`

Просмотреть файл

@ -96,6 +96,7 @@ class Capabilities implements IPublicCapability {
'publishing-permissions',
'clear-history',
'direct-mention-flag',
'notification-calls',
],
'config' => [
'attachments' => [

Просмотреть файл

@ -397,6 +397,7 @@ class RoomController extends AEnvironmentAwareController {
'canLeaveConversation' => false,
'canDeleteConversation' => false,
'notificationLevel' => Participant::NOTIFY_NEVER,
'notificationCalls' => Participant::NOTIFY_CALLS_OFF,
'lobbyState' => Webinary::LOBBY_NONE,
'lobbyTimer' => 0,
'lastPing' => 0,
@ -467,6 +468,7 @@ class RoomController extends AEnvironmentAwareController {
'callFlag' => $room->getCallFlag(),
'isFavorite' => $attendee->isFavorite(),
'notificationLevel' => $attendee->getNotificationLevel(),
'notificationCalls' => $attendee->getNotificationCalls(),
'lobbyState' => $room->getLobbyState(),
'lobbyTimer' => $lobbyTimer,
'actorType' => $attendee->getActorType(),
@ -828,6 +830,23 @@ class RoomController extends AEnvironmentAwareController {
return new DataResponse();
}
/**
* @NoAdminRequired
* @RequireLoggedInParticipant
*
* @param int $level
* @return DataResponse
*/
public function setNotificationCalls(int $level): DataResponse {
try {
$this->participantService->updateNotificationCalls($this->participant, $level);
} catch (\InvalidArgumentException $e) {
return new DataResponse([], Http::STATUS_BAD_REQUEST);
}
return new DataResponse();
}
/**
* @PublicPage
* @RequireModeratorParticipant

Просмотреть файл

@ -0,0 +1,55 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2021, Joas Schilling <coding@schilljs.com>
*
* @author Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Talk\Migration;
use Closure;
use Doctrine\DBAL\Types\Types;
use OCA\Talk\Participant;
use OCP\DB\ISchemaWrapper;
use OCP\Migration\IOutput;
use OCP\Migration\SimpleMigrationStep;
class Version13000Date20211007192733 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): ?ISchemaWrapper {
/** @var ISchemaWrapper $schema */
$schema = $schemaClosure();
$table = $schema->getTable('talk_attendees');
if (!$table->hasColumn('notification_calls')) {
$table->addColumn('notification_calls', Types::INTEGER, [
'default' => Participant::NOTIFY_CALLS_ON,
]);
}
return $schema;
}
}

Просмотреть файл

@ -41,6 +41,8 @@ use OCP\AppFramework\Db\Entity;
* @method bool isFavorite()
* @method void setNotificationLevel(int $notificationLevel)
* @method int getNotificationLevel()
* @method void setNotificationCalls(int $notificationCalls)
* @method int getNotificationCalls()
* @method void setLastJoinedCall(int $lastJoinedCall)
* @method int getLastJoinedCall()
* @method void setLastReadMessage(int $lastReadMessage)
@ -114,6 +116,9 @@ class Attendee extends Entity {
/** @var int */
protected $notificationLevel;
/** @var int */
protected $notificationCalls;
/** @var int */
protected $lastJoinedCall;
@ -147,6 +152,7 @@ class Attendee extends Entity {
$this->addType('participantType', 'int');
$this->addType('favorite', 'bool');
$this->addType('notificationLevel', 'int');
$this->addType('notificationCalls', 'int');
$this->addType('lastJoinedCall', 'int');
$this->addType('lastReadMessage', 'int');
$this->addType('lastMentionMessage', 'int');
@ -175,6 +181,7 @@ class Attendee extends Entity {
'participant_type' => $this->getParticipantType(),
'favorite' => $this->isFavorite(),
'notification_level' => $this->getNotificationLevel(),
'notification_calls' => $this->getNotificationCalls(),
'last_joined_call' => $this->getLastJoinedCall(),
'last_read_message' => $this->getLastReadMessage(),
'last_mention_message' => $this->getLastMentionMessage(),

Просмотреть файл

@ -48,6 +48,9 @@ class Participant {
public const NOTIFY_MENTION = 2;
public const NOTIFY_NEVER = 3;
public const NOTIFY_CALLS_OFF = 0;
public const NOTIFY_CALLS_ON = 1;
public const PRIVACY_PUBLIC = 0;
public const PRIVACY_PRIVATE = 1;

Просмотреть файл

@ -220,6 +220,23 @@ class ParticipantService {
$this->attendeeMapper->update($attendee);
}
/**
* @param Participant $participant
* @param int $level
*/
public function updateNotificationCalls(Participant $participant, int $level): void {
if (!\in_array($level, [
Participant::NOTIFY_CALLS_OFF,
Participant::NOTIFY_CALLS_ON,
], true)) {
throw new \InvalidArgumentException('Invalid notification level');
}
$attendee = $participant->getAttendee();
$attendee->setNotificationCalls($level);
$this->attendeeMapper->update($attendee);
}
/**
* @param Room $room
* @param IUser $user

Просмотреть файл

@ -93,6 +93,7 @@ class CapabilitiesTest extends TestCase {
'publishing-permissions',
'clear-history',
'direct-mention-flag',
'notification-calls',
];
}