diff --git a/lib/Listener/LoadViewerScript.php b/lib/Listener/LoadViewerScript.php index 0e4681c61..e8946edc9 100644 --- a/lib/Listener/LoadViewerScript.php +++ b/lib/Listener/LoadViewerScript.php @@ -54,6 +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 5b6dd86c9..abfe55e7e 100644 --- a/src/main.js +++ b/src/main.js @@ -24,7 +24,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: { @@ -46,12 +45,6 @@ __webpack_nonce__ = btoa(OC.requestToken) // eslint-disable-next-line __webpack_public_path__ = generateFilePath('viewer', '', 'js/') -// 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..71973a8b1 100644 --- a/src/services/FilesActionHandler.js +++ b/src/services/FilesActionHandler.ts @@ -20,12 +20,17 @@ * */ +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 +56,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 55e51e31c..cea55ef27 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') } /** diff --git a/src/views/Viewer.vue b/src/views/Viewer.vue index 52cd4a7ce..a3de851a8 100644 --- a/src/views/Viewer.vue +++ b/src/views/Viewer.vue @@ -193,7 +193,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 } from '@nextcloud/files' import getSortingConfig from '../services/FileSortingConfig.ts' import isFullscreen from '@nextcloud/vue/dist/Mixins/isFullscreen.js' @@ -205,7 +204,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' @@ -214,7 +212,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' @@ -286,8 +283,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: '', @@ -523,6 +519,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 @@ -542,16 +544,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() { @@ -939,31 +935,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/webpack.config.ts b/webpack.config.ts index 48aefd251..912f8db73 100644 --- a/webpack.config.ts +++ b/webpack.config.ts @@ -15,6 +15,11 @@ if (isTesting) { console.debug('TESTING MODE ENABLED') } +webpackConfig.entry = { + main: path.join(__dirname, 'src', 'main.js'), + init: path.join(__dirname, 'src', 'init.js'), +} + // vue-plyr uses .mjs file webpackRules.RULE_JS.test = /\.m?js$/ webpackRules.RULE_JS.exclude = BabelLoaderExcludeNodeModulesExcept([