@azure/communication-react 1.29.0-alpha-202506180019 → 1.29.0-alpha-202506190019

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.
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-VVb1N1dl.js');
3
+ var index = require('./index-CHekJd1H.js');
4
4
  require('react');
5
5
  require('@fluentui/react');
6
6
  require('@fluentui/react-components');
@@ -2,5 +2,5 @@
2
2
  // Copyright (c) Microsoft Corporation.
3
3
  // Licensed under the MIT License.
4
4
  // GENERATED FILE. DO NOT EDIT MANUALLY.
5
- module.exports = '1.29.0-alpha-202506180019';
5
+ module.exports = '1.29.0-alpha-202506190019';
6
6
  //# sourceMappingURL=telemetryVersion.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"telemetryVersion.js","sourceRoot":"","sources":["../../../../../acs-ui-common/src/telemetryVersion.js"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;AAElC,wCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,2BAA2B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n// GENERATED FILE. DO NOT EDIT MANUALLY.\n\nmodule.exports = '1.29.0-alpha-202506180019';\n"]}
1
+ {"version":3,"file":"telemetryVersion.js","sourceRoot":"","sources":["../../../../../acs-ui-common/src/telemetryVersion.js"],"names":[],"mappings":";AAAA,uCAAuC;AACvC,kCAAkC;AAElC,wCAAwC;AAExC,MAAM,CAAC,OAAO,GAAG,2BAA2B,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\n\n// GENERATED FILE. DO NOT EDIT MANUALLY.\n\nmodule.exports = '1.29.0-alpha-202506190019';\n"]}
@@ -0,0 +1,28 @@
1
+ /// <reference types="react" />
2
+ import { CaptionsInformation, RealTimeTextInformation } from './CaptionsBanner';
3
+ /** @internal */
4
+ export type _CaptionsAndRTTAnnouncerProps = {
5
+ /**
6
+ * Array of captions to be displayed
7
+ */
8
+ captions: CaptionsInformation[];
9
+ /**
10
+ * Array of finalized and partial real time text messages
11
+ */
12
+ realTimeTexts?: {
13
+ completedMessages?: RealTimeTextInformation[];
14
+ currentInProgress?: RealTimeTextInformation[];
15
+ myInProgress?: RealTimeTextInformation;
16
+ };
17
+ /**
18
+ * Title for the real time text messages
19
+ */
20
+ realTimeTextTitle: string;
21
+ /**
22
+ * Title for the captions
23
+ */
24
+ captionsTitle: string;
25
+ };
26
+ /** @internal */
27
+ export declare const _CaptionsAndRTTAnnouncer: (props: _CaptionsAndRTTAnnouncerProps) => JSX.Element;
28
+ //# sourceMappingURL=CaptionsAndRTTAnnouncer.d.ts.map
@@ -0,0 +1,44 @@
1
+ // Copyright (c) Microsoft Corporation.
2
+ // Licensed under the MIT License.
3
+ import React, { useEffect, useState } from 'react';
4
+ import { hiddenAnnouncementClassName } from './styles/Captions.style';
5
+ /** @internal */
6
+ export const _CaptionsAndRTTAnnouncer = (props) => {
7
+ const { captions, realTimeTexts, realTimeTextTitle, captionsTitle } = props;
8
+ const [announcedRTT, setAnnouncedRTT] = useState([]);
9
+ const [announcedCaption, setAnnouncedCaption] = useState([]);
10
+ const [captionAnnouncementText, setCaptionAnnouncementText] = useState([]);
11
+ const [rttAnnouncementText, setRTTAnnouncementText] = useState([]);
12
+ useEffect(() => {
13
+ if (realTimeTexts === null || realTimeTexts === void 0 ? void 0 : realTimeTexts.completedMessages) {
14
+ //filter out the messages that have already been announced
15
+ const rTTMessagesToAnnounce = realTimeTexts.completedMessages.filter((message) => !announcedRTT.includes(message.id));
16
+ if (rTTMessagesToAnnounce.length > 0) {
17
+ setRTTAnnouncementText(rTTMessagesToAnnounce);
18
+ setAnnouncedRTT((prev) => [...prev, ...rTTMessagesToAnnounce.map((message) => message.id)]);
19
+ }
20
+ }
21
+ if (captions.length > 0) {
22
+ // filter out the captions that have already been announced
23
+ const captionsToAnnounce = captions.filter((caption) => !announcedCaption.includes(caption.id) && caption.isFinalized);
24
+ if (captionsToAnnounce.length > 0) {
25
+ setCaptionAnnouncementText(captionsToAnnounce);
26
+ setAnnouncedCaption((prev) => [...prev, ...captionsToAnnounce.map((caption) => caption.id)]);
27
+ }
28
+ }
29
+ }, [captions, realTimeTexts === null || realTimeTexts === void 0 ? void 0 : realTimeTexts.completedMessages, announcedRTT, announcedCaption]);
30
+ return (React.createElement(React.Fragment, null, (rttAnnouncementText.length > 0 || (captionAnnouncementText === null || captionAnnouncementText === void 0 ? void 0 : captionAnnouncementText.length) > 0) && (React.createElement("div", { "aria-live": "assertive", role: "alert", "aria-atomic": "true", className: hiddenAnnouncementClassName },
31
+ React.createElement("span", null, rttAnnouncementText.map((text) => (React.createElement("span", null,
32
+ realTimeTextTitle,
33
+ " ",
34
+ text.displayName,
35
+ ": ",
36
+ text.message)))),
37
+ React.createElement("span", null, captionAnnouncementText.map((text) => (React.createElement("span", null,
38
+ captionsTitle,
39
+ " ",
40
+ text.displayName,
41
+ ": ",
42
+ text.captionText))))))));
43
+ };
44
+ //# sourceMappingURL=CaptionsAndRTTAnnouncer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CaptionsAndRTTAnnouncer.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/CaptionsAndRTTAnnouncer.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport React, { useEffect, useState } from 'react';\nimport { hiddenAnnouncementClassName } from './styles/Captions.style';\nimport { CaptionsInformation, RealTimeTextInformation } from './CaptionsBanner';\n\n/** @internal */\nexport type _CaptionsAndRTTAnnouncerProps = {\n /**\n * Array of captions to be displayed\n */\n captions: CaptionsInformation[];\n /**\n * Array of finalized and partial real time text messages\n */\n realTimeTexts?: {\n completedMessages?: RealTimeTextInformation[];\n currentInProgress?: RealTimeTextInformation[];\n myInProgress?: RealTimeTextInformation;\n };\n /**\n * Title for the real time text messages\n */\n realTimeTextTitle: string;\n /**\n * Title for the captions\n */\n captionsTitle: string;\n};\n\n/** @internal */\nexport const _CaptionsAndRTTAnnouncer = (props: _CaptionsAndRTTAnnouncerProps): JSX.Element => {\n const { captions, realTimeTexts, realTimeTextTitle, captionsTitle } = props;\n const [announcedRTT, setAnnouncedRTT] = useState<number[]>([]);\n const [announcedCaption, setAnnouncedCaption] = useState<string[]>([]);\n const [captionAnnouncementText, setCaptionAnnouncementText] = useState<CaptionsInformation[]>([]);\n const [rttAnnouncementText, setRTTAnnouncementText] = useState<RealTimeTextInformation[]>([]);\n\n useEffect(() => {\n if (realTimeTexts?.completedMessages) {\n //filter out the messages that have already been announced\n const rTTMessagesToAnnounce = realTimeTexts.completedMessages.filter(\n (message) => !announcedRTT.includes(message.id)\n );\n if (rTTMessagesToAnnounce.length > 0) {\n setRTTAnnouncementText(rTTMessagesToAnnounce);\n setAnnouncedRTT((prev) => [...prev, ...rTTMessagesToAnnounce.map((message) => message.id)]);\n }\n }\n if (captions.length > 0) {\n // filter out the captions that have already been announced\n const captionsToAnnounce = captions.filter(\n (caption) => !announcedCaption.includes(caption.id) && caption.isFinalized\n );\n if (captionsToAnnounce.length > 0) {\n setCaptionAnnouncementText(captionsToAnnounce);\n setAnnouncedCaption((prev) => [...prev, ...captionsToAnnounce.map((caption) => caption.id)]);\n }\n }\n }, [captions, realTimeTexts?.completedMessages, announcedRTT, announcedCaption]);\n return (\n <>\n {(rttAnnouncementText.length > 0 || captionAnnouncementText?.length > 0) && (\n <div aria-live=\"assertive\" role=\"alert\" aria-atomic=\"true\" className={hiddenAnnouncementClassName}>\n <span>\n {rttAnnouncementText.map((text) => (\n <span>\n {realTimeTextTitle} {text.displayName}: {text.message}\n </span>\n ))}\n </span>\n <span>\n {captionAnnouncementText.map((text) => (\n <span>\n {captionsTitle} {text.displayName}: {text.captionText}\n </span>\n ))}\n </span>\n </div>\n )}\n </>\n );\n};\n"]}
@@ -5,7 +5,7 @@ import { TextField } from '@fluentui/react';
5
5
  import React, { useEffect, useRef, useState, useCallback } from 'react';
