Skip to content

Commit

Permalink
fix(backend): Reset document session when updated from outside editor
Browse files Browse the repository at this point in the history
When a text file is updated via other means than from the editor (e.g.
when uploaded/synced via webdav) and there is no unsaved steps in the
document session, reset the document session  This will prevent conflict
resolution dialogs in this case. Client frontends will have to reload
the document afterwards though.

Signed-off-by: Jonas <[email protected]>
  • Loading branch information
mejo- committed Mar 14, 2024
1 parent 02c1e08 commit 57ed999
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 0 deletions.
1 change: 1 addition & 0 deletions composer/composer/autoload_classmap.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
'OCA\\Text\\Listeners\\BeforeAssistantNotificationListener' => $baseDir . '/../lib/Listeners/BeforeAssistantNotificationListener.php',
'OCA\\Text\\Listeners\\BeforeNodeDeletedListener' => $baseDir . '/../lib/Listeners/BeforeNodeDeletedListener.php',
'OCA\\Text\\Listeners\\BeforeNodeRenamedListener' => $baseDir . '/../lib/Listeners/BeforeNodeRenamedListener.php',
'OCA\\Text\\Listeners\\BeforeNodeWrittenListener' => $baseDir . '/../lib/Listeners/BeforeNodeWrittenListener.php',
'OCA\\Text\\Listeners\\FilesLoadAdditionalScriptsListener' => $baseDir . '/../lib/Listeners/FilesLoadAdditionalScriptsListener.php',
'OCA\\Text\\Listeners\\FilesSharingLoadAdditionalScriptsListener' => $baseDir . '/../lib/Listeners/FilesSharingLoadAdditionalScriptsListener.php',
'OCA\\Text\\Listeners\\LoadEditorListener' => $baseDir . '/../lib/Listeners/LoadEditorListener.php',
Expand Down
1 change: 1 addition & 0 deletions composer/composer/autoload_static.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ class ComposerStaticInitText
'OCA\\Text\\Listeners\\BeforeAssistantNotificationListener' => __DIR__ . '/..' . '/../lib/Listeners/BeforeAssistantNotificationListener.php',
'OCA\\Text\\Listeners\\BeforeNodeDeletedListener' => __DIR__ . '/..' . '/../lib/Listeners/BeforeNodeDeletedListener.php',
'OCA\\Text\\Listeners\\BeforeNodeRenamedListener' => __DIR__ . '/..' . '/../lib/Listeners/BeforeNodeRenamedListener.php',
'OCA\\Text\\Listeners\\BeforeNodeWrittenListener' => __DIR__ . '/..' . '/../lib/Listeners/BeforeNodeWrittenListener.php',
'OCA\\Text\\Listeners\\FilesLoadAdditionalScriptsListener' => __DIR__ . '/..' . '/../lib/Listeners/FilesLoadAdditionalScriptsListener.php',
'OCA\\Text\\Listeners\\FilesSharingLoadAdditionalScriptsListener' => __DIR__ . '/..' . '/../lib/Listeners/FilesSharingLoadAdditionalScriptsListener.php',
'OCA\\Text\\Listeners\\LoadEditorListener' => __DIR__ . '/..' . '/../lib/Listeners/LoadEditorListener.php',
Expand Down
3 changes: 3 additions & 0 deletions lib/AppInfo/Application.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
use OCA\Text\Listeners\BeforeAssistantNotificationListener;
use OCA\Text\Listeners\BeforeNodeDeletedListener;
use OCA\Text\Listeners\BeforeNodeRenamedListener;
use OCA\Text\Listeners\BeforeNodeWrittenListener;
use OCA\Text\Listeners\FilesLoadAdditionalScriptsListener;
use OCA\Text\Listeners\FilesSharingLoadAdditionalScriptsListener;
use OCA\Text\Listeners\LoadEditorListener;
Expand All @@ -51,6 +52,7 @@
use OCP\DirectEditing\RegisterDirectEditorEvent;
use OCP\Files\Events\Node\BeforeNodeDeletedEvent;
use OCP\Files\Events\Node\BeforeNodeRenamedEvent;
use OCP\Files\Events\Node\BeforeNodeWrittenEvent;
use OCP\Files\Events\Node\NodeCopiedEvent;
use OCP\Files\Template\ITemplateManager;
use OCP\Files\Template\TemplateFileCreator;
Expand All @@ -71,6 +73,7 @@ public function register(IRegistrationContext $context): void {
$context->registerEventListener(LoadEditor::class, LoadEditorListener::class);
// for attachments
$context->registerEventListener(NodeCopiedEvent::class, NodeCopiedListener::class);
$context->registerEventListener(BeforeNodeWrittenEvent::class, BeforeNodeWrittenListener::class);
$context->registerEventListener(BeforeNodeRenamedEvent::class, BeforeNodeRenamedListener::class);
$context->registerEventListener(BeforeNodeDeletedEvent::class, BeforeNodeDeletedListener::class);
$context->registerEventListener(AddMissingIndicesEvent::class, AddMissingIndicesListener::class);
Expand Down
56 changes: 56 additions & 0 deletions lib/Listeners/BeforeNodeWrittenListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);
/**
* @copyright Copyright (c) 2024 Jonas <[email protected]>
*
* @author Jonas <[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\Text\Listeners;

use OCA\Text\Service\DocumentService;
use OCP\EventDispatcher\Event;
use OCP\EventDispatcher\IEventListener;
use OCP\Files\Events\Node\BeforeNodeWrittenEvent;
use OCP\Files\File;

/**
* @template-implements IEventListener<Event|BeforeNodeWrittenEvent>
*/
class BeforeNodeWrittenListener implements IEventListener {
private DocumentService $documentService;

public function __construct(DocumentService $documentService) {
$this->documentService = $documentService;
}

public function handle(Event $event): void {
if (!$event instanceof BeforeNodeWrittenEvent) {
return;
}
$node = $event->getNode();
if ($node instanceof File && $node->getMimeType() === 'text/markdown') {
if (!$this->documentService->isSaveFromText()) {
// Reset document session to avoid manual conflict resolution if there's no unsaved steps
$this->documentService->resetDocument($node->getId());
}
}
}
}
7 changes: 7 additions & 0 deletions lib/Service/DocumentService.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ class DocumentService {
*/
public const AUTOSAVE_MINIMUM_DELAY = 10;

private bool $saveFromText = false;

private ?string $userId;
private DocumentMapper $documentMapper;
private SessionMapper $sessionMapper;
Expand Down Expand Up @@ -118,6 +120,10 @@ public function getDocument(int $id): ?Document {
}
}

public function isSaveFromText(): bool {
return $this->saveFromText;
}

/**
* @throws NotFoundException
* @throws InvalidPathException
Expand Down Expand Up @@ -389,6 +395,7 @@ public function autosave(Document $document, ?File $file, int $version, ?string
ILock::TYPE_APP,
Application::APP_NAME
), function () use ($file, $autoSaveDocument, $documentState) {
$this->saveFromText = true;
$file->putContent($autoSaveDocument);
if ($documentState) {
$this->writeDocumentState($file->getId(), $documentState);
Expand Down

0 comments on commit 57ed999

Please sign in to comment.