diff --git a/packages/web-client/src/sse.ts b/packages/web-client/src/sse.ts index 8142dd23f8d..6a25b66078f 100644 --- a/packages/web-client/src/sse.ts +++ b/packages/web-client/src/sse.ts @@ -3,7 +3,9 @@ import { fetchEventSource, FetchEventSourceInit } from '@microsoft/fetch-event-s export enum MESSAGE_TYPE { NOTIFICATION = 'userlog-notification', POSTPROCESSING_FINISHED = 'postprocessing-finished', - ITEM_RENAMED = 'item-renamed' + ITEM_RENAMED = 'item-renamed', + FILE_LOCKED = 'file-locked', + FILE_UNLOCKED = 'file-unlocked' } export class RetriableError extends Error { diff --git a/packages/web-runtime/src/container/bootstrap.ts b/packages/web-runtime/src/container/bootstrap.ts index 857c2b34205..a082ce3c52e 100644 --- a/packages/web-runtime/src/container/bootstrap.ts +++ b/packages/web-runtime/src/container/bootstrap.ts @@ -55,7 +55,7 @@ import { RawConfigSchema, SentryConfig } from '@ownclouders/web-pkg/src/composables/piniaStores/config/types' -import { onSSEItemRenamedEvent, onSSEProcessingFinishedEvent } from './sse' +import { onSSEFileLockingEvent, onSSEItemRenamedEvent, onSSEProcessingFinishedEvent } from './sse' const getEmbedConfigFromQuery = ( doesEmbedEnabledOptionExists: boolean @@ -667,6 +667,7 @@ export const registerSSEEventListeners = ({ clientService.sseAuthenticated.addEventListener(MESSAGE_TYPE.ITEM_RENAMED, (msg) => onSSEItemRenamedEvent({ + topic: MESSAGE_TYPE.ITEM_RENAMED, resourcesStore, spacesStore, msg, @@ -677,6 +678,7 @@ export const registerSSEEventListeners = ({ clientService.sseAuthenticated.addEventListener(MESSAGE_TYPE.POSTPROCESSING_FINISHED, (msg) => onSSEProcessingFinishedEvent({ + topic: MESSAGE_TYPE.POSTPROCESSING_FINISHED, resourcesStore, spacesStore, msg, @@ -685,6 +687,26 @@ export const registerSSEEventListeners = ({ resourceQueue }) ) + + clientService.sseAuthenticated.addEventListener(MESSAGE_TYPE.FILE_LOCKED, (msg) => + onSSEFileLockingEvent({ + topic: MESSAGE_TYPE.FILE_LOCKED, + resourcesStore, + spacesStore, + msg, + clientService + }) + ) + + clientService.sseAuthenticated.addEventListener(MESSAGE_TYPE.FILE_UNLOCKED, (msg) => + onSSEFileLockingEvent({ + topic: MESSAGE_TYPE.FILE_UNLOCKED, + resourcesStore, + spacesStore, + msg, + clientService + }) + ) } export const setViewOptions = ({ resourcesStore }: { resourcesStore: ResourcesStore }) => { diff --git a/packages/web-runtime/src/container/sse.ts b/packages/web-runtime/src/container/sse.ts index cd324d4389c..808e9eee33d 100644 --- a/packages/web-runtime/src/container/sse.ts +++ b/packages/web-runtime/src/container/sse.ts @@ -1,6 +1,7 @@ import { ClientService, createFileRouteOptions, + getIndicators, ImageDimension, PreviewService, ResourcesStore, @@ -23,10 +24,10 @@ type SSEMessageData = { const itemInCurrentFolder = ({ resourcesStore, - sseData + parentFolderId }: { resourcesStore: ResourcesStore - sseData: SSEMessageData + parentFolderId: string }) => { const currentFolder = resourcesStore.currentFolder if (!currentFolder) { @@ -35,11 +36,11 @@ const itemInCurrentFolder = ({ if (!extractNodeId(currentFolder.id)) { // if we don't have a nodeId here, we have a space (root) as current folder and can only check against the storageId - if (currentFolder.id !== extractStorageId(sseData.parentitemid)) { + if (currentFolder.id !== extractStorageId(parentFolderId)) { return false } } else { - if (currentFolder.id !== sseData.parentitemid) { + if (currentFolder.id !== parentFolderId) { return false } } @@ -48,12 +49,14 @@ const itemInCurrentFolder = ({ } export const onSSEItemRenamedEvent = async ({ + topic, resourcesStore, spacesStore, msg, clientService, router }: { + topic: string resourcesStore: ResourcesStore spacesStore: SpacesStore msg: MessageEvent @@ -62,18 +65,11 @@ export const onSSEItemRenamedEvent = async ({ }) => { try { const sseData = fileReadyEventSchema.parse(JSON.parse(msg.data)) - const currentFolder = resourcesStore.currentFolder const resourceIsCurrentFolder = currentFolder.id === sseData.itemid - - if (!resourceIsCurrentFolder && !itemInCurrentFolder({ resourcesStore, sseData })) { - return false - } - const resource = resourceIsCurrentFolder ? currentFolder : resourcesStore.resources.find((f) => f.id === sseData.itemid) - const space = spacesStore.spaces.find((s) => s.id === resource.storageId) if (!resource || !space) { @@ -94,22 +90,54 @@ export const onSSEItemRenamedEvent = async ({ ) } - resourcesStore.updateResourceField({ - id: sseData.itemid, - field: 'name', - value: updatedResource.name + resourcesStore.upsertResource(updatedResource) + } catch (e) { + console.error(`Unable to parse sse event ${topic} data`, e) + } +} + +export const onSSEFileLockingEvent = async ({ + topic, + resourcesStore, + spacesStore, + msg, + clientService +}: { + topic: string + resourcesStore: ResourcesStore + spacesStore: SpacesStore + msg: MessageEvent + clientService: ClientService +}) => { + try { + const sseData = fileReadyEventSchema.parse(JSON.parse(msg.data)) + const resource = resourcesStore.resources.find((f) => f.id === sseData.itemid) + const space = spacesStore.spaces.find((s) => s.id === resource.storageId) + + if (!resource || !space) { + return + } + + const updatedResource = await clientService.webdav.getFileInfo(space, { + fileId: sseData.itemid }) + resourcesStore.upsertResource(updatedResource) resourcesStore.updateResourceField({ - id: sseData.itemid, - field: 'path', - value: updatedResource.path + id: updatedResource.id, + field: 'indicators', + value: getIndicators({ + resource: updatedResource, + ancestorMetaData: resourcesStore.ancestorMetaData + }) }) } catch (e) { - console.error('Unable to parse sse event item renamed data', e) + console.error(`Unable to parse sse event ${topic} data`, e) } } + export const onSSEProcessingFinishedEvent = async ({ + topic, resourcesStore, spacesStore, msg, @@ -119,6 +147,7 @@ export const onSSEProcessingFinishedEvent = async ({ resourceQueue, previewService }: { + topic: string resourcesStore: ResourcesStore spacesStore: SpacesStore msg: MessageEvent @@ -129,7 +158,7 @@ export const onSSEProcessingFinishedEvent = async ({ try { const sseData = fileReadyEventSchema.parse(JSON.parse(msg.data)) - if (!itemInCurrentFolder({ resourcesStore, sseData })) { + if (!itemInCurrentFolder({ resourcesStore, parentFolderId: sseData.parentitemid })) { return false } @@ -171,6 +200,6 @@ export const onSSEProcessingFinishedEvent = async ({ // }) } } catch (e) { - console.error('Unable to parse sse event postprocessing-finished data', e) + console.error(`Unable to parse sse event ${topic} data`, e) } }