diff options
author | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2023-09-20 00:12:20 +0200 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2023-09-20 13:58:31 +0200 |
commit | fac5197486107559669b39c34fbd1330277e8847 (patch) | |
tree | 58f64409979c56941f2b74cf37172de4ebdba3cc /apps | |
parent | 6714e51b0ce25fe5d9223279a9484abd8c00f85e (diff) | |
download | nextcloud-server-fac5197486107559669b39c34fbd1330277e8847.tar.gz nextcloud-server-fac5197486107559669b39c34fbd1330277e8847.zip |
feat(files): add files_sharing indicator
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
Diffstat (limited to 'apps')
-rw-r--r-- | apps/files/src/actions/deleteAction.ts | 2 | ||||
-rw-r--r-- | apps/files/src/components/FileEntry.vue | 5 | ||||
-rw-r--r-- | apps/files/src/components/FilesListVirtual.vue | 4 | ||||
-rw-r--r-- | apps/files_sharing/lib/Listener/LoadAdditionalListener.php | 2 | ||||
-rw-r--r-- | apps/files_sharing/src/actions/sharingStatusAction.scss | 35 | ||||
-rw-r--r-- | apps/files_sharing/src/actions/sharingStatusAction.ts | 117 | ||||
-rw-r--r-- | apps/files_sharing/src/init.ts (renamed from apps/files_sharing/src/files_sharing.ts) | 1 |
7 files changed, 163 insertions, 3 deletions
diff --git a/apps/files/src/actions/deleteAction.ts b/apps/files/src/actions/deleteAction.ts index 528a0faecab..04c139fe38e 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 81a61843db0..83b991dcd50 100644 --- a/apps/files/src/components/FileEntry.vue +++ b/apps/files/src/components/FileEntry.vue @@ -109,9 +109,11 @@ <!-- Render actions --> <CustomElementRender v-for="action in enabledRenderActions" :key="action.id" + :class="'files-list__row-action-' + action.id" :current-view="currentView" :render="action.renderInline" - :source="source" /> + :source="source" + class="files-list__row-action--inline" /> <!-- Menu actions --> <NcActions v-if="visible" @@ -119,6 +121,7 @@ :boundaries-element="getBoundariesElement()" :container="getBoundariesElement()" :disabled="source._loading" + :force-name="true" :force-menu="enabledInlineActions.length === 0 /* forceMenu only if no inline actions */" :inline="enabledInlineActions.length" :open.sync="openedMenu"> diff --git a/apps/files/src/components/FilesListVirtual.vue b/apps/files/src/components/FilesListVirtual.vue index ace8d87fc8c..cd41a179ce9 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 583cd575793..e2122cb6ee2 100644 --- a/apps/files_sharing/lib/Listener/LoadAdditionalListener.php +++ b/apps/files_sharing/lib/Listener/LoadAdditionalListener.php @@ -44,7 +44,7 @@ class LoadAdditionalListener implements IEventListener { $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 00000000000..fd37732d47c --- /dev/null +++ b/apps/files_sharing/src/actions/sharingStatusAction.scss @@ -0,0 +1,35 @@ +/** + * @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/>. + * + */ + // 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 00000000000..054d6617ac9 --- /dev/null +++ b/apps/files_sharing/src/actions/sharingStatusAction.ts @@ -0,0 +1,117 @@ +/** + * @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 { Node, View, registerFileAction, FileAction, Permission } 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 `<svg width="32" height="32" viewBox="0 0 32 32" + xmlns="http://www.w3.org/2000/svg" class="sharing-status__avatar"> + <image href="${avatarUrl}" height="32" width="32" /> + </svg>` +} + +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 + } + + const node = nodes[0] + const ownerId = node?.attributes?.['owner-id'] + if (ownerId && ownerId !== getCurrentUser()?.uid) { + return true + } + + return (node.permissions & Permission.SHARE) !== 0 + }, + + async exec(node: Node, view: View, dir: string) { + // You need read permissions to see the sidebar + if ((node.permissions & Permission.READ) !== 0) { + window.OCA?.Files?.Sidebar?.setActiveTab?.('sharing') + return sidebarAction.exec(node, view, dir) + } + return null + }, + + inline: () => true, + +}) + +registerFileAction(action) diff --git a/apps/files_sharing/src/files_sharing.ts b/apps/files_sharing/src/init.ts index 939cc91905d..734f888cb7d 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() |