@100mslive/roomkit-react 0.3.8-alpha.0 → 0.3.8-alpha.2
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-CTZXD762.js → HLSView-XZDT3RRC.js} +2 -2
- package/dist/Prebuilt/common/constants.d.ts +2 -0
- package/dist/Prebuilt/common/hooks.d.ts +10 -0
- package/dist/Prebuilt/components/CaptionIcon.d.ts +2 -0
- package/dist/Prebuilt/components/FullPageProgress.d.ts +8 -0
- package/dist/Prebuilt/components/VirtualBackground/VBHandler.d.ts +3 -3
- package/dist/Prebuilt/plugins/CaptionsViewer.d.ts +2 -0
- package/dist/Text/Text.d.ts +1 -1
- package/dist/{chunk-NDLMRKFR.js → chunk-SQPIZNW2.js} +2367 -2128
- package/dist/chunk-SQPIZNW2.js.map +7 -0
- package/dist/index.cjs.js +3254 -2998
- package/dist/index.cjs.js.map +4 -4
- package/dist/index.js +1 -1
- package/dist/meta.cjs.json +244 -86
- package/dist/meta.esbuild.json +250 -92
- package/package.json +6 -6
- package/src/Prebuilt/common/constants.ts +2 -0
- package/src/Prebuilt/common/hooks.ts +72 -1
- package/src/Prebuilt/components/AppData/AppData.tsx +2 -0
- package/src/Prebuilt/components/AppData/useUISettings.js +10 -0
- package/src/Prebuilt/components/CaptionIcon.tsx +27 -0
- package/src/Prebuilt/components/ConferenceScreen.tsx +34 -4
- package/src/Prebuilt/components/Footer/Footer.tsx +2 -0
- package/src/Prebuilt/components/Footer/RoleAccordion.tsx +1 -1
- package/src/Prebuilt/components/{FullPageProgress.jsx → FullPageProgress.tsx} +10 -1
- package/src/Prebuilt/components/Header/StreamActions.tsx +3 -25
- package/src/Prebuilt/components/MoreSettings/SplitComponents/MwebOptions.tsx +25 -26
- package/src/Prebuilt/components/Notifications/PeerNotifications.tsx +1 -11
- package/src/Prebuilt/components/Preview/PreviewJoin.tsx +4 -9
- package/src/Prebuilt/components/Preview/PreviewScreen.tsx +0 -3
- package/src/Prebuilt/components/Settings/StartRecording.jsx +4 -37
- package/src/Prebuilt/components/Toast/ToastConfig.jsx +0 -22
- package/src/Prebuilt/components/VirtualBackground/VBHandler.tsx +3 -3
- package/src/Prebuilt/components/VirtualBackground/VBOption.tsx +3 -1
- package/src/Prebuilt/components/VirtualBackground/VBPicker.tsx +23 -7
- package/src/Prebuilt/components/VirtualBackground/VBToggle.tsx +5 -3
- package/src/Prebuilt/layouts/VideoStreamingSection.tsx +0 -3
- package/src/Prebuilt/plugins/CaptionsViewer.tsx +191 -0
- package/dist/chunk-NDLMRKFR.js.map +0 -7
- /package/dist/{HLSView-CTZXD762.js.map → HLSView-XZDT3RRC.js.map} +0 -0
| @@ -72,28 +72,6 @@ const HandRaiseAction = React.forwardRef(({ id = '', isSingleHandRaise = true }, | |
| 72 72 | 
             
            });
         | 
