diff --git a/.changeset/violet-frogs-cheer.md b/.changeset/violet-frogs-cheer.md new file mode 100644 index 00000000000..db48243c40e --- /dev/null +++ b/.changeset/violet-frogs-cheer.md @@ -0,0 +1,5 @@ +--- +'@rocket.chat/fuselage-ui-kit': patch +--- + +Handle invalid context on `VideoConferenceBlock` component diff --git a/packages/fuselage-ui-kit/package.json b/packages/fuselage-ui-kit/package.json index b5023a2c700..e0183c8f74f 100644 --- a/packages/fuselage-ui-kit/package.json +++ b/packages/fuselage-ui-kit/package.json @@ -31,8 +31,7 @@ ".:build:clean": "rimraf dist", ".:build:esm": "tsc -p tsconfig-esm.json", ".:build:cjs": "tsc -p tsconfig-cjs.json", - "eslint": "eslint --ext .js,.jsx,.ts,.tsx .", - "eslint:fix": "eslint --ext .js,.jsx,.ts,.tsx . --fix", + "lint": "eslint --ext .js,.jsx,.ts,.tsx .", "docs": "cross-env NODE_ENV=production build-storybook -o ../../static/fuselage-ui-kit", "storybook": "start-storybook -p 6006", "build-storybook": "cross-env NODE_ENV=production build-storybook", diff --git a/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx b/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx index e595d2706e7..41135e326c7 100644 --- a/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx +++ b/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/VideoConferenceBlock.tsx @@ -1,5 +1,5 @@ -import type * as UiKit from '@rocket.chat/ui-kit'; import { useTranslation, useUserId } from '@rocket.chat/ui-contexts'; +import type * as UiKit from '@rocket.chat/ui-kit'; import { VideoConfMessageSkeleton, VideoConfMessage, @@ -17,10 +17,10 @@ import { import type { MouseEventHandler, ReactElement } from 'react'; import { useContext, memo } from 'react'; +import { kitContext } from '../..'; import { useSurfaceType } from '../../contexts/SurfaceContext'; import type { BlockProps } from '../../utils/BlockProps'; import { useVideoConfDataStream } from './hooks/useVideoConfDataStream'; -import { kitContext } from '../..'; type VideoConferenceBlockProps = BlockProps; @@ -37,11 +37,11 @@ const VideoConferenceBlock = ({ const { action, viewId, rid } = useContext(kitContext); if (surfaceType !== 'message') { - return <>; + throw new Error('VideoConferenceBlock cannot be rendered outside message'); } - if (!callId || !rid) { - return <>; + if (!rid) { + throw new Error('VideoConferenceBlock cannot be rendered without rid'); } const result = useVideoConfDataStream({ rid, callId }); @@ -85,109 +85,110 @@ const VideoConferenceBlock = ({ ); }; - if (result.isSuccess) { - const { data } = result; - const isUserCaller = data.createdBy._id === userId; - - if ('endedAt' in data) { - return ( - - - - - {t('Call_ended')} - - - - - - - {data.type === 'direct' && ( - <> - - {isUserCaller ? t('Call_again') : t('Call_back')} - - - {t('Call_was_not_answered')} - - - )} - {data.type !== 'direct' && - (data.users.length ? ( - <> - - - {data.users.length > MAX_USERS - ? t('__usersCount__member_joined', { - usersCount: data.users.length - MAX_USERS, - }) - : t('joined')} - - - ) : ( - - {t('Call_was_not_answered')} - - ))} - - - ); - } - - if (data.type === 'direct' && data.status === 0) { - return ( - - - - - {t('Calling')} - - - - - - - - {t('Waiting_for_answer')} - - - - ); - } + if (result.isLoading || result.isError) { + // TODO: error handling + return ; + } + const { data } = result; + const isUserCaller = data.createdBy._id === userId; + + if ('endedAt' in data) { return ( - - {t('Call_ongoing')} + + {t('Call_ended')} - - {t('Join')} - - {Boolean(data.users.length) && ( + {data.type === 'direct' && ( <> - + + {isUserCaller ? t('Call_again') : t('Call_back')} + - {data.users.length > MAX_USERS - ? t('__usersCount__member_joined', { - usersCount: data.users.length - MAX_USERS, - }) - : t('joined')} + {t('Call_was_not_answered')} )} + {data.type !== 'direct' && + (data.users.length ? ( + <> + + + {data.users.length > MAX_USERS + ? t('__usersCount__member_joined', { + usersCount: data.users.length - MAX_USERS, + }) + : t('joined')} + + + ) : ( + + {t('Call_was_not_answered')} + + ))} + + + ); + } + + if (data.type === 'direct' && data.status === 0) { + return ( + + + + + {t('Calling')} + + + + + + + + {t('Waiting_for_answer')} + ); } - return ; + return ( + + + + + {t('Call_ongoing')} + + + + + + + + {t('Join')} + + {Boolean(data.users.length) && ( + <> + + + {data.users.length > MAX_USERS + ? t('__usersCount__member_joined', { + usersCount: data.users.length - MAX_USERS, + }) + : t('joined')} + + + )} + + + ); }; export default memo(VideoConferenceBlock); diff --git a/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/hooks/useVideoConfData.ts b/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/hooks/useVideoConfData.ts index 23b67327bba..cd520613fbb 100644 --- a/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/hooks/useVideoConfData.ts +++ b/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/hooks/useVideoConfData.ts @@ -1,5 +1,5 @@ -import { useQuery } from '@tanstack/react-query'; import { useEndpoint } from '@rocket.chat/ui-contexts'; +import { useQuery } from '@tanstack/react-query'; export const useVideoConfData = ({ callId }: { callId: string }) => { const getVideoConfInfo = useEndpoint('GET', '/v1/video-conference.info'); diff --git a/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/hooks/useVideoConfDataStream.ts b/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/hooks/useVideoConfDataStream.ts index 116d8058f05..bed07f955a9 100644 --- a/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/hooks/useVideoConfDataStream.ts +++ b/packages/fuselage-ui-kit/src/blocks/VideoConferenceBlock/hooks/useVideoConfDataStream.ts @@ -1,6 +1,7 @@ +import type { IRoom } from '@rocket.chat/core-typings'; import { useSingleStream } from '@rocket.chat/ui-contexts'; -import { useEffect } from 'react'; import { useQueryClient } from '@tanstack/react-query'; +import { useEffect } from 'react'; import { useVideoConfData } from './useVideoConfData'; @@ -8,7 +9,7 @@ export const useVideoConfDataStream = ({ rid, callId, }: { - rid: string; + rid: IRoom['_id']; callId: string; }) => { const queryClient = useQueryClient(); @@ -22,7 +23,7 @@ export const useVideoConfDataStream = ({ id === callId && queryClient.invalidateQueries(['video-conference', callId]) ); - }, [rid, callId]); + }, [rid, callId, subscribeNotifyRoom, queryClient]); return useVideoConfData({ callId }); }; diff --git a/packages/fuselage-ui-kit/src/elements/MarkdownTextElement.tsx b/packages/fuselage-ui-kit/src/elements/MarkdownTextElement.tsx index b4d516bc8c7..4105398d3ff 100644 --- a/packages/fuselage-ui-kit/src/elements/MarkdownTextElement.tsx +++ b/packages/fuselage-ui-kit/src/elements/MarkdownTextElement.tsx @@ -1,6 +1,6 @@ -import { useTranslation } from '@rocket.chat/ui-contexts'; -import { parse } from '@rocket.chat/message-parser'; import { Markup } from '@rocket.chat/gazzodown'; +import { parse } from '@rocket.chat/message-parser'; +import { useTranslation } from '@rocket.chat/ui-contexts'; import type { TextObject } from '@rocket.chat/ui-kit'; import { useUiKitContext } from '../contexts/kitContext'; diff --git a/packages/fuselage-ui-kit/src/elements/PlainTextElement.tsx b/packages/fuselage-ui-kit/src/elements/PlainTextElement.tsx index 3178caedd26..59b98e49273 100644 --- a/packages/fuselage-ui-kit/src/elements/PlainTextElement.tsx +++ b/packages/fuselage-ui-kit/src/elements/PlainTextElement.tsx @@ -1,6 +1,5 @@ -import type { TextObject } from '@rocket.chat/ui-kit'; -import { Fragment } from 'react'; import { useTranslation } from '@rocket.chat/ui-contexts'; +import type { TextObject } from '@rocket.chat/ui-kit'; import { useUiKitContext } from '../contexts/kitContext'; @@ -14,12 +13,10 @@ const PlainTextElement = ({ textObject }: { textObject: TextObject }) => { const { i18n } = textObject; if (i18n) { - return ( - {t(`apps-${appId}-${i18n.key}`, { ...i18n.args })} - ); + return <>{t(`apps-${appId}-${i18n.key}`, { ...i18n.args })}; } - return {textObject.text}; + return <>{textObject.text}; }; export default PlainTextElement; diff --git a/packages/fuselage-ui-kit/src/stories/Message.stories.tsx b/packages/fuselage-ui-kit/src/stories/Message.stories.tsx index 537110a5f63..c37f43049a9 100644 --- a/packages/fuselage-ui-kit/src/stories/Message.stories.tsx +++ b/packages/fuselage-ui-kit/src/stories/Message.stories.tsx @@ -35,7 +35,7 @@ const createStory = (blocks: readonly UiKit.LayoutBlock[]) => { 6hY+0yM88TzeNZY4luYwpVYyduOfrvhPTnr0pXSX9y5mCsyJMdyxxvwq599em+taItqCSNc90ChvZRUruUcT0JiO18Elpk7t8v41LWzacxkB SuvjQ/FFJayjDWrCTepAQ2vUH0oo/Jk3ovpwJJeVCP5CN+lFFaaMqy+nAyuChvrTI2kN9JAsi2ZOy4IBHMnkSCP+iqBexSWdxLazoUljJVlP UH2oorkV10pRc7b1zXb/hZOzuJvM86QWEXeELxOzHSIPcmiiiunVlF2RNTpRkrs//Z' - size={'x36'} + size='x36' /> diff --git a/packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx b/packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx index ae4365c2ddd..1adaea6089e 100644 --- a/packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx +++ b/packages/fuselage-ui-kit/src/surfaces/FuselageSurfaceRenderer.tsx @@ -2,6 +2,7 @@ import * as UiKit from '@rocket.chat/ui-kit'; import type { ReactElement } from 'react'; import ActionsBlock from '../blocks/ActionsBlock'; +import CalloutBlock from '../blocks/CalloutBlock'; import ContextBlock from '../blocks/ContextBlock'; import DividerBlock from '../blocks/DividerBlock'; import ImageBlock from '../blocks/ImageBlock'; @@ -9,20 +10,19 @@ import InputBlock from '../blocks/InputBlock'; import PreviewBlock from '../blocks/PreviewBlock'; import SectionBlock from '../blocks/SectionBlock'; import ButtonElement from '../elements/ButtonElement'; +import CheckboxElement from '../elements/CheckboxElement'; import DatePickerElement from '../elements/DatePickerElement'; import ImageElement from '../elements/ImageElement'; import LinearScaleElement from '../elements/LinearScaleElement'; +import MarkdownTextElement from '../elements/MarkdownTextElement'; import MultiStaticSelectElement from '../elements/MultiStaticSelectElement'; import OverflowElement from '../elements/OverflowElement'; +import PlainTextElement from '../elements/PlainTextElement'; import PlainTextInputElement from '../elements/PlainTextInputElement'; -import StaticSelectElement from '../elements/StaticSelectElement'; -import ToggleSwitchElement from '../elements/ToggleSwitchElement'; import RadioButtonElement from '../elements/RadioButtonElement'; -import CheckboxElement from '../elements/CheckboxElement'; -import CalloutBlock from '../blocks/CalloutBlock'; +import StaticSelectElement from '../elements/StaticSelectElement'; import TimePickerElement from '../elements/TimePickerElement'; -import MarkdownTextElement from '../elements/MarkdownTextElement'; -import PlainTextElement from '../elements/PlainTextElement'; +import ToggleSwitchElement from '../elements/ToggleSwitchElement'; export type FuselageSurfaceRendererProps = ConstructorParameters< typeof UiKit.SurfaceRenderer diff --git a/packages/fuselage-ui-kit/src/surfaces/index.ts b/packages/fuselage-ui-kit/src/surfaces/index.ts index 489fe921ddb..be873f6b464 100644 --- a/packages/fuselage-ui-kit/src/surfaces/index.ts +++ b/packages/fuselage-ui-kit/src/surfaces/index.ts @@ -1,12 +1,12 @@ import BannerSurface from './BannerSurface'; +import ContextualBarSurface from './ContextualBarSurface'; +import { FuselageContextualBarSurfaceRenderer } from './FuselageContextualBarRenderer'; +import { FuselageModalSurfaceRenderer } from './FuselageModalSurfaceRenderer'; import { FuselageSurfaceRenderer } from './FuselageSurfaceRenderer'; import MessageSurface from './MessageSurface'; +import { FuselageMessageSurfaceRenderer } from './MessageSurfaceRenderer'; import ModalSurface from './ModalSurface'; import { createSurfaceRenderer } from './createSurfaceRenderer'; -import { FuselageMessageSurfaceRenderer } from './MessageSurfaceRenderer'; -import { FuselageModalSurfaceRenderer } from './FuselageModalSurfaceRenderer'; -import { FuselageContextualBarSurfaceRenderer } from './FuselageContextualBarRenderer'; -import ContextualBarSurface from './ContextualBarSurface'; // export const attachmentParser = new FuselageSurfaceRenderer(); export const bannerParser = new FuselageSurfaceRenderer();