diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index c668e4acb..a8d0e965b 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -28,13 +28,16 @@ use OCA\Calendar\Dashboard\CalendarWidget; use OCA\Calendar\Dashboard\CalendarWidgetV2; use OCA\Calendar\Events\BeforeAppointmentBookedEvent; use OCA\Calendar\Listener\AppointmentBookedListener; +use OCA\Calendar\Listener\CalendarReferenceListener; use OCA\Calendar\Listener\UserDeletedListener; use OCA\Calendar\Notification\Notifier; use OCA\Calendar\Profile\AppointmentsAction; +use OCA\Calendar\Reference\ReferenceProvider; use OCP\AppFramework\App; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; +use OCP\Collaboration\Reference\RenderReferenceEvent; use OCP\Dashboard\IAPIWidgetV2; use OCP\User\Events\UserDeletedEvent; use function method_exists; @@ -65,9 +68,11 @@ class Application extends App implements IBootstrap { if (method_exists($context, 'registerProfileLinkAction')) { $context->registerProfileLinkAction(AppointmentsAction::class); } + $context->registerReferenceProvider(ReferenceProvider::class); $context->registerEventListener(BeforeAppointmentBookedEvent::class, AppointmentBookedListener::class); $context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class); + $context->registerEventListener(RenderReferenceEvent::class, CalendarReferenceListener::class); $context->registerNotifierService(Notifier::class); } diff --git a/lib/Listener/CalendarReferenceListener.php b/lib/Listener/CalendarReferenceListener.php new file mode 100644 index 000000000..f15a6c811 --- /dev/null +++ b/lib/Listener/CalendarReferenceListener.php @@ -0,0 +1,129 @@ + + * + * @author 2024 Hamza Mahjoubi + * + * @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 . + */ + +namespace OCA\Calendar\Listener; + +use OC\App\CompareVersion; +use OCA\Calendar\AppInfo\Application; +use OCP\App\IAppManager; +use OCP\AppFramework\Services\IInitialState; +use OCP\Collaboration\Reference\RenderReferenceEvent; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Files\IAppData; +use OCP\IConfig; + + + +use OCP\Util; + +/** + * @template-implements IEventListener + */ +class CalendarReferenceListener implements IEventListener { + + /** @var IInitialState */ + private $initialStateService; + + /** @var IAppManager */ + private $appManager; + + /** @var IConfig */ + private $config; + + /** @var CompareVersion */ + private $compareVersion; + + private IAppData $appData; + + public function __construct( + IInitialState $initialStateService, + IAppManager $appManager, + IConfig $config, + IAppData $appData, + CompareVersion $compareVersion, + ) { + $this->config = $config; + $this->initialStateService = $initialStateService; + $this->appManager = $appManager; + $this->appData = $appData; + $this->compareVersion = $compareVersion; + + } + + public function handle(Event $event): void { + if (!$event instanceof RenderReferenceEvent) { + return; + } + $defaultEventLimit = $this->config->getAppValue('calendar', 'eventLimit', 'yes'); + $defaultInitialView = $this->config->getAppValue('calendar', 'currentView', 'dayGridMonth'); + $defaultShowWeekends = $this->config->getAppValue('calendar', 'showWeekends', 'yes'); + $defaultWeekNumbers = $this->config->getAppValue('calendar', 'showWeekNr', 'no'); + $defaultSkipPopover = $this->config->getAppValue('calendar', 'skipPopover', 'no'); + $defaultTimezone = $this->config->getAppValue('calendar', 'timezone', 'automatic'); + $defaultSlotDuration = $this->config->getAppValue('calendar', 'slotDuration', '00:30:00'); + $defaultDefaultReminder = $this->config->getAppValue('calendar', 'defaultReminder', 'none'); + + $appVersion = $this->config->getAppValue('calendar', 'installed_version', ''); + $forceEventAlarmType = $this->config->getAppValue('calendar', 'forceEventAlarmType', ''); + if (!in_array($forceEventAlarmType, ['DISPLAY', 'EMAIL'], true)) { + $forceEventAlarmType = false; + } + $showResources = $this->config->getAppValue('calendar', 'showResources', 'yes') === 'yes'; + $publicCalendars = $this->config->getAppValue('calendar', 'publicCalendars', ''); + + $talkApiVersion = version_compare($this->appManager->getAppVersion('spreed'), '12.0.0', '>=') ? 'v4' : 'v1'; + $tasksEnabled = $this->appManager->isEnabledForUser('tasks'); + + $circleVersion = $this->appManager->getAppVersion('circles'); + $isCirclesEnabled = $this->appManager->isEnabledForUser('circles') === true; + // if circles is not installed, we use 0.0.0 + $isCircleVersionCompatible = $this->compareVersion->isCompatible($circleVersion ? $circleVersion : '0.0.0', '22'); + + $this->initialStateService->provideInitialState('app_version', $appVersion); + $this->initialStateService->provideInitialState('event_limit', $defaultEventLimit); + $this->initialStateService->provideInitialState('first_run', false); + $this->initialStateService->provideInitialState('initial_view', $defaultInitialView); + $this->initialStateService->provideInitialState('show_weekends', $defaultShowWeekends); + $this->initialStateService->provideInitialState('show_week_numbers', $defaultWeekNumbers === 'yes'); + $this->initialStateService->provideInitialState('skip_popover', true); + $this->initialStateService->provideInitialState('talk_enabled', false); + $this->initialStateService->provideInitialState('talk_api_version', $talkApiVersion); + $this->initialStateService->provideInitialState('show_tasks', false); + $this->initialStateService->provideInitialState('timezone', $defaultTimezone); + $this->initialStateService->provideInitialState('attachments_folder', '/Calendar'); + $this->initialStateService->provideInitialState('slot_duration', $defaultSlotDuration); + $this->initialStateService->provideInitialState('default_reminder', $defaultDefaultReminder); + $this->initialStateService->provideInitialState('tasks_enabled', $tasksEnabled); + $this->initialStateService->provideInitialState('hide_event_export', true); + $this->initialStateService->provideInitialState('force_event_alarm_type', $forceEventAlarmType); + $this->initialStateService->provideInitialState('disable_appointments', true); + $this->initialStateService->provideInitialState('can_subscribe_link', false); + $this->initialStateService->provideInitialState('show_resources', $showResources); + $this->initialStateService->provideInitialState('publicCalendars', $publicCalendars); + + Util::addScript(Application::APP_ID, 'calendar-reference'); + } +} diff --git a/lib/Reference/ReferenceProvider.php b/lib/Reference/ReferenceProvider.php new file mode 100644 index 000000000..f4048ca1d --- /dev/null +++ b/lib/Reference/ReferenceProvider.php @@ -0,0 +1,121 @@ + + * + * @author 2024 Hamza Mahjoubi + * + * @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 . + */ + +namespace OCA\Calendar\Reference; + +use OCA\Calendar\AppInfo\Application; +use OCP\Collaboration\Reference\ADiscoverableReferenceProvider; +use OCP\Collaboration\Reference\IReference; + +use OCP\Collaboration\Reference\Reference; +use OCP\IL10N; +use OCP\IURLGenerator; + +class ReferenceProvider extends ADiscoverableReferenceProvider { + + + public function __construct( + private IL10N $l10n, + private IURLGenerator $urlGenerator, + ) { + } + + + public function getId(): string { + return 'calendar'; + } + + /** + * @inheritDoc + */ + public function getTitle(): string { + return 'Calendar'; + } + + /** + * @inheritDoc + */ + public function getOrder(): int { + return 20; + } + + /** + * @inheritDoc + */ + public function getIconUrl(): string { + return $this->urlGenerator->getAbsoluteURL( + $this->urlGenerator->imagePath(Application::APP_ID, 'calendar-dark.svg') + ); + } + + public function matchReference(string $referenceText): bool { + $start = $this->urlGenerator->getAbsoluteURL('/apps/' . Application::APP_ID); + $startIndex = $this->urlGenerator->getAbsoluteURL('/index.php/apps/' . Application::APP_ID); + + return preg_match('/^' . preg_quote($start, '/') . '\/p\/[a-zA-Z0-9]+$/i', $referenceText) === 1 || preg_match('/^' . preg_quote($startIndex, '/') . '\/p\/[a-zA-Z0-9]+$/i', $referenceText) === 1; + } + + public function resolveReference(string $referenceText): ?IReference { + if ($this->matchReference($referenceText)) { + $token = $this->getCalendarTokenFromLink($referenceText); + + $reference = new Reference($referenceText); + $reference->setTitle('calendar'); + $reference->setDescription($token); + $reference->setRichObject( + 'calendar_widget', + [ + 'title' => 'calendar', + 'token' => $token, + 'url' => $referenceText,] + ); + + return $reference; + } + + return null; + } + + private function getCalendarTokenFromLink(string $url): ?string { + + + if (preg_match('/\/p\/([a-zA-Z0-9]+)/', $url, $output_array)) { + return $output_array[1]; + } + return $url; + + } + + public function getCachePrefix(string $referenceId): string { + return ''; + } + + /** + * @inheritDoc + */ + public function getCacheKey(string $referenceId): ?string { + return $referenceId; + } +} diff --git a/src/components/AppNavigation/AppNavigationHeader/AppNavigationHeaderDatePicker.vue b/src/components/AppNavigation/AppNavigationHeader/AppNavigationHeaderDatePicker.vue index 00eae06d9..c447faa4a 100644 --- a/src/components/AppNavigation/AppNavigationHeader/AppNavigationHeaderDatePicker.vue +++ b/src/components/AppNavigation/AppNavigationHeader/AppNavigationHeaderDatePicker.vue @@ -22,7 +22,8 @@ -