| 73 73 |  | 
| 74 74 | 
             
            export const ToastConfig = {
         | 
| 75 | 
            -
              PEER_LIST: {
         | 
| 76 | 
            -
                single: function (notification) {
         | 
| 77 | 
            -
                  if (notification.data.length === 1) {
         | 
| 78 | 
            -
                    return {
         | 
| 79 | 
            -
                      title: `${notification.data[0]?.name} joined`,
         | 
| 80 | 
            -
                      icon: <PeopleAddIcon />,
         | 
| 81 | 
            -
                    };
         | 
| 82 | 
            -
                  }
         | 
| 83 | 
            -
                  return {
         | 
| 84 | 
            -
                    title: `${notification.data[notification.data.length - 1]?.name} and ${
         | 
| 85 | 
            -
                      notification.data.length - 1
         | 
| 86 | 
            -
                    } others joined`,
         | 
| 87 | 
            -
                    icon: <PeopleAddIcon />,
         | 
| 88 | 
            -
                  };
         | 
| 89 | 
            -
                },
         | 
| 90 | 
            -
                multiple: notifications => {
         | 
| 91 | 
            -
                  return {
         | 
| 92 | 
            -
                    title: `${notifications[0].data.name} and ${notifications.length - 1} others joined`,
         | 
| 93 | 
            -
                    icon: <PeopleAddIcon />,
         | 
| 94 | 
            -
                  };
         | 
| 95 | 
            -
                },
         | 
| 96 | 
            -
              },
         | 
| 97 75 | 
             
              PEER_JOINED: {
         | 
| 98 76 | 
             
                single: function (notification) {
         | 
| 99 77 | 
             
                  return {
         | 
| @@ -4,12 +4,12 @@ export class VBPlugin { | |
| 4 4 | 
             
              private hmsPlugin?: HMSVBPlugin;
         | 
| 5 5 | 
             
              private effectsPlugin?: HMSEffectsPlugin | undefined;
         | 
| 6 6 |  | 
| 7 | 
            -
              initialisePlugin = (effectsSDKKey?: string) => {
         | 
| 7 | 
            +
              initialisePlugin = (effectsSDKKey?: string, onInit?: () => void) => {
         | 
| 8 8 | 
             
                if (this.getVBObject()) {
         | 
| 9 9 | 
             
                  return;
         | 
| 10 10 | 
             
                }
         | 
| 11 11 | 
             
                if (effectsSDKKey) {
         | 
| 12 | 
            -
                  this.effectsPlugin = new HMSEffectsPlugin(effectsSDKKey);
         | 
| 12 | 
            +
                  this.effectsPlugin = new HMSEffectsPlugin(effectsSDKKey, onInit);
         | 
| 13 13 | 
             
                } else {
         | 
| 14 14 | 
             
                  this.hmsPlugin = new HMSVBPlugin(HMSVirtualBackgroundTypes.NONE, HMSVirtualBackgroundTypes.NONE);
         | 
| 15 15 | 
             
                }
         | 
| @@ -70,7 +70,7 @@ export class VBPlugin { | |
| 70 70 | 
             
                }
         | 
| 71 71 | 
             
              };
         | 
| 72 72 |  | 
| 73 | 
            -
              setPreset = async (preset:  | 
| 73 | 
            +
              setPreset = async (preset: 'quality' | 'balanced') => {
         | 
| 74 74 | 
             
                if (this.effectsPlugin) {
         | 
| 75 75 | 
             
                  await this.effectsPlugin.setPreset(preset);
         | 
| 76 76 | 
             
                }
         | 
| @@ -28,7 +28,9 @@ const Root = ({ | |
| 28 28 | 
             
                  '&:hover': { border: '4px solid $primary_dim' },
         | 
| 29 29 | 
             
                  ...(mediaURL ? { height: '$20', backgroundImage: `url(${mediaURL})`, backgroundSize: 'cover' } : {}),
         | 
| 30 30 | 
             
                }}
         | 
| 31 | 
            -
                onClick={async () =>  | 
| 31 | 
            +
                onClick={async () => {
         | 
| 32 | 
            +
                  await onClick?.();
         | 
| 33 | 
            +
                }}
         | 
| 32 34 | 
             
              >
         | 
| 33 35 | 
             
                {children}
         | 
| 34 36 | 
             
              </Flex>
         | 
| @@ -1,4 +1,5 @@ | |
| 1 1 | 
             
            import React, { useEffect, useState } from 'react';
         | 
| 2 | 
            +
            import { useMedia } from 'react-use';
         | 
| 2 3 | 
             
            import {
         | 
| 3 4 | 
             
              selectAppData,
         | 
| 4 5 | 
             
              selectEffectsKey,
         | 
| @@ -19,14 +20,14 @@ import { | |
| 19 20 | 
             
              useHMSStore,
         | 
| 20 21 | 
             
            } from '@100mslive/react-sdk';
         | 
| 21 22 | 
             
            import { BlurPersonHighIcon, CrossCircleIcon, CrossIcon } from '@100mslive/react-icons';
         | 
| 22 | 
            -
            import { Box, Flex, Slider, Video } from '../../../index';
         | 
| 23 | 
            +
            import { Box, config as cssConfig, Flex, Loading, Slider, Video } from '../../../index';
         | 
| 23 24 | 
             
            import { Text } from '../../../Text';
         | 
| 24 25 | 
             
            import { VBCollection } from './VBCollection';
         | 
| 25 26 | 
             
            import { VBHandler } from './VBHandler';
         | 
| 26 27 | 
             
            // @ts-ignore
         | 
| 27 28 | 
             
            import { useSidepaneToggle } from '../AppData/useSidepane';
         | 
| 28 29 | 
             
            // @ts-ignore
         | 
| 29 | 
            -
            import { useUISettings } from '../AppData/useUISettings';
         | 
| 30 | 
            +
            import { useSetAppDataByKey, useUISettings } from '../AppData/useUISettings';
         | 
| 30 31 | 
             
            import { APP_DATA, SIDE_PANE_OPTIONS, UI_SETTINGS } from '../../common/constants';
         | 
| 31 32 | 
             
            import { defaultMedia } from './constants';
         | 
| 32 33 |  | 
| @@ -46,6 +47,8 @@ export const VBPicker = ({ backgroundMedia = [] }: { backgroundMedia: VirtualBac | |
| 46 47 | 
             
              const isLargeRoom = useHMSStore(selectIsLargeRoom);
         | 
| 47 48 | 
             
              const isEffectsEnabled = useHMSStore(selectIsEffectsEnabled);
         | 
| 48 49 | 
             
              const effectsKey = useHMSStore(selectEffectsKey);
         | 
| 50 | 
            +
              const isMobile = useMedia(cssConfig.media.md);
         | 
| 51 | 
            +
              const [loadingEffects, setLoadingEffects] = useSetAppDataByKey(APP_DATA.loadingEffects);
         | 
| 49 52 | 
             
              const isPluginAdded = useHMSStore(selectIsLocalVideoPluginPresent(VBHandler?.getName() || ''));
         | 
| 50 53 | 
             
              const background = useHMSStore(selectAppData(APP_DATA.background));
         | 
| 51 54 | 
             
              const mediaList = backgroundMedia.length
         | 
| @@ -61,13 +64,15 @@ export const VBPicker = ({ backgroundMedia = [] }: { backgroundMedia: VirtualBac | |
| 61 64 | 
             
                  return;
         | 
| 62 65 | 
             
                }
         | 
| 63 66 | 
             
                if (!isPluginAdded) {
         | 
| 67 | 
            +
                  setLoadingEffects(true);
         | 
| 64 68 | 
             
                  let vbObject = VBHandler.getVBObject();
         | 
| 65 69 | 
             
                  if (!vbObject) {
         | 
| 66 | 
            -
                    VBHandler.initialisePlugin(isEffectsEnabled && effectsKey ? effectsKey : '');
         | 
| 70 | 
            +
                    VBHandler.initialisePlugin(isEffectsEnabled && effectsKey ? effectsKey : '', () => setLoadingEffects(false));
         | 
| 67 71 | 
             
                    vbObject = VBHandler.getVBObject();
         | 
| 68 72 | 
             
                    if (isEffectsEnabled && effectsKey) {
         | 
| 69 73 | 
             
                      hmsActions.addPluginsToVideoStream([vbObject as HMSEffectsPlugin]);
         | 
| 70 74 | 
             
                    } else {
         | 
| 75 | 
            +
                      setLoadingEffects(false);
         | 
| 71 76 | 
             
                      if (!role) {
         | 
| 72 77 | 
             
                        return;
         | 
| 73 78 | 
             
                      }
         | 
| @@ -89,19 +94,30 @@ export const VBPicker = ({ backgroundMedia = [] }: { backgroundMedia: VirtualBac | |
| 89 94 | 
             
                  };
         | 
| 90 95 | 
             
                  handleDefaultBackground();
         | 
| 91 96 | 
             
                }
         | 
| 92 | 
            -
              }, [ | 
| 97 | 
            +
              }, [
         | 
| 98 | 
            +
                hmsActions,
         | 
| 99 | 
            +
                role,
         | 
| 100 | 
            +
                isPluginAdded,
         | 
| 101 | 
            +
                isEffectsEnabled,
         | 
| 102 | 
            +
                effectsKey,
         | 
| 103 | 
            +
                track?.id,
         | 
| 104 | 
            +
                background,
         | 
| 105 | 
            +
                blurAmount,
         | 
| 106 | 
            +
                setLoadingEffects,
         | 
| 107 | 
            +
              ]);
         | 
| 93 108 |  | 
| 94 109 | 
             
              useEffect(() => {
         | 
| 95 110 | 
             
                if (!isVideoOn) {
         | 
| 96 111 | 
             
                  toggleVB();
         | 
| 97 112 | 
             
                }
         | 
| 98 | 
            -
             | 
| 113 | 
            +
                return () => setLoadingEffects(false);
         | 
| 114 | 
            +
              }, [isVideoOn, setLoadingEffects, toggleVB]);
         | 
| 99 115 |  | 
| 100 116 | 
             
              return (
         | 
| 101 117 | 
             
                <Flex css={{ pr: '$6', size: '100%' }} direction="column">
         | 
| 102 118 | 
             
                  <Flex align="center" justify="between" css={{ w: '100%', background: '$surface_dim', pb: '$4' }}>
         | 
| 103 | 
            -
                    <Text variant="h6" css={{ color: '$on_surface_high' }}>
         | 
| 104 | 
            -
                      Virtual Background
         | 
| 119 | 
            +
                    <Text variant="h6" css={{ color: '$on_surface_high', display: 'flex', alignItems: 'center' }}>
         | 
| 120 | 
            +
                      Virtual Background {isMobile && loadingEffects ? <Loading size={18} style={{ marginLeft: '0.5rem' }} /> : ''}
         | 
| 105 121 | 
             
                    </Text>
         | 
| 106 122 | 
             
                    <Box
         | 
| 107 123 | 
             
                      css={{ color: '$on_surface_high', '&:hover': { color: '$on_surface_medium' }, cursor: 'pointer' }}
         | 
| @@ -1,17 +1,19 @@ | |
| 1 1 | 
             
            import React from 'react';
         | 
| 2 | 
            -
            import { selectIsEffectsEnabled, selectIsLocalVideoEnabled, useHMSStore } from '@100mslive/react-sdk';
         | 
| 2 | 
            +
            import { selectAppData, selectIsEffectsEnabled, selectIsLocalVideoEnabled, useHMSStore } from '@100mslive/react-sdk';
         | 
| 3 3 | 
             
            import { VirtualBackgroundIcon } from '@100mslive/react-icons';
         | 
| 4 | 
            +
            import { Loading } from '../../../Loading';
         | 
| 4 5 | 
             
            import { Tooltip } from '../../../Tooltip';
         | 
| 5 6 | 
             
            import IconButton from '../../IconButton';
         | 
| 6 7 | 
             
            // @ts-ignore
         | 
| 7 8 | 
             
            import { useIsSidepaneTypeOpen, useSidepaneToggle } from '../AppData/useSidepane';
         | 
| 8 | 
            -
            import { isSafari, SIDE_PANE_OPTIONS } from '../../common/constants';
         | 
| 9 | 
            +
            import { APP_DATA, isSafari, SIDE_PANE_OPTIONS } from '../../common/constants';
         | 
| 9 10 |  | 
| 10 11 | 
             
            export const VBToggle = () => {
         | 
| 11 12 | 
             
              const toggleVB = useSidepaneToggle(SIDE_PANE_OPTIONS.VB);
         | 
| 12 13 | 
             
              const isVBOpen = useIsSidepaneTypeOpen(SIDE_PANE_OPTIONS.VB);
         | 
| 13 14 | 
             
              const isVideoOn = useHMSStore(selectIsLocalVideoEnabled);
         | 
| 14 15 | 
             
              const isEffectsEnabled = useHMSStore(selectIsEffectsEnabled);
         | 
| 16 | 
            +
              const loadingEffects = useHMSStore(selectAppData(APP_DATA.loadingEffects));
         | 
| 15 17 |  | 
| 16 18 | 
             
              if (!isVideoOn || (!isEffectsEnabled && isSafari)) {
         | 
| 17 19 | 
             
                return null;
         | 
| @@ -20,7 +22,7 @@ export const VBToggle = () => { | |
| 20 22 | 
             
              return (
         | 
| 21 23 | 
             
                <Tooltip side="top" disabled={isVBOpen} title="Configure Virtual Background">
         | 
| 22 24 | 
             
                  <IconButton active={!isVBOpen} onClick={toggleVB} data-testid="virtual_bg_btn">
         | 
| 23 | 
            -
                    <VirtualBackgroundIcon />
         | 
| 25 | 
            +
                    {loadingEffects ? <Loading size={18} /> : <VirtualBackgroundIcon />}
         | 
| 24 26 | 
             
                  </IconButton>
         | 
| 25 27 | 
             
                </Tooltip>
         | 
| 26 28 | 
             
              );
         | 
| @@ -6,7 +6,6 @@ import { | |
| 6 6 | 
             
            } from '@100mslive/types-prebuilt';
         | 
| 7 7 | 
             
            import { match } from 'ts-pattern';
         | 
| 8 8 | 
             
            import { selectIsConnectedToRoom, selectLocalPeerRoleName, useHMSActions, useHMSStore } from '@100mslive/react-sdk';
         | 
| 9 | 
            -
            // @ts-ignore: No implicit Any
         | 
| 10 9 | 
             
            import FullPageProgress from '../components/FullPageProgress';
         | 
| 11 10 | 
             
            import { GridLayout } from '../components/VideoLayouts/GridLayout';
         | 
| 12 11 | 
             
            import { Box, Flex } from '../../Layout';
         | 
| @@ -25,7 +24,6 @@ import { | |
| 25 24 | 
             
            } from '../components/AppData/useUISettings';
         | 
| 26 25 | 
             
            import { useCloseScreenshareWhiteboard } from '../components/hooks/useCloseScreenshareWhiteboard';
         | 
| 27 26 | 
             
            import { useLandscapeHLSStream, useMobileHLSStream } from '../common/hooks';
         | 
| 28 | 
            -
            // @ts-ignore: No implicit Any
         | 
| 29 27 | 
             
            import { SESSION_STORE_KEY } from '../common/constants';
         | 
| 30 28 |  | 
| 31 29 | 
             
            // @ts-ignore: No implicit Any
         | 
| @@ -107,7 +105,6 @@ export const VideoStreamingSection = ({ | |
| 107 105 | 
             
                        // @ts-ignore
         | 
| 108 106 | 
             
                        return <GridLayout {...(elements as DefaultConferencingScreen_Elements)?.video_tile_layout?.grid} />;
         | 
| 109 107 | 
             
                      })}
         | 
| 110 | 
            -
             | 
| 111 108 | 
             
                    <Box
         | 
| 112 109 | 
             
                      css={{
         | 
| 113 110 | 
             
                        flex: match({ isLandscapeHLSStream, isMobileHLSStream })
         | 
| @@ -0,0 +1,191 @@ | |
| 1 | 
            +
            import React, { useEffect, useState } from 'react';
         | 
| 2 | 
            +
            import { HMSTranscript, selectPeerNameByID, useHMSStore, useTranscript } from '@100mslive/react-sdk';
         | 
| 3 | 
            +
            import { Flex } from '../../Layout';
         | 
| 4 | 
            +
            import { Text } from '../../Text';
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            interface CaptionQueueData extends HMSTranscript {
         | 
| 7 | 
            +
              transcriptQueue: SimpleQueue;
         | 
| 8 | 
            +
            }
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            interface TranscriptData extends HMSTranscript {
         | 
| 11 | 
            +
              timeout?: NodeJS.Timeout | undefined;
         | 
| 12 | 
            +
            }
         | 
| 13 | 
            +
            class SimpleQueue {
         | 
| 14 | 
            +
              private storage: TranscriptData[] = [];
         | 
| 15 | 
            +
              constructor(private capacity: number = 3, private MAX_STORAGE_TIME: number = 5000) {}
         | 
| 16 | 
            +
              enqueue(data: TranscriptData): void {
         | 
| 17 | 
            +
                if (this.size() === this.capacity && this.storage[this.size() - 1].final) {
         | 
| 18 | 
            +
                  this.dequeue(this.storage[this.size() - 1]);
         | 
| 19 | 
            +
                }
         | 
| 20 | 
            +
                if (this.size() === 0) {
         | 
| 21 | 
            +
                  this.storage.push(data);
         | 
| 22 | 
            +
                  this.addTimeout(this.storage[this.size() - 1], data.final);
         | 
| 23 | 
            +
                  return;
         | 
| 24 | 
            +
                }
         | 
| 25 | 
            +
                if (this.size() > 0 && this.storage[this.size() - 1]?.final === true) {
         | 
| 26 | 
            +
                  this.storage.push(data);
         | 
| 27 | 
            +
                  this.addTimeout(this.storage[this.size() - 1], data.final);
         | 
| 28 | 
            +
                  return;
         | 
| 29 | 
            +
                }
         | 
| 30 | 
            +
                this.storage[this.size() - 1].transcript = data.transcript;
         | 
| 31 | 
            +
                this.storage[this.size() - 1].final = data.final;
         | 
| 32 | 
            +
                this.storage[this.size() - 1].end = data.end;
         | 
| 33 | 
            +
                this.addTimeout(this.storage[this.size() - 1], data.final);
         | 
| 34 | 
            +
              }
         | 
| 35 | 
            +
              addTimeout(item: TranscriptData, isFinal: boolean) {
         | 
| 36 | 
            +
                if (!isFinal) {
         | 
| 37 | 
            +
                  return;
         | 
| 38 | 
            +
                }
         | 
| 39 | 
            +
                item.timeout = setTimeout(() => {
         | 
| 40 | 
            +
                  this.dequeue(item);
         | 
| 41 | 
            +
                }, this.MAX_STORAGE_TIME);
         | 
| 42 | 
            +
              }
         | 
| 43 | 
            +
              dequeue(item: TranscriptData): TranscriptData | undefined {
         | 
| 44 | 
            +
                const index = this.storage.indexOf(item);
         | 
| 45 | 
            +
                if (index === -1) {
         | 
| 46 | 
            +
                  return undefined;
         | 
| 47 | 
            +
                }
         | 
| 48 | 
            +
                const removedItem = this.storage.splice(index, 1);
         | 
| 49 | 
            +
                if (removedItem.length <= 0) {
         | 
| 50 | 
            +
                  return undefined;
         | 
| 51 | 
            +
                }
         | 
| 52 | 
            +
                this.clearTimeout(removedItem[0]);
         | 
| 53 | 
            +
                return item;
         | 
| 54 | 
            +
              }
         | 
| 55 | 
            +
              clearTimeout(item: TranscriptData) {
         | 
| 56 | 
            +
                if (!item.timeout) {
         | 
| 57 | 
            +
                  return;
         | 
| 58 | 
            +
                }
         | 
| 59 | 
            +
                clearTimeout(item.timeout);
         | 
| 60 | 
            +
              }
         | 
| 61 | 
            +
              peek(): TranscriptData | undefined {
         | 
| 62 | 
            +
                if (this.size() <= 0) {
         | 
| 63 | 
            +
                  return undefined;
         | 
| 64 | 
            +
                }
         | 
| 65 | 
            +
                return this.storage[0];
         | 
| 66 | 
            +
              }
         | 
| 67 | 
            +
              getTranscription(): string {
         | 
| 68 | 
            +
                let script = '';
         | 
| 69 | 
            +
                this.storage.forEach((value: TranscriptData) => (script += value.transcript + ' '));
         | 
| 70 | 
            +
                return script;
         | 
| 71 | 
            +
              }
         | 
| 72 | 
            +
              reset() {
         | 
| 73 | 
            +
                this.storage.length = 0;
         | 
| 74 | 
            +
              }
         | 
| 75 | 
            +
              size(): number {
         | 
| 76 | 
            +
                return this.storage.length;
         | 
| 77 | 
            +
              }
         | 
| 78 | 
            +
            }
         | 
| 79 | 
            +
            class Queue {
         | 
| 80 | 
            +
              private storage: Record<string, CaptionQueueData> = {};
         | 
| 81 | 
            +
              constructor(private capacity: number = 3) {}
         | 
| 82 | 
            +
             | 
| 83 | 
            +
              enqueue(data: HMSTranscript): void {
         | 
| 84 | 
            +
                if (this.size() === this.capacity) {
         | 
| 85 | 
            +
                  this.dequeue();
         | 
| 86 | 
            +
                }
         | 
| 87 | 
            +
                if (!this.storage[data.peer_id]) {
         | 
| 88 | 
            +
                  this.storage[data.peer_id] = {
         | 
| 89 | 
            +
                    peer_id: data.peer_id,
         | 
| 90 | 
            +
                    transcript: data.transcript,
         | 
| 91 | 
            +
                    final: data.final,
         | 
| 92 | 
            +
                    transcriptQueue: new SimpleQueue(),
         | 
| 93 | 
            +
                    start: data.start,
         | 
| 94 | 
            +
                    end: data.end,
         | 
| 95 | 
            +
                  };
         | 
| 96 | 
            +
                  this.storage[data.peer_id].transcriptQueue.enqueue(data as TranscriptData);
         | 
| 97 | 
            +
                  return;
         | 
| 98 | 
            +
                }
         | 
| 99 | 
            +
                this.storage[data.peer_id].transcriptQueue.enqueue(data as TranscriptData);
         | 
| 100 | 
            +
              }
         | 
| 101 | 
            +
              dequeue(): CaptionQueueData {
         | 
| 102 | 
            +
                const key: string = Object.keys(this.storage).shift() || '';
         | 
| 103 | 
            +
                const captionData = this.storage[key];
         | 
| 104 | 
            +
                captionData.transcriptQueue.reset();
         | 
| 105 | 
            +
                delete this.storage[key];
         | 
| 106 | 
            +
                return captionData;
         | 
| 107 | 
            +
              }
         | 
| 108 | 
            +
             | 
| 109 | 
            +
              peek(): CaptionQueueData | undefined {
         | 
| 110 | 
            +
                if (this.size() <= 0) return undefined;
         | 
| 111 | 
            +
                const key: string = Object.keys(this.storage).shift() || '';
         | 
| 112 | 
            +
                return this.storage[key];
         | 
| 113 | 
            +
              }
         | 
| 114 | 
            +
             | 
| 115 | 
            +
              findPeerData(): { [key: string]: string }[] {
         | 
| 116 | 
            +
                const keys = Object.keys(this.storage);
         | 
| 117 | 
            +
                const data = keys.map((key: string) => {
         | 
| 118 | 
            +
                  const data = this.storage[key];
         | 
| 119 | 
            +
                  const word = data.transcriptQueue.getTranscription();
         | 
| 120 | 
            +
                  return { [key]: word };
         | 
| 121 | 
            +
                });
         | 
| 122 | 
            +
                return data;
         | 
| 123 | 
            +
              }
         | 
| 124 | 
            +
              size(): number {
         | 
| 125 | 
            +
                return Object.keys(this.storage).length;
         | 
| 126 | 
            +
              }
         | 
| 127 | 
            +
            }
         | 
| 128 | 
            +
             | 
| 129 | 
            +
            class CaptionMaintainerQueue {
         | 
| 130 | 
            +
              captionData: Queue = new Queue();
         | 
| 131 | 
            +
              push(data: HMSTranscript[] = []) {
         | 
| 132 | 
            +
                data.forEach((value: HMSTranscript) => {
         | 
| 133 | 
            +
                  this.captionData.enqueue(value);
         | 
| 134 | 
            +
                });
         | 
| 135 | 
            +
              }
         | 
| 136 | 
            +
            }
         | 
| 137 | 
            +
            const TranscriptView = ({ peer_id, data }: { peer_id: string; data: string }) => {
         | 
| 138 | 
            +
              const peerName = useHMSStore(selectPeerNameByID(peer_id));
         | 
| 139 | 
            +
              data = data.trim();
         | 
| 140 | 
            +
              if (!data) return null;
         | 
| 141 | 
            +
              return (
         | 
| 142 | 
            +
                <Text
         | 
| 143 | 
            +
                  variant="body2"
         | 
| 144 | 
            +
                  css={{
         | 
| 145 | 
            +
                    fontWeight: '$normal',
         | 
| 146 | 
            +
                  }}
         | 
| 147 | 
            +
                >
         | 
| 148 | 
            +
                  {`${peerName}: ${data}`}
         | 
| 149 | 
            +
                </Text>
         | 
| 150 | 
            +
              );
         | 
| 151 | 
            +
            };
         | 
| 152 | 
            +
             | 
| 153 | 
            +
            export const CaptionsViewer = () => {
         | 
| 154 | 
            +
              const [captionQueue] = useState<CaptionMaintainerQueue>(new CaptionMaintainerQueue());
         | 
| 155 | 
            +
              const [currentData, setCurrentData] = useState<{ [key: string]: string }[]>([]);
         | 
| 156 | 
            +
             | 
| 157 | 
            +
              useEffect(() => {
         | 
| 158 | 
            +
                const timeInterval = setInterval(() => {
         | 
| 159 | 
            +
                  if (!captionQueue) {
         | 
| 160 | 
            +
                    return;
         | 
| 161 | 
            +
                  }
         | 
| 162 | 
            +
                  const data = captionQueue.captionData?.findPeerData();
         | 
| 163 | 
            +
                  setCurrentData(data);
         | 
| 164 | 
            +
                }, 1000);
         | 
| 165 | 
            +
                return () => clearInterval(timeInterval);
         | 
| 166 | 
            +
              }, [captionQueue]);
         | 
| 167 | 
            +
             | 
| 168 | 
            +
              useTranscript({
         | 
| 169 | 
            +
                onTranscript: (data: HMSTranscript[]) => {
         | 
| 170 | 
            +
                  captionQueue && captionQueue.push(data as HMSTranscript[]);
         | 
| 171 | 
            +
                },
         | 
| 172 | 
            +
              });
         | 
| 173 | 
            +
              const dataToShow = currentData.filter((data: { [key: string]: string }) => {
         | 
| 174 | 
            +
                const key = Object.keys(data)[0];
         | 
| 175 | 
            +
                if (data[key]) {
         | 
| 176 | 
            +
                  return true;
         | 
| 177 | 
            +
                }
         | 
| 178 | 
            +
                return false;
         | 
| 179 | 
            +
              });
         | 
| 180 | 
            +
              if (dataToShow.length <= 0) {
         | 
| 181 | 
            +
                return null;
         | 
| 182 | 
            +
              }
         | 
| 183 | 
            +
              return (
         | 
| 184 | 
            +
                <Flex direction="column" gap={1}>
         | 
| 185 | 
            +
                  {dataToShow.map((data: { [key: string]: string }, index: number) => {
         | 
| 186 | 
            +
                    const key = Object.keys(data)[0];
         | 
| 187 | 
            +
                    return <TranscriptView key={index} peer_id={key} data={data[key]} />;
         | 
| 188 | 
            +
                  })}
         | 
| 189 | 
            +
                </Flex>
         | 
| 190 | 
            +
              );
         | 
| 191 | 
            +
            };
         |