fix: avoid side-effect imports

Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
This commit is contained in:
John Molakvoæ (skjnldsv) 2023-09-21 12:15:11 +02:00 committed by Ferdinand Thiessen
parent a1a1b990e6
commit a5a8655beb
28 changed files with 129 additions and 228 deletions

View File

@ -42,5 +42,6 @@ class LoadAdditionalScripts implements IEventListener {
// TODO: make sure to only include the sidebar script when
// we properly split it between files list and sidebar
Util::addScript(Application::APP_ID, 'comments');
Util::addInitScript(Application::APP_ID, 'init');
}
}

View File

@ -24,6 +24,5 @@
import './app.js'
import './templates.js'
import './activitytabviewplugin.js'
import './actions/inlineUnreadCommentsAction.ts'
window.OCA.Comments = OCA.Comments

25
apps/comments/src/init.ts Normal file
View File

@ -0,0 +1,25 @@
/**
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
import { registerFileAction } from '@nextcloud/files'
import { action } from './actions/inlineUnreadCommentsAction'
registerFileAction(action)

View File

@ -217,6 +217,7 @@ class ViewController extends Controller {
}
// Load the files we need
\OCP\Util::addInitScript('files', 'init');
\OCP\Util::addStyle('files', 'merged');
\OCP\Util::addScript('files', 'merged-index', 'files');
\OCP\Util::addScript('files', 'main');

View File

@ -20,7 +20,7 @@
*
*/
import { emit } from '@nextcloud/event-bus'
import { Permission, Node, View, registerFileAction, FileAction } from '@nextcloud/files'
import { Permission, Node, View, FileAction } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import axios from '@nextcloud/axios'
import TrashCanSvg from '@mdi/svg/svg/trash-can.svg?raw'
@ -62,5 +62,3 @@ export const action = new FileAction({
order: 100,
})
registerFileAction(action)

View File

@ -20,7 +20,7 @@
*
*/
import { generateUrl } from '@nextcloud/router'
import { registerFileAction, FileAction, Permission, Node, FileType, View } from '@nextcloud/files'
import { FileAction, Permission, Node, FileType, View } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import ArrowDownSvg from '@mdi/svg/svg/arrow-down.svg?raw'
@ -86,5 +86,3 @@ export const action = new FileAction({
order: 30,
})
registerFileAction(action)

View File

