@100mslive/roomkit-react 0.3.10-alpha.9 → 0.3.11-alpha.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{HLSView-UIAB54GS.js → HLSView-HJ44JWJK.js} +18 -3
- package/dist/HLSView-HJ44JWJK.js.map +7 -0
- package/dist/{HLSView-5TZVXD62.css → HLSView-IBWU4R7W.css} +16 -3
- package/dist/{HLSView-5TZVXD62.css.map → HLSView-IBWU4R7W.css.map} +3 -3
- package/dist/Prebuilt/common/constants.d.ts +0 -2
- package/dist/Prebuilt/common/hooks.d.ts +8 -1
- package/dist/Prebuilt/components/MoreSettings/CaptionContent.d.ts +5 -0
- package/dist/Prebuilt/components/MoreSettings/CaptionModal.d.ts +4 -0
- package/dist/Prebuilt/components/Polls/Voting/StandardVoting.d.ts +4 -2
- package/dist/Prebuilt/components/Polls/Voting/TimedVoting.d.ts +4 -2
- package/dist/Prebuilt/layouts/WaitingView.d.ts +6 -0
- package/dist/{chunk-GQGXO6NF.js → chunk-WDZ4KRYM.js} +2148 -1858
- package/dist/chunk-WDZ4KRYM.js.map +7 -0
- package/dist/index.cjs.css +15 -2
- package/dist/index.cjs.css.map +3 -3
- package/dist/index.cjs.js +2790 -2484
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.css +15 -2
- package/dist/index.css.map +3 -3
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +296 -118
- package/dist/meta.esbuild.json +318 -139
- package/package.json +7 -7
- package/src/Prebuilt/common/constants.ts +0 -2
- package/src/Prebuilt/common/hooks.ts +34 -1
- package/src/Prebuilt/common/utils.js +11 -11
- package/src/Prebuilt/components/AppData/AppData.tsx +2 -4
- package/src/Prebuilt/components/AppData/useUISettings.js +0 -3
- package/src/Prebuilt/components/Chat/Chat.tsx +26 -6
- package/src/Prebuilt/components/Chat/ChatFooter.tsx +18 -2
- package/src/Prebuilt/components/Chat/ChatStates.tsx +1 -1
- package/src/Prebuilt/components/Footer/ChatToggle.tsx +5 -1
- package/src/Prebuilt/components/Footer/ParticipantList.tsx +4 -2
- package/src/Prebuilt/components/Footer/PollsToggle.tsx +1 -1
- package/src/Prebuilt/components/MoreSettings/CaptionContent.tsx +132 -0
- package/src/Prebuilt/components/MoreSettings/CaptionModal.tsx +37 -0
- package/src/Prebuilt/components/MoreSettings/SplitComponents/DesktopOptions.tsx +40 -3
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +19 -19
- package/src/Prebuilt/components/Polls/CreatePollQuiz/PollsQuizMenu.tsx +2 -15
- package/src/Prebuilt/components/Polls/Voting/LeaderboardSummary.tsx +71 -66
- package/src/Prebuilt/components/Polls/Voting/QuestionCard.jsx +39 -40
- package/src/Prebuilt/components/Polls/Voting/StandardVoting.tsx +12 -6
- package/src/Prebuilt/components/Polls/Voting/TimedVoting.tsx +21 -10
- package/src/Prebuilt/components/Polls/Voting/Voting.tsx +44 -2
- package/src/Prebuilt/components/VideoLayouts/EqualProminence.tsx +13 -17
- package/src/Prebuilt/components/VideoLayouts/GridLayout.tsx +17 -0
- package/src/Prebuilt/layouts/HLSView.jsx +14 -11
- package/src/Prebuilt/layouts/VideoStreamingSection.tsx +43 -9
- package/src/Prebuilt/layouts/WaitingView.tsx +52 -0
- package/dist/HLSView-UIAB54GS.js.map +0 -7
- package/dist/chunk-GQGXO6NF.js.map +0 -7
- package/src/Prebuilt/layouts/NonPublisherView.jsx +0 -51
- package/src/Prebuilt/layouts/WaitingView.jsx +0 -51
    
        package/package.json
    CHANGED
    
    | @@ -10,7 +10,7 @@ | |
| 10 10 | 
             
                "prebuilt",
         | 
| 11 11 | 
             
                "roomkit"
         | 
| 12 12 | 
             
              ],
         | 
| 13 | 
            -
              "version": "0.3. | 
| 13 | 
            +
              "version": "0.3.11-alpha.0",
         | 
| 14 14 | 
             
              "author": "100ms",
         | 
| 15 15 | 
             
              "license": "MIT",
         | 
| 16 16 | 
             
              "repository": {
         | 
| @@ -74,12 +74,12 @@ | |
| 74 74 | 
             
                "react": ">=17.0.2 <19.0.0"
         | 
| 75 75 | 
             
              },
         | 
| 76 76 | 
             
              "dependencies": {
         | 
| 77 | 
            -
                "@100mslive/hls-player": "0.3. | 
| 77 | 
            +
                "@100mslive/hls-player": "0.3.11-alpha.0",
         | 
| 78 78 | 
             
                "@100mslive/hms-noise-cancellation": "0.0.1",
         | 
| 79 | 
            -
                "@100mslive/hms-virtual-background": "1.13. | 
| 80 | 
            -
                "@100mslive/hms-whiteboard": "0.0. | 
| 81 | 
            -
                "@100mslive/react-icons": "0.10. | 
| 82 | 
            -
                "@100mslive/react-sdk": "0.10. | 
| 79 | 
            +
                "@100mslive/hms-virtual-background": "1.13.11-alpha.0",
         | 
| 80 | 
            +
                "@100mslive/hms-whiteboard": "0.0.1-alpha.0",
         | 
| 81 | 
            +
                "@100mslive/react-icons": "0.10.11-alpha.0",
         | 
| 82 | 
            +
                "@100mslive/react-sdk": "0.10.11-alpha.0",
         | 
| 83 83 | 
             
                "@100mslive/types-prebuilt": "0.12.8",
         | 
| 84 84 | 
             
                "@emoji-mart/data": "^1.0.6",
         | 
| 85 85 | 
             
                "@emoji-mart/react": "^1.0.1",
         | 
| @@ -115,5 +115,5 @@ | |
| 115 115 | 
             
                "uuid": "^8.3.2",
         | 
| 116 116 | 
             
                "worker-timers": "^7.0.40"
         | 
| 117 117 | 
             
              },
         | 
