From cde81b4e8ad8f9c7146f62c6e7644f689cf1a5c6 Mon Sep 17 00:00:00 2001 From: Elizabeth Danzberger Date: Fri, 12 Apr 2024 14:24:31 -0400 Subject: [PATCH] refactor: move to office.vue component Signed-off-by: Elizabeth Danzberger --- lib/AppInfo/Application.php | 2 + lib/Listener/LoadPublicViewerListener.php | 50 ++ src/document.js | 738 ---------------------- src/files.js | 2 - src/helpers/isDocument.js | 17 + src/helpers/isPublicPage.js | 12 + src/public.js | 17 + src/view/Office.vue | 4 +- templates/documents.php | 3 - webpack.js | 2 +- 10 files changed, 102 insertions(+), 745 deletions(-) create mode 100644 lib/Listener/LoadPublicViewerListener.php delete mode 100644 src/document.js create mode 100644 src/helpers/isDocument.js create mode 100644 src/helpers/isPublicPage.js create mode 100644 src/public.js diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 084edf8bf2..59a4141b65 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -33,6 +33,7 @@ use OCA\Richdocuments\Listener\BeforeFetchPreviewListener; use OCA\Richdocuments\Listener\BeforeTemplateRenderedListener; use OCA\Richdocuments\Listener\FileCreatedFromTemplateListener; +use OCA\Richdocuments\Listener\LoadPublicViewerListener; use OCA\Richdocuments\Listener\LoadViewerListener; use OCA\Richdocuments\Listener\ReferenceListener; use OCA\Richdocuments\Listener\ShareLinkListener; @@ -81,6 +82,7 @@ public function register(IRegistrationContext $context): void { $context->registerEventListener(FileCreatedFromTemplateEvent::class, FileCreatedFromTemplateListener::class); $context->registerEventListener(AddContentSecurityPolicyEvent::class, AddContentSecurityPolicyListener::class); $context->registerEventListener(AddFeaturePolicyEvent::class, AddFeaturePolicyListener::class); + $context->registerEventListener(BeforeTemplateRenderedEvent::class, LoadPublicViewerListener::class); $context->registerEventListener(LoadViewer::class, LoadViewerListener::class); $context->registerEventListener(ShareLinkAccessedEvent::class, ShareLinkListener::class); $context->registerEventListener(BeforePreviewFetchedEvent::class, BeforeFetchPreviewListener::class); diff --git a/lib/Listener/LoadPublicViewerListener.php b/lib/Listener/LoadPublicViewerListener.php new file mode 100644 index 0000000000..bba1bb4ccb --- /dev/null +++ b/lib/Listener/LoadPublicViewerListener.php @@ -0,0 +1,50 @@ + + * + * @author Elizabeth Danzberger + * + * @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\Richdocuments\Listener; + +use OCA\Richdocuments\AppInfo\Application; +use OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent; +use OCP\AppFramework\Http\TemplateResponse; +use OCP\EventDispatcher\Event; +use OCP\EventDispatcher\IEventListener; +use OCP\Util; + +class LoadPublicViewerListener implements IEventListener { + public function handle(Event $event): void { + if (!$event instanceof BeforeTemplateRenderedEvent) { + return; + } + + if ($event->getResponse()->getRenderAs() !== TemplateResponse::RENDER_AS_PUBLIC) { + return; + } + + Util::addScript(Application::APPNAME, 'richdocuments-public'); + } +} diff --git a/src/document.js b/src/document.js deleted file mode 100644 index f5e68db3bb..0000000000 --- a/src/document.js +++ /dev/null @@ -1,738 +0,0 @@ -import './init-shared.js' -import { emit } from '@nextcloud/event-bus' -import { generateOcsUrl, getRootUrl, imagePath } from '@nextcloud/router' -import { getRequestToken } from '@nextcloud/auth' -import { loadState } from '@nextcloud/initial-state' -import Config from './services/config.tsx' -import { setGuestName, shouldAskForGuestName } from './helpers/guestName.js' -import { getUIDefaults, generateCSSVarTokens, getCollaboraTheme } from './helpers/coolParameters.js' -import { enableScrollLock } from './helpers/safariFixer.js' - -import PostMessageService from './services/postMessage.tsx' -import { - callMobileMessage, - isDirectEditing, - isMobileInterfaceAvailable, -} from './helpers/mobile.js' -import { getWopiUrl, getSearchParam, getNextcloudUrl } from './helpers/url.js' - -import '../css/document.scss' -import axios from '@nextcloud/axios' -import { spawnDialog } from '@nextcloud/dialogs' -import SaveAs from './components/Modal/SaveAs.vue' - -const PostMessages = new PostMessageService({ - parent: window.parent, - loolframe: () => document.getElementById('loleafletframe').contentWindow, -}) - -if (isDirectEditing()) { - enableScrollLock() -} - -let checkingProxyStatus = false - -const checkProxyStatus = () => { - checkingProxyStatus = true - const url = Config.get('urlsrc').slice(0, Config.get('urlsrc').indexOf('proxy.php') + 'proxy.php'.length) - $.get(url + '?status').done(function(val) { - if (val && val.status && val.status !== 'OK') { - if (val.status === 'starting' || val.status === 'stopped') { - document.getElementById('proxyLoadingIcon').classList.add('icon-loading-small') - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Built-in CODE Server is starting up shortly, please wait.') - } else if (val.status === 'restarting') { - document.getElementById('proxyLoadingIcon').classList.add('icon-loading-small') - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Built-in CODE Server is restarting, please wait.') - } else if (val.status === 'error') { - if (val.error === 'appimage_missing') { - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Error: Cannot find the AppImage, please reinstall the Collabora Online Built-in server.') - } else if (val.error === 'chmod_failed' || val.error === 'appimage_not_executable') { - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Error: Unable to make the AppImage executable, please setup a standalone server.') - } else if (val.error === 'exec_disabled') { - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Error: Exec disabled in PHP, please enable it, or setup a standalone server.') - } else if (val.error === 'not_linux' || val.error === 'not_x86_64' || val.error === 'not_aarch64') { - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Error: Not running on x86-64 or ARM64 (aarch64) Linux, please setup a standalone server.') - } else if (val.error === 'no_fontconfig') { - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Error: The fontconfig library is not installed on your server, please install it or setup a standalone server.') - } else if (val.error === 'no_glibc') { - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Error: Not running on glibc-based Linux, please setup a standalone server.') - } else { - document.getElementById('proxyLoadingMessage').textContent = t('richdocuments', 'Error: Cannot start the Collabora Online Built-in server, please setup a standalone one.') - } - - // probably not even worth re-trying - return - } - - // retry... - setTimeout(function() { checkProxyStatus() }, 100) - return - } - - checkingProxyStatus = false - }) -} - -const showLoadingIndicator = () => { - if ((OC.appswebroots.richdocumentscode || OC.appswebroots.richdocumentscode_arm64) && Config.get('urlsrc').indexOf('proxy.php') >= 0) { - checkProxyStatus() - } else { - document.getElementById('loadingContainer').classList.add('icon-loading') - } -} - -const hideLoadingIndicator = () => { - if (checkingProxyStatus) { - setTimeout(function() { hideLoadingIndicator() }, 100) - return - } - - document.getElementById('loadingContainer').classList.remove('icon-loading') - document.getElementById('proxyLoadingIcon').classList.remove('icon-loading-small') - document.getElementById('proxyLoadingMessage').textContent = '' -} - -showLoadingIndicator() - -$.widget('oc.guestNamePicker', { - _create() { - hideLoadingIndicator() - - const text = document.createElement('div') - text.setAttribute('style', 'margin: 0 auto; margin-top: 100px; text-align: center;') - text.innerHTML = t('richdocuments', 'Please choose your nickname to continue as guest user.') - - const div = document.createElement('div') - div.setAttribute('style', 'margin: 0 auto; width: 250px; display: flex;') - const nick = '' - const btn = '' - div.innerHTML = nick + btn - - $('#documents-content').prepend(div) - $('#documents-content').prepend(text) - const setGuestNameSubmit = () => { - const username = $('#nickname').val() - div.remove() - text.innerText = '' - text.classList.add('icon-loading') - setGuestName(username).then(() => { - $('#documents-content').remove() - documentsMain.initSession() - }) - } - - $('#nickname').keyup(function(event) { - if (event.which === 13) { - setGuestNameSubmit() - } - }) - $('#btn').click(() => setGuestNameSubmit()) - }, -}) - -/** - * Type definitions for WOPI Post message objects - * - * @typedef {object} View - * @property {number} ViewId - * @property {string} UserName - * @property {string} UserId - * @property {number} Color - * @property {boolean} ReadOnly - * @property {boolean} IsCurrentView - */ - -const documentsMain = { - isEditorMode: false, - isViewerMode: false, - isFrameReady: false, - isPublic: false, - ready: false, - fileName: null, - baseName: null, - canShare: false, - canEdit: false, - renderComplete: false, // false till page is rendered with all required data about the document(s) - $deferredVersionRestoreAck: null, - wopiClientFeatures: null, - users: [], - - // generates docKey for given fileId - _generateDocKey(wopiFileId) { - let canonicalWebroot = Config.get('canonical_webroot') - let ocurl = getRootUrl() + '/index.php/apps/richdocuments/wopi/files/' + wopiFileId - if (canonicalWebroot) { - if (!canonicalWebroot.startsWith('/')) { - canonicalWebroot = '/' + canonicalWebroot - } - Config.update('canonical_webroot', canonicalWebroot) - ocurl = ocurl.replace(getRootUrl(), canonicalWebroot) - } - - return ocurl - }, - - UI: { - /* Editor wrapper HTML */ - container: '
' - + '
', - - viewContainer: '
' - + '
' - + '
', - - showViewer(fileId, title) { - // remove previous viewer, if open, and set a new one - if (documentsMain.isViewerMode) { - $('#revViewer').remove() - $('#revViewerContainer').prepend($('
')) - } - - const urlsrc = getWopiUrl({ fileId, title, readOnly: true, closeButton: !documentsMain.hideCloseButton }) - - // access_token & access_token_ttl - must be passed via a form post - const accessToken = encodeURIComponent(documentsMain.token) - const accessTokenTtl = encodeURIComponent(documentsMain.tokenTtl) - - // form to post the access token for WOPISrc - const form = '
' - + '' - + '' - + '' - + '' - + '' - // buy product for new customer users - + '' - + '
' - - // iframe that contains the Collabora Online Viewer - const frame = '