Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable28] enh(files_reminders): Allow clearing reminders #43591

Merged
merged 3 commits into from Feb 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions apps/files_reminders/appinfo/info.xml
Expand Up @@ -13,6 +13,10 @@ Set file reminders.
<author>Christopher Ng</author>
<namespace>FilesReminders</namespace>

<types>
<dav />
</types>

<category>files</category>

<bugs>https://github.com/nextcloud/server/issues</bugs>
Expand All @@ -29,4 +33,10 @@ Set file reminders.
<commands>
<command>OCA\FilesReminders\Command\ListCommand</command>
</commands>

<sabre>
<plugins>
<plugin>OCA\FilesReminders\Dav\PropFindPlugin</plugin>
</plugins>
</sabre>
</info>
Expand Up @@ -12,6 +12,7 @@
'OCA\\FilesReminders\\BackgroundJob\\ScheduledNotifications' => $baseDir . '/../lib/BackgroundJob/ScheduledNotifications.php',
'OCA\\FilesReminders\\Command\\ListCommand' => $baseDir . '/../lib/Command/ListCommand.php',
'OCA\\FilesReminders\\Controller\\ApiController' => $baseDir . '/../lib/Controller/ApiController.php',
'OCA\\FilesReminders\\Dav\\PropFindPlugin' => $baseDir . '/../lib/Dav/PropFindPlugin.php',
'OCA\\FilesReminders\\Db\\Reminder' => $baseDir . '/../lib/Db/Reminder.php',
'OCA\\FilesReminders\\Db\\ReminderMapper' => $baseDir . '/../lib/Db/ReminderMapper.php',
'OCA\\FilesReminders\\Exception\\NodeNotFoundException' => $baseDir . '/../lib/Exception/NodeNotFoundException.php',
Expand Down
1 change: 1 addition & 0 deletions apps/files_reminders/composer/composer/autoload_static.php
Expand Up @@ -27,6 +27,7 @@ class ComposerStaticInitFilesReminders
'OCA\\FilesReminders\\BackgroundJob\\ScheduledNotifications' => __DIR__ . '/..' . '/../lib/BackgroundJob/ScheduledNotifications.php',
'OCA\\FilesReminders\\Command\\ListCommand' => __DIR__ . '/..' . '/../lib/Command/ListCommand.php',
'OCA\\FilesReminders\\Controller\\ApiController' => __DIR__ . '/..' . '/../lib/Controller/ApiController.php',
'OCA\\FilesReminders\\Dav\\PropFindPlugin' => __DIR__ . '/..' . '/../lib/Dav/PropFindPlugin.php',
'OCA\\FilesReminders\\Db\\Reminder' => __DIR__ . '/..' . '/../lib/Db/Reminder.php',
'OCA\\FilesReminders\\Db\\ReminderMapper' => __DIR__ . '/..' . '/../lib/Db/ReminderMapper.php',
'OCA\\FilesReminders\\Exception\\NodeNotFoundException' => __DIR__ . '/..' . '/../lib/Exception/NodeNotFoundException.php',
Expand Down
82 changes: 82 additions & 0 deletions apps/files_reminders/lib/Dav/PropFindPlugin.php
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

/**
* @copyright 2024 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.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\FilesReminders\Dav;

use DateTimeInterface;
use OCA\DAV\Connector\Sabre\Node;
use OCA\FilesReminders\Service\ReminderService;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\IUser;
use OCP\IUserSession;
use Sabre\DAV\INode;
use Sabre\DAV\PropFind;
use Sabre\DAV\Server;
use Sabre\DAV\ServerPlugin;

class PropFindPlugin extends ServerPlugin {

public const REMINDER_DUE_DATE_PROPERTY = '{http://nextcloud.org/ns}reminder-due-date';

public function __construct(
private ReminderService $reminderService,
private IUserSession $userSession,
) {
}

public function initialize(Server $server): void {
$server->on('propFind', [$this, 'propFind']);
}

public function propFind(PropFind $propFind, INode $node) {
if (!in_array(static::REMINDER_DUE_DATE_PROPERTY, $propFind->getRequestedProperties())) {
return;
}

if (!($node instanceof Node)) {
return;
}

$propFind->handle(
static::REMINDER_DUE_DATE_PROPERTY,
function () use ($node) {
$user = $this->userSession->getUser();
if (!($user instanceof IUser)) {
return '';
}

$fileId = $node->getId();
try {
$reminder = $this->reminderService->getDueForUser($user, $fileId);
} catch (DoesNotExistException $e) {
return '';
}

return $reminder->getDueDate()->format(DateTimeInterface::ATOM); // ISO 8601
},
);
}
}
71 changes: 71 additions & 0 deletions apps/files_reminders/src/actions/clearReminderAction.ts
@@ -0,0 +1,71 @@
/**
* @copyright 2024 Christopher Ng <chrng8@gmail.com>
*
* @author Christopher Ng <chrng8@gmail.com>
*
* @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 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/>.
*
*/

