From 235cc6fef810e6657acc9a8a55361f2166218275 Mon Sep 17 00:00:00 2001 From: Louis Chemineau Date: Thu, 3 Oct 2024 11:58:48 +0200 Subject: [PATCH] fix: Make loading the viewer an init script Signed-off-by: Ferdinand Thiessen Signed-off-by: Louis Chemineau --- lib/Listener/LoadViewerScript.php | 2 + src/init.ts | 14 ++++++ src/main.js | 7 --- ...ActionHandler.js => FilesActionHandler.ts} | 34 ++++++++++++++- src/services/Viewer.js | 9 ++-- src/views/Viewer.vue | 43 +++---------------- vite.config.js | 1 + 7 files changed, 62 insertions(+), 48 deletions(-) create mode 100644 src/init.ts rename src/services/{FilesActionHandler.js => FilesActionHandler.ts} (66%) diff --git a/lib/Listener/LoadViewerScript.php b/lib/Listener/LoadViewerScript.php index c59f71b88..e749d6c12 100644 --- a/lib/Listener/LoadViewerScript.php +++ b/lib/Listener/LoadViewerScript.php @@ -54,7 +54,9 @@ public function handle(Event $event): void { return; } + Util::addStyle(Application::APP_ID, 'viewer-init'); Util::addStyle(Application::APP_ID, 'viewer-main'); + Util::addInitScript(Application::APP_ID, 'viewer-init', 'files'); Util::addScript(Application::APP_ID, 'viewer-main', 'files'); $this->initialStateService->provideInitialState('enabled_preview_providers', array_keys($this->previewManager->getProviders())); } diff --git a/src/init.ts b/src/init.ts new file mode 100644 index 000000000..d688d8cfb --- /dev/null +++ b/src/init.ts @@ -0,0 +1,14 @@ +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ +import { registerViewerAction } from './services/FilesActionHandler' +import ViewerService from './services/Viewer.js' + +// Register the files action +registerViewerAction() + +// Init Viewer Service +window.OCA = window.OCA ?? {} +window.OCA.Viewer = new ViewerService() +window.OCA.Viewer.version = appVersion diff --git a/src/main.js b/src/main.js index 9d38a9553..02beb9750 100644 --- a/src/main.js +++ b/src/main.js @@ -23,7 +23,6 @@ import { translate as t } from '@nextcloud/l10n' import Vue from 'vue' import ViewerComponent from './views/Viewer.vue' -import ViewerService from './services/Viewer.js' Vue.mixin({ methods: { @@ -34,12 +33,6 @@ Vue.mixin({ Vue.prototype.OC = window.OC Vue.prototype.OCA = window.OCA -// Init Viewer Service -if (window.OCA) { - Object.assign(window.OCA, { Viewer: new ViewerService() }) - window.OCA.Viewer.version = appVersion -} - // Create document root const ViewerRoot = document.createElement('div') ViewerRoot.id = 'viewer' diff --git a/src/services/FilesActionHandler.js b/src/services/FilesActionHandler.ts similarity index 66% rename from src/services/FilesActionHandler.js rename to src/services/FilesActionHandler.ts index 05ecdfdd7..c62ea6857 100644 --- a/src/services/FilesActionHandler.js +++ b/src/services/FilesActionHandler.ts @@ -20,12 +20,18 @@ * */ +import EyeSvg from '@mdi/svg/svg/eye.svg?raw' + +import { DefaultType, FileAction, Permission, registerFileAction } from "@nextcloud/files" +import { translate as t } from '@nextcloud/l10n' + + /** * @param {Node} node The file to open * @param {any} view any The files view * @param {string} dir the directory path */ -export default function(node, view, dir) { +function filesActionHandler(node, view, dir) { // replace potential leading double slashes const path = `${node.dirname}/${node.basename}`.replace(/^\/\//, '/') const onClose = () => { @@ -51,3 +57,29 @@ function pushToHistory(node, view, dir) { true, ) } + +/** + * + */ +export function registerViewerAction() { + registerFileAction(new FileAction({ + id: 'view', + displayName() { + return t('viewer', 'View') + }, + iconSvgInline: () => EyeSvg, + default: DefaultType.DEFAULT, + enabled: (nodes) => { + // Disable if not located in user root + if (nodes.some(node => !(node.isDavRessource && node.root?.startsWith('/files')))) { + return false + } + // Faster to check if at least one node doesn't match the requirements + return !nodes.some(node => ( + (node.permissions & Permission.READ) === 0 + || !window.OCA.Viewer.mimetypes.includes(node.mime) + )) + }, + exec: filesActionHandler, + })) +} diff --git a/src/services/Viewer.js b/src/services/Viewer.js index 3636293c3..f7f7b26cd 100644 --- a/src/services/Viewer.js +++ b/src/services/Viewer.js @@ -23,6 +23,7 @@ import Images from '../models/images.js' import Videos from '../models/videos.js' import Audios from '../models/audios.js' +import logger from './logger.js' /** * Handler type definition @@ -78,7 +79,7 @@ export default class Viewer { this.registerHandler(Videos) this.registerHandler(Audios) - console.debug('OCA.Viewer initialized') + logger.debug('OCA.Viewer initialized') } /** @@ -99,9 +100,9 @@ export default class Viewer { * @param {Handler} handler a new unregistered handler */ registerHandler(handler) { - const err = this.validateHandler(handler) - if (err) { - console.error(err, handler) + const error = this.validateHandler(handler) + if (error) { + logger.error('Could not register handler', { error, handler }) return } diff --git a/src/views/Viewer.vue b/src/views/Viewer.vue index b6fe3b62e..725a555c2 100644 --- a/src/views/Viewer.vue +++ b/src/views/Viewer.vue @@ -194,7 +194,6 @@ import Vue from 'vue' import axios from '@nextcloud/axios' import { showError } from '@nextcloud/dialogs' import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus' -import { registerFileAction, FileAction, Permission, DefaultType, Node } from '@nextcloud/files' import getSortingConfig from '../services/FileSortingConfig.ts' import isFullscreen from '@nextcloud/vue/dist/Mixins/isFullscreen.js' @@ -206,7 +205,6 @@ import canDownload from '../utils/canDownload.js' import cancelableRequest from '../utils/CancelableRequest.js' import Error from '../components/Error.vue' import File from '../models/file.js' -import filesActionHandler from '../services/FilesActionHandler.js' import legacyFilesActionHandler from '../services/LegacyFilesActionHandler.js' import getFileInfo from '../services/FileInfo.ts' import getFileList from '../services/FileList.ts' @@ -215,7 +213,6 @@ import logger from '../services/logger.js' import Delete from 'vue-material-design-icons/Delete.vue' import Download from 'vue-material-design-icons/Download.vue' -import EyeSvg from '@mdi/svg/svg/eye.svg?raw' import Fullscreen from 'vue-material-design-icons/Fullscreen.vue' import FullscreenExit from 'vue-material-design-icons/FullscreenExit.vue' import Pencil from 'vue-material-design-icons/Pencil.vue' @@ -287,8 +284,7 @@ export default { isSidebarShown: false, isFullscreenMode: false, canSwipe: true, - // TODO: remove OCA?.Files?.fileActions when public Files is Vue - isStandalone: OCP?.Files === undefined && OCA?.Files?.fileActions === undefined, + isStandalone: false, theme: null, root: getRootPath(), handlerId: '', @@ -524,6 +520,12 @@ export default { }, beforeMount() { + this.isStandalone = window.OCP?.Files === undefined && window.OCA?.Files?.fileActions === undefined + + if (this.isStandalone) { + logger.info('No OCP.Files app found, viewer is now in standalone mode') + } + // register on load document.addEventListener('DOMContentLoaded', () => { // register all primary components mimes @@ -543,16 +545,10 @@ export default { this.Sidebar = OCA.Files.Sidebar.state } - this.registerFileActions() - logger.info(`${this.handlers.length} viewer handlers registered`, { handlers: this.handlers }) }) window.addEventListener('resize', this.onResize) - - if (this.isStandalone) { - logger.info('No OCP.Files app found, viewer is now in standalone mode') - } }, mounted() { @@ -940,31 +936,6 @@ export default { } }, - registerFileActions() { - if (!this.isStandalone) { - registerFileAction(new FileAction({ - id: 'view', - displayName() { - return t('viewer', 'View') - }, - iconSvgInline: () => EyeSvg, - default: DefaultType.DEFAULT, - enabled: (nodes) => { - // Disable if not located in user root - if (nodes.some(node => !(node.isDavRessource && node.root?.startsWith('/files')))) { - return false - } - // Faster to check if at least one node doesn't match the requirements - return !nodes.some(node => ( - (node.permissions & Permission.READ) === 0 - || !this.Viewer.mimetypes.includes(node.mime) - )) - }, - exec: filesActionHandler, - })) - } - }, - /** * Close the viewer */ diff --git a/vite.config.js b/vite.config.js index fc836bec4..1c7a64dda 100644 --- a/vite.config.js +++ b/vite.config.js @@ -7,6 +7,7 @@ const plyrIcons = readFileSync(join(__dirname, 'node_modules', 'plyr', 'dist', ' export default createAppConfig({ main: 'src/main.js', + init: 'src/init.ts', }, { replace: { PLYR_ICONS: JSON.stringify(plyrIcons),