diff --git a/cypress/e2e/direct.spec.js b/cypress/e2e/direct.spec.js index 6ac25c0c34..e98a2cf3c2 100644 --- a/cypress/e2e/direct.spec.js +++ b/cypress/e2e/direct.spec.js @@ -128,6 +128,28 @@ describe('Direct editing (legacy)', function() { }) }) + it('Signals DirectEditingMobileInterface on document load', function() { + createDirectEditingLink(randUser, this.fileId) + .then((token) => { + cy.logout() + cy.visit(token, { + onBeforeLoad(win) { + win.DirectEditingMobileInterface = { + loaded: cy.stub().as('directEditingLoaded'), + documentLoaded: cy.stub().as('directEditingDocumentLoaded'), + close: cy.stub().callsFake(() => win.documentsMain.onClose()), + } + cy.spy(win, 'postMessage').as('postMessage') + }, + }) + cy.waitForCollabora(false) + cy.waitForPostMessage('App_LoadingStatus', { Status: 'Document_Loaded' }) + cy.get('@directEditingLoaded').should('have.been.called') + cy.get('@directEditingDocumentLoaded').should('have.been.called') + cy.closeDirectDocument() + }) + }) + it('Open an new file', function() { getTemplates(randUser, 'document') .then((templates) => { diff --git a/lib/Controller/OCSController.php b/lib/Controller/OCSController.php index ae562af9d7..63ddd2a2e3 100644 --- a/lib/Controller/OCSController.php +++ b/lib/Controller/OCSController.php @@ -86,21 +86,10 @@ public function createDirect($fileId) { throw new OCSBadRequestException('Cannot view folder'); } - // getRelativePath() can return null for nodes outside the user - // folder; Manager::open() requires a string, so fall back to the - // filename which is enough for the manager to resolve by fileId. - $path = $userFolder->getRelativePath($node->getPath()) ?? $node->getName(); - - // Register directly so the legacy endpoint keeps working for - // older mobile clients where RegisterDirectEditorListener gates - // out the editor from OCP\DirectEditing discovery. - $this->directEditingManager->registerDirectEditor($this->officeDirectEditor); - /** @psalm-suppress UndefinedInterfaceMethod IManager does not expose open() but the concrete Manager does, same pattern as files-app DirectEditingController */ - $token = $this->directEditingManager->open($path, Application::APPNAME, $node->getId()); - + $direct = $this->directMapper->newDirect($this->userId, $node->getId()); return new DataResponse([ - 'url' => $this->urlGenerator->linkToRouteAbsolute('files.DirectEditingView.edit', [ - 'token' => $token, + 'url' => $this->urlGenerator->linkToRouteAbsolute('richdocuments.directView.show', [ + 'token' => $direct->getToken(), ]), ]); } catch (NotFoundException) { diff --git a/lib/Listener/RegisterDirectEditorListener.php b/lib/Listener/RegisterDirectEditorListener.php index 396b4ba8e8..2737724fed 100644 --- a/lib/Listener/RegisterDirectEditorListener.php +++ b/lib/Listener/RegisterDirectEditorListener.php @@ -18,12 +18,6 @@ /** @template-implements IEventListener */ final class RegisterDirectEditorListener implements IEventListener { - /** - * Minimum iOS/Android client major version that knows how to drive the - * server-managed Direct Editing flow. Older clients keep using the - * legacy /apps/richdocuments/api/v1/document endpoint and should not - * see the editor in OCP\DirectEditing discovery responses. - */ private const MIN_MOBILE_CLIENT_VERSION = 34; public function __construct( diff --git a/src/helpers/mobile.js b/src/helpers/mobile.js index 129616c313..62b5e0100f 100644 --- a/src/helpers/mobile.js +++ b/src/helpers/mobile.js @@ -8,11 +8,13 @@ import Config from './../services/config.tsx' const isDirectEditing = () => Config.get('direct') const isMobileInterfaceAvailable = () => window.RichDocumentsMobileInterface + || window.DirectEditingMobileInterface || (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.RichDocumentsMobileInterface) const isMobileInterfaceOnIos = () => window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.RichDocumentsMobileInterface const isMobileInterfaceOnAndroid = () => window.RichDocumentsMobileInterface + || window.DirectEditingMobileInterface const callMobileMessage = (messageName, attributes) => { console.debug('callMobileMessage', messageName, attributes) @@ -29,7 +31,7 @@ const callMobileMessage = (messageName, attributes) => { } catch (e) { attributesString = null } - // Forward to mobile handler + // Forward to RichDocuments-specific mobile handler (legacy richdocuments WebView) if (window.RichDocumentsMobileInterface && typeof window.RichDocumentsMobileInterface[messageName] === 'function') { if (attributesString === null || typeof attributesString === 'undefined') { window.RichDocumentsMobileInterface[messageName]() @@ -38,6 +40,15 @@ const callMobileMessage = (messageName, attributes) => { } } + // Forward to generic direct editing mobile handler (server's OCP\DirectEditing WebView, Android v34+) + if (window.DirectEditingMobileInterface && typeof window.DirectEditingMobileInterface[messageName] === 'function') { + if (attributesString === null || typeof attributesString === 'undefined') { + window.DirectEditingMobileInterface[messageName]() + } else { + window.DirectEditingMobileInterface[messageName](attributesString) + } + } + // iOS webkit fallback if (window.webkit && window.webkit.messageHandlers