Skip to content

Commit effc659

Browse files
committed
fix(files): make sure nested changes are propagated to sidebar tabs
If an object is passed from one app to another app through a web component, then only reference changes (new objects) are marked as reactive changes in the receiving app. In this case e.g. `mtime` changes were not properly propagated, so to fix this we explicitly clone the objects before passing to the sidebar tab. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent e01a54c commit effc659

3 files changed

Lines changed: 38 additions & 23 deletions

File tree

apps/files/src/components/FilesSidebar/FilesSidebarTab.vue

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@
44
-->
55

66
<script setup lang="ts">
7-
import type { ISidebarTab } from '@nextcloud/files'
7+
import type { ISidebarContext, ISidebarTab } from '@nextcloud/files'
88
99
import { NcIconSvgWrapper, NcLoadingIcon } from '@nextcloud/vue'
10-
import { ref, toRef, watch } from 'vue'
10+
import { computed, ref, toRef, watch } from 'vue'
1111
import NcAppSidebarTab from '@nextcloud/vue/components/NcAppSidebarTab'
1212
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
13-
import { useActiveStore } from '../../store/active.ts'
1413
import { useSidebarStore } from '../../store/sidebar.ts'
1514
import { logger } from '../../utils/logger.ts'
1615
@@ -27,7 +26,17 @@ const props = defineProps<{
2726
}>()
2827
2928
const sidebar = useSidebarStore()
30-
const activeStore = useActiveStore()
29+
30+
const context = computed(() => {
31+
if (!sidebar.currentContext) {
32+
return undefined
33+
}
34+
return {
35+
folder: sidebar.currentContext.folder.clone(),
36+
node: sidebar.currentContext.node.clone(),
37+
view: sidebar.currentContext.view,
38+
}
39+
})
3140
3241
const loading = ref(true)
3342
watch(toRef(props, 'active'), async (active) => {
@@ -65,7 +74,7 @@ const initializedTabs = new Set<string>()
6574
<template #icon>
6675
<NcIconSvgWrapper :svg="tab.iconSvgInline" />
6776
</template>
68-
<NcEmptyContent v-if="loading">
77+
<NcEmptyContent v-if="loading || !context">
6978
<template #icon>
7079
<NcLoadingIcon />
7180
</template>
@@ -75,8 +84,8 @@ const initializedTabs = new Set<string>()
7584
:is="tab.tagName"
7685
v-else
7786
:active.prop="active"
78-
:node.prop="sidebar.currentNode"
79-
:folder.prop="activeStore.activeFolder"
80-
:view.prop="activeStore.activeView" />
87+
:node.prop="context.node"
88+
:folder.prop="context.folder"
89+
:view.prop="context.view" />
8190
</NcAppSidebarTab>
8291
</template>

apps/files/src/store/files.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { defineStore } from 'pinia'
1111
import Vue, { ref } from 'vue'
1212
import { fetchNode } from '../services/WebdavClient.ts'
1313
import { logger } from '../utils/logger.ts'
14+
import { useActiveStore } from './active.ts'
1415
import { usePathsStore } from './paths.ts'
1516

1617
/**
@@ -124,6 +125,12 @@ export const useFilesStore = defineStore('files', () => {
124125
}, {} as FilesStore)
125126

126127
files.value = { ...files.value, ...newNodes }
128+
129+
// handle updating the active node
130+
const activeStore = useActiveStore()
131+
if (activeStore.activeNode && activeStore.activeNode.source in newNodes) {
132+
activeStore.activeNode = files.value[activeStore.activeNode.source]
133+
}
127134
}
128135

129136
/**
@@ -232,7 +239,8 @@ export const useFilesStore = defineStore('files', () => {
232239
}
233240

234241
// Otherwise, it means we receive an event for a node that is not in the store
235-
fetchNode(node.path).then((n) => updateNodes([n]))
242+
const newNode = await fetchNode(node.path)
243+
updateNodes([newNode])
236244
}
237245

238246
/**

apps/files_versions/src/views/FilesVersionsSidebarTab.vue

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ import { showError, showSuccess } from '@nextcloud/dialogs'
4848
import { emit } from '@nextcloud/event-bus'
4949
import { t } from '@nextcloud/l10n'
5050
import { useIsMobile } from '@nextcloud/vue/composables/useIsMobile'
51-
import { computed, ref, toRef, watch } from 'vue'
51+
import { watchDebounced } from '@vueuse/core'
52+
import { computed, ref } from 'vue'
5253
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
5354
import VersionEntry from '../components/VersionEntry.vue'
5455
import VersionLabelDialog from '../components/VersionLabelDialog.vue'
@@ -72,19 +73,6 @@ const loading = ref(false)
7273
const showVersionLabelForm = ref(false)
7374
const editedVersion = ref<Version | null>(null)
7475
75-
watch(toRef(() => props.node), async () => {
76-
if (!props.node) {
77-
return
78-
}
79-
80-
try {
81-
loading.value = true
82-
versions.value = await fetchVersions(props.node)
83-
} finally {
84-
loading.value = false
85-
}
86-
}, { immediate: true })
87-
8876
const currentVersionMtime = computed(() => props.node?.mtime?.getTime() ?? 0)
8977
9078
/**
@@ -139,6 +127,16 @@ const canCompare = computed(() => {
139127
&& window.OCA.Viewer?.mimetypesCompare?.includes(props.node?.mime)
140128
})
141129
130+
// when either the current node to show or its mtime changes we need to refetch the versions
131+
watchDebounced([() => props.node.id, currentVersionMtime], async () => {
132+
try {
133+
loading.value = true
134+
versions.value = await fetchVersions(props.node)
135+
} finally {
136+
loading.value = false
137+
}
138+
}, { immediate: true, debounce: 600 })
139+
142140
/**
143141
* Handle restored event from Version.vue
144142
*

0 commit comments

Comments
 (0)