| 118 | 
            -
              "gitHead": " | 
| 118 | 
            +
              "gitHead": "a4ed4a99addf5a2e5b923743c65bd20bd41d4175"
         | 
| 119 119 | 
             
            }
         | 
| @@ -1,6 +1,5 @@ | |
| 1 1 | 
             
            import { parsedUserAgent } from '@100mslive/react-sdk';
         | 
| 2 2 |  | 
| 3 | 
            -
            export const DEFAULT_WAITING_VIEWER_ROLE = 'waiting-room';
         | 
| 4 3 | 
             
            export const QUERY_PARAM_SKIP_PREVIEW = 'skip_preview';
         | 
| 5 4 | 
             
            export const QUERY_PARAM_SKIP_PREVIEW_HEADFUL = 'skip_preview_headful';
         | 
| 6 5 | 
             
            export const QUERY_PARAM_NAME = 'name';
         | 
| @@ -30,7 +29,6 @@ export const APP_DATA = { | |
| 30 29 | 
             
              appConfig: 'appConfig',
         | 
| 31 30 | 
             
              sidePane: 'sidePane',
         | 
| 32 31 | 
             
              hlsStats: 'hlsStats',
         | 
| 33 | 
            -
              waitingViewerRole: 'waitingViewerRole',
         | 
| 34 32 | 
             
              subscribedNotifications: 'subscribedNotifications',
         | 
| 35 33 | 
             
              logo: 'logo',
         | 
| 36 34 | 
             
              hlsStarted: 'hlsStarted',
         | 
| @@ -1,17 +1,22 @@ | |
| 1 | 
            -
            import { useCallback, useEffect, useRef, useState } from 'react';
         | 
| 1 | 
            +
            import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
         | 
| 2 2 | 
             
            import { useMedia } from 'react-use';
         | 
| 3 3 | 
             
            import { HMSHLSPlayer } from '@100mslive/hls-player';
         | 
| 4 4 | 
             
            import { JoinForm_JoinBtnType } from '@100mslive/types-prebuilt/elements/join_form';
         | 
| 5 5 | 
             
            import {
         | 
| 6 | 
            +
              HMSPeer,
         | 
| 6 7 | 
             
              HMSRecording,
         | 
| 7 8 | 
             
              parsedUserAgent,
         | 
| 8 9 | 
             
              selectAvailableRoleNames,
         | 
| 10 | 
            +
              selectIsAllowedToPublish,
         | 
| 9 11 | 
             
              selectIsConnectedToRoom,
         | 
| 12 | 
            +
              selectLocalPeerRole,
         | 
| 10 13 | 
             
              selectPeerCount,
         | 
| 11 14 | 
             
              selectPeerMetadata,
         | 
| 12 15 | 
             
              selectPeers,
         | 
| 16 | 
            +
              selectPeersByRoles,
         | 
| 13 17 | 
             
              selectRecordingState,
         | 
| 14 18 | 
             
              selectRemotePeers,
         | 
| 19 | 
            +
              selectRolesMap,
         | 
| 15 20 | 
             
              useHMSActions,
         | 
| 16 21 | 
             
              useHMSStore,
         | 
| 17 22 | 
             
              useHMSVanillaStore,
         | 
| @@ -218,3 +223,31 @@ export function getResolution( | |
| 218 223 | 
             
              }
         | 
| 219 224 | 
             
              return resolution;
         | 
| 220 225 | 
             
            }
         | 
| 226 | 
            +
             | 
| 227 | 
            +
            export interface WaitingRoomInfo {
         | 
| 228 | 
            +
              isNotAllowedToPublish: boolean;
         | 
| 229 | 
            +
              isScreenOnlyPublishParams: boolean;
         | 
| 230 | 
            +
              hasSubscribedRolePublishing: boolean;
         | 
| 231 | 
            +
            }
         | 
| 232 | 
            +
            export function useWaitingRoomInfo(): WaitingRoomInfo {
         | 
| 233 | 
            +
              const localPeerRole = useHMSStore(selectLocalPeerRole);
         | 
| 234 | 
            +
              const { video, audio, screen } = useHMSStore(selectIsAllowedToPublish);
         | 
| 235 | 
            +
              const roles = useHMSStore(selectRolesMap);
         | 
| 236 | 
            +
              const peersByRoles = useHMSStore(selectPeersByRoles(localPeerRole?.subscribeParams.subscribeToRoles || []));
         | 
| 237 | 
            +
              const isNotAllowedToPublish = !(video || audio || screen);
         | 
| 238 | 
            +
              const isScreenOnlyPublishParams: boolean = screen && !(video || audio);
         | 
| 239 | 
            +
              const hasSubscribedRolePublishing: boolean = useMemo(() => {
         | 
| 240 | 
            +
                return peersByRoles.some((peer: HMSPeer) => {
         | 
| 241 | 
            +
                  if (peer.roleName && roles[peer.roleName] && !peer.isLocal) {
         | 
| 242 | 
            +
                    return !!roles[peer.roleName].publishParams?.allowed.length;
         | 
| 243 | 
            +
                  }
         | 
| 244 | 
            +
                  return false;
         | 
| 245 | 
            +
                });
         | 
| 246 | 
            +
              }, [peersByRoles, roles]);
         | 
| 247 | 
            +
             | 
| 248 | 
            +
              return {
         | 
| 249 | 
            +
                isNotAllowedToPublish,
         | 
| 250 | 
            +
                isScreenOnlyPublishParams,
         | 
| 251 | 
            +
                hasSubscribedRolePublishing,
         | 
| 252 | 
            +
              };
         | 
| 253 | 
            +
            }
         | 
| @@ -142,22 +142,22 @@ export const getPeerResponses = (questions, peerid, userid) => { | |
| 142 142 | 
             
              return questions.map(question =>
         | 
| 143 143 | 
             
                question.responses?.filter(
         | 
| 144 144 | 
             
                  response =>
         | 
| 145 | 
            -
                     | 
| 145 | 
            +
                    response && (response.peer?.peerid === peerid || response.peer?.userid === userid) && !response.skipped,
         | 
| 146 146 | 
             
                ),
         | 
| 147 147 | 
             
              );
         | 
| 148 148 | 
             
            };
         | 
| 149 149 |  | 
| 150 | 
            -
            export const  | 
| 151 | 
            -
               | 
| 152 | 
            -
             | 
| 153 | 
            -
             | 
| 154 | 
            -
                 | 
| 155 | 
            -
             | 
| 156 | 
            -
                   | 
| 150 | 
            +
            export const getIndexToShow = responses => {
         | 
| 151 | 
            +
              let lastAttemptedIndex = 0;
         | 
| 152 | 
            +
             | 
| 153 | 
            +
              Object.keys(responses).forEach(key => {
         | 
| 154 | 
            +
                const keyNum = parseInt(key);
         | 
| 155 | 
            +
                if (keyNum > lastAttemptedIndex && responses[key]) {
         | 
| 156 | 
            +
                  lastAttemptedIndex = keyNum;
         | 
| 157 157 | 
             
                }
         | 
| 158 | 
            -
              }
         | 
| 159 | 
            -
             | 
| 160 | 
            -
              return  | 
| 158 | 
            +
              });
         | 
| 159 | 
            +
             | 
| 160 | 
            +
              return lastAttemptedIndex + 1;
         | 
| 161 161 | 
             
            };
         | 
