Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
fix: Make loading the viewer an init script
Signed-off-by: Ferdinand Thiessen <[email protected]>
Signed-off-by: Louis Chemineau <[email protected]>
  • Loading branch information
artonge committed Oct 15, 2024
commit d91eac27e95270f358fa6e590bbcdbee0511acc8
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