Skip to content

Commit 7f3c7a8

Browse files
committed
refactor(files_sharing): migrate to new Files Sidebar API
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 4c7e643 commit 7f3c7a8

4 files changed

Lines changed: 80 additions & 59 deletions

File tree

apps/files_sharing/src/files_sharing_tab.js

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -5,61 +5,54 @@
55

66
import ShareVariant from '@mdi/svg/svg/share-variant.svg?raw'
77
import { getCSPNonce } from '@nextcloud/auth'
8+
import { registerSidebarTab } from '@nextcloud/files'
89
import { n, t } from '@nextcloud/l10n'
10+
import wrap from '@vue/web-component-wrapper'
911
import Vue from 'vue'
12+
import FilesSidebarTab from './views/FilesSidebarTab.vue'
1013
import ExternalShareActions from './services/ExternalShareActions.js'
1114
import ShareSearch from './services/ShareSearch.js'
1215
import TabSections from './services/TabSections.js'
1316

1417
__webpack_nonce__ = getCSPNonce()
1518

1619
// Init Sharing Tab Service
17-
if (!window.OCA.Sharing) {
18-
window.OCA.Sharing = {}
19-
}
20+
window.OCA.Sharing ??= {}
2021
Object.assign(window.OCA.Sharing, { ShareSearch: new ShareSearch() })
2122
Object.assign(window.OCA.Sharing, { ExternalShareActions: new ExternalShareActions() })
2223
Object.assign(window.OCA.Sharing, { ShareTabSections: new TabSections() })
2324

2425
Vue.prototype.t = t
2526
Vue.prototype.n = n
2627

27-
// Init Sharing tab component
28-
let TabInstance = null
29-
30-
window.addEventListener('DOMContentLoaded', function() {
31-
if (OCA.Files && OCA.Files.Sidebar) {
32-
OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({
33-
id: 'sharing',
34-
name: t('files_sharing', 'Sharing'),
35-
iconSvg: ShareVariant,
36-
37-
async mount(el, fileInfo, context) {
38-
const SharingTab = (await import('./views/SharingTab.vue')).default
39-
const View = Vue.extend(SharingTab)
40-
41-
if (TabInstance) {
42-
TabInstance.$destroy()
43-
}
44-
TabInstance = new View({
45-
// Better integration with vue parent component
46-
parent: context,
47-
})
48-
// Only mount after we have all the info we need
49-
await TabInstance.update(fileInfo)
50-
TabInstance.$mount(el)
51-
},
52-
53-
update(fileInfo) {
54-
TabInstance.update(fileInfo)
55-
},
56-
57-
destroy() {
58-
if (TabInstance) {
59-
TabInstance.$destroy()
60-
TabInstance = null
61-
}
62-
},
63-
}))
64-
}
28+
const tagName = 'files_sharing-sidebar-tab'
29+
30+
registerSidebarTab({
31+
id: 'sharing',
32+
displayName: t('files_sharing', 'Sharing'),
33+
iconSvgInline: ShareVariant,
34+
order: 10,
35+
tagName,
36+
enabled() {
37+
if (!window.customElements.get(tagName)) {
38+
setupSidebarTab()
39+
}
40+
return true
41+
},
6542
})
43+
44+
/**
45+
* Setup the sidebar tab as a web component
46+
*/
47+
function setupSidebarTab() {
48+
const webComponent = wrap(Vue, FilesSidebarTab)
49+
// In Vue 2, wrap doesn't support diseabling shadow. Disable with a hack
50+
Object.defineProperty(webComponent.prototype, 'attachShadow', {
51+
value() { return this },
52+
})
53+
Object.defineProperty(webComponent.prototype, 'shadowRoot', {
54+
get() { return this },
55+
})
56+
57+
window.customElements.define(tagName, webComponent)
58+
}

apps/files/src/services/FileInfo.ts renamed to apps/files_sharing/src/services/FileInfo.ts

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
1-
/**
1+
/*!
22
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
/* eslint-disable jsdoc/require-jsdoc */
7-
8-
import type { Attribute, Node } from '@nextcloud/files'
6+
import type { Attribute, INode } from '@nextcloud/files'
97

108
interface RawLegacyFileInfo {
119
id: number
@@ -30,11 +28,16 @@ export type LegacyFileInfo = RawLegacyFileInfo & {
3028
get: (key: keyof RawLegacyFileInfo) => unknown
3129
isDirectory: () => boolean
3230
canEdit: () => boolean
33-
node: Node
31+
node: INode
3432
canDownload: () => boolean
3533
}
3634

37-
export default function(node: Node): LegacyFileInfo {
35+
/**
36+
* Convert Node to legacy file info
37+
*
38+
* @param node - The Node to convert
39+
*/
40+
export default function(node: INode): LegacyFileInfo {
3841
const rawFileInfo: RawLegacyFileInfo = {
3942
id: node.fileid!,
4043
path: node.dirname,
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<script setup lang="ts">
2+
import type { IFolder, INode, IView } from '@nextcloud/files'
3+
4+
import { computed } from 'vue'
5+
import SharingTab from './SharingTab.vue'
6+
import FileInfo from '../services/FileInfo.ts'
7+
8+
const props = defineProps<{
9+
node?: INode
10+
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
11+
folder?: IFolder
12+
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
13+
view?: IView
14+
}>()
15+
16+
const fileInfo = computed(() => props.node && FileInfo(props.node))
17+
</script>
18+
19+
<template>
20+
<SharingTab v-if="fileInfo" :file-info="fileInfo" />
21+
</template>

apps/files_sharing/src/views/SharingTab.vue

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,13 @@ export default {
230230
231231
mixins: [ShareDetails],
232232
233+
props: {
234+
fileInfo: {
235+
type: Object,
236+
required: true,
237+
},
238+
},
239+
233240
data() {
234241
return {
235242
config: new Config(),
@@ -238,8 +245,6 @@ export default {
238245
expirationInterval: null,
239246
loading: true,
240247
241-
fileInfo: null,
242-
243248
// reshare Share object
244249
reshare: null,
245250
sharedWithMe: {},
@@ -328,18 +333,17 @@ export default {
328333
},
329334
},
330335
331-
methods: {
332-
/**
333-
* Update current fileInfo and fetch new data
334-
*
335-
* @param {object} fileInfo the current file FileInfo
336-
*/
337-
async update(fileInfo) {
338-
this.fileInfo = fileInfo
339-
this.resetState()
340-
this.getShares()
336+
watch: {
337+
fileInfo: {
338+
immediate: true,
339+
handler() {
340+
this.resetState()
341+
this.getShares()
342+
},
341343
},
344+
},
342345
346+
methods: {
343347
/**
344348
* Get the existing shares infos
345349
*/

0 commit comments

Comments
 (0)