From 1ebb7f812f86b38a3b49b2beb1c879937c70a76b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20Molakvo=C3=A6=20=28skjnldsv=29?= Date: Wed, 20 Sep 2023 00:12:20 +0200 Subject: [PATCH] feat(files): add files_sharing indicator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: John Molakvoæ (skjnldsv) --- apps/files/src/actions/deleteAction.ts | 2 +- apps/files/src/components/FileEntry.vue | 5 +- .../files/src/components/FilesListVirtual.vue | 4 + .../lib/Listener/LoadAdditionalListener.php | 2 +- .../src/actions/sharingStatusAction.scss | 35 ++++++ .../src/actions/sharingStatusAction.ts | 106 ++++++++++++++++++ .../src/{files_sharing.ts => init.ts} | 1 + webpack.modules.js | 2 +- 8 files changed, 153 insertions(+), 4 deletions(-) create mode 100644 apps/files_sharing/src/actions/sharingStatusAction.scss create mode 100644 apps/files_sharing/src/actions/sharingStatusAction.ts rename apps/files_sharing/src/{files_sharing.ts => init.ts} (96%) diff --git a/apps/files/src/actions/deleteAction.ts b/apps/files/src/actions/deleteAction.ts index 528a0faecabfd..04c139fe38e83 100644 --- a/apps/files/src/actions/deleteAction.ts +++ b/apps/files/src/actions/deleteAction.ts @@ -31,7 +31,7 @@ export const action = new FileAction({ id: 'delete', displayName(nodes: Node[], view: View) { return view.id === 'trashbin' - ? t('files_trashbin', 'Delete permanently') + ? t('files', 'Delete permanently') : t('files', 'Delete') }, iconSvgInline: () => TrashCanSvg, diff --git a/apps/files/src/components/FileEntry.vue b/apps/files/src/components/FileEntry.vue index 30ab98c9dc6f3..a058d25610044 100644 --- a/apps/files/src/components/FileEntry.vue +++ b/apps/files/src/components/FileEntry.vue @@ -109,9 +109,11 @@ + :source="source" + class="files-list__row-action--inline" /> diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index ace8d87fc8c19..cd41a179ce9b1 100644 --- a/apps/files/src/components/FilesListVirtual.vue +++ b/apps/files/src/components/FilesListVirtual.vue @@ -461,6 +461,10 @@ export default Vue.extend({ } } + .files-list__row-action--inline { + margin-right: 7px; + } + .files-list__row-mtime, .files-list__row-size { // Right align text diff --git a/apps/files_sharing/lib/Listener/LoadAdditionalListener.php b/apps/files_sharing/lib/Listener/LoadAdditionalListener.php index 583cd5757934f..e2122cb6ee2aa 100644 --- a/apps/files_sharing/lib/Listener/LoadAdditionalListener.php +++ b/apps/files_sharing/lib/Listener/LoadAdditionalListener.php @@ -44,7 +44,7 @@ public function handle(Event $event): void { $shareManager = \OC::$server->get(IManager::class); if ($shareManager->shareApiEnabled() && class_exists('\OCA\Files\App')) { - Util::addScript(Application::APP_ID, 'files_sharing', 'files'); + Util::addInitScript(Application::APP_ID, 'init'); } } } diff --git a/apps/files_sharing/src/actions/sharingStatusAction.scss b/apps/files_sharing/src/actions/sharingStatusAction.scss new file mode 100644 index 0000000000000..fd37732d47c00 --- /dev/null +++ b/apps/files_sharing/src/actions/sharingStatusAction.scss @@ -0,0 +1,35 @@ +/** + * @copyright Copyright (c) 2023 John Molakvoæ + * + * @author John Molakvoæ + * + * @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 . + * + */ + // Only when rendered inline, when not enough space, this is put in the menu +.action-items > .files-list__row-action-sharing-status { + // put icon at the end of the button + direction: rtl; + // align icons with textless inline actions + padding-right: 0 !important; +} + +svg.sharing-status__avatar { + height: 32px !important; + width: 32px !important; + border-radius: 32px; + overflow: hidden; +} \ No newline at end of file diff --git a/apps/files_sharing/src/actions/sharingStatusAction.ts b/apps/files_sharing/src/actions/sharingStatusAction.ts new file mode 100644 index 0000000000000..e27ea4e32cae1 --- /dev/null +++ b/apps/files_sharing/src/actions/sharingStatusAction.ts @@ -0,0 +1,106 @@ +/** + * @copyright Copyright (c) 2023 John Molakvoæ + * + * @author John Molakvoæ + * + * @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 . + * + */ +import { Node, View, registerFileAction, FileAction } from '@nextcloud/files' +import { translate as t } from '@nextcloud/l10n' +import { Type } from '@nextcloud/sharing' + +import AccountGroupSvg from '@mdi/svg/svg/account-group.svg?raw' +import AccountPlusSvg from '@mdi/svg/svg/account-plus.svg?raw' +import LinkSvg from '@mdi/svg/svg/link.svg?raw' +import CircleSvg from '../../../../core/img/apps/circles.svg?raw' + +import { action as sidebarAction } from '../../../files/src/actions/sidebarAction' +import { generateUrl } from '@nextcloud/router' +import { getCurrentUser } from '@nextcloud/auth' + +import './sharingStatusAction.scss' + +const generateAvatarSvg = (userId: string) => { + const avatarUrl = generateUrl('/avatar/{userId}/32', { userId }) + return `` +} + +export const action = new FileAction({ + id: 'sharing-status', + displayName(nodes: Node[]) { + const node = nodes[0] + const shareTypes = Object.values(node?.attributes?.['share-types'] || {}).flat() as number[] + if (shareTypes.length > 0) { + return t('files_sharing', 'Shared') + } + + const ownerId = node?.attributes?.['owner-id'] + if (ownerId && ownerId !== getCurrentUser()?.uid) { + return t('files_sharing', 'Shared') + } + + return '' + }, + iconSvgInline(nodes: Node[]) { + const node = nodes[0] + const shareTypes = Object.values(node?.attributes?.['share-types'] || {}).flat() as number[] + + // Link shares + if (shareTypes.includes(Type.SHARE_TYPE_LINK) + || shareTypes.includes(Type.SHARE_TYPE_EMAIL)) { + return LinkSvg + } + + // Group shares + if (shareTypes.includes(Type.SHARE_TYPE_GROUP) + || shareTypes.includes(Type.SHARE_TYPE_REMOTE_GROUP)) { + return AccountGroupSvg + } + + // Circle shares + if (shareTypes.includes(Type.SHARE_TYPE_CIRCLE)) { + return CircleSvg + } + + const ownerId = node?.attributes?.['owner-id'] + if (ownerId && ownerId !== getCurrentUser()?.uid) { + return generateAvatarSvg(ownerId) + } + + return AccountPlusSvg + }, + + enabled(nodes: Node[]) { + if (nodes.length !== 1) { + return false + } + return true + }, + + async exec(node: Node, view: View, dir: string) { + window.OCA?.Files?.Sidebar?.setActiveTab?.('sharing') + return sidebarAction.exec(node, view, dir) + }, + + inline: () => true, + +}) + +registerFileAction(action) diff --git a/apps/files_sharing/src/files_sharing.ts b/apps/files_sharing/src/init.ts similarity index 96% rename from apps/files_sharing/src/files_sharing.ts rename to apps/files_sharing/src/init.ts index 939cc91905db8..734f888cb7d70 100644 --- a/apps/files_sharing/src/files_sharing.ts +++ b/apps/files_sharing/src/init.ts @@ -26,5 +26,6 @@ import './actions/acceptShareAction' import './actions/openInFilesAction' import './actions/rejectShareAction' import './actions/restoreShareAction' +import './actions/sharingStatusAction' registerSharingViews() diff --git a/webpack.modules.js b/webpack.modules.js index 1e48e51bded69..55aecee1deef3 100644 --- a/webpack.modules.js +++ b/webpack.modules.js @@ -64,7 +64,7 @@ module.exports = { additionalScripts: path.join(__dirname, 'apps/files_sharing/src', 'additionalScripts.js'), collaboration: path.join(__dirname, 'apps/files_sharing/src', 'collaborationresourceshandler.js'), files_sharing_tab: path.join(__dirname, 'apps/files_sharing/src', 'files_sharing_tab.js'), - files_sharing: path.join(__dirname, 'apps/files_sharing/src', 'files_sharing.ts'), + init: path.join(__dirname, 'apps/files_sharing/src', 'init.ts'), main: path.join(__dirname, 'apps/files_sharing/src', 'main.ts'), 'personal-settings': path.join(__dirname, 'apps/files_sharing/src', 'personal-settings.js'), },