Set the user status as header, so clients can decide to not show notifications
Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Родитель
85f69ccaff
Коммит
a94e33e163
|
@ -26,7 +26,8 @@ In order to find out if notifications is installed/enabled on the server you can
|
|||
"delete-all",
|
||||
"icons",
|
||||
"rich-strings",
|
||||
"action-web"
|
||||
"action-web",
|
||||
"user-status"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -103,6 +104,13 @@ Status | Explanation
|
|||
`204 No Content` | please slow down the polling to once per hour, since there are no apps that can generate notifications
|
||||
`304 Not Modified` | The provided `If-None-Match` matches the ETag, response body is empty
|
||||
|
||||
### Headers
|
||||
|
||||
Status | Explanation
|
||||
---|---
|
||||
`ETag` | See https://tools.ietf.org/html/rfc7232#section-2.3
|
||||
`X-Nextcloud-User-Status` | Only available with the `user-status` capability. The user status (`away`, `dnd`, `offline`, `online`) should be taken into account and in case of `dnd` no notifications should be directly shown.
|
||||
|
||||
### Specification
|
||||
|
||||
Optional elements are still set in the array, the value is just empty:
|
||||
|
|
|
@ -46,6 +46,7 @@ class Capabilities implements ICapability {
|
|||
'icons',
|
||||
'rich-strings',
|
||||
'action-web',
|
||||
'user-status',
|
||||
],
|
||||
'push' => [
|
||||
'devices',
|
||||
|
|
|
@ -34,6 +34,8 @@ use OCP\L10N\IFactory;
|
|||
use OCP\Notification\IAction;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
use OCP\UserStatus\IManager as IUserStatusManager;
|
||||
use OCP\UserStatus\IUserStatus;
|
||||
|
||||
class EndpointController extends OCSController {
|
||||
/** @var Handler */
|
||||
|
@ -44,6 +46,8 @@ class EndpointController extends OCSController {
|
|||
private $l10nFactory;
|
||||
/** @var IUserSession */
|
||||
private $session;
|
||||
/** @var IUserStatusManager */
|
||||
private $userStatusManager;
|
||||
/** @var Push */
|
||||
private $push;
|
||||
|
||||
|
@ -53,6 +57,7 @@ class EndpointController extends OCSController {
|
|||
IManager $manager,
|
||||
IFactory $l10nFactory,
|
||||
IUserSession $session,
|
||||
IUserStatusManager $userStatusManager,
|
||||
Push $push) {
|
||||
parent::__construct($appName, $request);
|
||||
|
||||
|
@ -60,6 +65,7 @@ class EndpointController extends OCSController {
|
|||
$this->manager = $manager;
|
||||
$this->l10nFactory = $l10nFactory;
|
||||
$this->session = $session;
|
||||
$this->userStatusManager = $userStatusManager;
|
||||
$this->push = $push;
|
||||
}
|
||||
|
||||
|
@ -71,10 +77,20 @@ class EndpointController extends OCSController {
|
|||
* @return DataResponse
|
||||
*/
|
||||
public function listNotifications(string $apiVersion): DataResponse {
|
||||
$userStatus = $this->userStatusManager->getUserStatuses([
|
||||
$this->getCurrentUser(),
|
||||
]);
|
||||
|
||||
$headers = ['X-Nextcloud-User-Status' => IUserStatus::ONLINE];
|
||||
if (isset($userStatus[$this->getCurrentUser()])) {
|
||||
$userStatus = $userStatus[$this->getCurrentUser()];
|
||||
$headers['X-Nextcloud-User-Status'] = $userStatus->getStatus();
|
||||
}
|
||||
|
||||
// When there are no apps registered that use the notifications
|
||||
// We stop polling for them.
|
||||
if (!$this->manager->hasNotifiers()) {
|
||||
return new DataResponse(null, Http::STATUS_NO_CONTENT);
|
||||
return new DataResponse(null, Http::STATUS_NO_CONTENT, $headers);
|
||||
}
|
||||
|
||||
$filter = $this->manager->createNotification();
|
||||
|
@ -98,11 +114,13 @@ class EndpointController extends OCSController {
|
|||
}
|
||||
|
||||
$eTag = $this->generateETag($notificationIds);
|
||||
|
||||
$headers['ETag'] = $eTag;
|
||||
if ($apiVersion !== 'v1' && $this->request->getHeader('If-None-Match') === $eTag) {
|
||||
return new DataResponse([], Http::STATUS_NOT_MODIFIED);
|
||||
return new DataResponse([], Http::STATUS_NOT_MODIFIED, $headers);
|
||||
}
|
||||
|
||||
return new DataResponse($data, Http::STATUS_OK, ['ETag' => $eTag]);
|
||||
return new DataResponse($data, Http::STATUS_OK, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -39,6 +39,7 @@ class CapabilitiesTest extends TestCase {
|
|||
'icons',
|
||||
'rich-strings',
|
||||
'action-web',
|
||||
'user-status',
|
||||
],
|
||||
'push' => [
|
||||
'devices',
|
||||
|
|
|
@ -37,6 +37,7 @@ use OCP\L10N\IFactory;
|
|||
use OCP\Notification\IAction;
|
||||
use OCP\Notification\IManager;
|
||||
use OCP\Notification\INotification;
|
||||
use OCP\UserStatus\IManager as IUserStatusManager;
|
||||
use PHPUnit\Framework\MockObject\MockObject;
|
||||
use function Sabre\Event\Loop\instance;
|
||||
|
||||
|
@ -55,7 +56,8 @@ class EndpointControllerTest extends TestCase {
|
|||
|
||||
/** @var IUserSession|MockObject */
|
||||
protected $session;
|
||||
|
||||
/** @var IUserStatusManager|MockObject */
|
||||
protected $userStatusManager;
|
||||
/** @var EndpointController */
|
||||
protected $controller;
|
||||
|
||||
|
@ -72,6 +74,7 @@ class EndpointControllerTest extends TestCase {
|
|||
$this->manager = $this->createMock(IManager::class);
|
||||
$this->l10nFactory = $this->createMock(IFactory::class);
|
||||
$this->session = $this->createMock(IUserSession::class);
|
||||
$this->userStatusManager = $this->createMock(IUserStatusManager::class);
|
||||
$this->user = $this->createMock(IUser::class);
|
||||
$this->push = $this->createMock(Push::class);
|
||||
|
||||
|
@ -93,6 +96,7 @@ class EndpointControllerTest extends TestCase {
|
|||
$this->manager,
|
||||
$this->l10nFactory,
|
||||
$this->session,
|
||||
$this->userStatusManager,
|
||||
$this->push
|
||||
);
|
||||
}
|
||||
|
@ -105,6 +109,7 @@ class EndpointControllerTest extends TestCase {
|
|||
$this->manager,
|
||||
$this->l10nFactory,
|
||||
$this->session,
|
||||
$this->userStatusManager,
|
||||
$this->push,
|
||||
])
|
||||
->setMethods($methods)
|
||||
|
|
Загрузка…
Ссылка в новой задаче