import Vue from 'vue'
import { FileAction, type Node } from '@nextcloud/files'
import { emit } from '@nextcloud/event-bus'
import { translate as t } from '@nextcloud/l10n'

import AlarmOffSvg from '@mdi/svg/svg/alarm-off.svg?raw'

import { clearReminder } from '../services/reminderService.ts'
import { getVerboseDateString } from '../shared/utils.ts'

export const action = new FileAction({
id: 'clear-reminder',

displayName: () => t('files', 'Clear reminder'),

title: (nodes: Node[]) => {
const node = nodes.at(0)!
const dueDate = new Date(node.attributes['reminder-due-date'])
return `${t('files', 'Clear reminder')} – ${getVerboseDateString(dueDate)}`
},

iconSvgInline: () => AlarmOffSvg,

enabled: (nodes: Node[]) => {
// Only allow on a single node
if (nodes.length !== 1) {
return false
}
const node = nodes.at(0)!
const dueDate = node.attributes['reminder-due-date']
return Boolean(dueDate)
},

async exec(node: Node) {
if (node.fileid) {
try {
await clearReminder(node.fileid)
Vue.set(node.attributes, 'reminder-due-date', '')
emit('files:node:updated', node)
return true
} catch (error) {
return false
}
}
return null
},

order: 19,
})
Expand Up @@ -19,9 +19,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

import Vue from 'vue'
import type { Node } from '@nextcloud/files'

import { FileAction } from '@nextcloud/files'
import { emit } from '@nextcloud/event-bus'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { translate as t } from '@nextcloud/l10n'

Expand Down Expand Up @@ -101,7 +104,10 @@ const generateFileAction = (option: ReminderOption): FileAction|null => {

// Set the reminder
try {
await setReminder(node.fileid, getDateTime(option.dateTimePreset)!)
const dateTime = getDateTime(option.dateTimePreset)!
await setReminder(node.fileid, dateTime)
Vue.set(node.attributes, 'reminder-due-date', dateTime.toISOString())
emit('files:node:updated', node)
showSuccess(t('files_reminders', 'Reminder set for "{fileName}"', { fileName: node.basename }))
} catch (error) {
logger.error('Failed to set reminder', { error })
Expand Down
Expand Up @@ -64,10 +64,11 @@
</template>

<script lang="ts">
import Vue from 'vue'
import type { Node } from '@nextcloud/files'
import { emit } from '@nextcloud/event-bus'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { translate as t } from '@nextcloud/l10n'
import Vue from 'vue'

import NcButton from '@nextcloud/vue/dist/Components/NcButton.js'
import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js'
Expand Down Expand Up @@ -156,6 +157,8 @@ export default Vue.extend({

try {
await setReminder(this.fileId, this.customDueDate)
Vue.set(this.node.attributes, 'reminder-due-date', this.customDueDate.toISOString())
emit('files:node:updated', this.node)
showSuccess(t('files_reminders', 'Reminder set for "{fileName}"', { fileName: this.fileName }))
this.onClose()
} catch (error) {
Expand Down
7 changes: 6 additions & 1 deletion apps/files_reminders/src/init.ts
Expand Up @@ -19,11 +19,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { registerFileAction } from '@nextcloud/files'

import { registerDavProperty, registerFileAction } from '@nextcloud/files'
import { action as menuAction } from './actions/setReminderMenuAction'
import { action as clearAction } from './actions/clearReminderAction'
import { actions as suggestionActions } from './actions/setReminderSuggestionActions'
import { action as customAction } from './actions/setReminderCustomAction'

registerDavProperty('nc:reminder-due-date', { nc: 'http://nextcloud.org/ns' })

registerFileAction(clearAction)
registerFileAction(menuAction)
registerFileAction(customAction)
suggestionActions.forEach((action) => registerFileAction(action))
4 changes: 2 additions & 2 deletions dist/files_reminders-init.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files_reminders-init.js.map

Large diffs are not rendered by default.