Skip to content

Commit

Permalink
feat(dav): Add user setting to hide birthdays from deceased contacts
Browse files Browse the repository at this point in the history
Closes #24742

Signed-off-by: Thomas Citharel <[email protected]>
  • Loading branch information
tcitworld committed Jan 24, 2023
1 parent f867a2d commit c6a6af1
Show file tree
Hide file tree
Showing 18 changed files with 194 additions and 751 deletions.
1 change: 1 addition & 0 deletions apps/dav/appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
<settings>
<admin>OCA\DAV\Settings\CalDAVSettings</admin>
<personal>OCA\DAV\Settings\AvailabilitySettings</personal>
<personal>OCA\DAV\Settings\PersonalCalendarSettings</personal>
</settings>

<activity>
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@
'OCA\\DAV\\Server' => $baseDir . '/../lib/Server.php',
'OCA\\DAV\\Settings\\AvailabilitySettings' => $baseDir . '/../lib/Settings/AvailabilitySettings.php',
'OCA\\DAV\\Settings\\CalDAVSettings' => $baseDir . '/../lib/Settings/CalDAVSettings.php',
'OCA\\DAV\\Settings\\PersonalCalendarSettings' => $baseDir . '/../lib/Settings/PersonalCalendarSettings.php',
'OCA\\DAV\\Storage\\PublicOwnerWrapper' => $baseDir . '/../lib/Storage/PublicOwnerWrapper.php',
'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => $baseDir . '/../lib/SystemTag/SystemTagMappingNode.php',
'OCA\\DAV\\SystemTag\\SystemTagNode' => $baseDir . '/../lib/SystemTag/SystemTagNode.php',
Expand Down
1 change: 1 addition & 0 deletions apps/dav/composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Server' => __DIR__ . '/..' . '/../lib/Server.php',
'OCA\\DAV\\Settings\\AvailabilitySettings' => __DIR__ . '/..' . '/../lib/Settings/AvailabilitySettings.php',
'OCA\\DAV\\Settings\\CalDAVSettings' => __DIR__ . '/..' . '/../lib/Settings/CalDAVSettings.php',
'OCA\\DAV\\Settings\\PersonalCalendarSettings' => __DIR__ . '/..' . '/../lib/Settings/PersonalCalendarSettings.php',
'OCA\\DAV\\Storage\\PublicOwnerWrapper' => __DIR__ . '/..' . '/../lib/Storage/PublicOwnerWrapper.php',
'OCA\\DAV\\SystemTag\\SystemTagMappingNode' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagMappingNode.php',
'OCA\\DAV\\SystemTag\\SystemTagNode' => __DIR__ . '/..' . '/../lib/SystemTag/SystemTagNode.php',
Expand Down
34 changes: 30 additions & 4 deletions apps/dav/lib/CalDAV/BirthdayService.php
Original file line number Diff line number Diff line change
Expand Up @@ -110,8 +110,11 @@ public function onCardChanged(int $addressBookId,
if ($calendar === null) {
return;
}

$showBirthdaysFromDeceasedContacts = $this->doesUserHidesDeceasedContacts($principalUri);

foreach ($datesToSync as $type) {
$this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type, $reminderOffset);
$this->updateCalendar($cardUri, $cardData, $book, (int) $calendar['id'], $type, $reminderOffset, $showBirthdaysFromDeceasedContacts);
}
}
}
Expand Down Expand Up @@ -166,7 +169,8 @@ public function ensureCalendarExists(string $principal): ?array {
public function buildDateFromContact(string $cardData,
string $dateField,
string $postfix,
?string $reminderOffset):?VCalendar {
?string $reminderOffset,
bool $showBirthdaysFromDeceasedContacts):?VCalendar {
if (empty($cardData)) {
return null;
}
Expand All @@ -186,6 +190,10 @@ public function buildDateFromContact(string $cardData,
return null;
}

if (!$showBirthdaysFromDeceasedContacts && isset($doc->DEATHDATE)) {
return null;
}

if (!isset($doc->{$dateField})) {
return null;
}
Expand Down Expand Up @@ -372,9 +380,10 @@ private function updateCalendar(string $cardUri,
array $book,
int $calendarId,
array $type,
?string $reminderOffset):void {
?string $reminderOffset,
bool $showBirthdaysFromDeceasedContacts):void {
$objectUri = $book['uri'] . '-' . $cardUri . $type['postfix'] . '.ics';
$calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix'], $reminderOffset);
$calendarData = $this->buildDateFromContact($cardData, $type['field'], $type['postfix'], $reminderOffset, $showBirthdaysFromDeceasedContacts);
$existing = $this->calDavBackEnd->getCalendarObject($calendarId, $objectUri);
if ($calendarData === null) {
if ($existing !== null) {
Expand Down Expand Up @@ -461,6 +470,23 @@ private function getReminderOffsetForUser(string $userPrincipal):?string {
return 'PT9H';
}

/**
* Get the reminder offset value for a user. This is a duration string (e.g.
* PT9H) or null if no reminder is wanted.
*
* @param string $userPrincipal
* @return string|null
*/
private function doesUserHidesDeceasedContacts(string $userPrincipal): bool {
$userId = $this->principalToUserId($userPrincipal);
if ($userId !== null) {
return $this->config->getUserValue($userId, 'dav', 'show_birthdays_from_deceased_contacts', 'yes') === 'no';
}

// not sure how we got here, just be on the safe side and return the default value
return false;
}

/**
* Formats title of Birthday event
*
Expand Down
70 changes: 70 additions & 0 deletions apps/dav/lib/Settings/PersonalCalendarSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
<?php

declare(strict_types=1);

/*
* @copyright 2023 Thomas Citharel <[email protected]>
*
* @author 2023 Thomas Citharel <[email protected]>
*
* @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\DAV\Settings;

use OCA\DAV\AppInfo\Application;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\AppFramework\Services\IInitialState;
use OCP\IConfig;
use OCP\Settings\ISettings;
use OCP\Util;

class PersonalCalendarSettings implements ISettings {
protected IConfig $config;
protected IInitialState $initialState;
protected ?string $userId;

public function __construct(IConfig $config,
IInitialState $initialState,
?string $userId) {
$this->config = $config;
$this->initialState = $initialState;
$this->userId = $userId;
}

public function getForm(): TemplateResponse {
$this->initialState->provideInitialState(
'show_birthdays_from_deceased_contacts',
$this->config->getUserValue(
$this->userId,
'dav',
'show_birthdays_from_deceased_contacts',
'yes'
)
);

Util::addScript(Application::APP_ID, 'settings-personal-calendars');
return new TemplateResponse(Application::APP_ID, 'settings-personal-calendars');
}

public function getSection(): string {
return 'calendar';
}

public function getPriority(): int {
return 10;
}
}
9 changes: 9 additions & 0 deletions apps/dav/src/settings-personal-calendars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Vue from 'vue'
import { translate } from '@nextcloud/l10n'
import Calendars from './views/Calendars.vue'

Vue.prototype.$t = translate

const View = Vue.extend(Calendars);

(new View({})).$mount('#settings-personal-calendars')
44 changes: 44 additions & 0 deletions apps/dav/src/views/Calendars.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<template>
<NcSettingsSection :title="$t('dav', 'Birthday calendar')">
<NcCheckboxRadioSwitch :checked.sync="showBirthdaysFromDeceasedContacts">
{{ $t('dav', 'Show birthdays from deceased contacts') }}
</NcCheckboxRadioSwitch>
<p class="show_birthdays_from_deceased_contacts-hint">
{{ $t('dav', "You can also exclude specific contacts from the birthday calendar in the Contacts app.") }}
</p>
</NcSettingsSection>
</template>

<script>
import { loadState } from '@nextcloud/initial-state'
import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadioSwitch'
import NcSettingsSection from '@nextcloud/vue/dist/Components/NcSettingsSection'
export default {
name: 'Calendars',
components: {
NcCheckboxRadioSwitch,
NcSettingsSection,
},
data() {
return {
showBirthdaysFromDeceasedContacts: loadState('dav', 'show_birthdays_from_deceased_contacts') === 'yes',
}
},
watch: {
showBirthdaysFromDeceasedContacts(value) {
OCP.AppConfig.setValue(
'dav',
'show_birthdays_from_deceased_contacts',
value ? 'yes' : 'no'
)
},
},
}
</script>
<style lang="scss">
.show_birthdays_from_deceased_contacts-hint {
opacity: 0.7;
padding-left: 1.5rem;
}
</style>
25 changes: 25 additions & 0 deletions apps/dav/templates/settings-personal-calendars.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php
/**
* @copyright 2023 Thomas Citharel <[email protected]>
*
* @author Thomas Citharel <[email protected]>
*
* @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/>.
*
*/
?>

<div id="settings-personal-calendars"></div>
4 changes: 2 additions & 2 deletions dist/core-common.js

Large diffs are not rendered by default.

Loading

0 comments on commit c6a6af1

Please sign in to comment.