perf(dashboard): implement widget item api v2

The old, bundled widget has to stay until we exclusively support the
corresponding server versions.

Signed-off-by: Richard Steinmetz <richard@steinmetz.cloud>
This commit is contained in:
Richard Steinmetz 2023-08-17 15:29:16 +02:00
parent 050819a757
commit a00f34419e
No known key found for this signature in database
GPG Key ID: 27137D9E7D273FB2
6 changed files with 107 additions and 10 deletions

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
* Calendar App
*
* @author Georg Ehrke
* @author Richard Steinmetz <richard@steinmetz.cloud>
* @copyright 2019 Georg Ehrke <oc.list@georgehrke.com>
*
* This library is free software; you can redistribute it and/or
@ -24,6 +25,7 @@ declare(strict_types=1);
namespace OCA\Calendar\AppInfo;
use OCA\Calendar\Dashboard\CalendarWidget;
use OCA\Calendar\Dashboard\CalendarWidgetV2;
use OCA\Calendar\Events\BeforeAppointmentBookedEvent;
use OCA\Calendar\Listener\AppointmentBookedListener;
use OCA\Calendar\Listener\UserDeletedListener;
@ -33,6 +35,7 @@ use OCP\AppFramework\App;
use OCP\AppFramework\Bootstrap\IBootContext;
use OCP\AppFramework\Bootstrap\IBootstrap;
use OCP\AppFramework\Bootstrap\IRegistrationContext;
use OCP\Dashboard\IAPIWidgetV2;
use OCP\User\Events\UserDeletedEvent;
use function method_exists;
@ -51,7 +54,12 @@ class Application extends App implements IBootstrap {
* @inheritDoc
*/
public function register(IRegistrationContext $context): void {
$context->registerDashboardWidget(CalendarWidget::class);
// TODO: drop conditional code when the app is 27.1+
if (interface_exists(IAPIWidgetV2::class)) {
$context->registerDashboardWidget(CalendarWidgetV2::class);
} else {
$context->registerDashboardWidget(CalendarWidget::class);
}
// TODO: drop conditional code when the app is 23+
if (method_exists($context, 'registerProfileLinkAction')) {

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
* Calendar App
*
* @author Georg Ehrke
* @author Richard Steinmetz <richard@steinmetz.cloud>
* @copyright 2019 Georg Ehrke <oc.list@georgehrke.com>
* @copyright Copyright (c) 2022 Informatyka Boguslawski sp. z o.o. sp.k., http://www.ib.pl/
*
@ -201,6 +202,8 @@ class ViewController extends Controller {
}
$file = $folder->newFile($color . '.svg', $svg);
$response = new FileDisplayResponse($file);
// Some browsers won't render SVGs without content types (for security reasons)
$response->addHeader('Content-Type', 'image/svg+xml');
$response->cacheFor(24 * 3600); // 1 day
return $response;
}

View File

@ -5,6 +5,7 @@ declare(strict_types=1);
* @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net>
*
* @author Julius Härtl <jus@bitgrid.net>
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* @license GNU AGPL version 3 or any later version
*
@ -46,13 +47,13 @@ use OCP\IURLGenerator;
use OCP\Util;
class CalendarWidget implements IAPIWidget, IButtonWidget, IIconWidget, IOptionWidget {
private IL10N $l10n;
private IInitialState $initialStateService;
private JSDataService $dataService;
private IDateTimeFormatter $dateTimeFormatter;
private IURLGenerator $urlGenerator;
private IManager $calendarManager;
private ITimeFactory $timeFactory;
protected IL10N $l10n;
protected IInitialState $initialStateService;
protected JSDataService $dataService;
protected IDateTimeFormatter $dateTimeFormatter;
protected IURLGenerator $urlGenerator;
protected IManager $calendarManager;
protected ITimeFactory $timeFactory;
/**
* CalendarWidget constructor.

View File

@ -0,0 +1,73 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2023 Richard Steinmetz <richard@steinmetz.cloud>
*
* @author Richard Steinmetz <richard@steinmetz.cloud>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Calendar\Dashboard;
use OCP\Dashboard\IAPIWidgetV2;
use OCP\Dashboard\Model\WidgetItems;
/**
* Requires Nextcloud >= 27.1.0
*/
class CalendarWidgetV2 extends CalendarWidget implements IAPIWidgetV2 {
/**
* @inheritDoc
*/
public function getItemsV2(string $userId, ?string $since = null, int $limit = 7): WidgetItems {
$widgetItems = $this->getItems($userId, $since, $limit);
$halfEmptyContentMessage = '';
if (!empty($widgetItems)) {
$startOfTomorrow = $this->timeFactory->getDateTime('tomorrow')->getTimestamp();
foreach ($widgetItems as $item) {
if ((int)$item->getSinceId() >= $startOfTomorrow) {
$halfEmptyContentMessage = $this->l10n->t('No more events today');
}
}
}
return new WidgetItems(
$widgetItems,
empty($widgetItems) ? $this->l10n->t('No upcoming events') : '',
$halfEmptyContentMessage,
);
}
/**
* @inheritDoc
*/
public function load(): void {
// No assets need to be loaded anymore as the widget is rendered from the API
}
/**
* @inheritDoc
*/
public function getIconClass(): string {
return 'icon-calendar-dark';
}
}

View File

@ -5,7 +5,6 @@
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config"
errorBaseline="tests/psalm-baseline.xml"
findUnusedBaselineEntry="true"
findUnusedCode="false"
>
<projectFiles>

View File

@ -1,11 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.13.1@086b94371304750d1c673315321a55d15fc59015">
<files psalm-version="5.15.0@5c774aca4746caf3d239d9c8cadb9f882ca29352">
<file src="lib/AppInfo/Application.php">
<MissingDependency>
<code>CalendarWidgetV2</code>
</MissingDependency>
<UndefinedClass>
<code>IAPIWidgetV2</code>
</UndefinedClass>
</file>
<file src="lib/Controller/AppointmentConfigController.php">
<RedundantCondition>
<code>$expectedDayKeys !== $actualDayKeys</code>
<code><![CDATA[$slotKeys !== ['end', 'start']]]></code>
</RedundantCondition>
</file>
<file src="lib/Dashboard/CalendarWidgetV2.php">
<UndefinedClass>
<code>IAPIWidgetV2</code>
</UndefinedClass>
</file>
<file src="lib/Listener/AppointmentBookedListener.php">
<MissingTemplateParam>
<code>IEventListener</code>