summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2023-09-20 00:12:20 +0200
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2023-09-20 13:58:31 +0200
commitfac5197486107559669b39c34fbd1330277e8847 (patch)
tree58f64409979c56941f2b74cf37172de4ebdba3cc /apps
parent6714e51b0ce25fe5d9223279a9484abd8c00f85e (diff)
downloadnextcloud-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.ts2
-rw-r--r--apps/files/src/components/FileEntry.vue5
-rw-r--r--apps/files/src/components/FilesListVirtual.vue4
-rw-r--r--apps/files_sharing/lib/Listener/LoadAdditionalListener.php2
-rw-r--r--apps/files_sharing/src/actions/sharingStatusAction.scss35
-rw-r--r--apps/files_sharing/src/actions/sharingStatusAction.ts117
-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()