Skip to content

Commit 1a55a34

Browse files
committed
feat(sidebar): Show node owner in metadata subline
Resolves: #46178 Signed-off-by: fenn-cs <fenn25.fn@gmail.com>
1 parent 1198f64 commit 1a55a34

2 files changed

Lines changed: 76 additions & 18 deletions

File tree

apps/files/src/services/WebdavClient.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
5-
import { davGetClient } from '@nextcloud/files'
5+
import { davGetClient, davGetDefaultPropfind, davResultToNode, davRootPath } from '@nextcloud/files'
6+
import type { FileStat, ResponseDataDetailed } from 'webdav'
7+
import type { Node } from '@nextcloud/files'
68

79
export const client = davGetClient()
10+
11+
export const fetchNode = async (node: Node): Promise<Node> => {
12+
const propfindPayload = davGetDefaultPropfind()
13+
const result = await client.stat(`${davRootPath}${node.path}`, {
14+
details: true,
15+
data: propfindPayload,
16+
}) as ResponseDataDetailed<FileStat>
17+
return davResultToNode(result.data)
18+
}

apps/files/src/views/Sidebar.vue

Lines changed: 64 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,20 @@
1717
@closing="handleClosing"
1818
@closed="handleClosed">
1919
<template v-if="fileInfo" #subname>
20-
<NcIconSvgWrapper v-if="fileInfo.isFavourited"
21-
:path="mdiStar"
22-
:name="t('files', 'Favorite')"
23-
inline />
24-
{{ size }}
25-
<NcDateTime :timestamp="fileInfo.mtime" />
20+
<div class="sidebar__subname">
21+
<NcIconSvgWrapper v-if="fileInfo.isFavourited"
22+
:path="mdiStar"
23+
:name="t('files', 'Favorite')"
24+
inline />
25+
<span>{{ size }}</span>
26+
<span class="sidebar__subname-separator">.</span>
27+
<NcDateTime :timestamp="fileInfo.mtime" />
28+
<span class="sidebar__subname-separator">.</span>
29+
<span>{{ t('files', 'Owned by') }}</span>
30+
<NcUserBubble :user="ownerId"
31+
:display-name="nodeOwnerLabel" />
32+
</div>
2633
</template>
27-
2834
<!-- TODO: create a standard to allow multiple elements here? -->
2935
<template v-if="fileInfo" #description>
3036
<div class="sidebar__description">
@@ -95,6 +101,7 @@ import { encodePath } from '@nextcloud/paths'
95101
import { generateRemoteUrl, generateUrl } from '@nextcloud/router'
96102
import { ShareType } from '@nextcloud/sharing'
97103
import { mdiStar, mdiStarOutline } from '@mdi/js'
104+
import { fetchNode } from '../services/WebdavClient.ts'
98105
import axios from '@nextcloud/axios'
99106
import $ from 'jquery'
100107
@@ -103,6 +110,7 @@ import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
103110
import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js'
104111
import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
105112
import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
113+
import NcUserBubble from '@nextcloud/vue/dist/Components/NcUserBubble.js'
106114
107115
import FileInfo from '../services/FileInfo.js'
108116
import LegacyView from '../components/LegacyView.vue'
@@ -122,15 +130,12 @@ export default {
122130
NcIconSvgWrapper,
123131
SidebarTab,
124132
SystemTags,
133+
NcUserBubble,
125134
},
126135
127136
setup() {
128-
const currentUser = getCurrentUser()
129-
130137
// Non reactive properties
131138
return {
132-
currentUser,
133-
134139
mdiStar,
135140
mdiStarOutline,
136141
}
@@ -139,12 +144,14 @@ export default {
139144
data() {
140145
return {
141146
// reactive state
147+
currentUser: getCurrentUser(),
142148
Sidebar: OCA.Files.Sidebar.state,
143149
showTags: false,
144150
showTagsDefault: true,
145151
error: null,
146152
loading: true,
147153
fileInfo: null,
154+
node: null,
148155
isFullScreen: false,
149156
hasLowHeight: false,
150157
}
@@ -287,6 +294,25 @@ export default {
287294
isSystemTagsEnabled() {
288295
return getCapabilities()?.systemtags?.enabled === true
289296
},
297+
ownerId() {
298+
return this.node?.attributes?.['owner-id'] ?? this.currentUser.uid
299+
},
300+
currentUserIsOwner() {
301+
return this.ownerId === this.currentUser.uid
302+
},
303+
nodeOwnerLabel() {
304+
if (this.currentUserIsOwner) {
305+
return t('files', 'you')
306+
}
307+
const ownerDisplayName = this.node?.attributes?.['owner-display-name']
308+
return ownerDisplayName
309+
},
310+
sharedMultipleTimes() {
311+
if (Array.isArray(node.attributes?.['share-types']) && node.attributes?.['share-types'].length > 1) {
312+
return t('files', 'Shared multiple times with different people')
313+
}
314+
return null
315+
},
290316
},
291317
created() {
292318
subscribe('files:node:deleted', this.onNodeDeleted)
@@ -298,7 +324,6 @@ export default {
298324
unsubscribe('file:node:deleted', this.onNodeDeleted)
299325
window.removeEventListener('resize', this.handleWindowResize)
300326
},
301-
302327
methods: {
303328
/**
304329
* Can this tab be displayed ?
@@ -460,6 +485,7 @@ export default {
460485
this.fileInfo = await FileInfo(this.davPath)
461486
// adding this as fallback because other apps expect it
462487
this.fileInfo.dir = this.file.split('/').slice(0, -1).join('/')
488+
this.node = await fetchNode({ path: (this.fileInfo.path + '/' + this.fileInfo.name).replace('//', '/') })
463489
464490
// DEPRECATED legacy views
465491
// TODO: remove
@@ -549,6 +575,12 @@ export default {
549575
handleWindowResize() {
550576
this.hasLowHeight = document.documentElement.clientHeight < 1024
551577
},
578+
sharedMultipleTimes() {
579+
// Mixed share types
580+
if (Array.isArray(this.node.attributes?.['share-types']) && this.node.attributes?.['share-types'].length > 1) {
581+
return t('files', 'Shared multiple times with different people')
582+
}
583+
},
552584
},
553585
}
554586
</script>
@@ -589,10 +621,25 @@ export default {
589621
}
590622
}
591623
592-
.sidebar__description {
593-
display: flex;
594-
flex-direction: column;
595-
width: 100%;
596-
gap: 8px 0;
624+
.sidebar__subname {
625+
display: flex;
626+
align-items: center;
627+
gap: 0 8px;
628+
629+
&-separator {
630+
display: inline-block;
631+
font-weight: bold !important;
632+
}
633+
634+
.user-bubble__wrapper {
635+
display: inline-flex;
636+
}
597637
}
638+
639+
.sidebar__description {
640+
display: flex;
641+
flex-direction: column;
642+
width: 100%;
643+
gap: 8px 0;
644+
}
598645
</style>

0 commit comments

Comments
 (0)