6
6
  import { useMemo } from 'react';
7
7
  import { _Caption } from './Caption';
8
- import { captionContainerClassName, captionsBannerClassName, captionsBannerFullHeightClassName, captionsContainerClassName, hiddenAnnouncementClassName, loadingBannerFullHeightStyles, loadingBannerStyles } from './styles/Captions.style';
8
+ import { captionContainerClassName, captionsBannerClassName, captionsBannerFullHeightClassName, captionsContainerClassName, loadingBannerFullHeightStyles, loadingBannerStyles } from './styles/Captions.style';
9
9
  import { rttDisclosureBannerClassName } from './styles/Captions.style';
10
10
  import { useLocale } from '../localization';
11
11
  import { RealTimeText } from './RealTimeText';
@@ -14,13 +14,14 @@ import { sortCaptionsAndRealTimeTexts } from './utils/sortCaptionsAndRealTimeTex
14
14
  import { expandIconClassName, bannerTitleContainerClassName, realTimeTextInputBoxStyles } from './styles/Captions.style';
15
15
  import { titleClassName } from './styles/CaptionsSettingsModal.styles';
16
16
  import { Text, IconButton } from '@fluentui/react';
17
+ import { _CaptionsAndRTTAnnouncer } from './CaptionsAndRTTAnnouncer';
17
18
  const SCROLL_OFFSET_ALLOWANCE = 20;
18
19
  /**
19
20
  * @public
20
21
  * A component for displaying a CaptionsBanner with user icon, displayName and captions text.
21
22
  */
22
23
  export const CaptionsBanner = (props) => {
23
- var _a, _b, _c;
24
+ var _a, _b, _c, _d, _e;
24
25
  const { captions, realTimeTexts, isCaptionsOn, startCaptionsInProgress, onRenderAvatar, formFactor = 'default', captionsOptions, isRealTimeTextOn, onSendRealTimeText, latestLocalRealTimeText } = props;
25
26
  const localeStrings = useLocale().strings.captionsBanner;
26
27
  const strings = Object.assign(Object.assign({}, localeStrings), props.strings);
@@ -28,10 +29,6 @@ export const CaptionsBanner = (props) => {
28
29
  const [isAtBottomOfScroll, setIsAtBottomOfScroll] = useState(true);
29
30
  const theme = useTheme();
30
31
  const [expandBannerHeight, setExpandBannerHeight] = useState(false);
31
- const [announcedRTT, setAnnouncedRTT] = useState([]);
32
- const [announcedCaption, setAnnouncedCaption] = useState([]);
33
- const [captionAnnouncementText, setCaptionAnnouncementText] = useState([]);
34
- const [rttAnnouncementText, setRTTAnnouncementText] = useState([]);
35
32
  const getTitle = () => {
36
33
  var _a, _b, _c;
37
34
  if (isCaptionsOn && isRealTimeTextOn) {
@@ -88,24 +85,6 @@ export const CaptionsBanner = (props) => {
88
85
  setTextFieldValue('');
89
86
  }
90
87
  }, [latestLocalRealTimeText]);
91
- useEffect(() => {
92
- if (realTimeTexts === null || realTimeTexts === void 0 ? void 0 : realTimeTexts.completedMessages) {
93
- //filter out the messages that have already been announced
94
- const rTTMessagesToAnnounce = realTimeTexts.completedMessages.filter((message) => !announcedRTT.includes(message.id));
95
- if (rTTMessagesToAnnounce.length > 0) {
96
- setRTTAnnouncementText(rTTMessagesToAnnounce);
97
- setAnnouncedRTT((prev) => [...prev, ...rTTMessagesToAnnounce.map((message) => message.id)]);
98
- }
99
- }
100
- if (captions.length > 0) {
101
- // filter out the captions that have already been announced
102
- const captionsToAnnounce = captions.filter((caption) => !announcedCaption.includes(caption.id) && caption.isFinalized);
103
- if (captionsToAnnounce.length > 0) {
104
- setCaptionAnnouncementText(captionsToAnnounce);
105
- setAnnouncedCaption((prev) => [...prev, ...captionsToAnnounce.map((caption) => caption.id)]);
106
- }
107
- }
108
- }, [captions, realTimeTexts === null || realTimeTexts === void 0 ? void 0 : realTimeTexts.completedMessages, announcedRTT, announcedCaption]);
109
88
  const handleKeyDown = (event) => {
110
89
  if (event.key === 'Enter') {
111
90
  event.preventDefault();
@@ -133,19 +112,7 @@ export const CaptionsBanner = (props) => {
133
112
  })));
134
113
  };
