diff --git a/src/cloud/components/EventSource.tsx b/src/cloud/components/EventSource.tsx index 8ad4598fe3..e9a78d32e8 100644 --- a/src/cloud/components/EventSource.tsx +++ b/src/cloud/components/EventSource.tsx @@ -20,6 +20,7 @@ import { getUniqueFolderAndDocIdsFromResourcesIds } from '../lib/utils/patterns' import { getAccessToken, useElectron } from '../lib/stores/electron' import { useNotifications } from '../../design/lib/stores/notifications' import { useComments } from '../lib/stores/comments' +import { useBlocks } from '../lib/stores/blocks' interface EventSourceProps { teamId: string @@ -67,6 +68,7 @@ const EventSource = ({ teamId }: EventSourceProps) => { } = useGlobalData() const { commentsEventListener } = useComments() const { notificationsEventListener } = useNotifications() + const { blockEventListener } = useBlocks() const setupEventSource = useCallback( (url: string) => { @@ -452,6 +454,11 @@ const EventSource = ({ teamId }: EventSourceProps) => { case 'notificationViewed': notificationsEventListener(event) break + case 'blockCreated': + case 'blockDeleted': + case 'blockUpdated': + blockEventListener(event) + break } updateAppEventsMap([event.id, event]) } @@ -474,6 +481,7 @@ const EventSource = ({ teamId }: EventSourceProps) => { smartFolderDeleteHandler, updateAppEventsMap, notificationsEventListener, + blockEventListener, ]) return null diff --git a/src/cloud/interfaces/db/appEvents.ts b/src/cloud/interfaces/db/appEvents.ts index cc6dd42c39..c4e4486edf 100644 --- a/src/cloud/interfaces/db/appEvents.ts +++ b/src/cloud/interfaces/db/appEvents.ts @@ -35,6 +35,9 @@ export type SseEventType = | 'smartFolderDelete' | 'notificationCreated' | 'notificationViewed' + | 'blockCreated' + | 'blockUpdated' + | 'blockDeleted' export interface SerializableAppEventProps { id: string diff --git a/src/cloud/lib/stores/blocks/index.ts b/src/cloud/lib/stores/blocks/index.ts index 3cf5bad8fd..c598e7b25c 100644 --- a/src/cloud/lib/stores/blocks/index.ts +++ b/src/cloud/lib/stores/blocks/index.ts @@ -1,7 +1,8 @@ import { createStoreContext } from '../../utils/context' -import { useRef, useCallback } from 'react' +import { useRef, useCallback, useEffect } from 'react' import { Block, getBlockTree } from '../../../api/blocks' import { useToast } from '../../../../design/lib/stores/toast' +import { SerializedAppEvent } from '../../../interfaces/db/appEvents' type BlocksObserver = (blocks: Block) => void @@ -11,7 +12,7 @@ function useBlocksStore() { const treeObservers = useRef>>(new Map()) const getBlocks = useCallback( - async (rootBlock: string) => { + async (rootBlock: string, suppressError = false) => { try { const blocks = await getBlockTree(rootBlock) treeCache.current.set(rootBlock, blocks) @@ -21,7 +22,9 @@ function useBlocksStore() { } return true } catch (err) { - pushApiErrorMessage(err) + if (!suppressError) { + pushApiErrorMessage(err) + } return false } }, @@ -46,9 +49,26 @@ function useBlocksStore() { [getBlocks] ) + const getBlocksRef = useRef(getBlocks) + useEffect(() => { + getBlocksRef.current = getBlocks + }, [getBlocks]) + const blockEventListener = useCallback(async (event: SerializedAppEvent) => { + switch (event.type) { + case 'blockCreated': + case 'blockUpdated': + case 'blockDeleted': { + if (typeof event.data.rootBlockId === 'string') { + getBlocksRef.current(event.data.rootBlockId, true) + } + } + } + }, []) + return { observeDocBlocks, getBlocks, + blockEventListener, } }