| 162 162 |  | 
| 163 163 | 
             
            export const getPeerParticipationSummary = (poll, localPeerID, localCustomerUserID) => {
         | 
| @@ -21,7 +21,6 @@ import { useSetAppDataByKey } from './useUISettings'; | |
| 21 21 | 
             
            import {
         | 
| 22 22 | 
             
              APP_DATA,
         | 
| 23 23 | 
             
              CHAT_SELECTOR,
         | 
| 24 | 
            -
              DEFAULT_WAITING_VIEWER_ROLE,
         | 
| 25 24 | 
             
              POLL_STATE,
         | 
| 26 25 | 
             
              SIDE_PANE_OPTIONS,
         | 
| 27 26 | 
             
              UI_MODE_GRID,
         | 
| @@ -56,7 +55,6 @@ const initialAppData = { | |
| 56 55 | 
             
              [APP_DATA.hlsStarted]: false,
         | 
| 57 56 | 
             
              [APP_DATA.rtmpStarted]: false,
         | 
| 58 57 | 
             
              [APP_DATA.recordingStarted]: false,
         | 
| 59 | 
            -
              [APP_DATA.waitingViewerRole]: DEFAULT_WAITING_VIEWER_ROLE,
         | 
| 60 58 | 
             
              [APP_DATA.dropdownList]: [],
         | 
| 61 59 | 
             
              [APP_DATA.authToken]: '',
         | 
| 62 60 | 
             
              [APP_DATA.minimiseInset]: false,
         | 
| @@ -68,8 +66,8 @@ const initialAppData = { | |
| 68 66 | 
             
                [POLL_STATE.pollInView]: '',
         | 
| 69 67 | 
             
                [POLL_STATE.view]: '',
         | 
| 70 68 | 
             
              },
         | 
| 71 | 
            -
              // by default  | 
| 72 | 
            -
              [APP_DATA.caption]:  | 
| 69 | 
            +
              // by default on because of on demand now
         | 
| 70 | 
            +
              [APP_DATA.caption]: true,
         | 
| 73 71 | 
             
            };
         | 
| 74 72 |  | 
| 75 73 | 
             
            export const AppData = React.memo(() => {
         | 
| @@ -48,9 +48,6 @@ export const useSetUiSettings = uiSettingKey => { | |
| 48 48 | 
             
              return [value, setValue];
         | 
| 49 49 | 
             
            };
         | 
| 50 50 |  | 
| 51 | 
            -
            export const useWaitingViewerRole = () => {
         | 
| 52 | 
            -
              return useHMSStore(selectAppData(APP_DATA.waitingViewerRole));
         | 
| 53 | 
            -
            };
         | 
| 54 51 | 
             
            export const useIsHLSStartedFromUI = () => {
         | 
| 55 52 | 
             
              return useHMSStore(selectAppData(APP_DATA.hlsStarted));
         | 
| 56 53 | 
             
            };
         | 
| @@ -10,17 +10,20 @@ import { Box, Flex } from '../../../Layout'; | |
| 10 10 | 
             
            import { config as cssConfig } from '../../../Theme';
         | 
| 11 11 | 
             
            // @ts-ignore: No implicit any
         | 
| 12 12 | 
             
            import { EmojiReaction } from '../EmojiReaction';
         | 
| 13 | 
            +
            import { MoreSettings } from '../MoreSettings/MoreSettings';
         | 
| 14 | 
            +
            import { RaiseHand } from '../RaiseHand';
         | 
| 13 15 | 
             
            import { ChatBody } from './ChatBody';
         | 
| 14 16 | 
             
            import { ChatFooter } from './ChatFooter';
         | 
| 15 17 | 
             
            import { ChatBlocked, ChatPaused } from './ChatStates';
         | 
| 16 18 | 
             
            import { PinnedMessage } from './PinnedMessage';
         | 
| 17 19 | 
             
            import { useRoomLayoutConferencingScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
         | 
| 18 20 | 
             
            import { useSidepaneResetOnLayoutUpdate } from '../AppData/useSidepaneResetOnLayoutUpdate';
         | 
| 21 | 
            +
            import { useIsPeerBlacklisted } from '../hooks/useChatBlacklist';
         | 
| 19 22 | 
             
            import { useLandscapeHLSStream, useMobileHLSStream } from '../../common/hooks';
         | 
| 20 23 | 
             
            import { SESSION_STORE_KEY, SIDE_PANE_OPTIONS } from '../../common/constants';
         | 
| 21 24 |  | 
| 22 25 | 
             
            export const Chat = () => {
         | 
| 23 | 
            -
              const { elements } = useRoomLayoutConferencingScreen();
         | 
| 26 | 
            +
              const { elements, screenType } = useRoomLayoutConferencingScreen();
         | 
| 24 27 | 
             
              const listRef = useRef<VariableSizeList | null>(null);
         | 
| 25 28 | 
             
              const hmsActions = useHMSActions();
         | 
| 26 29 | 
             
              const vanillaStore = useHMSVanillaStore();
         | 
| @@ -29,6 +32,7 @@ export const Chat = () => { | |
| 29 32 | 
             
              const isMobileHLSStream = useMobileHLSStream();
         | 
| 30 33 | 
             
              const isLandscapeStream = useLandscapeHLSStream();
         | 
| 31 34 | 
             
              useSidepaneResetOnLayoutUpdate('chat', SIDE_PANE_OPTIONS.CHAT);
         | 
| 35 | 
            +
              const isLocalPeerBlacklisted = useIsPeerBlacklisted({ local: true });
         | 
| 32 36 |  | 
| 33 37 | 
             
              const scrollToBottom = useCallback(
         | 
| 34 38 | 
             
                (unreadCount = 0) => {
         | 
| @@ -57,20 +61,27 @@ export const Chat = () => { | |
| 57 61 | 
             
                >
         | 
| 58 62 | 
             
                  {isMobile && elements?.chat?.is_overlay && !streaming ? null : <PinnedMessage />}
         | 
| 59 63 | 
             
                  <ChatBody ref={listRef} scrollToBottom={scrollToBottom} />
         | 
| 60 | 
            -
             | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 64 | 
            +
                  <Flex align="center" css={{ w: '100%', gap: '$2' }}>
         | 
| 65 | 
            +
                    <ChatPaused />
         | 
| 66 | 
            +
                    <ChatBlocked />
         | 
| 67 | 
            +
                    {streaming && (!isChatEnabled || isLocalPeerBlacklisted) && (
         | 
| 68 | 
            +
                      <>
         | 
| 69 | 
            +
                        <RaiseHand css={{ bg: '$surface_default' }} />
         | 
| 70 | 
            +
                        <MoreSettings elements={elements} screenType={screenType} />
         | 
| 71 | 
            +
                      </>
         | 
| 72 | 
            +
                    )}
         | 
| 73 | 
            +
                  </Flex>
         | 
| 63 74 | 
             
                  {isMobile && elements?.chat?.is_overlay && !streaming ? <PinnedMessage /> : null}
         | 
| 64 75 | 
             
                  {isChatEnabled ? (
         | 
| 65 76 | 
             
                    <ChatFooter onSend={scrollToBottom}>
         | 
| 66 77 | 
             
                      <NewMessageIndicator scrollToBottom={scrollToBottom} listRef={listRef} />
         | 
| 67 78 | 
             
                    </ChatFooter>
         | 
| 68 79 | 
             
                  ) : null}
         | 
| 69 | 
            -
                  { | 
| 80 | 
            +
                  {streaming && (
         | 
| 70 81 | 
             
                    <Box
         | 
| 71 82 | 
             
                      css={{
         | 
| 72 83 | 
             
                        position: 'absolute',
         | 
| 73 | 
            -
                        ...match({ isLandscapeStream, isMobileHLSStream, isChatEnabled })
         | 
| 84 | 
            +
                        ...match({ isLandscapeStream, isMobileHLSStream, isChatEnabled, isLocalPeerBlacklisted })
         | 
| 74 85 | 
             
                          .with(
         | 
| 75 86 | 
             
                            {
         | 
| 76 87 | 
             
                              isLandscapeStream: true,
         | 
| @@ -96,6 +107,7 @@ export const Chat = () => { | |
| 96 107 | 
             
                            {
         | 
| 97 108 | 
             
                              isMobileHLSStream: true,
         | 
| 98 109 | 
             
                              isChatEnabled: true,
         | 
| 110 | 
            +
                              isLocalPeerBlacklisted: false,
         | 
| 99 111 | 
             
                            },
         | 
| 100 112 | 
             
                            () => ({ bottom: '$17', right: '$8' }),
         | 
| 101 113 | 
             
                          )
         | 
| @@ -103,6 +115,14 @@ export const Chat = () => { | |
| 103 115 | 
             
                            {
         | 
| 104 116 | 
             
                              isLandscapeStream: false,
         | 
| 105 117 | 
             
                              isChatEnabled: true,
         | 
| 118 | 
            +
                              isLocalPeerBlacklisted: true,
         | 
| 119 | 
            +
                            },
         | 
| 120 | 
            +
                            () => ({ bottom: '$18', right: '$8' }),
         | 
| 121 | 
            +
                          )
         | 
| 122 | 
            +
                          .with(
         | 
| 123 | 
            +
                            {
         | 
| 124 | 
            +
                              isMobileHLSStream: true,
         | 
| 125 | 
            +
                              isLocalPeerBlacklisted: true,
         | 
| 106 126 | 
             
                            },
         | 
| 107 127 | 
             
                            () => ({ bottom: '$20', right: '$8' }),
         | 
| 108 128 | 
             
                          )
         | 
| @@ -102,6 +102,19 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo | |
| 102 102 | 
             
                  }
         | 
| 103 103 | 
             
                }
         | 
| 104 104 | 
             
              }, [defaultSelection, selectedPeer, selectedRole, setRoleSelector, isMobile, isLandscapeHLSStream, elements?.chat]);
         | 
| 105 | 
            +
             | 
| 106 | 
            +
              const resetInputHeight = useCallback(() => {
         | 
| 107 | 
            +
                if (inputRef.current) {
         | 
| 108 | 
            +
                  inputRef.current.style.height = `${Math.max(32, inputRef.current.value ? inputRef.current.scrollHeight : 0)}px`;
         | 
| 109 | 
            +
                }
         | 
| 110 | 
            +
              }, []);
         | 
| 111 | 
            +
             | 
| 112 | 
            +
              const updateInputHeight = useCallback(() => {
         | 
| 113 | 
            +
                if (inputRef.current) {
         | 
| 114 | 
            +
                  inputRef.current.style.height = `${Math.max(32, Math.min(inputRef.current.scrollHeight, 24 * 4))}px`;
         | 
| 115 | 
            +
                }
         | 
| 116 | 
            +
              }, []);
         | 
| 117 | 
            +
             | 
| 105 118 | 
             
              const sendMessage = useCallback(async () => {
         | 
| 106 119 | 
             
                const message = inputRef?.current?.value;
         | 
| 107 120 | 
             
                if (!message || !message.trim().length) {
         | 
| @@ -116,6 +129,7 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo | |
| 116 129 | 
             
                    await hmsActions.sendBroadcastMessage(message);
         | 
| 117 130 | 
             
                  }
         | 
| 118 131 | 
             
                  inputRef.current.value = '';
         | 
| 132 | 
            +
                  resetInputHeight();
         | 
| 119 133 | 
             
                  setTimeout(() => {
         | 
| 120 134 | 
             
                    onSend(1);
         | 
| 121 135 | 
             
                  }, 0);
         | 
| @@ -131,6 +145,7 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo | |
| 131 145 | 
             
                const messageElement = inputRef.current;
         | 
| 132 146 | 
             
                if (messageElement) {
         | 
| 133 147 | 
             
                  messageElement.value = draftMessage;
         | 
| 148 | 
            +
                  updateInputHeight();
         | 
| 134 149 | 
             
                }
         | 
| 135 150 | 
             
              }, [draftMessage]);
         | 
| 136 151 |  | 
| @@ -197,11 +212,10 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo | |
| 197 212 | 
             
                  {selection && (
         | 
| 198 213 | 
             
                    <Flex align="center" css={{ gap: '$4', w: '100%' }}>
         | 
| 199 214 | 
             
                      <Flex
         | 
| 200 | 
            -
                        align=" | 
| 215 | 
            +
                        align="end"
         | 
| 201 216 | 
             
                        css={{
         | 
| 202 217 | 
             
                          bg: isOverlayChat && isMobile ? '$surface_dim' : '$surface_default',
         | 
| 203 218 | 
             
                          minHeight: '$16',
         | 
| 204 | 
            -
                          maxHeight: '$24',
         | 
| 205 219 | 
             
                          position: 'relative',
         | 
| 206 220 | 
             
                          py: '$6',
         | 
| 207 221 | 
             
                          pl: '$8',
         | 
| @@ -238,6 +252,8 @@ export const ChatFooter = ({ onSend, children }: { onSend: (count: number) => vo | |
| 238 252 | 
             
                          }}
         | 
| 239 253 | 
             
                          autoComplete="off"
         | 
| 240 254 | 
             
                          aria-autocomplete="none"
         | 
| 255 | 
            +
                          onChange={updateInputHeight}
         | 
| 256 | 
            +
                          onBlur={resetInputHeight}
         | 
| 241 257 | 
             
                          onPaste={e => e.stopPropagation()}
         | 
| 242 258 | 
             
                          onCut={e => e.stopPropagation()}
         | 
| 243 259 | 
             
                          onCopy={e => e.stopPropagation()}
         | 
| @@ -30,7 +30,7 @@ export const ChatPaused = () => { | |
| 30 30 | 
             
                <Flex
         | 
| 31 31 | 
             
                  align="center"
         | 
| 32 32 | 
             
                  justify="between"
         | 
| 33 | 
            -
                  css={{ borderRadius: '$1', bg: '$surface_default', p: '$ | 
| 33 | 
            +
                  css={{ borderRadius: '$1', bg: '$surface_default', p: '$2 $4 $2 $8', w: '100%' }}
         | 
| 34 34 | 
             
                >
         | 
| 35 35 | 
             
                  <Box>
         | 
| 36 36 | 
             
                    <Text variant="sm" css={{ fontWeight: '$semiBold', color: '$on_surface_high' }}>
         | 
| @@ -21,7 +21,11 @@ export const ChatToggle = ({ onClick }: { onClick?: () => void }) => { | |
| 21 21 | 
             
                  }}
         | 
| 22 22 | 
             
                >
         | 
| 23 23 | 
             
                  <Tooltip key="chat" title={`${isChatOpen ? 'Close' : 'Open'} chat`}>
         | 
| 24 | 
            -
                    <IconButton | 
| 24 | 
            +
                    <IconButton
         | 
| 25 | 
            +
                      onClick={() => (onClick ? onClick() : toggleChat())}
         | 
| 26 | 
            +
                      css={{ bg: isChatOpen ? '$surface_brighter' : '' }}
         | 
| 27 | 
            +
                      data-testid="chat_btn"
         | 
| 28 | 
            +
                    >
         | 
| 25 29 | 
             
                      <ChatIcon />
         | 
| 26 30 | 
             
                    </IconButton>
         | 
| 27 31 | 
             
                  </Tooltip>
         | 
| @@ -86,6 +86,7 @@ export const ParticipantList = ({ | |
| 86 86 | 
             
                  return { ...filterValue };
         | 
| 87 87 | 
             
                });
         | 
| 88 88 | 
             
              }, []);
         | 
| 89 | 
            +
             | 
| 89 90 | 
             
              if (peerCount === 0) {
         | 
| 90 91 | 
             
                return null;
         | 
| 91 92 | 
             
              }
         | 
| @@ -128,7 +129,7 @@ export const ParticipantList = ({ | |
| 128 129 | 
             
            export const ParticipantCount = () => {
         | 
| 129 130 | 
             
              const peerCount = useHMSStore(selectPeerCount);
         | 
| 130 131 | 
             
              const toggleSidepane = useSidepaneToggle(SIDE_PANE_OPTIONS.PARTICIPANTS);
         | 
| 131 | 
            -
              const  | 
| 132 | 
            +
              const isPeerListOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.PARTICIPANTS);
         | 
| 132 133 |  | 
| 133 134 | 
             
              if (peerCount === 0) {
         | 
| 134 135 | 
             
                return null;
         | 
| @@ -139,13 +140,13 @@ export const ParticipantCount = () => { | |
| 139 140 | 
             
                    w: 'auto',
         | 
| 140 141 | 
             
                    p: '$4',
         | 
| 141 142 | 
             
                    h: 'auto',
         | 
| 143 | 
            +
                    bg: isPeerListOpen ? '$surface_brighter' : '',
         | 
| 142 144 | 
             
                  }}
         | 
| 143 145 | 
             
                  onClick={() => {
         | 
| 144 146 | 
             
                    if (peerCount > 0) {
         | 
| 145 147 | 
             
                      toggleSidepane();
         | 
| 146 148 | 
             
                    }
         | 
| 147 149 | 
             
                  }}
         | 
| 148 | 
            -
                  active={!isParticipantsOpen}
         | 
| 149 150 | 
             
                  data-testid="participant_list"
         | 
| 150 151 | 
             
                >
         | 
| 151 152 | 
             
                  <PeopleIcon />
         | 
| @@ -447,6 +448,7 @@ export const ParticipantSearch = ({ | |
| 447 448 | 
             
                300,
         | 
| 448 449 | 
             
                [value, onSearch],
         | 
| 449 450 | 
             
              );
         | 
| 451 | 
            +
             | 
| 450 452 | 
             
              return (
         | 
| 451 453 | 
             
                <Flex
         | 
| 452 454 | 
             
                  align="center"
         | 
| @@ -0,0 +1,132 @@ | |
| 1 | 
            +
            import React from 'react';
         | 
| 2 | 
            +
            import { HMSTranscriptionMode, selectIsTranscriptionEnabled, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
         | 
| 3 | 
            +
            import { AlertTriangleIcon, CrossIcon } from '@100mslive/react-icons';
         | 
| 4 | 
            +
            import { Button } from '../../../Button';
         | 
| 5 | 
            +
            import { Box, Flex } from '../../../Layout';
         | 
| 6 | 
            +
            import { Loading } from '../../../Loading';
         | 
| 7 | 
            +
            import { Text } from '../../../Text';
         | 
| 8 | 
            +
            // @ts-ignore: No implicit Any
         | 
| 9 | 
            +
            import { ToastManager } from '../Toast/ToastManager';
         | 
| 10 | 
            +
            // @ts-ignore: No implicit Any
         | 
| 11 | 
            +
            import { useSetIsCaptionEnabled } from '../AppData/useUISettings';
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            export const CaptionContent = ({ isMobile, onExit }: { isMobile: boolean; onExit: () => void }) => {
         | 
| 14 | 
            +
              const DURATION = 2000;
         | 
| 15 | 
            +
              const actions = useHMSActions();
         | 
| 16 | 
            +
              const isTranscriptionEnabled = useHMSStore(selectIsTranscriptionEnabled);
         | 
| 17 | 
            +
             | 
| 18 | 
            +
              const [isCaptionEnabled, setIsCaptionEnabled] = useSetIsCaptionEnabled();
         | 
| 19 | 
            +
              return (
         | 
| 20 | 
            +
                <>
         | 
| 21 | 
            +
                  <Text
         | 
| 22 | 
            +
                    variant={isMobile ? 'md' : 'lg'}
         | 
| 23 | 
            +
                    css={{
         | 
| 24 | 
            +
                      color: '$on_surface_high',
         | 
| 25 | 
            +
                      fontWeight: '$semiBold',
         | 
| 26 | 
            +
                      display: 'flex',
         | 
| 27 | 
            +
                      pb: '$4',
         | 
| 28 | 
            +
                      '@md': { px: '$8', borderBottom: '1px solid $border_default' },
         | 
| 29 | 
            +
                    }}
         | 
| 30 | 
            +
                  >
         | 
| 31 | 
            +
                    {isTranscriptionEnabled ? 'Disable' : 'Enable'} Closed Caption (CC) for this session?
         | 
| 32 | 
            +
                    <Box
         | 
| 33 | 
            +
                      css={{ color: 'inherit', ml: 'auto', '&:hover': { color: '$on_surface_medium', cursor: 'pointer' } }}
         | 
| 34 | 
            +
                      onClick={onExit}
         | 
| 35 | 
            +
                    >
         | 
| 36 | 
            +
                      <CrossIcon />
         | 
| 37 | 
            +
                    </Box>
         | 
| 38 | 
            +
                  </Text>
         | 
| 39 | 
            +
                  {!isMobile ? (
         | 
| 40 | 
            +
                    <Text variant="sm" css={{ color: '$on_surface_medium', pb: '$6', mb: '$8', '@md': { px: '$8', mt: '$4' } }}>
         | 
| 41 | 
            +
                      This will {isTranscriptionEnabled ? 'disable' : 'enable'} Closed Captions for everyone in this room. You can
         | 
| 42 | 
            +
                      {isTranscriptionEnabled ? 'enable' : 'disable'} it later.
         | 
| 43 | 
            +
                    </Text>
         | 
| 44 | 
            +
                  ) : null}
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                  <Flex
         | 
| 47 | 
            +
                    justify="between"
         | 
| 48 | 
            +
                    align="center"
         | 
| 49 | 
            +
                    css={{
         | 
| 50 | 
            +
                      width: '100%',
         | 
| 51 | 
            +
                      gap: '$md',
         | 
| 52 | 
            +
                      mt: '$10',
         | 
| 53 | 
            +
                      '@md': { px: '$4' },
         | 
| 54 | 
            +
                    }}
         | 
| 55 | 
            +
                  >
         | 
| 56 | 
            +
                    {isMobile ? null : (
         | 
| 57 | 
            +
                      <Button variant="standard" css={{ w: '100%' }} outlined onClick={onExit}>
         | 
| 58 | 
            +
                        Cancel
         | 
| 59 | 
            +
                      </Button>
         | 
| 60 | 
            +
                    )}
         | 
| 61 | 
            +
                    <Flex
         | 
| 62 | 
            +
                      direction="column"
         | 
| 63 | 
            +
                      justify="between"
         | 
| 64 | 
            +
                      align="center"
         | 
| 65 | 
            +
                      css={{
         | 
| 66 | 
            +
                        width: '100%',
         | 
| 67 | 
            +
                      }}
         | 
| 68 | 
            +
                    >
         | 
| 69 | 
            +
                      {isMobile && isTranscriptionEnabled ? (
         | 
| 70 | 
            +
                        <Button
         | 
| 71 | 
            +
                          variant="standard"
         | 
| 72 | 
            +
                          css={{ w: '100%', mb: '$8' }}
         | 
| 73 | 
            +
                          outlined
         | 
| 74 | 
            +
                          onClick={() => {
         | 
| 75 | 
            +
                            setIsCaptionEnabled(!isCaptionEnabled);
         | 
| 76 | 
            +
                            onExit();
         | 
| 77 | 
            +
                          }}
         | 
| 78 | 
            +
                        >
         | 
| 79 | 
            +
                          {isCaptionEnabled ? 'Hide For Me' : 'Show For Me'}
         | 
| 80 | 
            +
                        </Button>
         | 
| 81 | 
            +
                      ) : null}
         | 
| 82 | 
            +
                      <Button
         | 
| 83 | 
            +
                        variant={isTranscriptionEnabled ? 'danger' : 'primary'}
         | 
| 84 | 
            +
                        css={{ width: '100%' }}
         | 
| 85 | 
            +
                        data-testid="popup_change_btn"
         | 
| 86 | 
            +
                        onClick={async () => {
         | 
| 87 | 
            +
                          try {
         | 
| 88 | 
            +
                            if (isTranscriptionEnabled) {
         | 
| 89 | 
            +
                              await actions.stopTranscription({
         | 
| 90 | 
            +
                                mode: HMSTranscriptionMode.CAPTION,
         | 
| 91 | 
            +
                              });
         | 
| 92 | 
            +
                              ToastManager.addToast({
         | 
| 93 | 
            +
                                title: `Disabling Closed Caption for everyone.`,
         | 
| 94 | 
            +
                                variant: 'standard',
         | 
| 95 | 
            +
                                duration: DURATION,
         | 
| 96 | 
            +
                                icon: <Loading color="currentColor" />,
         | 
| 97 | 
            +
                              });
         | 
| 98 | 
            +
                              onExit();
         | 
| 99 | 
            +
                              return;
         | 
| 100 | 
            +
                            }
         | 
| 101 | 
            +
                            await actions.startTranscription({
         | 
| 102 | 
            +
                              mode: HMSTranscriptionMode.CAPTION,
         | 
| 103 | 
            +
                            });
         | 
| 104 | 
            +
                            ToastManager.addToast({
         | 
| 105 | 
            +
                              title: `Enabling Closed Caption for everyone.`,
         | 
| 106 | 
            +
                              variant: 'standard',
         | 
| 107 | 
            +
                              duration: DURATION,
         | 
| 108 | 
            +
                              icon: <Loading color="currentColor" />,
         | 
| 109 | 
            +
                            });
         | 
| 110 | 
            +
                          } catch (err) {
         | 
| 111 | 
            +
                            ToastManager.addToast({
         | 
| 112 | 
            +
                              title: `Failed to ${isTranscriptionEnabled ? 'disabled' : 'enabled'} closed caption`,
         | 
| 113 | 
            +
                              variant: 'error',
         | 
| 114 | 
            +
                              icon: <AlertTriangleIcon style={{ marginRight: '0.5rem' }} />,
         | 
| 115 | 
            +
                            });
         | 
| 116 | 
            +
                          }
         | 
| 117 | 
            +
                          onExit();
         | 
| 118 | 
            +
                        }}
         | 
| 119 | 
            +
                      >
         | 
| 120 | 
            +
                        {isTranscriptionEnabled ? 'Disable' : 'Enable'} for Everyone
         | 
| 121 | 
            +
                      </Button>
         | 
| 122 | 
            +
                    </Flex>
         | 
| 123 | 
            +
                  </Flex>
         | 
| 124 | 
            +
                  {isMobile && (
         | 
| 125 | 
            +
                    <Text variant="sm" css={{ color: '$on_surface_medium', pb: '$6', mb: '$8', '@md': { px: '$8', mt: '$4' } }}>
         | 
| 126 | 
            +
                      This will {isTranscriptionEnabled ? 'disable' : 'enable'} Closed Captions for everyone in this room. You can
         | 
| 127 | 
            +
                      {isTranscriptionEnabled ? 'enable' : 'disable'} it later.
         | 
| 128 | 
            +
                    </Text>
         | 
| 129 | 
            +
                  )}
         | 
| 130 | 
            +
                </>
         | 
| 131 | 
            +
              );
         | 
| 132 | 
            +
            };
         | 
| @@ -0,0 +1,37 @@ | |
| 1 | 
            +
            import React from 'react';
         | 
| 2 | 
            +
            import { useMedia } from 'react-use';
         | 
| 3 | 
            +
            import { config as cssConfig, Dialog } from '../../..';
         | 
| 4 | 
            +
            import { Sheet } from '../../../Sheet';
         | 
| 5 | 
            +
            import { CaptionContent } from './CaptionContent';
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            export const CaptionModal = ({ onOpenChange }: { onOpenChange: (value: boolean) => void }) => {
         | 
| 8 | 
            +
              const isMobile = useMedia(cssConfig.media.md);
         | 
| 9 | 
            +
             | 
| 10 | 
            +
              const props = {
         | 
| 11 | 
            +
                isMobile,
         | 
| 12 | 
            +
                onExit: () => {
         | 
| 13 | 
            +
                  onOpenChange(false);
         | 
| 14 | 
            +
                },
         | 
| 15 | 
            +
              };
         | 
| 16 | 
            +
             | 
| 17 | 
            +
              if (isMobile) {
         | 
| 18 | 
            +
                return (
         | 
| 19 | 
            +
                  <Sheet.Root defaultOpen onOpenChange={onOpenChange}>
         | 
| 20 | 
            +
                    <Sheet.Content css={{ bg: '$surface_dim', p: '$8 0' }}>
         | 
| 21 | 
            +
                      <CaptionContent {...props} />
         | 
| 22 | 
            +
                    </Sheet.Content>
         | 
| 23 | 
            +
                  </Sheet.Root>
         | 
| 24 | 
            +
                );
         | 
| 25 | 
            +
              }
         | 
| 26 | 
            +
             | 
| 27 | 
            +
              return (
         | 
| 28 | 
            +
                <Dialog.Root defaultOpen onOpenChange={onOpenChange}>
         | 
| 29 | 
            +
                  <Dialog.Portal>
         | 
| 30 | 
            +
                    <Dialog.Overlay />
         | 
| 31 | 
            +
                    <Dialog.Content css={{ bg: '$surface_dim', width: 'min(400px,80%)', p: '$10' }}>
         | 
| 32 | 
            +
                      <CaptionContent {...props} />
         | 
| 33 | 
            +
                    </Dialog.Content>
         | 
| 34 | 
            +
                  </Dialog.Portal>
         | 
| 35 | 
            +
                </Dialog.Root>
         | 
| 36 | 
            +
              );
         | 
| 37 | 
            +
            };
         | 
| @@ -6,9 +6,23 @@ import { | |
| 6 6 | 
             
              HLSLiveStreamingScreen_Elements,
         | 
| 7 7 | 
             
            } from '@100mslive/types-prebuilt';
         | 
| 8 8 | 
             
            import { match } from 'ts-pattern';
         | 
| 9 | 
            -
            import { | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 9 | 
            +
            import {
         | 
| 10 | 
            +
              selectAppData,
         | 
| 11 | 
            +
              selectIsTranscriptionEnabled,
         | 
| 12 | 
            +
              selectLocalPeerID,
         | 
| 13 | 
            +
              useHMSActions,
         | 
| 14 | 
            +
              useHMSStore,
         | 
| 15 | 
            +
            } from '@100mslive/react-sdk';
         | 
| 16 | 
            +
            import {
         | 
| 17 | 
            +
              BrbIcon,
         | 
| 18 | 
            +
              CheckIcon,
         | 
| 19 | 
            +
              HamburgerMenuIcon,
         | 
| 20 | 
            +
              InfoIcon,
         | 
| 21 | 
            +
              OpenCaptionIcon,
         | 
| 22 | 
            +
              PipIcon,
         | 
| 23 | 
            +
              SettingsIcon,
         | 
| 24 | 
            +
            } from '@100mslive/react-icons';
         | 
| 25 | 
            +
            import { Checkbox, Dropdown, Flex, Switch, Text, Tooltip } from '../../../..';
         | 
| 12 26 | 
             
            import IconButton from '../../../IconButton';
         | 
| 13 27 | 
             
            // @ts-ignore: No implicit any
         | 
| 14 28 | 
             
            import { PIP } from '../../PIP';
         | 
| @@ -24,6 +38,7 @@ import StartRecording from '../../Settings/StartRecording'; | |
| 24 38 | 
             
            import { StatsForNerds } from '../../StatsForNerds';
         | 
| 25 39 | 
             
            // @ts-ignore: No implicit any
         | 
| 26 40 | 
             
            import { BulkRoleChangeModal } from '../BulkRoleChangeModal';
         | 
| 41 | 
            +
            import { CaptionModal } from '../CaptionModal';
         | 
| 27 42 | 
             
            // @ts-ignore: No implicit any
         | 
| 28 43 | 
             
            import { FullScreenItem } from '../FullScreenItem';
         | 
| 29 44 | 
             
            import { MuteAllModal } from '../MuteAllModal';
         | 
| @@ -43,6 +58,7 @@ const MODALS = { | |
| 43 58 | 
             
              BULK_ROLE_CHANGE: 'bulkRoleChange',
         | 
| 44 59 | 
             
              MUTE_ALL: 'muteAll',
         | 
| 45 60 | 
             
              EMBED_URL: 'embedUrl',
         | 
| 61 | 
            +
              CAPTION: 'caption',
         | 
| 46 62 | 
             
            };
         | 
| 47 63 |  | 
| 48 64 | 
             
            export const DesktopOptions = ({
         | 
| @@ -59,6 +75,7 @@ export const DesktopOptions = ({ | |
| 59 75 | 
             
              const { isBRBOn, toggleBRB } = useMyMetadata();
         | 
| 60 76 | 
             
              const isPipOn = PictureInPicture.isOn();
         | 
| 61 77 | 
             
              const isBRBEnabled = !!elements?.brb;
         | 
| 78 | 
            +
              const isTranscriptionEnabled = useHMSStore(selectIsTranscriptionEnabled);
         | 
| 62 79 |  | 
| 63 80 | 
             
              useDropdownList({ open: openModals.size > 0, name: 'MoreSettings' });
         | 
| 64 81 |  | 
| @@ -115,6 +132,23 @@ export const DesktopOptions = ({ | |
| 115 132 | 
             
                        </Dropdown.Item>
         | 
| 116 133 | 
             
                      ) : null}
         | 
| 117 134 |  | 
| 135 | 
            +
                      <Dropdown.Item
         | 
| 136 | 
            +
                        data-testid="closed_caption_admin"
         | 
| 137 | 
            +
                        onClick={() => {
         | 
| 138 | 
            +
                          updateState(MODALS.CAPTION, true);
         | 
| 139 | 
            +
                        }}
         | 
| 140 | 
            +
                      >
         | 
| 141 | 
            +
                        <OpenCaptionIcon />
         | 
| 142 | 
            +
                        <Flex direction="column" css={{ flexGrow: '1' }}>
         | 
| 143 | 
            +
                          <Text variant="sm" css={{ ml: '$4', color: '$on_surface_high' }}>
         | 
| 144 | 
            +
                            Closed Captions
         | 
| 145 | 
            +
                          </Text>
         | 
| 146 | 
            +
                          <Text variant="caption" css={{ ml: '$4', color: '$on_surface_medium' }}>
         | 
| 147 | 
            +
                            {isTranscriptionEnabled ? 'Enabled' : 'Disabled'}
         | 
| 148 | 
            +
                          </Text>
         | 
| 149 | 
            +
                        </Flex>
         | 
| 150 | 
            +
                        <Switch id="closed_caption_start_stop" checked={isTranscriptionEnabled} disabled={false} />
         | 
| 151 | 
            +
                      </Dropdown.Item>
         | 
| 118 152 | 
             
                      {screenType !== 'hls_live_streaming' ? (
         | 
| 119 153 | 
             
                        <Dropdown.Item css={{ p: 0, '&:empty': { display: 'none' } }}>
         | 
| 120 154 | 
             
                          <PIP
         | 
| @@ -211,6 +245,9 @@ export const DesktopOptions = ({ | |
| 211 245 | 
             
                      onOpenChange={(value: boolean) => updateState(MODALS.SELF_ROLE_CHANGE, value)}
         | 
| 212 246 | 
             
                    />
         | 
| 213 247 | 
             
                  )}
         | 
| 248 | 
            +
                  {openModals.has(MODALS.CAPTION) && (
         | 
| 249 | 
            +
                    <CaptionModal onOpenChange={(value: boolean) => updateState(MODALS.CAPTION, value)} />
         | 
| 250 | 
            +
                  )}
         | 
| 214 251 | 
             
                  {/* {openModals.has(MODALS.EMBED_URL) && (
         | 
| 215 252 | 
             
                    <EmbedUrlModal onOpenChange={value => updateState(MODALS.EMBED_URL, value)} />
         | 
| 216 253 | 
             
                  )} */}
         |