135
114
  return (React.createElement(React.Fragment, null, (startCaptionsInProgress || isCaptionsOn || isRealTimeTextOn) && (React.createElement(FocusZone, { shouldFocusOnMount: true, className: captionsContainerClassName, "data-ui-id": "captions-banner" },
136
- (rttAnnouncementText.length > 0 || (captionAnnouncementText === null || captionAnnouncementText === void 0 ? void 0 : captionAnnouncementText.length) > 0) && (React.createElement("div", { "aria-live": "assertive", role: "alert", "aria-atomic": "true", className: hiddenAnnouncementClassName },
137
- React.createElement("span", null, rttAnnouncementText.map((text) => (React.createElement("span", null,
138
- strings.realTimeTextBannerTitle,
139
- " ",
140
- text.displayName,
141
- ": ",
142
- text.message)))),
143
- React.createElement("span", null, captionAnnouncementText.map((text) => (React.createElement("span", null,
144
- strings.captionsOnlyContainerTitle,
145
- " ",
146
- text.displayName,
147
- ": ",
148
- text.captionText)))))),
115
+ React.createElement(_CaptionsAndRTTAnnouncer, { captions: captions, realTimeTexts: realTimeTexts, realTimeTextTitle: (_d = strings.realTimeTextBannerTitle) !== null && _d !== void 0 ? _d : '', captionsTitle: (_e = strings.captionsOnlyContainerTitle) !== null && _e !== void 0 ? _e : '' }),
149
116
  (isCaptionsOn || isRealTimeTextOn) && formFactor === 'compact' && (React.createElement(Stack, { horizontal: true, horizontalAlign: "space-between", verticalAlign: "center", className: bannerTitleContainerClassName },
150
117
  React.createElement(Text, { className: titleClassName }, getTitle()),
151
118
  React.createElement(IconButton, { "data-ui-id": "captions-banner-expand-icon", iconProps: { iconName: expandBannerHeight ? 'MinimizeIcon' : 'ExpandIcon' }, ariaLabel: expandBannerHeight ? strings.minimizeButtonAriaLabel : strings.expandButtonAriaLabel, onClick: () => setExpandBannerHeight(!expandBannerHeight), styles: expandIconClassName(theme) }))),
@@ -1 +1 @@
1
- {"version":3,"file":"CaptionsBanner.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/CaptionsBanner.tsx"],"names":[],"mappings":"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","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Stack, FocusZone, Spinner, useTheme } from '@fluentui/react';\nimport { TextField } from '@fluentui/react';\nimport React, { useEffect, useRef, useState, useCallback } from 'react';\nimport { useMemo } from 'react';\nimport { _Caption } from './Caption';\nimport {\n captionContainerClassName,\n captionsBannerClassName,\n captionsBannerFullHeightClassName,\n captionsContainerClassName,\n hiddenAnnouncementClassName,\n loadingBannerFullHeightStyles,\n loadingBannerStyles\n} from './styles/Captions.style';\nimport { rttDisclosureBannerClassName } from './styles/Captions.style';\nimport { OnRenderAvatarCallback } from '../types';\nimport { useLocale } from '../localization';\nimport { RealTimeText } from './RealTimeText';\nimport { _RTTDisclosureBanner } from './RTTDisclosureBanner';\nimport { sortCaptionsAndRealTimeTexts } from './utils/sortCaptionsAndRealTimeTexts';\nimport {\n expandIconClassName,\n bannerTitleContainerClassName,\n realTimeTextInputBoxStyles\n} from './styles/Captions.style';\nimport { titleClassName } from './styles/CaptionsSettingsModal.styles';\nimport { Text, IconButton } from '@fluentui/react';\n\n/**\n * @public\n * information required for each line of caption\n */\nexport type CaptionsInformation = {\n /**\n * unique id for each caption\n */\n id: string;\n /**\n * speaker's display name\n */\n displayName: string;\n /**\n * content of the caption\n */\n captionText: string;\n /**\n * id of the speaker\n */\n userId?: string;\n /**\n * timestamp when the caption was created\n * Please note that this value is essential for determining the order of captions and real time text messages\n * If you are using both captions and real time text, please ensure that the createdTimeStamp is populated\n */\n createdTimeStamp?: Date;\n /**\n * If caption is finalized\n */\n isFinalized?: boolean;\n};\n\n/**\n * @public\n * information required for each line of real time text\n */\nexport type RealTimeTextInformation = {\n /**\n * The id of the real time text.\n */\n id: number;\n /**\n * sender's display name\n */\n displayName: string;\n /**\n * id of the sender\n */\n userId?: string;\n /**\n * The real time text message.\n */\n message: string;\n /**\n * if the real time text received is partial\n */\n isTyping: boolean;\n /**\n * timestamp when the real time text was finalized\n */\n finalizedTimeStamp: Date;\n /**\n * If message originated from the local participant\n * default value is false\n */\n isMe?: boolean;\n};\n/**\n * @public\n * strings for captions banner\n */\nexport interface CaptionsBannerStrings {\n /**\n * Spinner text for captions banner\n */\n captionsBannerSpinnerText?: string;\n\n /**\n * Default text for RTT input text box\n */\n realTimeTextInputBoxDefaultText?: string;\n\n /**\n * Error message for RTT input text box when the size exceeds the limit 2000\n */\n realTimeTextInputErrorMessage?: string;\n\n /**\n * Real time text disclosure banner title\n */\n realTimeTextBannerTitle?: string;\n\n /**\n * Real time text disclosure banner content\n */\n realTimeTextBannerContent?: string;\n\n /**\n * Real time text disclosure banner link label\n */\n realTimeTextBannerLinkLabel?: string;\n\n /**\n * Title for the container when only captions is enabled\n */\n captionsOnlyContainerTitle?: string;\n /**\n * Title for the container when only real time text is enabled\n */\n realTimeTextOnlyContainerTitle?: string;\n /**\n * Title for the container when both captions and real time text is enabled\n */\n captionsAndRealTimeTextContainerTitle?: string;\n /**\n * Expand button aria label\n */\n expandButtonAriaLabel?: string;\n /**\n * Minimize button aria label\n */\n minimizeButtonAriaLabel?: string;\n}\n\n/**\n * @public\n * CaptionsBanner Component Props.\n */\nexport interface CaptionsBannerProps {\n /**\n * Array of captions to be displayed\n */\n captions: CaptionsInformation[];\n /**\n * Array of finalized and partial real time text messages\n */\n realTimeTexts?: {\n completedMessages?: RealTimeTextInformation[];\n currentInProgress?: RealTimeTextInformation[];\n myInProgress?: RealTimeTextInformation;\n };\n /**\n * Flag to indicate if captions are on\n */\n isCaptionsOn?: boolean;\n\n /**\n * Flag to indicate if real time text is on\n */\n isRealTimeTextOn?: boolean;\n /**\n * Flag to indicate if captions are being started\n * This is used to show spinner while captions are being started\n */\n startCaptionsInProgress?: boolean;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n /**\n * Optional strings for the component\n */\n strings?: CaptionsBannerStrings;\n /**\n * Optional form factor for the component.\n * @defaultValue 'default'\n */\n formFactor?: 'default' | 'compact';\n /**\n * Optional options for the component.\n */\n captionsOptions?: {\n height: 'full' | 'default';\n };\n\n /**\n * Optional callback to send real time text.\n */\n onSendRealTimeText?: (text: string, isFinalized: boolean) => Promise<void>;\n\n /**\n * Latest local real time text\n */\n latestLocalRealTimeText?: RealTimeTextInformation;\n}\n\nconst SCROLL_OFFSET_ALLOWANCE = 20;\n\n/**\n * @public\n * A component for displaying a CaptionsBanner with user icon, displayName and captions text.\n */\nexport const CaptionsBanner = (props: CaptionsBannerProps): JSX.Element => {\n const {\n captions,\n realTimeTexts,\n isCaptionsOn,\n startCaptionsInProgress,\n onRenderAvatar,\n formFactor = 'default',\n captionsOptions,\n isRealTimeTextOn,\n onSendRealTimeText,\n latestLocalRealTimeText\n } = props;\n const localeStrings = useLocale().strings.captionsBanner;\n const strings = { ...localeStrings, ...props.strings };\n const captionsScrollDivRef = useRef<HTMLDivElement>(null);\n const [isAtBottomOfScroll, setIsAtBottomOfScroll] = useState<boolean>(true);\n const theme = useTheme();\n\n const [expandBannerHeight, setExpandBannerHeight] = useState<boolean>(false);\n const [announcedRTT, setAnnouncedRTT] = useState<number[]>([]);\n const [announcedCaption, setAnnouncedCaption] = useState<string[]>([]);\n const [captionAnnouncementText, setCaptionAnnouncementText] = useState<CaptionsInformation[]>([]);\n const [rttAnnouncementText, setRTTAnnouncementText] = useState<RealTimeTextInformation[]>([]);\n\n const getTitle = (): string => {\n if (isCaptionsOn && isRealTimeTextOn) {\n return strings.captionsAndRealTimeTextContainerTitle ?? '';\n } else if (isCaptionsOn) {\n return strings.captionsOnlyContainerTitle ?? '';\n } else if (isRealTimeTextOn) {\n return strings.realTimeTextOnlyContainerTitle ?? '';\n }\n return '';\n };\n\n // merge realtimetexts and captions into one array based on timestamp\n // Combine captions and realTimeTexts into one list\n const combinedList: (CaptionsInformation | RealTimeTextInformation)[] = useMemo(() => {\n return sortCaptionsAndRealTimeTexts(captions, realTimeTexts?.completedMessages ?? []);\n }, [captions, realTimeTexts?.completedMessages]);\n\n const mergedCaptions: (CaptionsInformation | RealTimeTextInformation)[] = useMemo(() => {\n return [...combinedList, ...(realTimeTexts?.currentInProgress ?? []), realTimeTexts?.myInProgress].slice(-50) as (\n | CaptionsInformation\n | RealTimeTextInformation\n )[];\n }, [combinedList, realTimeTexts]);\n\n const scrollToBottom = (): void => {\n if (captionsScrollDivRef.current) {\n captionsScrollDivRef.current.scrollTop = captionsScrollDivRef.current.scrollHeight;\n }\n };\n\n const handleScrollToTheBottom = useCallback((): void => {\n if (!captionsScrollDivRef.current) {\n return;\n }\n const atBottom =\n Math.ceil(captionsScrollDivRef.current.scrollTop) >=\n captionsScrollDivRef.current.scrollHeight - captionsScrollDivRef.current.clientHeight - SCROLL_OFFSET_ALLOWANCE;\n\n setIsAtBottomOfScroll(atBottom);\n }, []);\n\n useEffect(() => {\n const captionsScrollDiv = captionsScrollDivRef.current;\n captionsScrollDiv?.addEventListener('scroll', handleScrollToTheBottom);\n\n return () => {\n captionsScrollDiv?.removeEventListener('scroll', handleScrollToTheBottom);\n };\n }, [handleScrollToTheBottom, isCaptionsOn, isRealTimeTextOn]);\n\n useEffect(() => {\n // only auto scroll to bottom is already is at bottom of scroll before new caption comes in\n if (isAtBottomOfScroll) {\n scrollToBottom();\n }\n }, [captions, realTimeTexts, isAtBottomOfScroll]);\n\n const [textFieldValue, setTextFieldValue] = useState<string>('');\n\n useEffect(() => {\n // if the latest real time text sent by myself is final, clear the text field\n if (latestLocalRealTimeText && !latestLocalRealTimeText.isTyping) {\n setTextFieldValue('');\n }\n }, [latestLocalRealTimeText]);\n\n useEffect(() => {\n if (realTimeTexts?.completedMessages) {\n //filter out the messages that have already been announced\n const rTTMessagesToAnnounce = realTimeTexts.completedMessages.filter(\n (message) => !announcedRTT.includes(message.id)\n );\n if (rTTMessagesToAnnounce.length > 0) {\n setRTTAnnouncementText(rTTMessagesToAnnounce);\n setAnnouncedRTT((prev) => [...prev, ...rTTMessagesToAnnounce.map((message) => message.id)]);\n }\n }\n if (captions.length > 0) {\n // filter out the captions that have already been announced\n const captionsToAnnounce = captions.filter(\n (caption) => !announcedCaption.includes(caption.id) && caption.isFinalized\n );\n if (captionsToAnnounce.length > 0) {\n setCaptionAnnouncementText(captionsToAnnounce);\n setAnnouncedCaption((prev) => [...prev, ...captionsToAnnounce.map((caption) => caption.id)]);\n }\n }\n }, [captions, realTimeTexts?.completedMessages, announcedRTT, announcedCaption]);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>): void => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (textFieldValue && onSendRealTimeText) {\n onSendRealTimeText(textFieldValue, true);\n setTextFieldValue('');\n }\n }\n };\n\n const realTimeTextDisclosureBannerStrings = {\n bannerTitle: strings.realTimeTextBannerTitle ?? '',\n bannerContent: strings.realTimeTextBannerContent ?? '',\n bannerLinkLabel: strings.realTimeTextBannerLinkLabel ?? ''\n };\n\n const captionsAndRealTimeText = (): JSX.Element => {\n return (\n <>\n {mergedCaptions\n .filter((caption) => caption)\n .map((caption) => {\n if ('message' in caption) {\n return (\n <div\n key={`RealTimeText - ${caption.id}`}\n className={captionContainerClassName}\n data-is-focusable={true}\n >\n <RealTimeText {...(caption as RealTimeTextInformation)} />\n </div>\n );\n }\n return (\n <div key={`Captions - ${caption.id}`} className={captionContainerClassName} data-is-focusable={true}>\n <_Caption {...(caption as CaptionsInformation)} onRenderAvatar={onRenderAvatar} />\n </div>\n );\n })}\n </>\n );\n };\n\n return (\n <>\n {(startCaptionsInProgress || isCaptionsOn || isRealTimeTextOn) && (\n <FocusZone shouldFocusOnMount className={captionsContainerClassName} data-ui-id=\"captions-banner\">\n {/* ARIA live region */}\n {(rttAnnouncementText.length > 0 || captionAnnouncementText?.length > 0) && (\n <div aria-live=\"assertive\" role=\"alert\" aria-atomic=\"true\" className={hiddenAnnouncementClassName}>\n <span>\n {rttAnnouncementText.map((text) => (\n <span>\n {strings.realTimeTextBannerTitle} {text.displayName}: {text.message}\n </span>\n ))}\n </span>\n <span>\n {captionAnnouncementText.map((text) => (\n <span>\n {strings.captionsOnlyContainerTitle} {text.displayName}: {text.captionText}\n </span>\n ))}\n </span>\n </div>\n )}\n\n {(isCaptionsOn || isRealTimeTextOn) && formFactor === 'compact' && (\n <Stack\n horizontal\n horizontalAlign=\"space-between\"\n verticalAlign=\"center\"\n className={bannerTitleContainerClassName}\n >\n <Text className={titleClassName}>{getTitle()}</Text>\n <IconButton\n data-ui-id=\"captions-banner-expand-icon\"\n iconProps={{ iconName: expandBannerHeight ? 'MinimizeIcon' : 'ExpandIcon' }}\n ariaLabel={expandBannerHeight ? strings.minimizeButtonAriaLabel : strings.expandButtonAriaLabel}\n onClick={() => setExpandBannerHeight(!expandBannerHeight)}\n styles={expandIconClassName(theme)}\n />\n </Stack>\n )}\n {(isCaptionsOn || isRealTimeTextOn) && (\n <div\n ref={captionsScrollDivRef}\n className={\n captionsOptions?.height === 'full'\n ? captionsBannerFullHeightClassName(theme)\n : captionsBannerClassName(formFactor, expandBannerHeight)\n }\n data-ui-id=\"captions-banner-inner\"\n data-is-focusable={true}\n >\n {isRealTimeTextOn && (\n <Stack className={rttDisclosureBannerClassName()}>\n <_RTTDisclosureBanner strings={realTimeTextDisclosureBannerStrings} />\n </Stack>\n )}\n {captionsAndRealTimeText()}\n </div>\n )}\n {isRealTimeTextOn && onSendRealTimeText && (\n <TextField\n styles={realTimeTextInputBoxStyles(theme)}\n placeholder={strings.realTimeTextInputBoxDefaultText}\n value={textFieldValue}\n onKeyDown={handleKeyDown}\n onChange={(_, newValue) => {\n setTextFieldValue(newValue || '');\n onSendRealTimeText(newValue || '', false);\n }}\n maxLength={2000}\n errorMessage={textFieldValue.length >= 2000 ? strings.realTimeTextInputErrorMessage : undefined}\n />\n )}\n {!isCaptionsOn && !isRealTimeTextOn && (\n <Stack\n verticalAlign=\"center\"\n styles={\n captionsOptions?.height === 'full'\n ? loadingBannerFullHeightStyles(theme)\n : loadingBannerStyles(formFactor)\n }\n data-is-focusable={true}\n >\n <Spinner label={strings?.captionsBannerSpinnerText} ariaLive=\"assertive\" labelPosition=\"right\" />\n </Stack>\n )}\n </FocusZone>\n )}\n </>\n );\n};\n"]}
1
+ {"version":3,"file":"CaptionsBanner.js","sourceRoot":"","sources":["../../../../../../react-components/src/components/CaptionsBanner.tsx"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,kCAAkC;AAClC,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AACrC,OAAO,EACL,yBAAyB,EACzB,uBAAuB,EACvB,iCAAiC,EACjC,0BAA0B,EAC1B,6BAA6B,EAC7B,mBAAmB,EACpB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,4BAA4B,EAAE,MAAM,yBAAyB,CAAC;AAEvE,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,sCAAsC,CAAC;AACpF,OAAO,EACL,mBAAmB,EACnB,6BAA6B,EAC7B,0BAA0B,EAC3B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,wBAAwB,EAAE,MAAM,2BAA2B,CAAC;AA8LrE,MAAM,uBAAuB,GAAG,EAAE,CAAC;AAEnC;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,KAA0B,EAAe,EAAE;;IACxE,MAAM,EACJ,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,uBAAuB,EACvB,cAAc,EACd,UAAU,GAAG,SAAS,EACtB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,EACxB,GAAG,KAAK,CAAC;IACV,MAAM,aAAa,GAAG,SAAS,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC;IACzD,MAAM,OAAO,mCAAQ,aAAa,GAAK,KAAK,CAAC,OAAO,CAAE,CAAC;IACvD,MAAM,oBAAoB,GAAG,MAAM,CAAiB,IAAI,CAAC,CAAC;IAC1D,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAU,IAAI,CAAC,CAAC;IAC5E,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IAEzB,MAAM,CAAC,kBAAkB,EAAE,qBAAqB,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IAE7E,MAAM,QAAQ,GAAG,GAAW,EAAE;;QAC5B,IAAI,YAAY,IAAI,gBAAgB,EAAE,CAAC;YACrC,OAAO,MAAA,OAAO,CAAC,qCAAqC,mCAAI,EAAE,CAAC;QAC7D,CAAC;aAAM,IAAI,YAAY,EAAE,CAAC;YACxB,OAAO,MAAA,OAAO,CAAC,0BAA0B,mCAAI,EAAE,CAAC;QAClD,CAAC;aAAM,IAAI,gBAAgB,EAAE,CAAC;YAC5B,OAAO,MAAA,OAAO,CAAC,8BAA8B,mCAAI,EAAE,CAAC;QACtD,CAAC;QACD,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;IAEF,qEAAqE;IACrE,mDAAmD;IACnD,MAAM,YAAY,GAAsD,OAAO,CAAC,GAAG,EAAE;;QACnF,OAAO,4BAA4B,CAAC,QAAQ,EAAE,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,iBAAiB,mCAAI,EAAE,CAAC,CAAC;IACxF,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,iBAAiB,CAAC,CAAC,CAAC;IAEjD,MAAM,cAAc,GAAsD,OAAO,CAAC,GAAG,EAAE;;QACrF,OAAO,CAAC,GAAG,YAAY,EAAE,GAAG,CAAC,MAAA,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,iBAAiB,mCAAI,EAAE,CAAC,EAAE,aAAa,aAAb,aAAa,uBAAb,aAAa,CAAE,YAAY,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAGzG,CAAC;IACN,CAAC,EAAE,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC;IAElC,MAAM,cAAc,GAAG,GAAS,EAAE;QAChC,IAAI,oBAAoB,CAAC,OAAO,EAAE,CAAC;YACjC,oBAAoB,CAAC,OAAO,CAAC,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,YAAY,CAAC;QACrF,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,uBAAuB,GAAG,WAAW,CAAC,GAAS,EAAE;QACrD,IAAI,CAAC,oBAAoB,CAAC,OAAO,EAAE,CAAC;YAClC,OAAO;QACT,CAAC;QACD,MAAM,QAAQ,GACZ,IAAI,CAAC,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,SAAS,CAAC;YACjD,oBAAoB,CAAC,OAAO,CAAC,YAAY,GAAG,oBAAoB,CAAC,OAAO,CAAC,YAAY,GAAG,uBAAuB,CAAC;QAElH,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAClC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,iBAAiB,GAAG,oBAAoB,CAAC,OAAO,CAAC;QACvD,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,gBAAgB,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC;QAEvE,OAAO,GAAG,EAAE;YACV,iBAAiB,aAAjB,iBAAiB,uBAAjB,iBAAiB,CAAE,mBAAmB,CAAC,QAAQ,EAAE,uBAAuB,CAAC,CAAC;QAC5E,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,uBAAuB,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC,CAAC;IAE9D,SAAS,CAAC,GAAG,EAAE;QACb,2FAA2F;QAC3F,IAAI,kBAAkB,EAAE,CAAC;YACvB,cAAc,EAAE,CAAC;QACnB,CAAC;IACH,CAAC,EAAE,CAAC,QAAQ,EAAE,aAAa,EAAE,kBAAkB,CAAC,CAAC,CAAC;IAElD,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IAEjE,SAAS,CAAC,GAAG,EAAE;QACb,6EAA6E;QAC7E,IAAI,uBAAuB,IAAI,CAAC,uBAAuB,CAAC,QAAQ,EAAE,CAAC;YACjE,iBAAiB,CAAC,EAAE,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,EAAE,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAE9B,MAAM,aAAa,GAAG,CAAC,KAAkE,EAAQ,EAAE;QACjG,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;YAC1B,KAAK,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,cAAc,IAAI,kBAAkB,EAAE,CAAC;gBACzC,kBAAkB,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC;gBACzC,iBAAiB,CAAC,EAAE,CAAC,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,mCAAmC,GAAG;QAC1C,WAAW,EAAE,MAAA,OAAO,CAAC,uBAAuB,mCAAI,EAAE;QAClD,aAAa,EAAE,MAAA,OAAO,CAAC,yBAAyB,mCAAI,EAAE;QACtD,eAAe,EAAE,MAAA,OAAO,CAAC,2BAA2B,mCAAI,EAAE;KAC3D,CAAC;IAEF,MAAM,uBAAuB,GAAG,GAAgB,EAAE;QAChD,OAAO,CACL,0CACG,cAAc;aACZ,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC;aAC5B,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YACf,IAAI,SAAS,IAAI,OAAO,EAAE,CAAC;gBACzB,OAAO,CACL,6BACE,GAAG,EAAE,kBAAkB,OAAO,CAAC,EAAE,EAAE,EACnC,SAAS,EAAE,yBAAyB,uBACjB,IAAI;oBAEvB,oBAAC,YAAY,oBAAM,OAAmC,EAAI,CACtD,CACP,CAAC;YACJ,CAAC;YACD,OAAO,CACL,6BAAK,GAAG,EAAE,cAAc,OAAO,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,yBAAyB,uBAAqB,IAAI;gBACjG,oBAAC,QAAQ,oBAAM,OAA+B,IAAE,cAAc,EAAE,cAAc,IAAI,CAC9E,CACP,CAAC;QACJ,CAAC,CAAC,CACH,CACJ,CAAC;IACJ,CAAC,CAAC;IAEF,OAAO,CACL,0CACG,CAAC,uBAAuB,IAAI,YAAY,IAAI,gBAAgB,CAAC,IAAI,CAChE,oBAAC,SAAS,IAAC,kBAAkB,QAAC,SAAS,EAAE,0BAA0B,gBAAa,iBAAiB;QAC/F,oBAAC,wBAAwB,IACvB,QAAQ,EAAE,QAAQ,EAClB,aAAa,EAAE,aAAa,EAC5B,iBAAiB,EAAE,MAAA,OAAO,CAAC,uBAAuB,mCAAI,EAAE,EACxD,aAAa,EAAE,MAAA,OAAO,CAAC,0BAA0B,mCAAI,EAAE,GACvD;QACD,CAAC,YAAY,IAAI,gBAAgB,CAAC,IAAI,UAAU,KAAK,SAAS,IAAI,CACjE,oBAAC,KAAK,IACJ,UAAU,QACV,eAAe,EAAC,eAAe,EAC/B,aAAa,EAAC,QAAQ,EACtB,SAAS,EAAE,6BAA6B;YAExC,oBAAC,IAAI,IAAC,SAAS,EAAE,cAAc,IAAG,QAAQ,EAAE,CAAQ;YACpD,oBAAC,UAAU,kBACE,6BAA6B,EACxC,SAAS,EAAE,EAAE,QAAQ,EAAE,kBAAkB,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,EAAE,EAC3E,SAAS,EAAE,kBAAkB,CAAC,CAAC,CAAC,OAAO,CAAC,uBAAuB,CAAC,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAC/F,OAAO,EAAE,GAAG,EAAE,CAAC,qBAAqB,CAAC,CAAC,kBAAkB,CAAC,EACzD,MAAM,EAAE,mBAAmB,CAAC,KAAK,CAAC,GAClC,CACI,CACT;QACA,CAAC,YAAY,IAAI,gBAAgB,CAAC,IAAI,CACrC,6BACE,GAAG,EAAE,oBAAoB,EACzB,SAAS,EACP,CAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,MAAM,MAAK,MAAM;gBAChC,CAAC,CAAC,iCAAiC,CAAC,KAAK,CAAC;gBAC1C,CAAC,CAAC,uBAAuB,CAAC,UAAU,EAAE,kBAAkB,CAAC,gBAElD,uBAAuB,uBACf,IAAI;YAEtB,gBAAgB,IAAI,CACnB,oBAAC,KAAK,IAAC,SAAS,EAAE,4BAA4B,EAAE;gBAC9C,oBAAC,oBAAoB,IAAC,OAAO,EAAE,mCAAmC,GAAI,CAChE,CACT;YACA,uBAAuB,EAAE,CACtB,CACP;QACA,gBAAgB,IAAI,kBAAkB,IAAI,CACzC,oBAAC,SAAS,IACR,MAAM,EAAE,0BAA0B,CAAC,KAAK,CAAC,EACzC,WAAW,EAAE,OAAO,CAAC,+BAA+B,EACpD,KAAK,EAAE,cAAc,EACrB,SAAS,EAAE,aAAa,EACxB,QAAQ,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,EAAE;gBACxB,iBAAiB,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;gBAClC,kBAAkB,CAAC,QAAQ,IAAI,EAAE,EAAE,KAAK,CAAC,CAAC;YAC5C,CAAC,EACD,SAAS,EAAE,IAAI,EACf,YAAY,EAAE,cAAc,CAAC,MAAM,IAAI,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,CAAC,SAAS,GAC/F,CACH;QACA,CAAC,YAAY,IAAI,CAAC,gBAAgB,IAAI,CACrC,oBAAC,KAAK,IACJ,aAAa,EAAC,QAAQ,EACtB,MAAM,EACJ,CAAA,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,MAAM,MAAK,MAAM;gBAChC,CAAC,CAAC,6BAA6B,CAAC,KAAK,CAAC;gBACtC,CAAC,CAAC,mBAAmB,CAAC,UAAU,CAAC,uBAElB,IAAI;YAEvB,oBAAC,OAAO,IAAC,KAAK,EAAE,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,yBAAyB,EAAE,QAAQ,EAAC,WAAW,EAAC,aAAa,EAAC,OAAO,GAAG,CAC3F,CACT,CACS,CACb,CACA,CACJ,CAAC;AACJ,CAAC,CAAC","sourcesContent":["// Copyright (c) Microsoft Corporation.\n// Licensed under the MIT License.\nimport { Stack, FocusZone, Spinner, useTheme } from '@fluentui/react';\nimport { TextField } from '@fluentui/react';\nimport React, { useEffect, useRef, useState, useCallback } from 'react';\nimport { useMemo } from 'react';\nimport { _Caption } from './Caption';\nimport {\n captionContainerClassName,\n captionsBannerClassName,\n captionsBannerFullHeightClassName,\n captionsContainerClassName,\n loadingBannerFullHeightStyles,\n loadingBannerStyles\n} from './styles/Captions.style';\nimport { rttDisclosureBannerClassName } from './styles/Captions.style';\nimport { OnRenderAvatarCallback } from '../types';\nimport { useLocale } from '../localization';\nimport { RealTimeText } from './RealTimeText';\nimport { _RTTDisclosureBanner } from './RTTDisclosureBanner';\nimport { sortCaptionsAndRealTimeTexts } from './utils/sortCaptionsAndRealTimeTexts';\nimport {\n expandIconClassName,\n bannerTitleContainerClassName,\n realTimeTextInputBoxStyles\n} from './styles/Captions.style';\nimport { titleClassName } from './styles/CaptionsSettingsModal.styles';\nimport { Text, IconButton } from '@fluentui/react';\nimport { _CaptionsAndRTTAnnouncer } from './CaptionsAndRTTAnnouncer';\n/**\n * @public\n * information required for each line of caption\n */\nexport type CaptionsInformation = {\n /**\n * unique id for each caption\n */\n id: string;\n /**\n * speaker's display name\n */\n displayName: string;\n /**\n * content of the caption\n */\n captionText: string;\n /**\n * id of the speaker\n */\n userId?: string;\n /**\n * timestamp when the caption was created\n * Please note that this value is essential for determining the order of captions and real time text messages\n * If you are using both captions and real time text, please ensure that the createdTimeStamp is populated\n */\n createdTimeStamp?: Date;\n /**\n * If caption is finalized\n */\n isFinalized?: boolean;\n};\n\n/**\n * @public\n * information required for each line of real time text\n */\nexport type RealTimeTextInformation = {\n /**\n * The id of the real time text.\n */\n id: number;\n /**\n * sender's display name\n */\n displayName: string;\n /**\n * id of the sender\n */\n userId?: string;\n /**\n * The real time text message.\n */\n message: string;\n /**\n * if the real time text received is partial\n */\n isTyping: boolean;\n /**\n * timestamp when the real time text was finalized\n */\n finalizedTimeStamp: Date;\n /**\n * If message originated from the local participant\n * default value is false\n */\n isMe?: boolean;\n};\n/**\n * @public\n * strings for captions banner\n */\nexport interface CaptionsBannerStrings {\n /**\n * Spinner text for captions banner\n */\n captionsBannerSpinnerText?: string;\n\n /**\n * Default text for RTT input text box\n */\n realTimeTextInputBoxDefaultText?: string;\n\n /**\n * Error message for RTT input text box when the size exceeds the limit 2000\n */\n realTimeTextInputErrorMessage?: string;\n\n /**\n * Real time text disclosure banner title\n */\n realTimeTextBannerTitle?: string;\n\n /**\n * Real time text disclosure banner content\n */\n realTimeTextBannerContent?: string;\n\n /**\n * Real time text disclosure banner link label\n */\n realTimeTextBannerLinkLabel?: string;\n\n /**\n * Title for the container when only captions is enabled\n */\n captionsOnlyContainerTitle?: string;\n /**\n * Title for the container when only real time text is enabled\n */\n realTimeTextOnlyContainerTitle?: string;\n /**\n * Title for the container when both captions and real time text is enabled\n */\n captionsAndRealTimeTextContainerTitle?: string;\n /**\n * Expand button aria label\n */\n expandButtonAriaLabel?: string;\n /**\n * Minimize button aria label\n */\n minimizeButtonAriaLabel?: string;\n}\n\n/**\n * @public\n * CaptionsBanner Component Props.\n */\nexport interface CaptionsBannerProps {\n /**\n * Array of captions to be displayed\n */\n captions: CaptionsInformation[];\n /**\n * Array of finalized and partial real time text messages\n */\n realTimeTexts?: {\n completedMessages?: RealTimeTextInformation[];\n currentInProgress?: RealTimeTextInformation[];\n myInProgress?: RealTimeTextInformation;\n };\n /**\n * Flag to indicate if captions are on\n */\n isCaptionsOn?: boolean;\n\n /**\n * Flag to indicate if real time text is on\n */\n isRealTimeTextOn?: boolean;\n /**\n * Flag to indicate if captions are being started\n * This is used to show spinner while captions are being started\n */\n startCaptionsInProgress?: boolean;\n /**\n * Optional callback to override render of the avatar.\n *\n * @param userId - user Id\n */\n onRenderAvatar?: OnRenderAvatarCallback;\n /**\n * Optional strings for the component\n */\n strings?: CaptionsBannerStrings;\n /**\n * Optional form factor for the component.\n * @defaultValue 'default'\n */\n formFactor?: 'default' | 'compact';\n /**\n * Optional options for the component.\n */\n captionsOptions?: {\n height: 'full' | 'default';\n };\n\n /**\n * Optional callback to send real time text.\n */\n onSendRealTimeText?: (text: string, isFinalized: boolean) => Promise<void>;\n\n /**\n * Latest local real time text\n */\n latestLocalRealTimeText?: RealTimeTextInformation;\n}\n\nconst SCROLL_OFFSET_ALLOWANCE = 20;\n\n/**\n * @public\n * A component for displaying a CaptionsBanner with user icon, displayName and captions text.\n */\nexport const CaptionsBanner = (props: CaptionsBannerProps): JSX.Element => {\n const {\n captions,\n realTimeTexts,\n isCaptionsOn,\n startCaptionsInProgress,\n onRenderAvatar,\n formFactor = 'default',\n captionsOptions,\n isRealTimeTextOn,\n onSendRealTimeText,\n latestLocalRealTimeText\n } = props;\n const localeStrings = useLocale().strings.captionsBanner;\n const strings = { ...localeStrings, ...props.strings };\n const captionsScrollDivRef = useRef<HTMLDivElement>(null);\n const [isAtBottomOfScroll, setIsAtBottomOfScroll] = useState<boolean>(true);\n const theme = useTheme();\n\n const [expandBannerHeight, setExpandBannerHeight] = useState<boolean>(false);\n\n const getTitle = (): string => {\n if (isCaptionsOn && isRealTimeTextOn) {\n return strings.captionsAndRealTimeTextContainerTitle ?? '';\n } else if (isCaptionsOn) {\n return strings.captionsOnlyContainerTitle ?? '';\n } else if (isRealTimeTextOn) {\n return strings.realTimeTextOnlyContainerTitle ?? '';\n }\n return '';\n };\n\n // merge realtimetexts and captions into one array based on timestamp\n // Combine captions and realTimeTexts into one list\n const combinedList: (CaptionsInformation | RealTimeTextInformation)[] = useMemo(() => {\n return sortCaptionsAndRealTimeTexts(captions, realTimeTexts?.completedMessages ?? []);\n }, [captions, realTimeTexts?.completedMessages]);\n\n const mergedCaptions: (CaptionsInformation | RealTimeTextInformation)[] = useMemo(() => {\n return [...combinedList, ...(realTimeTexts?.currentInProgress ?? []), realTimeTexts?.myInProgress].slice(-50) as (\n | CaptionsInformation\n | RealTimeTextInformation\n )[];\n }, [combinedList, realTimeTexts]);\n\n const scrollToBottom = (): void => {\n if (captionsScrollDivRef.current) {\n captionsScrollDivRef.current.scrollTop = captionsScrollDivRef.current.scrollHeight;\n }\n };\n\n const handleScrollToTheBottom = useCallback((): void => {\n if (!captionsScrollDivRef.current) {\n return;\n }\n const atBottom =\n Math.ceil(captionsScrollDivRef.current.scrollTop) >=\n captionsScrollDivRef.current.scrollHeight - captionsScrollDivRef.current.clientHeight - SCROLL_OFFSET_ALLOWANCE;\n\n setIsAtBottomOfScroll(atBottom);\n }, []);\n\n useEffect(() => {\n const captionsScrollDiv = captionsScrollDivRef.current;\n captionsScrollDiv?.addEventListener('scroll', handleScrollToTheBottom);\n\n return () => {\n captionsScrollDiv?.removeEventListener('scroll', handleScrollToTheBottom);\n };\n }, [handleScrollToTheBottom, isCaptionsOn, isRealTimeTextOn]);\n\n useEffect(() => {\n // only auto scroll to bottom is already is at bottom of scroll before new caption comes in\n if (isAtBottomOfScroll) {\n scrollToBottom();\n }\n }, [captions, realTimeTexts, isAtBottomOfScroll]);\n\n const [textFieldValue, setTextFieldValue] = useState<string>('');\n\n useEffect(() => {\n // if the latest real time text sent by myself is final, clear the text field\n if (latestLocalRealTimeText && !latestLocalRealTimeText.isTyping) {\n setTextFieldValue('');\n }\n }, [latestLocalRealTimeText]);\n\n const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>): void => {\n if (event.key === 'Enter') {\n event.preventDefault();\n if (textFieldValue && onSendRealTimeText) {\n onSendRealTimeText(textFieldValue, true);\n setTextFieldValue('');\n }\n }\n };\n\n const realTimeTextDisclosureBannerStrings = {\n bannerTitle: strings.realTimeTextBannerTitle ?? '',\n bannerContent: strings.realTimeTextBannerContent ?? '',\n bannerLinkLabel: strings.realTimeTextBannerLinkLabel ?? ''\n };\n\n const captionsAndRealTimeText = (): JSX.Element => {\n return (\n <>\n {mergedCaptions\n .filter((caption) => caption)\n .map((caption) => {\n if ('message' in caption) {\n return (\n <div\n key={`RealTimeText - ${caption.id}`}\n className={captionContainerClassName}\n data-is-focusable={true}\n >\n <RealTimeText {...(caption as RealTimeTextInformation)} />\n </div>\n );\n }\n return (\n <div key={`Captions - ${caption.id}`} className={captionContainerClassName} data-is-focusable={true}>\n <_Caption {...(caption as CaptionsInformation)} onRenderAvatar={onRenderAvatar} />\n </div>\n );\n })}\n </>\n );\n };\n\n return (\n <>\n {(startCaptionsInProgress || isCaptionsOn || isRealTimeTextOn) && (\n <FocusZone shouldFocusOnMount className={captionsContainerClassName} data-ui-id=\"captions-banner\">\n <_CaptionsAndRTTAnnouncer\n captions={captions}\n realTimeTexts={realTimeTexts}\n realTimeTextTitle={strings.realTimeTextBannerTitle ?? ''}\n captionsTitle={strings.captionsOnlyContainerTitle ?? ''}\n />\n {(isCaptionsOn || isRealTimeTextOn) && formFactor === 'compact' && (\n <Stack\n horizontal\n horizontalAlign=\"space-between\"\n verticalAlign=\"center\"\n className={bannerTitleContainerClassName}\n >\n <Text className={titleClassName}>{getTitle()}</Text>\n <IconButton\n data-ui-id=\"captions-banner-expand-icon\"\n iconProps={{ iconName: expandBannerHeight ? 'MinimizeIcon' : 'ExpandIcon' }}\n ariaLabel={expandBannerHeight ? strings.minimizeButtonAriaLabel : strings.expandButtonAriaLabel}\n onClick={() => setExpandBannerHeight(!expandBannerHeight)}\n styles={expandIconClassName(theme)}\n />\n </Stack>\n )}\n {(isCaptionsOn || isRealTimeTextOn) && (\n <div\n ref={captionsScrollDivRef}\n className={\n captionsOptions?.height === 'full'\n ? captionsBannerFullHeightClassName(theme)\n : captionsBannerClassName(formFactor, expandBannerHeight)\n }\n data-ui-id=\"captions-banner-inner\"\n data-is-focusable={true}\n >\n {isRealTimeTextOn && (\n <Stack className={rttDisclosureBannerClassName()}>\n <_RTTDisclosureBanner strings={realTimeTextDisclosureBannerStrings} />\n </Stack>\n )}\n {captionsAndRealTimeText()}\n </div>\n )}\n {isRealTimeTextOn && onSendRealTimeText && (\n <TextField\n styles={realTimeTextInputBoxStyles(theme)}\n placeholder={strings.realTimeTextInputBoxDefaultText}\n value={textFieldValue}\n onKeyDown={handleKeyDown}\n onChange={(_, newValue) => {\n setTextFieldValue(newValue || '');\n onSendRealTimeText(newValue || '', false);\n }}\n maxLength={2000}\n errorMessage={textFieldValue.length >= 2000 ? strings.realTimeTextInputErrorMessage : undefined}\n />\n )}\n {!isCaptionsOn && !isRealTimeTextOn && (\n <Stack\n verticalAlign=\"center\"\n styles={\n captionsOptions?.height === 'full'\n ? loadingBannerFullHeightStyles(theme)\n : loadingBannerStyles(formFactor)\n }\n data-is-focusable={true}\n >\n <Spinner label={strings?.captionsBannerSpinnerText} ariaLive=\"assertive\" labelPosition=\"right\" />\n </Stack>\n )}\n </FocusZone>\n )}\n </>\n );\n};\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@azure/communication-react",
3
- "version": "1.29.0-alpha-202506180019",
3
+ "version": "1.29.0-alpha-202506190019",
4
4
  "sideEffects": false,
5
5
  "description": "React library for building modern communication user experiences utilizing Azure Communication Services",
6
6
  "keywords": [
@@ -56,7 +56,7 @@
56
56
  },
57
57
  "peerDependencies": {
58
58
  "@azure/communication-calling-effects": "^1.1.4",
59
- "@azure/communication-calling": "1.36.3-beta.1",
59
+ "@azure/communication-calling": "1.37.1-beta.1",
60
60
  "@azure/communication-chat": "1.6.0-beta.7",
61
61
  "@types/react": ">=16.8.0 <19.0.0",
62
62
  "@types/react-dom": ">=16.8.0 <19.0.0",