@ -22,7 +22,7 @@
import { encodePath } from '@nextcloud/paths'
import { generateOcsUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import { registerFileAction, FileAction, Permission, type Node } from '@nextcloud/files'
import { FileAction, Permission, type Node } from '@nextcloud/files'
import { showError } from '@nextcloud/dialogs'
import { translate as t } from '@nextcloud/l10n'
import axios from '@nextcloud/axios'
@ -66,7 +66,3 @@ export const action = new FileAction({
order: 25,
})
if (!/Android|iPhone|iPad|iPod/i.test(navigator.userAgent)) {
registerFileAction(action)
}

View File

@ -21,7 +21,7 @@
*/
import { emit } from '@nextcloud/event-bus'
import { generateUrl } from '@nextcloud/router'
import { Permission, type Node, View, registerFileAction, FileAction } from '@nextcloud/files'
import { Permission, type Node, View, FileAction } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import axios from '@nextcloud/axios'
import Vue from 'vue'
@ -101,5 +101,3 @@ export const action = new FileAction({
order: -50,
})
registerFileAction(action)

View File

@ -20,7 +20,7 @@
*
*/
import { join } from 'path'
import { Permission, Node, FileType, View, registerFileAction, FileAction, DefaultType } from '@nextcloud/files'
import { Permission, Node, FileType, View, FileAction, DefaultType } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import FolderSvg from '@mdi/svg/svg/folder.svg?raw'
@ -66,5 +66,3 @@ export const action = new FileAction({
default: DefaultType.HIDDEN,
order: -100,
})
registerFileAction(action)

View File

@ -20,9 +20,7 @@
*
*/
import { translate as t } from '@nextcloud/l10n'
import { FileType, type Node } from '@nextcloud/files'
import { registerFileAction, FileAction, DefaultType } from '@nextcloud/files'
import { type Node, FileType, FileAction, DefaultType } from '@nextcloud/files'
/**
* TODO: Move away from a redirect and handle
@ -53,5 +51,3 @@ export const action = new FileAction({
order: -1000,
default: DefaultType.HIDDEN,
})
registerFileAction(action)

View File

@ -20,7 +20,7 @@
*
*/
import { emit } from '@nextcloud/event-bus'
import { Permission, type Node, registerFileAction, FileAction } from '@nextcloud/files'
import { Permission, type Node, FileAction } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import PencilSvg from '@mdi/svg/svg/pencil.svg?raw'
@ -45,5 +45,3 @@ export const action = new FileAction({
order: 10,
})
registerFileAction(action)

View File

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { Permission, type Node, View, registerFileAction, FileAction, FileType } from '@nextcloud/files'
import { Permission, type Node, View, FileAction, FileType } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import InformationSvg from '@mdi/svg/svg/information-variant.svg?raw'
@ -73,5 +73,3 @@ export const action = new FileAction({
order: -50,
})
registerFileAction(action)

View File

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { Node, FileType, Permission, View, registerFileAction, FileAction } from '@nextcloud/files'
import { Node, FileType, Permission, View, FileAction } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import FolderMoveSvg from '@mdi/svg/svg/folder-move.svg?raw'
@ -64,5 +64,3 @@ export const action = new FileAction({
order: 80,
})
registerFileAction(action)

59
apps/files/src/init.ts Normal file
View File

@ -0,0 +1,59 @@
/**
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
import { action as deleteAction } from './actions/deleteAction'
import { action as downloadAction } from './actions/downloadAction'
import { action as editLocallyAction } from './actions/editLocallyAction'
import { action as favoriteAction } from './actions/favoriteAction'
import { action as openFolderAction } from './actions/openFolderAction'
import { action as openInFilesAction } from './actions/openInFilesAction'
import { action as renameAction } from './actions/renameAction'
import { action as sidebarAction } from './actions/sidebarAction'
import { action as viewInFolderAction } from './actions/viewInFolderAction'
import { entry as newFolderEntry } from './newMenu/newFolder'
import registerFavoritesView from './views/favorites'
import registerRecentView from './views/recent'
import registerFilesView from './views/files'
import registerPreviewServiceWorker from './services/ServiceWorker.js'
import { addNewFileMenuEntry, registerFileAction } from '@nextcloud/files'
// Register file actions
registerFileAction(deleteAction)
registerFileAction(downloadAction)
registerFileAction(editLocallyAction)
registerFileAction(favoriteAction)
registerFileAction(openFolderAction)
registerFileAction(openInFilesAction)
registerFileAction(renameAction)
registerFileAction(sidebarAction)
registerFileAction(viewInFolderAction)
// Register new menu entry
addNewFileMenuEntry(newFolderEntry)
// Register files views
registerFavoritesView()
registerFilesView()
registerRecentView()
// Register preview service worker
registerPreviewServiceWorker()

View File

@ -1,17 +1,6 @@
import './templates.js'
import './legacy/filelistSearch.js'
import './actions/deleteAction'
import './actions/downloadAction'
import './actions/editLocallyAction'
import './actions/favoriteAction'
import './actions/openFolderAction'
import './actions/openInFilesAction.js'
import './actions/renameAction'
import './actions/sidebarAction'
import './actions/viewInFolderAction'
import './newMenu/newFolder'
import Vue from 'vue'
import { createPinia, PiniaVuePlugin } from 'pinia'
import { getNavigation } from '@nextcloud/files'
@ -19,10 +8,6 @@ import { getRequestToken } from '@nextcloud/auth'
import FilesListView from './views/FilesList.vue'
import NavigationView from './views/Navigation.vue'
import registerFavoritesView from './views/favorites'
import registerRecentView from './views/recent'
import registerFilesView from './views/files'
import registerPreviewServiceWorker from './services/ServiceWorker.js'
import router from './router/router'
import RouterService from './services/RouterService'
import SettingsModel from './models/Setting.js'
@ -80,11 +65,3 @@ const FilesList = new ListView({
pinia,
})
FilesList.$mount('#app-content-vue')
// Init legacy and new files views
registerFavoritesView()
registerFilesView()
registerRecentView()
// Register preview service worker
registerPreviewServiceWorker()

View File

@ -62,7 +62,7 @@ export const getUniqueName = (name: string, names: string[]): string => {
return newName
}
const entry = {
export const entry = {
id: 'newFolder',
displayName: t('files', 'New folder'),
if: (context: Folder) => (context.permissions & Permission.CREATE) !== 0,
@ -92,5 +92,3 @@ const entry = {
emit('files:node:rename', folder)
},
} as Entry
addNewFileMenuEntry(entry)

View File

@ -1,130 +0,0 @@
/**
* @copyright Copyright (c) 2023 John Molakvoæ <skjnldsv@protonmail.com>
*
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* 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 <http://www.gnu.org/licenses/>.
*
*/
import logger from '../logger'
type DavProperty = { [key: string]: string }
declare global {
interface Window {
OC: any;
_nc_dav_properties: string[];
_nc_dav_namespaces: DavProperty;
}
}
const defaultDavProperties = [
'd:getcontentlength',
'd:getcontenttype',
'd:getetag',
'd:getlastmodified',
'd:quota-available-bytes',
'd:resourcetype',
'nc:has-preview',
'nc:is-encrypted',
'nc:mount-type',
'nc:share-attributes',
'oc:comments-unread',
'oc:favorite',
'oc:fileid',
'oc:owner-display-name',
'oc:owner-id',
'oc:permissions',
'oc:share-types',
'oc:size',
'ocs:share-permissions',
]
const defaultDavNamespaces = {
d: 'DAV:',
nc: 'http://nextcloud.org/ns',
oc: 'http://owncloud.org/ns',
ocs: 'http://open-collaboration-services.org/ns',
}
/**
* TODO: remove and move to @nextcloud/files
* @param prop
* @param namespace
*/
export const registerDavProperty = function(prop: string, namespace: DavProperty = { nc: 'http://nextcloud.org/ns' }): void {
if (typeof window._nc_dav_properties === 'undefined') {
window._nc_dav_properties = defaultDavProperties
window._nc_dav_namespaces = defaultDavNamespaces
}
const namespaces = { ...window._nc_dav_namespaces, ...namespace }
// Check duplicates
if (window._nc_dav_properties.find(search => search === prop)) {
logger.error(`${prop} already registered`, { prop })
return
}
if (prop.startsWith('<') || prop.split(':').length !== 2) {
logger.error(`${prop} is not valid. See example: 'oc:fileid'`, { prop })
return
}
const ns = prop.split(':')[0]
if (!namespaces[ns]) {
logger.error(`${prop} namespace unknown`, { prop, namespaces })
return
}
window._nc_dav_properties.push(prop)
window._nc_dav_namespaces = namespaces
}
/**
* Get the registered dav properties
*/
export const getDavProperties = function(): string {
if (typeof window._nc_dav_properties === 'undefined') {
window._nc_dav_properties = defaultDavProperties
}
return window._nc_dav_properties.map(prop => `<${prop} />`).join(' ')
}
/**
* Get the registered dav namespaces
*/
export const getDavNameSpaces = function(): string {
if (typeof window._nc_dav_namespaces === 'undefined') {
window._nc_dav_namespaces = defaultDavNamespaces
}
return Object.keys(window._nc_dav_namespaces).map(ns => `xmlns:${ns}="${window._nc_dav_namespaces[ns]}"`).join(' ')
}
/**
* Get the default PROPFIND request payload
*/
export const getDefaultPropfind = function() {
return `<?xml version="1.0"?>
<d:propfind ${getDavNameSpaces()}>
<d:prop>
${getDavProperties()}
</d:prop>
</d:propfind>`
}

View File

@ -20,14 +20,11 @@
*
*/
import type { ContentsWithRoot } from '@nextcloud/files'
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
import type { FileStat, ResponseDataDetailed } from 'webdav'
import { File, Folder, davParsePermissions } from '@nextcloud/files'
import { generateRemoteUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import { Folder, getDavNameSpaces, getDavProperties, davGetDefaultPropfind } from '@nextcloud/files'
import { getClient, rootPath } from './WebdavClient'
import { getDavNameSpaces, getDavProperties, getDefaultPropfind } from './DavProperties'
import { getClient } from './WebdavClient'
import { resultToNode } from './Files'
const client = getClient()
@ -42,21 +39,15 @@ const reportPayload = `<?xml version="1.0"?>
</oc:filter-rules>
</oc:filter-files>`
interface ResponseProps extends DAVResultResponseProps {
permissions: string,
fileid: number,
size: number,
}
export const getContents = async (path = '/'): Promise<ContentsWithRoot> => {
const propfindPayload = getDefaultPropfind()
const propfindPayload = davGetDefaultPropfind()
// Get root folder
let rootResponse
if (path === '/') {
rootResponse = await client.stat(path, {
details: true,
data: getDefaultPropfind(),
data: propfindPayload,
}) as ResponseDataDetailed<FileStat>
}

View File

@ -22,13 +22,12 @@
import type { ContentsWithRoot } from '@nextcloud/files'
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
import { cancelable, CancelablePromise } from 'cancelable-promise'
import { File, Folder, davParsePermissions } from '@nextcloud/files'
import { CancelablePromise } from 'cancelable-promise'
import { File, Folder, davParsePermissions, davGetDefaultPropfind } from '@nextcloud/files'
import { generateRemoteUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import { getClient, rootPath } from './WebdavClient'
import { getDefaultPropfind } from './DavProperties'
import { hashCode } from '../utils/hashUtils'
import logger from '../logger'
@ -76,7 +75,7 @@ export const resultToNode = function(node: FileStat): File | Folder {
export const getContents = (path = '/'): Promise<ContentsWithRoot> => {
const controller = new AbortController()
const propfindPayload = getDefaultPropfind()
const propfindPayload = davGetDefaultPropfind()
return new CancelablePromise(async (resolve, reject, onCancel) => {
onCancel(() => controller.abort())

View File

@ -22,12 +22,11 @@
import type { ContentsWithRoot } from '@nextcloud/files'
import type { FileStat, ResponseDataDetailed, DAVResultResponseProps } from 'webdav'
import { File, Folder, Permission, davParsePermissions } from '@nextcloud/files'
import { Folder, Permission, getDavNameSpaces, getDavProperties } from '@nextcloud/files'
import { generateRemoteUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import { getClient, rootPath } from './WebdavClient'
import { getDavNameSpaces, getDavProperties } from './DavProperties'
import { resultToNode } from './Files'
const client = getClient(generateRemoteUrl('dav'))

View File

@ -50,6 +50,8 @@ class LoadAdditionalListener implements IEventListener {
$allowUserMounting = $this->config->getAppValue('files_external', 'allow_user_mounting', 'no') === 'yes';
$this->initialState->provideInitialState('allowUserMounting', $allowUserMounting);
Util::addInitScript(Application::APP_ID, 'init');
Util::addScript(Application::APP_ID, 'main', 'files');
}
}

View File

@ -31,7 +31,7 @@ import axios from '@nextcloud/axios'
import LoginSvg from '@mdi/svg/svg/login.svg?raw'
import Vue from 'vue'
import { registerFileAction, FileAction, DefaultType } from '@nextcloud/files'
import { FileAction, DefaultType } from '@nextcloud/files'
import { STORAGE_STATUS, isMissingAuthConfig } from '../utils/credentialsUtils'
import { isNodeExternalStorage } from '../utils/externalStorageUtils'
@ -106,5 +106,3 @@ export const action = new FileAction({
default: DefaultType.DEFAULT,
inline: () => true,
})
registerFileAction(action)

View File

@ -32,7 +32,7 @@ import '../css/fileEntryStatus.scss'
import { getStatus, type StorageConfig } from '../services/externalStorage'
import { isMissingAuthConfig, STORAGE_STATUS } from '../utils/credentialsUtils'
import { isNodeExternalStorage } from '../utils/externalStorageUtils'
import { registerFileAction, FileAction } from '@nextcloud/files'
import { FileAction } from '@nextcloud/files'
export const action = new FileAction({
id: 'check-external-storage',
@ -92,5 +92,3 @@ export const action = new FileAction({
order: 10,
})
registerFileAction(action)

View File

@ -25,7 +25,7 @@ import type { StorageConfig } from '../services/externalStorage'
import { generateUrl } from '@nextcloud/router'
import { translate as t } from '@nextcloud/l10n'
import { registerFileAction, FileAction, DefaultType } from '@nextcloud/files'
import { FileAction, DefaultType } from '@nextcloud/files'
import { STORAGE_STATUS } from '../utils/credentialsUtils'
export const action = new FileAction({
@ -71,5 +71,3 @@ export const action = new FileAction({
order: -1000,
default: DefaultType.HIDDEN,
})
registerFileAction(action)

View File

@ -19,18 +19,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { translate as t } from '@nextcloud/l10n'
import { loadState } from '@nextcloud/initial-state'
import { translate as t } from '@nextcloud/l10n'
import { View, getNavigation, Column, registerFileAction } from '@nextcloud/files'
import FolderNetworkSvg from '@mdi/svg/svg/folder-network.svg?raw'
import './actions/enterCredentialsAction'
import './actions/inlineStorageCheckAction'
import './actions/openInFilesAction'
import { action as enterCredentialsAction } from './actions/enterCredentialsAction'
import { action as inlineStorageCheckAction } from './actions/inlineStorageCheckAction'
import { action as openInFilesAction } from './actions/openInFilesAction'
import { getContents } from './services/externalStorage'
import { View, getNavigation, Column } from '@nextcloud/files'
const allowUserMounting = loadState('files_external', 'allowUserMounting', false)
// Register view
const Navigation = getNavigation()
Navigation.register(new View({
id: 'extstoragemounts',
@ -73,3 +74,8 @@ Navigation.register(new View({
getContents,
}))
// Register actions
registerFileAction(enterCredentialsAction)
registerFileAction(inlineStorageCheckAction)
registerFileAction(openInFilesAction)

View File

@ -19,12 +19,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
import { File, Folder, davParsePermissions, type ContentsWithRoot } from '@nextcloud/files'
import type { FileStat, ResponseDataDetailed } from 'webdav'
import type { ContentsWithRoot } from '@nextcloud/files'
import { File, Folder, davParsePermissions, getDavNameSpaces, getDavProperties } from '@nextcloud/files'
import { generateRemoteUrl, generateUrl } from '@nextcloud/router'
import { getCurrentUser } from '@nextcloud/auth'
import type { FileStat, ResponseDataDetailed } from 'webdav'
import { getDavNameSpaces, getDavProperties } from '../../../files/src/services/DavProperties'
import client, { rootPath } from './client'

View File

@ -23,7 +23,7 @@
import './actions/inlineSystemTagsAction.js'
import { translate as t } from '@nextcloud/l10n'
import { Column, Node, View, getNavigation } from '@nextcloud/files'
import { View, getNavigation } from '@nextcloud/files'
import TagMultipleSvg from '@mdi/svg/svg/tag-multiple.svg?raw'
import { getContents } from './services/systemtags.js'

View File

@ -26,6 +26,7 @@ module.exports = {
comments: path.join(__dirname, 'apps/comments/src', 'comments.js'),
'comments-app': path.join(__dirname, 'apps/comments/src', 'comments-app.js'),
'comments-tab': path.join(__dirname, 'apps/comments/src', 'comments-tab.js'),
init: path.join(__dirname, 'apps/comments/src', 'init.ts'),
},
core: {
files_client: path.join(__dirname, 'core/src', 'files/client.js'),
@ -51,11 +52,12 @@ module.exports = {
files: {
sidebar: path.join(__dirname, 'apps/files/src', 'sidebar.js'),
main: path.join(__dirname, 'apps/files/src', 'main.ts'),
init: path.join(__dirname, 'apps/files/src', 'init.ts'),
'personal-settings': path.join(__dirname, 'apps/files/src', 'main-personal-settings.js'),
'reference-files': path.join(__dirname, 'apps/files/src', 'reference-files.js'),
},
files_external: {
main: path.join(__dirname, 'apps/files_external/src', 'main.ts'),
init: path.join(__dirname, 'apps/files_external/src', 'init.ts'),
},
files_reminders: {
main: path.join(__dirname, 'apps/files_reminders/src', 'main.ts'),