Skip to content

Commit

Permalink
fix: Make loading the viewer an init script
Browse files Browse the repository at this point in the history
Signed-off-by: Ferdinand Thiessen <[email protected]>
Signed-off-by: Louis Chemineau <[email protected]>
  • Loading branch information
artonge committed Oct 15, 2024
1 parent ba69ea0 commit d91eac2
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 50 deletions.
1 change: 1 addition & 0 deletions lib/Listener/LoadViewerScript.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ public function handle(Event $event): void {
return;
}

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()));
}
Expand Down
4 changes: 0 additions & 4 deletions src/components/Images.vue
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,6 @@
</template>

<script>
import Vue from 'vue'
import AsyncComputed from 'vue-async-computed'
import PlayCircleOutline from 'vue-material-design-icons/PlayCircleOutline.vue'
import axios from '@nextcloud/axios'
Expand All @@ -99,8 +97,6 @@ import ImageEditor from './ImageEditor.vue'
import { findLivePhotoPeerFromFileId } from '../utils/livePhotoUtils'
import { getDavPath } from '../utils/fileUtils'
Vue.use(AsyncComputed)
export default {
name: 'Images',
Expand Down
14 changes: 14 additions & 0 deletions src/init.js
Original file line number Diff line number Diff line change
@@ -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.js'
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
10 changes: 3 additions & 7 deletions src/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
import { generateFilePath } from '@nextcloud/router'
import { translate as t } from '@nextcloud/l10n'
import Vue from 'vue'
import AsyncComputed from 'vue-async-computed'

import ViewerComponent from './views/Viewer.vue'
import ViewerService from './services/Viewer.js'

Vue.mixin({
methods: {
Expand All @@ -46,12 +46,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'
Expand All @@ -64,6 +58,8 @@ VideoControls.innerHTML = PLYR_ICONS
VideoControls.style.display = 'none'
document.body.appendChild(VideoControls)

Vue.use(AsyncComputed)

// Init vue
export default new Vue({
el: '#viewer',
Expand Down
36 changes: 34 additions & 2 deletions src/services/FilesActionHandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,18 @@
*
*/

// eslint-disable-next-line import/no-unresolved
import EyeSvg from '@mdi/svg/svg/eye.svg?raw'

import { DefaultType, FileAction, Node, Permission, registerFileAction, View } 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 {View} 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 = () => {
Expand All @@ -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,
}))
}
3 changes: 2 additions & 1 deletion src/services/Viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -78,7 +79,7 @@ export default class Viewer {
this.registerHandler(Videos)
this.registerHandler(Audios)

console.debug('OCA.Viewer initialized')
logger.debug('OCA.Viewer initialized')
}

/**
Expand Down
43 changes: 7 additions & 36 deletions src/views/Viewer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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'
Expand All @@ -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'
Expand Down Expand Up @@ -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: '',
Expand Down Expand Up @@ -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
Expand All @@ -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() {
Expand Down Expand Up @@ -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
*/
Expand Down
5 changes: 5 additions & 0 deletions webpack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand Down

0 comments on commit d91eac2

Please sign in to comment.