aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/src/views/Sidebar.vue
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/src/views/Sidebar.vue')
-rw-r--r--apps/files/src/views/Sidebar.vue147
1 files changed, 100 insertions, 47 deletions
diff --git a/apps/files/src/views/Sidebar.vue b/apps/files/src/views/Sidebar.vue
index 1facff4642d..40a16d42b42 100644
--- a/apps/files/src/views/Sidebar.vue
+++ b/apps/files/src/views/Sidebar.vue
@@ -17,12 +17,19 @@
@closing="handleClosing"
@closed="handleClosed">
<template v-if="fileInfo" #subname>
- <NcIconSvgWrapper v-if="fileInfo.isFavourited"
- :path="mdiStar"
- :name="t('files', 'Favorite')"
- inline />
- {{ size }}
- <NcDateTime :timestamp="fileInfo.mtime" />
+ <div class="sidebar__subname">
+ <NcIconSvgWrapper v-if="fileInfo.isFavourited"
+ :path="mdiStar"
+ :name="t('files', 'Favorite')"
+ inline />
+ <span>{{ size }}</span>
+ <span class="sidebar__subname-separator">•</span>
+ <NcDateTime :timestamp="fileInfo.mtime" />
+ <span class="sidebar__subname-separator">•</span>
+ <span>{{ t('files', 'Owner') }}</span>
+ <NcUserBubble :user="ownerId"
+ :display-name="nodeOwnerLabel" />
+ </div>
</template>
<!-- TODO: create a standard to allow multiple elements here? -->
@@ -30,8 +37,8 @@
<div class="sidebar__description">
<SystemTags v-if="isSystemTagsEnabled && showTagsDefault"
v-show="showTags"
- :file-id="fileInfo.id"
- @has-tags="value => showTags = value" />
+ :disabled="!fileInfo?.canEdit()"
+ :file-id="fileInfo.id" />
<LegacyView v-for="view in views"
:key="view.cid"
:component="view"
@@ -85,32 +92,35 @@
</template>
</NcAppSidebar>
</template>
-<script>
-import { getCurrentUser } from '@nextcloud/auth'
-import { getCapabilities } from '@nextcloud/capabilities'
-import { showError } from '@nextcloud/dialogs'
+<script lang="ts">
+import { davRemoteURL, davRootPath, File, Folder, formatFileSize } from '@nextcloud/files'
+import { defineComponent } from 'vue'
import { emit, subscribe, unsubscribe } from '@nextcloud/event-bus'
-import { File, Folder, formatFileSize } from '@nextcloud/files'
import { encodePath } from '@nextcloud/paths'
-import { generateRemoteUrl, generateUrl } from '@nextcloud/router'
-import { Type as ShareTypes } from '@nextcloud/sharing'
+import { fetchNode } from '../services/WebdavClient.ts'
+import { generateUrl } from '@nextcloud/router'
+import { getCapabilities } from '@nextcloud/capabilities'
+import { getCurrentUser } from '@nextcloud/auth'
import { mdiStar, mdiStarOutline } from '@mdi/js'
-import axios from '@nextcloud/axios'
+import { ShareType } from '@nextcloud/sharing'
+import { showError } from '@nextcloud/dialogs'
import $ from 'jquery'
+import axios from '@nextcloud/axios'
-import NcAppSidebar from '@nextcloud/vue/dist/Components/NcAppSidebar.js'
-import NcActionButton from '@nextcloud/vue/dist/Components/NcActionButton.js'
-import NcDateTime from '@nextcloud/vue/dist/Components/NcDateTime.js'
-import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'
-import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js'
+import NcAppSidebar from '@nextcloud/vue/components/NcAppSidebar'
+import NcActionButton from '@nextcloud/vue/components/NcActionButton'
+import NcDateTime from '@nextcloud/vue/components/NcDateTime'
+import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
+import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
+import NcUserBubble from '@nextcloud/vue/components/NcUserBubble'
import FileInfo from '../services/FileInfo.js'
import LegacyView from '../components/LegacyView.vue'
import SidebarTab from '../components/SidebarTab.vue'
import SystemTags from '../../../systemtags/src/components/SystemTags.vue'
-import logger from '../logger.js'
+import logger from '../logger.ts'
-export default {
+export default defineComponent({
name: 'Sidebar',
components: {
@@ -122,6 +132,7 @@ export default {
NcIconSvgWrapper,
SidebarTab,
SystemTags,
+ NcUserBubble,
},
setup() {
@@ -145,6 +156,7 @@ export default {
error: null,
loading: true,
fileInfo: null,
+ node: null,
isFullScreen: false,
hasLowHeight: false,
}
@@ -186,8 +198,7 @@ export default {
* @return {string}
*/
davPath() {
- const user = this.currentUser.uid
- return generateRemoteUrl(`dav/files/${user}${encodePath(this.file)}`)
+ return `${davRemoteURL}${davRootPath}${encodePath(this.file)}`
},
/**
@@ -234,8 +245,8 @@ export default {
},
compact: this.hasLowHeight || !this.fileInfo.hasPreview || this.isFullScreen,
loading: this.loading,
- name: this.fileInfo.name,
- title: this.fileInfo.name,
+ name: this.node?.displayname ?? this.fileInfo.name,
+ title: this.node?.displayname ?? this.fileInfo.name,
}
} else if (this.error) {
return {
@@ -287,6 +298,25 @@ export default {
isSystemTagsEnabled() {
return getCapabilities()?.systemtags?.enabled === true
},
+ ownerId() {
+ return this.node?.attributes?.['owner-id'] ?? this.currentUser.uid
+ },
+ currentUserIsOwner() {
+ return this.ownerId === this.currentUser.uid
+ },
+ nodeOwnerLabel() {
+ let ownerDisplayName = this.node?.attributes?.['owner-display-name']
+ if (this.currentUserIsOwner) {
+ ownerDisplayName = `${ownerDisplayName} (${t('files', 'You')})`
+ }
+ return ownerDisplayName
+ },
+ sharedMultipleTimes() {
+ if (Array.isArray(node.attributes?.['share-types']) && node.attributes?.['share-types'].length > 1) {
+ return t('files', 'Shared multiple times with different people')
+ }
+ return null
+ },
},
created() {
subscribe('files:node:deleted', this.onNodeDeleted)
@@ -345,8 +375,8 @@ export default {
} else if (fileInfo.mountType !== undefined && fileInfo.mountType !== '') {
return OC.MimeType.getIconUrl('dir-' + fileInfo.mountType)
} else if (fileInfo.shareTypes && (
- fileInfo.shareTypes.indexOf(ShareTypes.SHARE_TYPE_LINK) > -1
- || fileInfo.shareTypes.indexOf(ShareTypes.SHARE_TYPE_EMAIL) > -1)
+ fileInfo.shareTypes.indexOf(ShareType.Link) > -1
+ || fileInfo.shareTypes.indexOf(ShareType.Email) > -1)
) {
return OC.MimeType.getIconUrl('dir-public')
} else if (fileInfo.shareTypes && fileInfo.shareTypes.length > 0) {
@@ -374,10 +404,10 @@ export default {
},
/**
- * Toggle favourite state
+ * Toggle favorite state
* TODO: better implementation
*
- * @param {boolean} state favourited or not
+ * @param {boolean} state is favorite or not
*/
async toggleStarred(state) {
try {
@@ -400,17 +430,21 @@ export default {
*/
const isDir = this.fileInfo.type === 'dir'
const Node = isDir ? Folder : File
- emit(state ? 'files:favorites:added' : 'files:favorites:removed', new Node({
+ const node = new Node({
fileid: this.fileInfo.id,
- source: this.davPath,
- root: `/files/${getCurrentUser().uid}`,
+ source: `${davRemoteURL}${davRootPath}${this.file}`,
+ root: davRootPath,
mime: isDir ? undefined : this.fileInfo.mimetype,
- }))
+ attributes: {
+ favorite: 1,
+ },
+ })
+ emit(state ? 'files:favorites:added' : 'files:favorites:removed', node)
this.fileInfo.isFavourited = state
} catch (error) {
- showError(t('files', 'Unable to change the favourite state of the file'))
- logger.error('Unable to change favourite state', { error })
+ showError(t('files', 'Unable to change the favorite state of the file'))
+ logger.error('Unable to change favorite state', { error })
}
},
@@ -430,7 +464,10 @@ export default {
* Toggle the tags selector
*/
toggleTags() {
- this.showTagsDefault = this.showTags = !this.showTags
+ // toggle
+ this.showTags = !this.showTags
+ // save the new state
+ this.setShowTagsDefault(this.showTags)
},
/**
@@ -457,7 +494,8 @@ export default {
this.loading = true
try {
- this.fileInfo = await FileInfo(this.davPath)
+ this.node = await fetchNode(this.file)
+ this.fileInfo = FileInfo(this.node)
// adding this as fallback because other apps expect it
this.fileInfo.dir = this.file.split('/').slice(0, -1).join('/')
@@ -475,7 +513,7 @@ export default {
await this.$nextTick()
- if (focusTabAfterLoad) {
+ if (focusTabAfterLoad && this.$refs.sidebar) {
this.$refs.sidebar.focusActiveTabContent()
}
} catch (error) {
@@ -550,7 +588,7 @@ export default {
this.hasLowHeight = document.documentElement.clientHeight < 1024
},
},
-}
+})
</script>
<style lang="scss" scoped>
.app-sidebar {
@@ -581,7 +619,7 @@ export default {
}
.svg-icon {
- ::v-deep svg {
+ :deep(svg) {
width: 20px;
height: 20px;
fill: currentColor;
@@ -589,10 +627,25 @@ export default {
}
}
-.sidebar__description {
- display: flex;
- flex-direction: column;
- width: 100%;
- gap: 8px 0;
+.sidebar__subname {
+ display: flex;
+ align-items: center;
+ gap: 0 8px;
+
+ &-separator {
+ display: inline-block;
+ font-weight: bold !important;
+ }
+
+ .user-bubble__wrapper {
+ display: inline-flex;
+ }
}
+
+.sidebar__description {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ gap: 8px 0;
+ }
</style>