diff --git a/apps/files/lib/Controller/TemplateController.php b/apps/files/lib/Controller/TemplateController.php index 69d2790df1..08a324a46e 100644 --- a/apps/files/lib/Controller/TemplateController.php +++ b/apps/files/lib/Controller/TemplateController.php @@ -1,5 +1,5 @@ * * @author Julius Härtl diff --git a/apps/files/lib/Controller/ViewController.php b/apps/files/lib/Controller/ViewController.php index 124363f07b..846ec14c4a 100644 --- a/apps/files/lib/Controller/ViewController.php +++ b/apps/files/lib/Controller/ViewController.php @@ -190,6 +190,7 @@ class ViewController extends Controller { // Load the files we need \OCP\Util::addStyle('files', 'merged'); \OCP\Util::addScript('files', 'merged-index'); + \OCP\Util::addScript('files', 'dist/templates'); // mostly for the home storage's free space // FIXME: Make non static diff --git a/apps/files/lib/Event/LoadAdditionalScriptsEvent.php b/apps/files/lib/Event/LoadAdditionalScriptsEvent.php index de222ccc55..e5943c6f89 100644 --- a/apps/files/lib/Event/LoadAdditionalScriptsEvent.php +++ b/apps/files/lib/Event/LoadAdditionalScriptsEvent.php @@ -30,7 +30,8 @@ namespace OCA\Files\Event; use OCP\EventDispatcher\Event; /** - * This event is triggered when the files app is rendered. It canb e used to add additional scripts to the files app. + * This event is triggered when the files app is rendered. + * It can be used to add additional scripts to the files app. * * @since 17.0.0 */ diff --git a/apps/files/src/components/TemplatePreview.vue b/apps/files/src/components/TemplatePreview.vue new file mode 100644 index 0000000000..538e1bcff7 --- /dev/null +++ b/apps/files/src/components/TemplatePreview.vue @@ -0,0 +1,203 @@ + + + + + + + diff --git a/apps/files/src/templates.js b/apps/files/src/templates.js new file mode 100644 index 0000000000..3cffc30085 --- /dev/null +++ b/apps/files/src/templates.js @@ -0,0 +1,92 @@ +/** + * @copyright Copyright (c) 2020 John Molakvoæ + * + * @author John Molakvoæ + * + * @license GNU AGPL version 3 or any later version + * + * 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 . + * + */ + +import { getLoggerBuilder } from '@nextcloud/logger' +import { loadState } from '@nextcloud/initial-state' +import { translate as t, translatePlural as n } from '@nextcloud/l10n' +import Vue from 'vue' + +import TemplatePickerView from './views/TemplatePicker' + +// Set up logger +const logger = getLoggerBuilder() + .setApp('files') + .detectUser() + .build() + +// Add translates functions +Vue.mixin({ + methods: { + t, + n, + }, +}) + +// Create document root +const TemplatePickerRoot = document.createElement('div') +TemplatePickerRoot.id = 'template-picker' +document.body.appendChild(TemplatePickerRoot) + +// Retrieve and init templates +const templates = loadState('files', 'templates', []) +logger.debug('Templates providers', templates) + +// Init vue app +const View = Vue.extend(TemplatePickerView) +const TemplatePicker = new View({ + name: 'TemplatePicker', + propsData: { + logger, + }, +}) +TemplatePicker.$mount('#template-picker') + +// Init template engine after load +window.addEventListener('DOMContentLoaded', function() { + // Init template files menu + templates.forEach((provider, index) => { + + const newTemplatePlugin = { + attach(menu) { + const fileList = menu.fileList + + // only attach to main file list, public view is not supported yet + if (fileList.id !== 'files' && fileList.id !== 'files.public') { + return + } + + // register the new menu entry + menu.addMenuEntry({ + id: `template-new-${provider.app}-${index}`, + displayName: provider.label, + templateName: provider.label + provider.extension, + iconClass: provider.iconClass || 'icon-file', + fileType: 'file', + actionHandler(name) { + TemplatePicker.open(name, provider) + }, + }) + }, + } + OC.Plugins.register('OCA.Files.NewFileMenu', newTemplatePlugin) + }) +}) diff --git a/apps/files/src/utils/davUtils.js b/apps/files/src/utils/davUtils.js new file mode 100644 index 0000000000..f64801f08d --- /dev/null +++ b/apps/files/src/utils/davUtils.js @@ -0,0 +1,42 @@ +/** + * @copyright Copyright (c) 2019 John Molakvoæ + * + * @author John Molakvoæ + * + * @license GNU AGPL version 3 or any later version + * + * 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 . + * + */ + +import { generateRemoteUrl } from '@nextcloud/router' +import { getCurrentUser } from '@nextcloud/auth' + +const getRootPath = function() { + if (getCurrentUser()) { + return generateRemoteUrl(`dav/files/${getCurrentUser().uid}`) + } else { + return generateRemoteUrl('webdav').replace('/remote.php', '/public.php') + } +} + +const isPublic = function() { + return !getCurrentUser() +} + +const getToken = function() { + return document.getElementById('sharingToken') && document.getElementById('sharingToken').value +} + +export { getRootPath, getToken, isPublic } diff --git a/apps/files/src/utils/fileUtils.js b/apps/files/src/utils/fileUtils.js new file mode 100644 index 0000000000..97d1c33356 --- /dev/null +++ b/apps/files/src/utils/fileUtils.js @@ -0,0 +1,53 @@ +/** + * @copyright Copyright (c) 2021 John Molakvoæ + * + * @author John Molakvoæ + * + * @license GNU AGPL version 3 or any later version + * + * 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 . + * + */ + +/** + * Get an url encoded path + * + * @param {String} path the full path + * @returns {string} url encoded file path + */ +const encodeFilePath = function(path) { + const pathSections = (path.startsWith('/') ? path : `/${path}`).split('/') + let relativePath = '' + pathSections.forEach((section) => { + if (section !== '') { + relativePath += '/' + encodeURIComponent(section) + } + }) + return relativePath +} + +/** + * Extract dir and name from file path + * + * @param {String} path the full path + * @returns {String[]} [dirPath, fileName] + */ +const extractFilePaths = function(path) { + const pathSections = path.split('/') + const fileName = pathSections[pathSections.length - 1] + const dirPath = pathSections.slice(0, pathSections.length - 1).join('/') + return [dirPath, fileName] +} + +export { encodeFilePath, extractFilePaths } diff --git a/apps/files/src/views/TemplatePicker.vue b/apps/files/src/views/TemplatePicker.vue new file mode 100644 index 0000000000..84c7c38aba --- /dev/null +++ b/apps/files/src/views/TemplatePicker.vue @@ -0,0 +1,268 @@ + + + + + + + diff --git a/apps/files/webpack.js b/apps/files/webpack.js index 0c16e47653..8dbbad5081 100644 --- a/apps/files/webpack.js +++ b/apps/files/webpack.js @@ -2,7 +2,8 @@ const path = require('path'); module.exports = { entry: { - 'sidebar': path.join(__dirname, 'src', 'sidebar.js'), + sidebar: path.join(__dirname, 'src', 'sidebar.js'), + templates: path.join(__dirname, 'src', 'templates.js'), 'files-app-settings': path.join(__dirname, 'src', 'files-app-settings.js'), 'personal-settings': path.join(__dirname, 'src', 'main-personal-settings.js'), }, diff --git a/lib/private/Files/Template/TemplateManager.php b/lib/private/Files/Template/TemplateManager.php index 8b0c78d0b9..3b033a4404 100644 --- a/lib/private/Files/Template/TemplateManager.php +++ b/lib/private/Files/Template/TemplateManager.php @@ -1,5 +1,5 @@ * * @author Julius Härtl diff --git a/lib/public/Files/Template/ITemplateManager.php b/lib/public/Files/Template/ITemplateManager.php index 61dbb68cd7..94545c17b4 100644 --- a/lib/public/Files/Template/ITemplateManager.php +++ b/lib/public/Files/Template/ITemplateManager.php @@ -1,5 +1,5 @@ * * @author Julius Härtl